Statistics
| Branch: | Tag: | Revision:

amiro-blt / Target / Source / ARMCM4_STM32 / can.c @ f4758731

History | View | Annotate | Download (22.176 KB)

1 69661903 Thomas Schöpping
/************************************************************************************//**
2
* \file         Source\ARMCM4_STM32\can.c
3
* \brief        Bootloader CAN communication interface source file.
4
* \ingroup      Target_ARMCM4_STM32
5
* \internal
6
*----------------------------------------------------------------------------------------
7
*                          C O P Y R I G H T
8
*----------------------------------------------------------------------------------------
9
*   Copyright (c) 2013  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
/****************************************************************************************
36
* Include files
37
****************************************************************************************/
38
#include "boot.h"                                /* bootloader generic header          */
39
40
41
#if (BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0)
42
/****************************************************************************************
43
* Type definitions
44
****************************************************************************************/
45
/** \brief CAN transmission mailbox layout. */
46
typedef struct
47
{
48
  volatile blt_int32u TIR;
49
  volatile blt_int32u TDTR;
50
  volatile blt_int32u TDLR;
51
  volatile blt_int32u TDHR;
52
} tCanTxMailBox;
53
54
/** \brief CAN reception FIFO mailbox layout. */
55
typedef struct
56
{
57
  volatile blt_int32u RIR;
58
  volatile blt_int32u RDTR;
59
  volatile blt_int32u RDLR;
60
  volatile blt_int32u RDHR;
61
} tCanRxFIFOMailBox; 
62
63
/** \brief CAN filter register layout. */
64
typedef struct
65
{
66
  volatile blt_int32u FR1;
67
  volatile blt_int32u FR2;
68
} tCanFilter;
69
70
/** \brief CAN controller register layout. */
71
typedef struct
72
{
73
  volatile blt_int32u MCR;
74
  volatile blt_int32u MSR;
75
  volatile blt_int32u TSR;
76
  volatile blt_int32u RF0R;
77
  volatile blt_int32u RF1R;
78
  volatile blt_int32u IER;
79
  volatile blt_int32u ESR;
80
  volatile blt_int32u BTR;
81
  blt_int32u          RESERVED0[88];
82
  tCanTxMailBox       sTxMailBox[3];
83
  tCanRxFIFOMailBox   sFIFOMailBox[2];
84
  blt_int32u          RESERVED1[12];
85
  volatile blt_int32u FMR;
86
  volatile blt_int32u FM1R;
87
  blt_int32u          RESERVED2;
88
  volatile blt_int32u FS1R;
89
  blt_int32u          RESERVED3;
90
  volatile blt_int32u FFA1R;
91
  blt_int32u          RESERVED4;
92
  volatile blt_int32u FA1R;
93
  blt_int32u          RESERVED5[8];
94
  tCanFilter          sFilterRegister[28];
95
} tCanRegs;                                           
96
97
98
/****************************************************************************************
99
* Macro definitions
100
****************************************************************************************/
101
/** \brief Reset request bit. */
102
#define CAN_BIT_RESET    ((blt_int32u)0x00008000)
103
/** \brief Initialization request bit. */
104
#define CAN_BIT_INRQ     ((blt_int32u)0x00000001)
105
/** \brief Initialization acknowledge bit. */
106
#define CAN_BIT_INAK     ((blt_int32u)0x00000001)
107
/** \brief Sleep mode request bit. */
108
#define CAN_BIT_SLEEP    ((blt_int32u)0x00000002)
109
/** \brief Filter 0 selection bit. */
110
#define CAN_BIT_FILTER0  ((blt_int32u)0x00000001)
111
/** \brief Filter 14 selection bit. */
112
#define CAN_BIT_FILTER14 ((blt_int32u)0x00004000)
113
/** \brief Filter init mode bit. */
114
#define CAN_BIT_FINIT    ((blt_int32u)0x00000001)
115
/** \brief Transmit mailbox 0 empty bit. */
116
#define CAN_BIT_TME0     ((blt_int32u)0x04000000)
117
/** \brief Transmit mailbox request bit. */
118
#define CAN_BIT_TXRQ     ((blt_int32u)0x00000001)
119
/** \brief Release FIFO 0 mailbox bit. */
120
#define CAN_BIT_RFOM0    ((blt_int32u)0x00000020)
121
122
#if (BOOT_GATE_CAN_ENABLE > 0)
123
blt_bool commandSend;
124
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
125
126
127
/****************************************************************************************
128
* Register definitions
129
****************************************************************************************/
130
#if (BOOT_COM_CAN_CHANNEL_INDEX == 0)
131
/** \brief Macro for accessing CAN1 controller registers. */
132
#define CANx             ((tCanRegs *) (blt_int32u)0x40006400)
133
#else
134
/** \brief Macro for accessing CAN2 controller registers. */
135
#define CANx             ((tCanRegs *) (blt_int32u)0x40006800)
136
#endif
137
/** \brief Macro for accessing CAN1 controller registers. */
138
#define CAN1             ((tCanRegs *) (blt_int32u)0x40006400)
139
140
141
/****************************************************************************************
142
* Type definitions
143
****************************************************************************************/
144
/** \brief Structure type for grouping CAN bus timing related information. */
145
typedef struct t_can_bus_timing
146
{
147
  blt_int8u tseg1;                                    /**< CAN time segment 1          */
148
  blt_int8u tseg2;                                    /**< CAN time segment 2          */
149
} tCanBusTiming;
150
151
152
/****************************************************************************************
153
* Local constant declarations
154
****************************************************************************************/
155
/** \brief CAN bittiming table for dynamically calculating the bittiming settings.
156
 *  \details According to the CAN protocol 1 bit-time can be made up of between 8..25 
157
 *           time quanta (TQ). The total TQ in a bit is SYNC + TSEG1 + TSEG2 with SYNC 
158
 *           always being 1. The sample point is (SYNC + TSEG1) / (SYNC + TSEG1 + SEG2) * 
159
 *           100%. This array contains possible and valid time quanta configurations with
160
 *           a sample point between 68..78%.
161
 */
