Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / xcp.c @ d7238092

History | View | Annotate | Download (52.263 KB)

1
/************************************************************************************//**
2
* \file         Source\xcp.c
3
* \brief        XCP 1.0 protocol core source file.
4
* \ingroup      Core
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2011  by Feaser    http://www.feaser.com    All rights reserved
10
*
11
*----------------------------------------------------------------------------------------
12
*                            L I C E N S E
13
*----------------------------------------------------------------------------------------
14
* This file is part of OpenBLT. OpenBLT is free software: you can redistribute it and/or
15
* modify it under the terms of the GNU General Public License as published by the Free
16
* Software Foundation, either version 3 of the License, or (at your option) any later
17
* version.
18
*
19
* OpenBLT is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
20
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21
* PURPOSE. See the GNU General Public License for more details.
22
*
23
* You should have received a copy of the GNU General Public License along with OpenBLT.
24
* If not, see <http://www.gnu.org/licenses/>.
25
*
26
* A special exception to the GPL is included to allow you to distribute a combined work
27
* that includes OpenBLT without being obliged to provide the source code for any
28
* proprietary components. The exception text is included at the bottom of the license
29
* file <license.html>.
30
*
31
* \endinternal
32
****************************************************************************************/
33

    
34
/****************************************************************************************
35
* Include files
36
****************************************************************************************/
37
#include "boot.h"                                /* bootloader generic header          */
38

    
39
#include <helper.h>
40

    
41
/****************************************************************************************
42
* Defines
43
****************************************************************************************/
44
/** \brief XCP protocol layer version number (16-bit). */
45
#define XCP_VERSION_PROTOCOL_LAYER  (0x0100)
46

    
47
/** \brief XCP transport layer version number (16-bit). */
48
#define XCP_VERSION_TRANSPORT_LAYER (0x0100)
49

    
50
/* XCP packet identifiers */
51
/** \brief Command response packet identifier. */
52
#define XCP_PID_RES                 (0xff)
53
/** \brief Error packet identifier. */
54
#define XCP_PID_ERR                 (0xfe)
55

    
56
/* XCP error codes */
57
/** \brief Cmd processor synchronization error code. */
58
#define XCP_ERR_CMD_SYNCH           (0x00)
59
/** \brief Command was not executed error code. */
60
#define XCP_ERR_CMD_BUSY            (0x10)
61
/** \brief Unknown or unsupported command error code. */
62
#define XCP_ERR_CMD_UNKNOWN         (0x20)
63
/** \brief Parameter out of range error code. */
64
#define XCP_ERR_OUT_OF_RANGE        (0x22)
65
/** \brief Protected error code. Seed/key required. */
66
#define XCP_ERR_ACCESS_LOCKED       (0x25)
67
/** \brief Cal page not valid error code. */
68
#define XCP_ERR_PAGE_NOT_VALID      (0x26)
69
/** \brief Sequence error code. */
70
#define XCP_ERR_SEQUENCE            (0x29)
71
/** \brief Generic error code. */
72
#define XCP_ERR_GENERIC             (0x31)
73

    
74
/* XCP command codes */
75
/** \brief CONNECT command code. */
76
#define XCP_CMD_CONNECT             (0xff)
77
/** \brief DISCONNECT command code. */
78
#define XCP_CMD_DISCONNECT          (0xfe)
79
/** \brief GET_STATUS command code. */
80
#define XCP_CMD_GET_STATUS          (0xfd)
81
/** \brief SYNCH command code. */
82
#define XCP_CMD_SYNCH               (0xfc)
83
/** \brief GET_ID command code. */
84
#define XCP_CMD_GET_ID              (0xfa)
85
/** \brief GET_SEED command code. */
86
#define XCP_CMD_GET_SEED            (0xf8)
87
/** \brief UNLOCK command code. */
88
#define XCP_CMD_UNLOCK              (0xf7)
89
/** \brief SET_MTA command code. */
90
#define XCP_CMD_SET_MTA             (0xf6)
91
/** \brief UPLOAD command code. */
92
#define XCP_CMD_UPLOAD              (0xf5)
93
/** \brief SHORT_UPLOAD command code. */
94
#define XCP_CMD_SHORT_UPLOAD        (0xf4)
95
/** \brief BUILD_CHECKSUM command code. */
96
#define XCP_CMD_BUILD_CHECKSUM      (0xf3)
97
/** \brief DOWNLOAD command code. */
98
#define XCP_CMD_DOWNLOAD            (0xf0)
99
/** \brief DOWNLOAD_MAX command code. */
100
#define XCP_CMD_DOWLOAD_MAX         (0xee)
101
/** \brief SET_CALPAGE command code. */
102
#define XCP_CMD_SET_CAL_PAGE        (0xeb)
103
/** \brief GET_CALPAGE command code. */
104
#define XCP_CMD_GET_CAL_PAGE        (0xea)
105
/** \brief PROGRAM_START command code. */
106
#define XCP_CMD_PROGRAM_START       (0xd2)
107
/** \brief PROGRAM_CLEAR command code. */
108
#define XCP_CMD_PROGRAM_CLEAR       (0xd1)
109
/** \brief PROGRAM command code. */
110
#define XCP_CMD_PROGRAM             (0xd0)
111
/** \brief PROGRAM_RESET command code. */
112
#define XCP_CMD_PROGRAM_RESET       (0xcf)
113
/** \brief PROGRAM_PREPARE command code. */
114
#define XCP_CMD_PROGRAM_PREPARE     (0xcc)
115
/** \brief PROGRAM_MAX command code. */
116
#define XCP_CMD_PROGRAM_MAX         (0xc9)
117

    
118

    
119
/****************************************************************************************
120
* Type definitions
121
****************************************************************************************/
122
/** \brief Struture type for grouping XCP internal module information. */
123
typedef struct
124
{
125
  blt_int8u  connected;                             /**< connection established                      */
126
#if (BOOT_GATE_ENABLE > 0)
127
  blt_int32u  other_connection;                      /**< connection to other device established      */
128
#endif
129
#if (BOOTLOADER_OF_MAIN_DEVICE > 0)
130
  blt_bool   wasMainConnection;                     /**< connection to serialboot (0x00) established */
131
#endif
132
  blt_int8u  oldData[BOOT_COM_RX_MAX_DATA];         /**< old packet data buffer                      */
133
  blt_int8u  protection;                            /**< protection state                            */
134
  blt_int8u  s_n_k_resource;                        /**< for seed/key sequence                       */
135
  blt_int8u  ctoData[BOOT_COM_RX_MAX_DATA];         /**< cto packet data buffer                      */
136
  blt_int8u  ctoPending;                            /**< cto transmission pending flag               */
137
  blt_int16s ctoLen;                                /**< cto current packet length                   */
138
  blt_int32u mta;                                   /**< memory transfer address                     */
139
} tXcpInfo;
140

    
141

    
142
/****************************************************************************************
143
* Function prototypes
144
****************************************************************************************/
145
/* transport layer specific functions */
146
#if (BOOT_GATE_ENABLE > 0)
147
static void      XcpTransmitPacket(blt_int8u *data, blt_int16s len, blt_bool fromGate);
148
#else
149
static void      XcpTransmitPacket(blt_int8u *data, blt_int16s len);
150
#endif /* BOOT_GATE_ENABLE > 0 */
151

    
152
/* application specific functions */
153
static blt_int8u XcpComputeChecksum(blt_int32u address, blt_int32u length,
154
                                    blt_int32u *checksum);
155

    
156
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
157
static blt_int8u XcpGetSeed(blt_int8u resource, blt_int8u *seed);
158
static blt_int8u XcpVerifyKey(blt_int8u resource, blt_int8u *key, blt_int8u len);
159
#endif
160

    
161
/* general utility functions */
162
static void XcpProtectResources(void);
163
static void XcpSetCtoError(blt_int8u error);
164

    
165
/* XCP command processors */
166
static void XcpCmdConnect(blt_int8u *data, blt_int16s dataLength);
167
static void XcpCmdDisconnect(blt_int8u *data);
168
static void XcpCmdGetStatus(blt_int8u *data);
169
static void XcpCmdSynch(blt_int8u *data);
170
static void XcpCmdGetId(blt_int8u *data);
171
static void XcpCmdSetMta(blt_int8u *data);
172
static void XcpCmdUpload(blt_int8u *data);
173
static void XcpCmdShortUpload(blt_int8u *data);
174
static void XcpCmdBuildCheckSum(blt_int8u *data);
175
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
176
static void XcpCmdGetSeed(blt_int8u *data);
177
static void XcpCmdUnlock(blt_int8u *data);
178
#endif
179
#if (XCP_RES_CALIBRATION_EN == 1)
180
static void XcpCmdDownload(blt_int8u *data);
181
static void XcpCmdDownloadMax(blt_int8u *data);
182
#endif
183
#if (XCP_RES_PAGING_EN == 1)
184
static void XcpCmdSetCalPage(blt_int8u *data);
185
static void XcpCmdGetCalPage(blt_int8u *data);
186
#endif
187
#if (XCP_RES_PROGRAMMING_EN == 1)
188
static void XcpCmdProgramMax(blt_int8u *data);
189
static void XcpCmdProgram(blt_int8u *data);
190
static void XcpCmdProgramStart(blt_int8u *data);
191
static void XcpCmdProgramClear(blt_int8u *data);
192
static void XcpCmdProgramReset(blt_int8u *data);
193
static void XcpCmdProgramPrepare(blt_int8u *data);
194
#endif
195
static void portedTransmission(blt_int8u *data);
196

    
197

    
198
/****************************************************************************************
199
* Hook functions
200
****************************************************************************************/
201
#if (XCP_RES_PAGING_EN == 1)
202
extern blt_int8u XcpCalSetPageHook(blt_int8u segment, blt_int8u page);
203
extern blt_int8u XcpCalGetPageHook(blt_int8u segment);
204
#endif
205

    
206
#if (XCP_CONNECT_MODE_HOOK_EN == 1)
207
extern blt_bool XcpConnectModeHook(blt_int8u mode);
208
#endif
209

    
210
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
211
extern blt_int8u XcpGetSeedHook(blt_int8u resource, blt_int8u *seed);
212
extern blt_int8u XcpVerifyKeyHook(blt_int8u resource, blt_int8u *key, blt_int8u len);
213
#endif
214

    
215

    
216

    
217
/****************************************************************************************
218
* External functions
219
****************************************************************************************/
220
#if (BOOT_COM_ENABLE == 0)
221
/* in case no internally supported communication interface is used, a custom
222
 * communication module can be added. In order to use the XCP protocol in the custom
223
 * communication module, this hook function needs to be implemented. In the XCP protocol
224
 * is not needed, then simply remove the xcp.c source from the project.
225
 */