162
static const tCanBusTiming canTiming[] =
163
{                       /*  TQ | TSEG1 | TSEG2 | SP  */
164
                        /* ------------------------- */
165
    {  5, 2 },          /*   8 |   5   |   2   | 75% */
166
    {  6, 2 },          /*   9 |   6   |   2   | 78% */
167
    {  6, 3 },          /*  10 |   6   |   3   | 70% */
168
    {  7, 3 },          /*  11 |   7   |   3   | 73% */
169
    {  8, 3 },          /*  12 |   8   |   3   | 75% */
170
    {  9, 3 },          /*  13 |   9   |   3   | 77% */
171
    {  9, 4 },          /*  14 |   9   |   4   | 71% */
172
    { 10, 4 },          /*  15 |  10   |   4   | 73% */
173
    { 11, 4 },          /*  16 |  11   |   4   | 75% */
174
    { 12, 4 },          /*  17 |  12   |   4   | 76% */
175
    { 12, 5 },          /*  18 |  12   |   5   | 72% */
176
    { 13, 5 },          /*  19 |  13   |   5   | 74% */
177
    { 14, 5 },          /*  20 |  14   |   5   | 75% */
178
    { 15, 5 },          /*  21 |  15   |   5   | 76% */
179
    { 15, 6 },          /*  22 |  15   |   6   | 73% */
180
    { 16, 6 },          /*  23 |  16   |   6   | 74% */
181
    { 16, 7 },          /*  24 |  16   |   7   | 71% */
182
    { 16, 8 }           /*  25 |  16   |   8   | 68% */
183
};
184
185
int counter = 0;
186
/************************************************************************************//**
187
** \brief     Search algorithm to match the desired baudrate to a possible bus 
188
**            timing configuration.
189
** \param     baud The desired baudrate in kbps. Valid values are 10..1000.
190
** \param     prescaler Pointer to where the value for the prescaler will be stored.
191
** \param     tseg1 Pointer to where the value for TSEG2 will be stored.
192
** \param     tseg2 Pointer to where the value for TSEG2 will be stored.
193
** \return    BLT_TRUE if the CAN bustiming register values were found, BLT_FALSE 
194
**            otherwise.
195
**
196
****************************************************************************************/
197
static blt_bool CanGetSpeedConfig(blt_int16u baud, blt_int16u *prescaler, 
198
                                  blt_int8u *tseg1, blt_int8u *tseg2)
199
{
200
  blt_int8u  cnt;
201
202
  /* loop through all possible time quanta configurations to find a match */
203
  for (cnt=0; cnt < sizeof(canTiming)/sizeof(canTiming[0]); cnt++)
204
  {
205
    if (((BOOT_CPU_SYSTEM_SPEED_KHZ/4) % (baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1))) == 0)
206
    {
207
      /* compute the prescaler that goes with this TQ configuration */
208
      *prescaler = (BOOT_CPU_SYSTEM_SPEED_KHZ/4)/(baud*(canTiming[cnt].tseg1+canTiming[cnt].tseg2+1));
209
210
      /* make sure the prescaler is valid */
211
      if ( (*prescaler > 0) && (*prescaler <= 1024) )
212
      {
213
        /* store the bustiming configuration */
214
        *tseg1 = canTiming[cnt].tseg1;
215
        *tseg2 = canTiming[cnt].tseg2;
216
        /* found a good bus timing configuration */
217
        return BLT_TRUE;
218
      }
219
    }
220
  }
221
  /* could not find a good bus timing configuration */
222
  return BLT_FALSE;
223
} /*** end of CanGetSpeedConfig ***/
224
225
226
/************************************************************************************//**
227
** \brief     Initializes the CAN controller and synchronizes it to the CAN bus.
228
** \return    none.
229
**
230
****************************************************************************************/
231
void CanInit(void)
232
{
233
  blt_int16u prescaler;
234
  blt_int8u  tseg1, tseg2;
235
  blt_bool   result;
236
237
#if (BOOT_GATE_CAN_ENABLE > 0)
238
  commandSend = BLT_FALSE;
239
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
240
241
  /* the current implementation supports CAN1 and 2. throw an assertion error in case a 
242
   * different CAN channel is configured.  
243
   */
244
  ASSERT_CT((BOOT_COM_CAN_CHANNEL_INDEX == 0 || BOOT_COM_CAN_CHANNEL_INDEX == 1)); 
245
246
  /* obtain bittiming configuration information */
247
  result = CanGetSpeedConfig(BOOT_COM_CAN_BAUDRATE/1000, &prescaler, &tseg1, &tseg2);
248
  ASSERT_RT(result == BLT_TRUE);
249
  /* disable all can interrupt. this driver works in polling mode */
250
  CANx->IER = (blt_int32u)0;
251
  /* set request to reset the can controller */
252
  CANx->MCR |= CAN_BIT_RESET ;
253
  /* wait for acknowledge that the can controller was reset */
254
  while ((CANx->MCR & CAN_BIT_RESET) != 0)
255
  {
256
    /* keep the watchdog happy */
257
    CopService();
258
  }
259
  /* exit from sleep mode, which is the default mode after reset */
260
  CANx->MCR &= ~CAN_BIT_SLEEP;
261
  /* set request to enter initialisation mode */
262
  CANx->MCR |= CAN_BIT_INRQ ;
263
  /* wait for acknowledge that initialization mode was entered */
264
  while ((CANx->MSR & CAN_BIT_INAK) == 0)
265
  {
266
    /* keep the watchdog happy */
267
    CopService();
268
  }
269
  /* configure the bittming */
270
  CANx->BTR = (blt_int32u)((blt_int32u)(3) << 24) | \
271
              (blt_int32u)((blt_int32u)(tseg1 - 1) << 16) | \
272
              (blt_int32u)((blt_int32u)(tseg2 - 1) << 20) | \
273
              (blt_int32u)(prescaler - 1);
274
//  CANx->BTR = (blt_int32u)((blt_int32u)(tseg1 - 1) << 16) | \
275
              (blt_int32u)((blt_int32u)(tseg2 - 1) << 20) | \
276
              (blt_int32u)(prescaler - 1) | \
277
              (blt_int32u)(0x3 << 30);
278
//  CANx->BTR = (blt_int32u)((blt_int32u)(15) << 16) | \
279
              (blt_int32u)((blt_int32u)(3) << 20) | \
280
              (blt_int32u)((blt_int32u)(1) << 24) | \
281
              (blt_int32u)(1) | \
282
              (blt_int32u)(0x3 << 30);
283
  /* set request to leave initialisation mode */
284
  CANx->MCR &= ~CAN_BIT_INRQ;
285
  /* wait for acknowledge that initialization mode was exited */
286
  while ((CANx->MSR & CAN_BIT_INAK) != 0)
287
  {
288
    /* keep the watchdog happy */
289
    CopService();
290
  }
291
292
#if (BOOT_COM_CAN_CHANNEL_INDEX == 0)
293
  /* enter initialisation mode for the acceptance filter */
294
  CAN1->FMR |= CAN_BIT_FINIT;
295
  /* deactivate filter 0 */
296
  CAN1->FA1R &= ~CAN_BIT_FILTER0;
297
  /* 32-bit scale for the filter */
298
  CAN1->FS1R |= CAN_BIT_FILTER0;
299
  /* open up the acceptance filter to receive all messages */
300
  CAN1->sFilterRegister[0].FR1 = 0; 
301
  CAN1->sFilterRegister[0].FR2 = 0; 
302
  /* select id/mask mode for the filter */
303
  CAN1->FM1R &= ~CAN_BIT_FILTER0;
304
  /* FIFO 0 assignation for the filter */
305
  CAN1->FFA1R &= ~CAN_BIT_FILTER0;
306
  /* filter activation */
307
  CAN1->FA1R |= CAN_BIT_FILTER0;
308
  /* leave initialisation mode for the acceptance filter */
309
  CAN1->FMR &= ~CAN_BIT_FINIT;
310
#else
311
  /* enter initialisation mode for the acceptance filter */
312
  CAN1->FMR |= CAN_BIT_FINIT;
313
  /* deactivate filter 14 */
314
  CAN1->FA1R &= ~CAN_BIT_FILTER14;
315
  /* 32-bit scale for the filter */
316
  CAN1->FS1R |= CAN_BIT_FILTER14;
317
  /* open up the acceptance filter to receive all messages */
318
  CAN1->sFilterRegister[14].FR1 = 0; 
319
  CAN1->sFilterRegister[14].FR2 = 0; 
320
  /* select id/mask mode for the filter */
321
  CAN1->FM1R &= ~CAN_BIT_FILTER14;
322
  /* FIFO 0 assignation for the filter */
323
  CAN1->FFA1R &= ~CAN_BIT_FILTER14;
324
  /* filter activation */
325
  CAN1->FA1R |= CAN_BIT_FILTER14;
326
  /* leave initialisation mode for the acceptance filter */
327
  CAN1->FMR &= ~CAN_BIT_FINIT;
328
#endif  
329
} /*** end of CanInit ***/
330
331
332
/************************************************************************************//**
333
** \brief     Transmits a packet formatted for the communication interface.
334
** \param     data Pointer to byte array with data that it to be transmitted.
335
** \param     len  Number of bytes that are to be transmitted.
336
** \return    none.
337
**
338
****************************************************************************************/
339
void CanTransmitPacket(blt_int8u *data, blt_int8u len, blt_int8u deviceID)
340
{
341
  /* make sure that transmit mailbox 0 is available */
342
  ASSERT_RT((CANx->TSR&CAN_BIT_TME0) == CAN_BIT_TME0);
343
  /* store the 11-bit message identifier */
344
  CANx->sTxMailBox[0].TIR &= CAN_BIT_TXRQ;
345
346
  blt_int32u address;
347
#if (BOOT_GATE_CAN_ENABLE > 0)
348
  if (deviceID == 0) {
349
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
350
    address = (blt_int32u)BOOT_COM_CAN_TX_MSG_ID;
351
#if (BOOT_GATE_CAN_ENABLE > 0)
352
    commandSend = BLT_FALSE;
353
  } else {
354
    address = ((blt_int32u)BOOT_COM_CAN_RX_MSG_ID | (blt_int32u)deviceID);
355
    commandSend = BLT_TRUE;
356
  }
357
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
358
359
  /* init variables */
360
  blt_int8u canData[8];
361
  blt_int8u restLen = len;
362
  blt_int8u canIdx = 0;
363
364
  /* send the given package in 8 byte packages */
365
  while (restLen > 0) {
366
367
    CANx->sTxMailBox[0].TIR |= (address << 21);
368
    /* store the message date length code (DLC) */
369
    if (restLen > 7) {
370
      CANx->sTxMailBox[0].TDTR = 8;
371
    } else {
372
      CANx->sTxMailBox[0].TDTR = restLen+1;
373
    }
374
    /* Load max 8 bytes into message data bytes */
375
    canData[0] = restLen;
376
    canIdx = 1;
377
    while (restLen > 0 && canIdx < 8) {
378
      canData[canIdx] = data[len-restLen];
379
      canIdx++;
380
      restLen--;
381
    }
382
    /* fill rest with nulls */
383
    while (canIdx < 8) {
384
      canData[canIdx] = 0;
385
      canIdx++;
386
    }
387
    /* store the message data bytes */
388
    CANx->sTxMailBox[0].TDLR = (((blt_int32u)canData[3] << 24) | \
389
                                ((blt_int32u)canData[2] << 16) | \
390
                                ((blt_int32u)canData[1] <<  8) | \
391
                                ((blt_int32u)canData[0]));
392
    CANx->sTxMailBox[0].TDHR = (((blt_int32u)canData[7] << 24) | \
393
                                ((blt_int32u)canData[6] << 16) | \
394
                                ((blt_int32u)canData[5] <<  8) | \
395
                                ((blt_int32u)canData[4]));
396
    /* request the start of message transmission */
397
    CANx->sTxMailBox[0].TIR |= CAN_BIT_TXRQ;
398
    /* wait for transmit completion */
399
    while ((CANx->TSR&CAN_BIT_TME0) == 0)
400
    {
401
      /* keep the watchdog happy */
402
      CopService();
403
    }
404
405
  }
406
} /*** end of CanTransmitSinglePacket ***/
407
408
409
/************************************************************************************//**
410
** \brief     Transmits many packets formatted for the communication interface.
411
** \param     data Pointer to byte array with data that it to be transmitted.
412
** \param     len  Number of bytes that are to be transmitted.
413
** \return    none.
414

415
**
416
****************************************************************************************/
417
/*void CanTransmitPacket(blt_int8u *data, blt_int8u len, blt_int8u deviceID)
418
{
419
  static blt_int8u canPacketData[8];
420

421
  canPacketData[0] = len;
422
  blt_int8u restLength = len;
423
  while (restLength > 0) {
424
    blt_int8u canIdx = 0;
425
    if (restLength == len) {
426
      canIdx = 1;
427
    }
428

429
/*    while (restLength > 0 && canIdx < 8) {
430
      canPacketData[canIdx] = data[len-restLength];
431
      canIdx++;
432
      restLength--;
433
    }*/