226
extern void XcpTransmitPacketHook(blt_int8u *data, blt_int16u len);
227
#endif
228

    
229

    
230
/****************************************************************************************
231
* Local constants
232
****************************************************************************************/
233
/** \brief String buffer with station id. */
234
static const blt_int8s xcpStationId[] = XCP_STATION_ID_STRING;
235

    
236

    
237
/****************************************************************************************
238
* Local data definitions
239
****************************************************************************************/
240
/** \brief Local variable for storing XCP internal module info. */
241
static tXcpInfo xcpInfo;
242

    
243

    
244
/************************************************************************************//**
245
** \brief     Initializes the XCP driver. Should be called once upon system startup.
246
** \return    none
247
**
248
****************************************************************************************/
249
void XcpInit(void)
250
{
251
  /* reset xcp module info */
252
  xcpInfo.connected = 0;
253
#if (BOOT_GATE_ENABLE > 0)
254
  xcpInfo.other_connection = 0;
255
#endif
256
#if (BOOTLOADER_OF_MAIN_DEVICE > 0)
257
  xcpInfo.wasMainConnection = BLT_FALSE;
258
#endif
259
  xcpInfo.mta = 0;
260
  xcpInfo.ctoPending = 0;
261
  xcpInfo.ctoLen = 0;
262
  xcpInfo.s_n_k_resource = 0;
263
  xcpInfo.protection = 0;
264
} /*** end of XcpInit ***/
265

    
266

    
267
/************************************************************************************//**
268
** \brief     Obtains information about the XCP connection state.
269
** \return    BLT_TRUE is an XCP connection is established, BLT_FALSE otherwise.
270
**
271
****************************************************************************************/
272
blt_bool XcpIsConnected(void)
273
{
274
#if (BOOT_GATE_ENABLE > 0)
275
  if (xcpInfo.connected == 0 && xcpInfo.other_connection == 0)
276
#else
277
  if (xcpInfo.connected == 0)
278
#endif
279
  {
280
    return BLT_FALSE;
281
  }
282
  return BLT_TRUE;
283
} /*** end of XcpIsConnected ***/
284

    
285

    
286
#if (BOOTLOADER_OF_MAIN_DEVICE > 0)
287
/************************************************************************************//**
288
** \brief     Obtains information about the XCP main connection state.
289
** \return    BLT_TRUE is an XCP connection to main was established, BLT_FALSE otherwise.
290
**
291
****************************************************************************************/
292
blt_bool XcpWasConnectedToMain(void)
293
{
294
  return xcpInfo.wasMainConnection;
295
} /*** end of XcpWasConnectedToMain ***/
296
#endif
297

    
298

    
299
/************************************************************************************//**
300
** \brief     Informs the core that a pending packet transmission was completed by
301
**            the transport layer.
302
** \return    none
303
**
304
****************************************************************************************/
305
void XcpPacketTransmitted(void)
306
{
307
  /* reset packet transmission pending flag */
308
  xcpInfo.ctoPending = 0;
309
} /*** end of XcpPacketTransmitted ***/
310

    
311

    
312
/************************************************************************************//**
313
** \brief     Informs the core that a new packet was received by the transport layer.
314
** \param     data       Pointer to byte buffer with packet data.
315
** \param     dataLength Number of data bytes that need to be transmitted.
316
** \return    none
317
**
318
****************************************************************************************/
319
#if (BOOT_GATE_ENABLE > 0)
320
void XcpPacketReceived(blt_int8u *data, blt_int16s dataLength, blt_bool fromGate)
321
#else
322
void XcpPacketReceived(blt_int8u *data, blt_int16s dataLength)
323
#endif /* BOOT_GATE_ENABLE > 0 */
324
{
325
  /* was this a connect command? */
326
  if (data[0] == XCP_CMD_CONNECT)
327
  {
328
    /* process the connect command */
329
    XcpCmdConnect(data, dataLength);
330
  }
331
  /* only continue if connected */
332
  else if (xcpInfo.connected == 1)
333
  {
334
    switch (data[0])
335
    {
336
      case XCP_CMD_UPLOAD:
337
        XcpCmdUpload(data);
338
        break;
339
      case XCP_CMD_SHORT_UPLOAD:
340
        XcpCmdShortUpload(data);
341
        break;
342
      case XCP_CMD_SET_MTA:
343
        XcpCmdSetMta(data);
344
        break;
345
      case XCP_CMD_BUILD_CHECKSUM:
346
        XcpCmdBuildCheckSum(data);
347
        break;
348
      case XCP_CMD_GET_ID:
349
        XcpCmdGetId(data);
350
        break;
351
      case XCP_CMD_SYNCH:
352
        XcpCmdSynch(data);
353
        break;
354
      case XCP_CMD_GET_STATUS:
355
        XcpCmdGetStatus(data);
356
        break;
357
      case XCP_CMD_DISCONNECT:
358
        XcpCmdDisconnect(data);
359
        break;
360
#if (XCP_RES_CALIBRATION_EN == 1)
361
      case XCP_CMD_DOWNLOAD:
362
        XcpCmdDownload(data);
363
        break;
364
      case XCP_CMD_DOWLOAD_MAX:
365
        XcpCmdDownloadMax(data);
366
        break;
367
#endif
368
#if (XCP_RES_PROGRAMMING_EN == 1)
369
      case XCP_CMD_PROGRAM_MAX:
370
        XcpCmdProgramMax(data);
371
        break;
372
      case XCP_CMD_PROGRAM:
373
        XcpCmdProgram(data);
374
        break;
375
      case XCP_CMD_PROGRAM_START:
376
        XcpCmdProgramStart(data);
377
        break;
378
      case XCP_CMD_PROGRAM_CLEAR:
379
        XcpCmdProgramClear(data);
380
        break;
381
      case XCP_CMD_PROGRAM_RESET:
382
        XcpCmdProgramReset(data);
383
        break;
384
      case XCP_CMD_PROGRAM_PREPARE:
385
        XcpCmdProgramPrepare(data);
386
        break;
387
#endif
388
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
389
      case XCP_CMD_GET_SEED:
390
        XcpCmdGetSeed(data);
391
        break;
392
      case XCP_CMD_UNLOCK:
393
        XcpCmdUnlock(data);
394
        break;
395
#endif
396
#if (XCP_RES_PAGING_EN == 1)
397
      case XCP_CMD_SET_CAL_PAGE:
398
        XcpCmdSetCalPage(data);
399
        break;
400
      case XCP_CMD_GET_CAL_PAGE:
401
        XcpCmdGetCalPage(data);
402
        break;
403
#endif
404
      default:
405
        XcpSetCtoError(XCP_ERR_CMD_UNKNOWN);
406
        break;
407
    }
408
  }
409
#if (BOOT_GATE_ENABLE > 0)
410
  /* check if there is still an other connection */
411
  else if (xcpInfo.other_connection > 0) {
412
    /* Forwarding message */
413
    XcpPacketReceivedForwarding(data, dataLength);
414
    return;
415
  }
416
#endif /* (BOOT_GATE_ENABLE > 0) */
417
  else
418
  {
419
    /* return to make sure response packet is not send because we are not connected */
420
    return;
421
  }
422

    
423
  /* make sure the previous command was completed */
424
  if (xcpInfo.ctoPending == 1)
425
  {
426
    /* command overrun occurred */
427
    XcpSetCtoError(XCP_ERR_CMD_BUSY);
428
  }
429

    
430
  /* send the response if it contains something */
431
  if (xcpInfo.ctoLen > 0)
432
  {
433
    /* set cto packet transmission pending flag */
434
    xcpInfo.ctoPending = 1;
435

    
436
    /* transmit the cto response packet */
437
#if (BOOT_GATE_ENABLE > 0)
438
    XcpTransmitPacket(xcpInfo.ctoData, xcpInfo.ctoLen, fromGate);
439
#else
440
    XcpTransmitPacket(xcpInfo.ctoData, xcpInfo.ctoLen);
441
#endif /* BOOT_GATE_ENABLE > 0 */
442
  }
443

    
444
} /*** end of XcpPacketReceived ***/
445

    
446

    
447

    
448
#if (BOOT_GATE_ENABLE > 0)
449
/************************************************************************************//**
450
** \brief     Forwards the packet to other device.
451
** \param     data       Pointer to the byte buffer with packet data.
452
** \param     dataLength Number of data bytes that need to be transmitted.
453
** \return    none
454
**
455
****************************************************************************************/
456
void XcpPacketReceivedForwarding(blt_int8u *data, blt_int16s dataLength) {
457
  /* save id of connected device */
458
  blt_int32u connectionTo = xcpInfo.other_connection;
459

    
460
  /* proof commands */
461
  switch (data[0]) {
462
    /* if there is a disconnection command, everything else in xcp info
463
     * has to be set on disconnection
464
     */
465
    case XCP_CMD_DISCONNECT:
466
      xcpInfo.other_connection = 0;
467
      xcpInfo.connected = 0;
468
      setLed(0);
469
      break;
470
    /* if there is a reset command, it has to be handled like a disconnection
471
     * (above) because other devices shouldn't get the ability to reset
472
     * themselves alone without any general reset command to all devices
473
     */
474
    case XCP_CMD_PROGRAM_RESET:
475
      xcpInfo.other_connection = 0;
476
      xcpInfo.connected = 0;
477
      setLed(0);
478
      data[0] = XCP_CMD_DISCONNECT;
479
      break;
480
    default:
481
      break;
482
  }
483

    
484
  xcpInfo.ctoPending = 1;
485
#if (BOOT_DEBUGGING_UART2_ENABLE > 0)
486
  /* send debugging information */
487
  BuildData(&debugDataTCan, data, (blt_int8u)dataLength);
488
#endif
489
  /* send packet direct with CAN */
490
  GateTransmitPacketDirect(data, (blt_int8u)dataLength, connectionTo);
491
} /*** end of XcpPacketReceivedForwarding ***/
492

    
493

    
494
/************************************************************************************//**
495
** \brief     Transmits the packet from gateway to com.
496
** \param     data       Pointer to the byte buffer with packet data.
497
** \param     dataLength Number of data bytes that need to be transmitted.
498
** \return    none
499
**
500
****************************************************************************************/
501
void XcpGatewayPacketReceived(blt_int8u *data, blt_int16s dataLength) {
502
  xcpInfo.ctoPending = 1;
503
#if (BOOT_DEBUGGING_UART2_ENABLE > 0)
504
  /* send debugging information */
505
  BuildData(&debugDataRCan, data, (blt_int8u)dataLength);
506
#endif
507
  /* send packet direct with UART */
508
  ComTransmitPacketDirect(data, (blt_int8u)dataLength);
509
} /*** end of XcpGatewayPacketReceived ***/
510

    
511
#endif /* (BOOT_GATE_ENABLE > 0) */
512

    
513

    
514

    
515
/************************************************************************************//**
516
** \brief     Transmits the packet using the xcp transport layer.
517
** \param     data Pointer to the byte buffer with packet data.
518
** \param     len  Number of data bytes that need to be transmitted.
519
** \return    none
520
**
521
****************************************************************************************/
522

    
523
#if (BOOT_GATE_ENABLE > 0)
524
static void XcpTransmitPacket(blt_int8u *data, blt_int16s len, blt_bool fromGate)
525
#else
526
static void XcpTransmitPacket(blt_int8u *data, blt_int16s len)
527
#endif /* BOOT_GATE_ENABLE > 0 */
528
{
529
  /* submit packet to the communication interface for transmission */
530
#if (BOOT_GATE_ENABLE > 0)
531
  if (fromGate == BLT_TRUE) {
532
    GateTransmitPacket(data, len);
533
    return;
534
  }
535
#endif /* BOOT_GATE_ENABLE > 0 */
536
#if (BOOT_COM_ENABLE == 0)
537
  XcpTransmitPacketHook(data, len);
538
#else
539
  ComTransmitPacket(data, len);
540
#endif
541

    
542
} /*** end of XcpTransmitPacket ***/
543

    
544

    
545
/************************************************************************************//**
546
** \brief     Called by the BUILD_CHECKSUM command to perform a checksum calculation
547
**            over the specified memory region.
548
** \param     address   The start address of the memory region.
549
** \param     length    Length of the memory region in bytes.
550
** \param     checksum  Pointer to where the calculated checksum is to be stored.
551
** \return    Checksum type that was used during the checksum calculation.
552
**
553
****************************************************************************************/
554
static blt_int8u XcpComputeChecksum(blt_int32u address, blt_int32u length,
555
                                    blt_int32u *checksum)