434
/*    blt_int8u dataLength = 8;
435
    if (dataLength > restLength) {
436
      dataLength = restLength;
437
    }
438
    CpuMemCopy((blt_int32u)&canPacketData[1], (blt_int32u)&data[], toReceive);
439

440
    CanTransmitSinglePacket(canPacketData, canIdx, deviceID);
441
  }
442
} /*** end of CanTransmitPacket ***/
443
444
445
/************************************************************************************//**
446
** \brief     Receives a communication interface packet if one is present.
447
** \param     data Pointer to byte array where the data is to be stored.
448
** \return    Length of message (if the message is invalid, the length will be 0).
449
**
450
****************************************************************************************/
451
blt_int8u CanReceivePacket(blt_int8u *data)
452
{
453
  blt_int32u rxMsgId;
454
  blt_bool   result = BLT_FALSE;
455
  blt_int8u  length = 0;
456
457
  static blt_int8u readData[BOOT_COM_RX_MAX_DATA];
458 470d0567 Thomas Schöpping
  static blt_int8u receivedLen = 0;
459
  static blt_int8u lastLen = 0;
460
  static blt_int8u toReceive = 0;
461 69661903 Thomas Schöpping
  blt_int8u canData[8];
462
  blt_int8u restLen;
463
  blt_int8u canLength;
464
465
  /* check if a new message was received */
466
  if ((CANx->RF0R&(blt_int32u)0x00000003) > 0)
467
  {
468
    /* read out the message identifier */
469
    rxMsgId = (blt_int32u)0x000007FF & (CANx->sFIFOMailBox[0].RIR >> 21);
470
    /* is this the packet identifier */
471
472
    blt_int32u compID;
473
#if (BOOT_GATE_CAN_ENABLE > 0)
474
    if (commandSend == BLT_TRUE) {
475
      compID = (blt_int32u)BOOT_COM_CAN_TX_MSG_ID;
476
    } else {
477
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
478
      compID = (blt_int32u)BOOT_COM_CAN_RX_MSG_ID | (blt_int32u)BOOT_COM_DEVICE_ID;
479
#if (BOOT_GATE_CAN_ENABLE > 0)
480
    }
481
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
482
483
    if (rxMsgId == compID)
484
    {
485
#if (BOOT_GATE_CAN_ENABLE > 0)
486
      commandSend = BLT_FALSE;
487
#endif /* BOOT_GATE_CAN_ENABLE > 0 */
488
      result = BLT_TRUE;
489
490
      /* save length */
491
      canLength = (blt_int8u)0x0F & CANx->sFIFOMailBox[0].RDTR;
492
      /* store the received packet data */
493
      canData[0] = (blt_int8u)0xFF & CANx->sFIFOMailBox[0].RDLR;
494
      canData[1] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDLR >> 8);
495
      canData[2] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDLR >> 16);
496
      canData[3] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDLR >> 24);