556
{
557
  blt_int8u cs = 0;
558

    
559
  /* this example computes the checksum using the add byte to byte algorithm */
560
  while (length-- > 0)
561
  {
562
    cs += *((blt_int8u*)(blt_addr)address);
563
    address++;
564
  }
565

    
566
  *checksum = cs;
567

    
568
  return XCP_CS_ADD11;
569
} /*** end of XcpComputeChecksum ***/
570

    
571

    
572
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
573
/************************************************************************************//**
574
** \brief     Provides a seed to the XCP master that will be used for the key
575
**            generation when the master attempts to unlock the specified resource.
576
**            Called by the GET_SEED command.
577
** \param     resource  Resource that the seed if requested for (XCP_RES_XXX).
578
** \param     seed      Pointer to byte buffer wher the seed will be stored.
579
** \return    Length of the seed in bytes.
580
**
581
****************************************************************************************/
582
static blt_int8u XcpGetSeed(blt_int8u resource, blt_int8u *seed)
583
{
584
  /* pass request on to the application through a hook function */
585
  return XcpGetSeedHook(resource, seed);
586
} /*** end of XcpGetSeed ***/
587

    
588

    
589
/************************************************************************************//**
590
** \brief     Called by the UNLOCK command and checks if the key to unlock the
591
**            specified resource was correct. If so, then the resource protection
592
**            will be removed.
593
** \param     resource  resource to unlock (XCP_RES_XXX).
594
** \param     key       pointer to the byte buffer holding the key.
595
** \param     len       length of the key in bytes.
596
** \return    1 if the key was correct, 0 otherwise.
597
**
598
****************************************************************************************/
599
static blt_int8u XcpVerifyKey(blt_int8u resource, blt_int8u *key, blt_int8u len)
600
{
601
  /* pass request on to the application through a hook function */
602
  return XcpVerifyKeyHook(resource, key, len);
603
} /*** end of XcpVerifyKey ***/
604
#endif /* XCP_SEED_KEY_PROTECTION_EN == 1 */
605

    
606

    
607
/************************************************************************************//**
608
** \brief     Utility function to protects all the available resources.
609
** \return    none
610
**
611
****************************************************************************************/
612
static void XcpProtectResources(void)
613
{
614
  xcpInfo.protection = 0;
615

    
616
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
617
  #if (XCP_RES_CALIBRATION_EN == 1)
618
  xcpInfo.protection |= XCP_RES_CALPAG;
619
  #endif
620

    
621
  #if (XCP_RES_PAGING_EN == 1)
622
  xcpInfo.protection |= XCP_RES_CALPAG;
623
  #endif
624

    
625
  #if (XCP_RES_PROGRAMMING_EN == 1)
626
  xcpInfo.protection |= XCP_RES_PGM;
627
  #endif
628

    
629
  #if (XCP_RES_DATA_ACQUISITION_EN == 1)
630
  xcpInfo.protection |= XCP_RES_DAQ;
631
  #endif
632

    
633
  #if (XCP_RES_DATA_STIMULATION_EN == 1)
634
  xcpInfo.protection |= XCP_RES_STIM;
635
  #endif
636
#endif /* XCP_SEED_KEY_PROTECTION_EN == 1 */
637
} /*** end of XcpProtectResources ***/
638

    
639

    
640
/************************************************************************************//**
641
** \brief     Prepares the cto packet data for the specified error.
642
** \param     error XCP error code (XCP_ERR_XXX).
643
** \return    none
644
**
645
****************************************************************************************/
646
static void XcpSetCtoError(blt_int8u error)
647
{
648
  /* prepare the error packet */
649
  xcpInfo.ctoData[0] = XCP_PID_ERR;
650
  xcpInfo.ctoData[1] = error;
651
  xcpInfo.ctoLen = 2;
652
} /*** end of XcpSetCtoError ***/
653

    
654

    
655
/************************************************************************************//**
656
** \brief     XCP command processor function which handles the CONNECT command as
657
**            defined by the protocol.
658
** \param     data Pointer to a byte buffer with the packet data.
659
** \return    none
660
**
661
****************************************************************************************/
662
static void XcpCmdConnect(blt_int8u *data, blt_int16s dataLength)
663
{
664
  /* suppress compiler warning for unused parameter */
665
  data = data;
666

    
667
  #if (BOOT_FILE_SYS_ENABLE > 0)
668
  /* reject the connection if the file module is not idle. this means that a firmware
669
   * update from the locally attached storage is in progress
670
   */
671
  if (FileIsIdle() == BLT_FALSE)
672
  {
673
    /* command not processed because we are busy */
674
    XcpSetCtoError(XCP_ERR_CMD_BUSY);
675
    return;
676
  }
677
  #endif
678

    
679
//  #if (XCP_CONNECT_MODE_HOOK_EN == 1)
680
//  /* pass on the mode to a application specific hook function. This function can determine
681
//   * is the mode is supported or not. A return value of BLT_FALSE causes the CONNECT command
682
//   * to be ignored. Note that this mode could potentially be used to specify a node ID in a
683
//   * multi XCP slave system.
684
//   */
685
//  if (XcpConnectModeHook(data[1]) == BLT_FALSE)
686
//  {
687
//    /* set the response length to 0 to suppress it */
688
//    xcpInfo.ctoLen = 0;
689
//    return;
690
//  }
691
//  #endif
692

    
693
  /* enable resource protection */
694
  XcpProtectResources();
695

    
696
  /* extract the device ID.
697
   * NOTE: For legacy support the following code depends on the data length.
698
   *       If two bytes were received the system switches to legacy mode.
699
   *       In legacy mode, the device ID was only one byte.
700
   */
701
  blt_int32u deviceID;
702
  if (dataLength == 2) {
703
    deviceID = ((blt_int32u)0 << 24) | \
704
               ((blt_int32u)0 << 16) | \
705
               ((blt_int32u)0 <<  8) | \
706
               ((blt_int32u)data[1]);
707
  } else if (dataLength == 5) {
708
    deviceID = ((blt_int32u)data[4] << 24) | \
709
               ((blt_int32u)data[3] << 16) | \
710
               ((blt_int32u)data[2] <<  8) | \
711
               ((blt_int32u)data[1]);
712
  } else {
713
    blinkSOSinf();
714
  }
715
  /* indicate that the connection is established */
716
#if (BOOT_GATE_ENABLE > 0)
717
  if (deviceID == 0 ||
718
      deviceID == (blt_int32u)BOOT_COM_DEVICE_ID ||
719
      deviceID == (blt_int32u)BOOT_COM_DEVICE_LEGACY_ID) {
720
#endif
721
    xcpInfo.connected = 1;
722
    setLed(1);
723
#if (BOOT_GATE_ENABLE > 0)
724
    xcpInfo.other_connection = 0;
725
#endif
726
#if (BOOTLOADER_OF_MAIN_DEVICE > 0)
727
    if (deviceID == 0x00) {
728
      xcpInfo.wasMainConnection = BLT_TRUE;
729
    }
730
#endif
731

    
732
    /* set packet id to command response packet */
733
    xcpInfo.ctoData[0] = XCP_PID_RES;
734

    
735
    /* report available resources */
736
    xcpInfo.ctoData[1] = 0;
737
#if (XCP_RES_CALIBRATION_EN == 1)
738
    xcpInfo.ctoData[1] |= XCP_RES_CALPAG;
739
#endif
740

    
741
#if (XCP_RES_PAGING_EN == 1)
742
    xcpInfo.ctoData[1] |= XCP_RES_CALPAG;
743
#endif
744

    
745
#if (XCP_RES_PROGRAMMING_EN == 1)
746
    xcpInfo.ctoData[1] |= XCP_RES_PGM;
747
#endif
748

    
749
#if (XCP_RES_DATA_ACQUISITION_EN == 1)
750
    xcpInfo.ctoData[1] |= XCP_RES_DAQ;
751
#endif
752

    
753
#if (XCP_RES_DATA_STIMULATION_EN == 1)
754
    xcpInfo.ctoData[1] |= XCP_RES_STIM;
755
#endif
756

    
757
    /* report communication mode info. only byte granularity is supported */
758
    xcpInfo.ctoData[2] = 0;
759
    /* configure for motorola or intel byte ordering */
760
    xcpInfo.ctoData[2] |= XCP_MOTOROLA_FORMAT;
761

    
762
    /* report max cto data length */
763
    xcpInfo.ctoData[3] = (blt_int8u)XCP_CTO_PACKET_LEN;
764

    
765
    /* report max dto data length */
766
#if (XCP_MOTOROLA_FORMAT == 0)
767
    xcpInfo.ctoData[4] = (blt_int8u)XCP_DTO_PACKET_LEN;
768
    xcpInfo.ctoData[5] = (blt_int8u)(XCP_DTO_PACKET_LEN >> 8);
769
#else
770
    xcpInfo.ctoData[4] = (blt_int8u)(XCP_DTO_PACKET_LEN >> 8);
771
    xcpInfo.ctoData[5] = (blt_int8u)XCP_DTO_PACKET_LEN;
772
#endif
773

    
774
    /* report msb of protocol layer version number */
775
    xcpInfo.ctoData[6] = XCP_VERSION_PROTOCOL_LAYER >> 8;
776

    
777
    /* report msb of transport layer version number */
778
    xcpInfo.ctoData[7] = XCP_VERSION_TRANSPORT_LAYER >> 8;
779

    
780
    /* set packet length */
781
    xcpInfo.ctoLen = 8;
782

    
783
#if (BOOT_GATE_ENABLE > 0)
784
  } else {
785
    xcpInfo.other_connection = deviceID;
786
    setLed(1);
787
    xcpInfo.connected = 0;
788
    XcpPacketReceivedForwarding(data, dataLength);
789
    xcpInfo.ctoLen = 0;
790
    // TODO better cancel definition!
791
//    if (xcpInfo.ctoLen == 0) {
792
//      xcpInfo.other_connection = 0;
793
//    }
794
  }
795
#endif
796

    
797

    
798
} /*** end of XcpCmdConnect ***/
799

    
800

    
801
/************************************************************************************//**
802
** \brief     XCP command processor function which handles the DISCONNECT command as
803
**            defined by the protocol.
804
** \param     data Pointer to a byte buffer with the packet data.
805
** \return    none
806
**
807
****************************************************************************************/
808
static void XcpCmdDisconnect(blt_int8u *data)
809
{
810
  /* suppress compiler warning for unused parameter */
811
  data = data;
812

    
813
  /* indicate that the xcp connection is disconnected */
814
  xcpInfo.connected = 0;
815
#if (BOOT_GATE_ENABLE > 0)
816
  xcpInfo.other_connection = 0;
817
#endif
818
  setLed(0);
819

    
820
  /* enable resource protection */
821
  XcpProtectResources();
822

    
823
  /* set packet id to command response packet */
824
  xcpInfo.ctoData[0] = XCP_PID_RES;
825

    
826
  /* set packet length */
827
  xcpInfo.ctoLen = 1;
828

    
829
} /*** end of XcpCmdDisconnect ***/
830

    
831

    
832
/************************************************************************************//**
833
** \brief     XCP command processor function which handles the GET_STATUS command as
834
**            defined by the protocol.
835
** \param     data Pointer to a byte buffer with the packet data.
836
** \return    none
837
**
838
****************************************************************************************/
839
static void XcpCmdGetStatus(blt_int8u *data)
840
{
841
  /* suppress compiler warning for unused parameter */
842
  data = data;
843

    
844
  /* set packet id to command response packet */
845
  xcpInfo.ctoData[0] = XCP_PID_RES;
846

    
847
  /* report session status */
848
  xcpInfo.ctoData[1] = 0;
849

    
850
  /* report current resource protection status */
851
  xcpInfo.ctoData[2] = xcpInfo.protection;
852

    
853
  /* reset reserved and session configuration id values */
854
  xcpInfo.ctoData[3] = 0;
855
  xcpInfo.ctoData[4] = 0;
856
  xcpInfo.ctoData[5] = 0;
857

    
858
  /* set packet length */
859
  xcpInfo.ctoLen = 6;
860
} /*** end of XcpCmdGetStatus ***/
861

    
862

    
863
/************************************************************************************//**
864
** \brief     XCP command processor function which handles the SYNCH command as
865
**            defined by the protocol.
866
** \param     data Pointer to a byte buffer with the packet data.
867
** \return    none
868
**
869
****************************************************************************************/
870
static void XcpCmdSynch(blt_int8u *data)
871
{
872
  /* suppress compiler warning for unused parameter */
873
  data = data;
874

    
875
  /* synch requires a negative response */
876
  XcpSetCtoError(XCP_ERR_CMD_SYNCH);
877
} /*** end of XcpCmdSynch ***/
878

    
879

    
880
/************************************************************************************//**
881
** \brief     XCP command processor function which handles the GET_ID command as
882
**            defined by the protocol.
883
** \param     data Pointer to a byte buffer with the packet data.
884
** \return    none
885
**
886
****************************************************************************************/
887
static void XcpCmdGetId(blt_int8u *data)
888
{
889
  /* suppress compiler warning for unused parameter */
890
  data = data;
891

    
892
  /* set packet id to command response packet */
893
  xcpInfo.ctoData[0] = XCP_PID_RES;
894

    
895
  /* point mta to start of station id string */
896
  xcpInfo.mta = (blt_int32u)&xcpStationId[0];
897

    
898
  /* set station id mode to 0 */
899
  xcpInfo.ctoData[1] = 0;
900

    
901
  /* reset reserved values */
902
  xcpInfo.ctoData[2] = 0;
903
  xcpInfo.ctoData[3] = 0;
904

    
905
  /* store station id length (excl. null termination) for response packet */
906
  *(blt_int32u*)&xcpInfo.ctoData[4] = (sizeof(xcpStationId)/sizeof(xcpStationId[0])) - 1;
907

    
908
  /* set packet length */
909
  xcpInfo.ctoLen = 8;
910
} /*** end of XcpCmdGetId ***/
911

    
912

    
913
/************************************************************************************//**
914
** \brief     XCP command processor function which handles the SET_MTA command as
915
**            defined by the protocol.
916
** \param     data Pointer to a byte buffer with the packet data.
917
** \return    none
918
**
919
****************************************************************************************/
920
static void XcpCmdSetMta(blt_int8u *data)
921
{
922
  /* set packet id to command response packet */
923
  xcpInfo.ctoData[0] = XCP_PID_RES;
924

    
925
  /* update mta. current implementation ignores address extension */
926
  xcpInfo.mta = *(blt_int32u*)&data[4];
927

    
928
  /* set packet length */
929
  xcpInfo.ctoLen = 1;
930
} /*** end of XcpCmdSetMta ***/
931

    
932

    
933
/************************************************************************************//**
934
** \brief     XCP command processor function which handles the UPLOAD command as
935
**            defined by the protocol.
936
** \param     data Pointer to a byte buffer with the packet data.
937
** \return    none
938
**
939
****************************************************************************************/
940
static void XcpCmdUpload(blt_int8u *data)
941
{
942
  /* validate length of upload request */
943
  if (data[1] > (XCP_CTO_PACKET_LEN-1))
944
  {
945
    /* requested data length is too long */
946
    XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
947
    return;
948
  }
949

    
950
  /* copy the data from memory to the data packet */
951
  CpuMemCopy(((blt_addr)(blt_int32u)&xcpInfo.ctoData[1]),(blt_addr)xcpInfo.mta, data[1]);
952

    
953
  /* set packet id to command response packet */
954
  xcpInfo.ctoData[0] = XCP_PID_RES;
955

    
956
  /* post increment the mta */
957
  xcpInfo.mta += data[1];
958

    
959
  /* set packet length */
960
  xcpInfo.ctoLen = data[1]+1;
961
} /*** end of XcpCmdUpload ***/
962

    
963

    
964
/************************************************************************************//**
965
** \brief     XCP command processor function which handles the SHORT_UPLOAD command as
966
**            defined by the protocol.
967
** \param     data Pointer to a byte buffer with the packet data.
968
** \return    none
969
**
970
****************************************************************************************/
971
static void XcpCmdShortUpload(blt_int8u *data)
972
{
973
  /* validate length of upload request */
974
  if (data[1] > (XCP_CTO_PACKET_LEN-1))
975
  {
976
    /* requested data length is too long */
977
    XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
978
    return;
979
  }
980

    
981
  /* update mta. current implementation ignores address extension */
982
  xcpInfo.mta = *(blt_int32u*)&data[4];
983

    
984
  /* copy the data from memory to the data packet */
985
  CpuMemCopy((blt_addr)((blt_int32u)&xcpInfo.ctoData[1]),(blt_addr)xcpInfo.mta, data[1]);
986
  /* set packet id to command response packet */
987
  xcpInfo.ctoData[0] = XCP_PID_RES;
988

    
989
  /* post increment the mta */
990
  xcpInfo.mta += data[1];
991

    
992
  /* set packet length */
993
  xcpInfo.ctoLen = data[1]+1;
994
} /*** end of XcpCmdShortUpload ***/
995

    
996

    
997
#if (XCP_RES_CALIBRATION_EN == 1)
998
/************************************************************************************//**
999
** \brief     XCP command processor function which handles the DOWNLOAD command as
1000
**            defined by the protocol.
1001
** \param     data Pointer to a byte buffer with the packet data.
1002
** \return    none
1003
**
1004
****************************************************************************************/
1005
static void XcpCmdDownload(blt_int8u *data)
1006
{
1007
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1008
  /* check if CAL_PAG resource is unlocked */
1009
  if ((xcpInfo.protection & XCP_RES_CALPAG) != 0)
1010
  {
1011
    /* resource is locked. use seed/key sequence to unlock */
1012
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1013
    return;
1014
  }
1015
#endif
1016

    
1017
  /* validate length of download request */
1018
  if (data[1] > (XCP_CTO_PACKET_LEN-2))
1019
  {
1020
    /* requested data length is too long */
1021
    XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
1022
    return;
1023
  }
1024

    
1025
  /* copy the data from the data packet to memory */
1026
  CpuMemCopy((blt_addr)xcpInfo.mta, (blt_addr)((blt_int32u)&data[2]), data[1]);
1027
  /* set packet id to command response packet */
1028
  xcpInfo.ctoData[0] = XCP_PID_RES;
1029

    
1030
  /* post increment the mta */
1031
  xcpInfo.mta += data[1];
1032

    
1033
  /* set packet length */
1034
  xcpInfo.ctoLen = 1;
1035
} /*** end of XcpCmdDownload ***/
1036

    
1037

    
1038
/************************************************************************************//**
1039
** \brief     XCP command processor function which handles the DOWNLOAD_MAX command as
1040
**            defined by the protocol.
1041
** \param     data Pointer to a byte buffer with the packet data.
1042
** \return    none
1043
**
1044
****************************************************************************************/
1045
static void XcpCmdDownloadMax(blt_int8u *data)
1046
{
1047
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1048
  /* check if CAL_PAG resource is unlocked */
1049
  if ((xcpInfo.protection & XCP_RES_CALPAG) != 0)
1050
  {
1051
    /* resource is locked. use seed/key sequence to unlock */
1052
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1053
    return;
1054
  }
1055
#endif
1056

    
1057
  /* copy the data from the data packet to memory */
1058
  CpuMemCopy((blt_addr)xcpInfo.mta, (blt_addr)((blt_int32u)&data[1]), \
1059
              XCP_CTO_PACKET_LEN-1);
1060

    
1061
  /* set packet id to command response packet */
1062
  xcpInfo.ctoData[0] = XCP_PID_RES;
1063

    
1064
  /* post increment the mta */
1065
  xcpInfo.mta += XCP_CTO_PACKET_LEN-1;
1066

    
1067
  /* set packet length */
1068
  xcpInfo.ctoLen = 1;
1069
} /*** end of XcpCmdDownloadMax ***/
1070
#endif /* XCP_RES_CALIBRATION_EN == 1 */
1071

    
1072

    
1073
/************************************************************************************//**
1074
** \brief     XCP command processor function which handles the BUILD_CHECKSUM command as
1075
**            defined by the protocol.
1076
** \param     data Pointer to a byte buffer with the packet data.
1077
** \return    none
1078
**
1079
****************************************************************************************/
1080
static void XcpCmdBuildCheckSum(blt_int8u *data)
1081
{
1082
  /* set packet id to command response packet */
1083
  xcpInfo.ctoData[0] = XCP_PID_RES;
1084

    
1085
  /* obtain checksum and checksum type */
1086
  xcpInfo.ctoData[1] = XcpComputeChecksum(xcpInfo.mta, *(blt_int32u*)&data[4],
1087
                                          (blt_int32u*)&xcpInfo.ctoData[4]);
1088

    
1089
  /* initialize reserved parameters */
1090
  xcpInfo.ctoData[2] = 0;
1091
  xcpInfo.ctoData[3] = 0;
1092

    
1093
  /* set packet length */
1094
  xcpInfo.ctoLen = 8;
1095
} /*** end of XcpCmdBuildCheckSum ***/
1096

    
1097

    
1098
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1099
/************************************************************************************//**
1100
** \brief     XCP command processor function which handles the GET_SEED command as
1101
**            defined by the protocol.
1102
** \param     data Pointer to a byte buffer with the packet data.
1103
** \return    none
1104
**
1105
****************************************************************************************/
1106
static void XcpCmdGetSeed(blt_int8u *data)
1107
{
1108
  blt_int8u resourceOK;
1109

    
1110
  /* init resource check variable as if an illegal resource is requested */
1111
  resourceOK = 0;
1112

    
1113
  /* check if calibration/paging resource is requested for seed/key and make
1114
   * sure this is the only requested resource
1115
   */
1116
  if (((data[2] & XCP_RES_CALPAG) > 0) && ((data[2] & ~XCP_RES_CALPAG) == 0))
1117
  {
1118
    resourceOK = 1;
1119
  }
1120

    
1121
  /* check if programming resource is requested for seed/key and make
1122
   * sure this is the only requested resource
1123
   */
1124
  if (((data[2] & XCP_RES_PGM) > 0) && ((data[2] & ~XCP_RES_PGM) == 0))
1125
  {
1126
    resourceOK = 1;
1127
  }
1128

    
1129
  /* check if data acquisition resource is requested for seed/key and make
1130
   * sure this is the only requested resource
1131
   */
1132
  if (((data[2] & XCP_RES_DAQ) > 0) && ((data[2] & ~XCP_RES_DAQ) == 0))
1133
  {
1134
    resourceOK = 1;
1135
  }
1136

    
1137
  /* check if data stimulation resource is requested for seed/key and make
1138
   * sure this is the only requested resource
1139
   */
1140
  if (((data[2] & XCP_RES_STIM) > 0) && ((data[2] & ~XCP_RES_STIM) == 0))
1141
  {
1142
    resourceOK = 1;
1143
  }
1144

    
1145
  /* now process the resource validation */
1146
  if (resourceOK == 0)
1147
  {
1148
    XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
1149
    return;
1150
  }
1151

    
1152
  /* store resource for which the seed/key sequence is started */
1153
  xcpInfo.s_n_k_resource = data[2];
1154

    
1155
  /* set packet id to command response packet */
1156
  xcpInfo.ctoData[0] = XCP_PID_RES;
1157

    
1158
  /* request the seed from the application */
1159
  xcpInfo.ctoData[1] = XcpGetSeed(xcpInfo.s_n_k_resource, &xcpInfo.ctoData[2]);
1160

    
1161
  /* seed cannot be longer than XCP_CTO_PACKET_LEN-2 */
1162
  if (xcpInfo.ctoData[1] > (XCP_CTO_PACKET_LEN-2))
1163
  {
1164
    /* seed length length is too long */
1165
    XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
1166
    return;
1167
  }
1168

    
1169
  /* set packet length */
1170
  xcpInfo.ctoLen = xcpInfo.ctoData[1] + 2;
1171
} /*** end of XcpCmdGetSeed ***/
1172

    
1173

    
1174
/************************************************************************************//**
1175
** \brief     XCP command processor function which handles the UNLOCK command as
1176
**            defined by the protocol.
1177
** \param     data Pointer to a byte buffer with the packet data.
1178
** \return    none
1179
**
1180
****************************************************************************************/
1181
static void XcpCmdUnlock(blt_int8u *data)
1182
{
1183
  /* key cannot be longer than XCP_CTO_PACKET_LEN-2 */
1184
  if (data[1] > (XCP_CTO_PACKET_LEN-2))
1185
  {
1186
    /* key is too long incorrect */
1187
    XcpSetCtoError(XCP_ERR_SEQUENCE);
1188
    return;
1189
  }
1190

    
1191
  /* verify the key */
1192
  if (XcpVerifyKey(xcpInfo.s_n_k_resource, &data[2], data[1]) == 0)
1193
  {
1194
    /* invalid key so inform the master and do a disconnect */
1195
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1196

    
1197
    /* indicate that the xcp connection is disconnected */
1198
    xcpInfo.connected = 0;
1199

    
1200
    /* enable resource protection */
1201
    XcpProtectResources();
1202

    
1203
    return;
1204
  }
1205

    
1206
  /* key correct so unlock the resource */
1207
  xcpInfo.protection &= ~xcpInfo.s_n_k_resource;
1208

    
1209
  /* reset seed/key resource variable for possible next unlock */
1210
  xcpInfo.s_n_k_resource = 0;
1211

    
1212
  /* set packet id to command response packet */
1213
  xcpInfo.ctoData[0] = XCP_PID_RES;
1214

    
1215
  /* report the current resource protection */
1216
  xcpInfo.ctoData[1] = xcpInfo.protection;
1217

    
1218
  /* set packet length */
1219
  xcpInfo.ctoLen = 2;
1220
} /*** end of XcpCmdUnlock ***/
1221
#endif /* XCP_SEED_KEY_PROTECTION_EN == 1 */
1222

    
1223

    
1224
#if (XCP_RES_PAGING_EN == 1)
1225
/************************************************************************************//**
1226
** \brief     XCP command processor function which handles the SET_CAL_PAGE command as
1227
**            defined by the protocol.
1228
** \param     data Pointer to a byte buffer with the packet data.
1229
** \return    none
1230
**
1231
****************************************************************************************/
1232
static void XcpCmdSetCalPage(blt_int8u *data)
1233
{
1234
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1235
  /* check if CAL_PAG resource is unlocked */
1236
  if ((xcpInfo.protection & XCP_RES_CALPAG) == XCP_RES_CALPAG)
1237
  {
1238
    /* resource is locked. use seed/key sequence to unlock */
1239
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1240
    return;
1241
  }
1242
#endif
1243

    
1244
  /* select the page. note that the mode parameter is ignored */
1245
  if (XcpCalSetPageHook(data[2], data[3]) == 0)
1246
  {
1247
    /* calibration page could not be selected */
1248
    XcpSetCtoError(XCP_ERR_PAGE_NOT_VALID);
1249
    return;
1250
  }
1251

    
1252
  /* set packet id to command response packet */
1253
  xcpInfo.ctoData[0] = XCP_PID_RES;
1254

    
1255
  /* set packet length */
1256
  xcpInfo.ctoLen = 1;
1257
} /*** end of XcpCmdSetCalPage ***/
1258

    
1259

    
1260
/************************************************************************************//**
1261
** \brief     XCP command processor function which handles the GET_CAL_PAGE command as
1262
**            defined by the protocol.
1263
** \param     data Pointer to a byte buffer with the packet data.
1264
** \return    none
1265
**
1266
****************************************************************************************/
1267
static void XcpCmdGetCalPage(blt_int8u *data)
1268
{
1269
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1270
  /* check if CAL_PAG resource is unlocked */
1271
  if ((xcpInfo.protection & XCP_RES_CALPAG) == XCP_RES_CALPAG)
1272
  {
1273
    /* resource is locked. use seed/key sequence to unlock */
1274
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1275
    return;
1276
  }
1277
#endif
1278

    
1279
  /* set packet id to command response packet */
1280
  xcpInfo.ctoData[0] = XCP_PID_RES;
1281

    
1282
  /* initialize reserved parameters */
1283
  xcpInfo.ctoData[1] = 0;
1284
  xcpInfo.ctoData[2] = 0;
1285

    
1286
  /* store the calibration page */
1287
  xcpInfo.ctoData[3] = XcpCalGetPageHook(data[2]);
1288

    
1289
  /* set packet length */
1290
  xcpInfo.ctoLen = 4;
1291
} /*** end of XcpCmdGetCalPage ***/
1292
#endif /* XCP_RES_PAGING_EN == 1 */
1293

    
1294

    
1295
#if (XCP_RES_PROGRAMMING_EN == 1)
1296
/************************************************************************************//**
1297
** \brief     XCP command processor function which handles the PROGRAM_START command as
1298
**            defined by the protocol.
1299
** \param     data Pointer to a byte buffer with the packet data.
1300
** \return    none
1301
**
1302
****************************************************************************************/
1303
static void XcpCmdProgramStart(blt_int8u *data)
1304
{
1305
  /* suppress compiler warning for unused parameter */
1306
  data = data;
1307

    
1308
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1309
  /* check if PGM resource is unlocked */
1310
  if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM)