497
      canData[4] = (blt_int8u)0xFF & CANx->sFIFOMailBox[0].RDHR;
498
      canData[5] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDHR >> 8);
499
      canData[6] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDHR >> 16);
500
      canData[7] = (blt_int8u)0xFF & (CANx->sFIFOMailBox[0].RDHR >> 24);
501
502
      /* Store rest length of package and check if possible */
503
      if (receivedLen == 0) {
504
        toReceive = canData[0];
505
        lastLen = canData[0];
506
      } else {
507
        restLen = canData[0];
508
        if (lastLen-restLen != 7) {
509
          // package has been lost - but nothing happens
510
        }
511
        lastLen = restLen;
512
      }
513
514
      /* store data in data package */
515
      blt_int8u idx;
516
      for (idx=1; idx < canLength; idx++) {
517
        readData[receivedLen] = canData[idx];
518
        receivedLen++;
519
      }
520
521
      /* check if full package has been received */
522
      if (receivedLen >= toReceive) {
523
        receivedLen = 0;
524
        for (idx = 0; idx < toReceive; idx++) {
525
          data[idx] = readData[idx];
526
        }
527
        length = toReceive;
528
      } else {
529
        length = 0;
530
      }
531
    }
532
    /* release FIFO0 */
533
    CANx->RF0R |= CAN_BIT_RFOM0;