1311
  {
1312
    /* resource is locked. use seed/key sequence to unlock */
1313
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1314
    return;
1315
  }
1316
#endif
1317

    
1318
  /* set packet id to command response packet */
1319
  xcpInfo.ctoData[0] = XCP_PID_RES;
1320

    
1321
  /* initialize reserved parameter */
1322
  xcpInfo.ctoData[1] = 0;
1323

    
1324
  /* no special communication mode supported during programming */
1325
  xcpInfo.ctoData[2] = 0;
1326

    
1327
  /* cto packet length stays the same during programming */
1328
  xcpInfo.ctoData[3] = (blt_int8u)XCP_CTO_PACKET_LEN;
1329

    
1330
  /* no block size, st-min time, or queue size supported */
1331
  xcpInfo.ctoData[4] = 0;
1332
  xcpInfo.ctoData[5] = 0;
1333
  xcpInfo.ctoData[6] = 0;
1334

    
1335
  /* set packet length */
1336
  xcpInfo.ctoLen = 7;
1337
} /*** end of XcpCmdProgramStart ***/
1338

    
1339

    
1340
/************************************************************************************//**
1341
** \brief     XCP command processor function which handles the PROGRAM_MAX command as
1342
**            defined by the protocol.
1343
** \param     data Pointer to a byte buffer with the packet data.
1344
** \return    none
1345
**
1346
****************************************************************************************/
1347
static void XcpCmdProgramMax(blt_int8u *data)
1348
{
1349
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1350
  /* check if PGM resource is unlocked */
1351
  if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM)
1352
  {
1353
    /* resource is locked. use seed/key sequence to unlock */
1354
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1355
    return;
1356
  }
1357
#endif
1358

    
1359
  /* program the data */
1360
  if (NvmWrite((blt_addr)xcpInfo.mta, XCP_CTO_PACKET_LEN-1, &data[1]) == 0)
1361
  {
1362
    /* error occurred during programming */
1363
    XcpSetCtoError(XCP_ERR_GENERIC);
1364
    return;
1365
  }
1366

    
1367
  /* set packet id to command response packet */
1368
  xcpInfo.ctoData[0] = XCP_PID_RES;
1369

    
1370
  /* post increment the mta */
1371
  xcpInfo.mta += XCP_CTO_PACKET_LEN-1;
1372

    
1373
  /* set packet length */
1374
  xcpInfo.ctoLen = 1;
1375
} /*** end of XcpCmdProgramMax ***/
1376

    
1377

    
1378
/************************************************************************************//**
1379
** \brief     XCP command processor function which handles the PROGRAM command as
1380
**            defined by the protocol.
1381
** \param     data Pointer to a byte buffer with the packet data.
1382
** \return    none
1383
**
1384
****************************************************************************************/
1385
static void XcpCmdProgram(blt_int8u *data)
1386
{
1387
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1388
  /* check if PGM resource is unlocked */
1389
  if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM)