534
  }
535
  return length;
536
} /*** end of CanReceiveSinglePacket ***/
537
538
539
/************************************************************************************//**
540
** \brief     Receives some communication interface packets if they are present.
541
** \param     data Pointer to byte array where the data is to be stored.
542
** \return    Length of message (if the message is invalid, the length will be 0).
543
**
544
****************************************************************************************/
545
#if (0)
546
blt_int8u CanReceivePacket(blt_int8u *data)
547
{
548
  static blt_int8u canPacketData[8];
549
  static blt_int8u canData[BOOT_COM_RX_MAX_DATA];
550
  static blt_int8u receivedLength = 0;
551
  static blt_int8u toReceive = 0;
552
553
  // get CAN packet
554
  blt_int8u len = CanReceiveSinglePacket(canPacketData);
555
556
  // check, if packet has been received
557
  if (len == 0) {
558
    return 0;
559
  }
560
561
  // if it's the first packet of a flow, save data length
562
  blt_int8u startRead = 0;
563
  if (receivedLength == 0) {
564
    toReceive = canPacketData[0];
565
    startRead = 1;
566
  }
567
568
  // copy CAN packet data into complete data packet
569
  blt_int8u canIdx = 0;
570
  while (receivedLength < toReceive && canIdx < 8) {
571
    canData[receivedLength] = canPacketData[canIdx];
572
    receivedLength++;
573
    canIdx++;
574
  }
575
576
  // check, if data packet is finished
577
  if (receivedLength == toReceive) {
578
    receivedLength = 0;
579
    CpuMemCopy((blt_int32u)data, (blt_int32u)&canData[0], toReceive);
580
    return toReceive;
581
  } else {
582
    return 0;
583
  }
584
  
585
586
} /*** end of CanReceivePacket ***/
587
#endif
588
#endif /* BOOT_COM_CAN_ENABLE > 0 || BOOT_GATE_CAN_ENABLE > 0 */
589
590
591
/*********************************** end of can.c **************************************/