1390
  {
1391
    /* resource is locked. use seed/key sequence to unlock */
1392
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1393
    return;
1394
  }
1395
#endif
1396

    
1397
  /* validate length of download request */
1398
  if (data[1] > (XCP_CTO_PACKET_LEN-2))
1399
  {
1400
    /* requested data length is too long */
1401
    XcpSetCtoError(XCP_ERR_OUT_OF_RANGE);
1402
    return;
1403
  }
1404

    
1405
  /* set packet id to command response packet */
1406
  xcpInfo.ctoData[0] = XCP_PID_RES;
1407

    
1408
  /* set packet length */
1409
  xcpInfo.ctoLen = 1;
1410

    
1411
  /* end of programming sequence (datasize is 0)? */
1412
  if (data[1] == 0)
1413
  {
1414
    /* call erase/programming cleanup routine */
1415
    if (NvmDone() == BLT_FALSE)
1416
    {
1417
      /* error occurred while finishing up programming */
1418
      XcpSetCtoError(XCP_ERR_GENERIC);
1419
    }
1420
    return;
1421
  }
1422
  /* program the data */
1423
  if (NvmWrite((blt_addr)xcpInfo.mta, data[1], &data[2]) == 0)
1424
  {
1425
    /* error occurred during programming */
1426
    XcpSetCtoError(XCP_ERR_GENERIC);
1427
    return;
1428
  }
1429

    
1430
  /* post increment the mta */
1431
  xcpInfo.mta += data[1];
1432
} /*** end of XcpCmdProgram ***/
1433

    
1434

    
1435
/************************************************************************************//**
1436
** \brief     XCP command processor function which handles the PROGRAM_CLEAR command as
1437
**            defined by the protocol.
1438
** \param     data Pointer to a byte buffer with the packet data.
1439
** \return    none
1440
**
1441
****************************************************************************************/
1442
static void XcpCmdProgramClear(blt_int8u *data)
1443
{
1444
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1445
  /* check if PGM resource is unlocked */
1446
  if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM)
1447
  {
1448
    /* resource is locked. use seed/key sequence to unlock */
1449
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1450
    return;
1451
  }
1452
#endif
1453

    
1454
  /* erase the memory */
1455
  if (NvmErase((blt_addr)xcpInfo.mta, *(blt_int32u*)&data[4]) == 0)
1456
  {
1457
    /* error occurred during erasure */
1458
    XcpSetCtoError(XCP_ERR_GENERIC);
1459
    return;
1460
  }
1461

    
1462
  /* set packet id to command response packet */
1463
  xcpInfo.ctoData[0] = XCP_PID_RES;
1464

    
1465
  /* set packet length */
1466
  xcpInfo.ctoLen = 1;
1467
} /*** end of XcpCmdProgramClear ***/
1468

    
1469

    
1470
/************************************************************************************//**
1471
** \brief     XCP command processor function which handles the PROGRAM_RESET command as
1472
**            defined by the protocol.
1473
** \param     data Pointer to a byte buffer with the packet data.
1474
** \return    none
1475
**
1476
****************************************************************************************/
1477
static void XcpCmdProgramReset(blt_int8u *data)
1478
{
1479
  /* suppress compiler warning for unused parameter */
1480
  data = data;
1481

    
1482
  xcpInfo.connected = 0;
1483
#if (BOOT_GATE_ENABLE > 0)
1484
  xcpInfo.other_connection = 0;
1485
#endif
1486
  setLed(0);
1487

    
1488
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1489
  /* check if PGM resource is unlocked */
1490
  if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM)
1491
  {
1492
    /* resource is locked. use seed/key sequence to unlock */
1493
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1494
    return;
1495
  }
1496
#endif
1497

    
1498
  /* reset the ecu after programming is done. so basically, just start the newly programmed
1499
   * firmware. it is okay if the code does not return here. if CpuReset() is used here, then
1500
   * the bootloader is first activated again, including the backdoor timer which is not
1501
   * desired.
1502
   */
1503
  CpuStartUserProgram();
1504

    
1505
  /* set packet id to command response packet */
1506
  xcpInfo.ctoData[0] = XCP_PID_RES;
1507

    
1508
  /* set packet length */
1509
  xcpInfo.ctoLen = 1;
1510
} /*** end of XcpCmdProgramReset ***/
1511

    
1512

    
1513
/************************************************************************************//**
1514
** \brief     XCP command processor function which handles the PROGRAM_PREPARE command as
1515
**            defined by the protocol.
1516
** \param     data Pointer to a byte buffer with the packet data.
1517
** \return    none
1518
**
1519
****************************************************************************************/
1520
static void XcpCmdProgramPrepare(blt_int8u *data)
1521
{
1522
#if (XCP_SEED_KEY_PROTECTION_EN == 1)
1523
  /* check if PGM resource is unlocked */
1524
  if ((xcpInfo.protection & XCP_RES_PGM) == XCP_RES_PGM)
1525
  {
1526
    /* resource is locked. use seed/key sequence to unlock */
1527
    XcpSetCtoError(XCP_ERR_ACCESS_LOCKED);
1528
    return;
1529
  }
1530
#endif
1531

    
1532
  /* programming with kernel currently not needed and therefore not supported */
1533
  XcpSetCtoError(XCP_ERR_GENERIC);
1534
  return;
1535
} /*** end of XcpCmdProgramPrepare ***/
1536
#endif /* XCP_RES_PROGRAMMING_EN == 1 */
1537

    
1538

    
1539

    
1540
/******************************** end of xcp.c *****************************************/