]> begriffs open source - cmsis-driver-validation/blob - Source/DV_CAN.c
Updated Core conditions in the pdsc file
[cmsis-driver-validation] / Source / DV_CAN.c
1 /*-----------------------------------------------------------------------------
2  *      Name:         DV_CAN.c
3  *      Purpose:      CAN test cases
4  *----------------------------------------------------------------------------
5  *      Copyright(c) KEIL - An ARM Company
6  *----------------------------------------------------------------------------*/
7 #include "cmsis_dv.h"
8 #include "DV_Config.h"
9 #include "DV_Framework.h"
10 #include "Driver_CAN.h"
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14
15 #define CAN_MSG_SIZE          8U    // CAN data size bytes
16 #define CAN_MSG_SIZE_FD       64U   // CAN FD data size bytes
17
18 // CAN frame format according to BOSCH "CAN with Flexible Data-Rate" Specification Version 1.0
19 // released April 17th 2012
20
21 // CAN extended frame format bits (without datafield)
22                                       // SOF BASEID SRR IDE IDEXT RTR r1     r0         DLC DATA CRC CRCDEL ACK EOF
23 #define CAN_EXT_FRAME_BITS            (    1    +11  +1  +1   +18  +1 +1     +1          +4      +21     +1  +2  +7 )
24
25 // CAN FD extended frame format bits sent at NOMINAL bitrate
26                                       // SOF BASEID SRR IDE IDEXT     r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
27 #define CAN_EXT_FRAME_BITS_NOMINAL    (    1    +11  +1  +1   +18     +1  +1 +1  +1                          +2  +7 )
28
29 // CAN FD extended frame format bits sent at FD_DATA bitrate (without datafield)
30                                       // SOF BASEID SRR IDE IDEXT     r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
31 #define CAN_EXT_FRAME_BITS_FD_DATA    (                                              +1  +4      +21     +1         )
32
33 // CAN buffer pointers
34 static uint8_t *buffer_out;
35 static uint8_t *buffer_in;
36
37 // CAN bitrates
38 const uint32_t CAN_BR[] = {
39 #if (CAN_BR_1>0)
40   CAN_BR_1,
41 #endif
42 #if (CAN_BR_2>0)
43   CAN_BR_2,
44 #endif
45 #if (CAN_BR_3>0)
46   CAN_BR_3,
47 #endif
48 #if (CAN_BR_4>0)
49   CAN_BR_4,
50 #endif
51 #if (CAN_BR_5>0)
52   CAN_BR_5,
53 #endif
54 #if (CAN_BR_6>0)
55   CAN_BR_6,
56 #endif
57 };
58 const uint32_t CAN_BR_NUM = ARRAY_SIZE(CAN_BR);
59
60 // Register Driver_CAN#
61 extern ARM_DRIVER_CAN CREATE_SYMBOL(Driver_CAN, DRV_CAN);
62 static ARM_DRIVER_CAN *drv = &CREATE_SYMBOL(Driver_CAN, DRV_CAN);
63 static ARM_CAN_CAPABILITIES capab;
64 static ARM_CAN_OBJ_CAPABILITIES obj_capab;
65
66 // Event flags
67 static uint32_t volatile Event;
68
69 // Object index
70 uint32_t Obj_idx;
71
72 // CAN Signal Unit Event Callback
73 void CAN_SignalUnitEvent (uint32_t event) {
74
75   switch (event) {
76     case ARM_CAN_EVENT_UNIT_ACTIVE:
77       break;
78     case ARM_CAN_EVENT_UNIT_WARNING:
79       break;
80     case ARM_CAN_EVENT_UNIT_PASSIVE:
81       break;
82     case ARM_CAN_EVENT_UNIT_BUS_OFF:
83       break;
84   }
85 }
86
87 // CAN Signal Object Event Callback
88 void CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event) {
89   Obj_idx = obj_idx;
90   Event = event;
91 }
92
93 // CAN transfer
94 int8_t CAN_RunTransfer (uint32_t tx_obj_idx, ARM_CAN_MSG_INFO *tx_msg_info, const uint8_t *tx_data,
95                         uint32_t rx_obj_idx, ARM_CAN_MSG_INFO *rx_msg_info, uint8_t *rx_data,
96                         uint8_t size) {
97   uint32_t tick;
98
99   Event &= ~ARM_CAN_EVENT_RECEIVE;
100   drv->MessageSend(tx_obj_idx, tx_msg_info, tx_data, size);
101
102   tick = GET_SYSTICK();
103   do {
104     if ((Event & ARM_CAN_EVENT_RECEIVE)&&(Obj_idx == rx_obj_idx)) {
105       drv->MessageRead(rx_obj_idx, rx_msg_info, rx_data, size);
106       return 0;
107     }
108   }
109   while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(CAN_TRANSFER_TIMEOUT));
110   return -1;
111 }
112
113
114 /*-----------------------------------------------------------------------------
115  *      Test cases
116  *----------------------------------------------------------------------------*/
117
118 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
119 /**
120 \defgroup can_funcs CAN Validation
121 \brief CAN test cases
122 \details
123 The CAN validation test checks the API interface compliance.
124 @{
125 */
126
127 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
128 /**
129 \brief Test case: CAN_GetCapabilities
130 \details
131 The test case \b CAN_GetCapabilities verifies the function \b GetCapabilities.
132 */
133 void CAN_GetCapabilities (void) {
134   /* Get CAN capabilities */
135   capab = drv->GetCapabilities();
136   ASSERT_TRUE(&capab != NULL);
137   /* Check number of available objects */
138   if (capab.num_objects < 2U) {
139     SET_RESULT(FAILED, "Driver has less than 2 objects available");
140   }
141 }
142
143 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
144 /**
145 \brief  Test case: CAN_Initialization
146 \details
147 The test case \b CAN_Initialization verifies the CAN functions with the sequence:
148   - Initialize  without callback
149   - Uninitialize
150   - Initialize with callback
151   - Uninitialize
152 */
153 void CAN_Initialization (void) {
154
155   /* Initialize without callback */
156   ASSERT_TRUE(drv->Initialize(NULL, NULL) == ARM_DRIVER_OK);
157
158   /* Uninitialize */
159   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
160
161   /* Initialize with callback */
162   ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
163
164   /* Uninitialize */
165   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
166 }
167
168 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
169 /**
170 \brief  Test case: CAN_CheckInvalidInit
171 \details
172 The test case \b CAN_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
173   - Uninitialize
174   - PowerControl with Power off
175   - PowerControl with Power on
176   - Set Mode
177   - PowerControl with Power off
178   - Uninitialize
179 */
180 void CAN_CheckInvalidInit (void) {
181
182   /* Uninitialize */
183   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
184
185   /* Power off */
186   ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
187
188   /* Try to power on */
189   ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
190
191   /* Try to set mode */
192   ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) != ARM_DRIVER_OK);
193
194   /* Power off */
195   ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
196
197   /* Uninitialize */
198   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
199 }
200
201 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
202 /**
203 \brief  Test case: CAN_PowerControl
204 \details
205 The test case \b CAN_PowerControl verifies the \b PowerControl function with the sequence:
206  - Initialize
207  - Power on
208  - Power low
209  - Power off
210  - Uninitialize
211 */
212 void CAN_PowerControl (void) {
213   int32_t val;
214
215   /* Initialize with callback */
216   ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
217
218   /* Power on */
219   ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
220
221   /* Power low */
222   val = drv->PowerControl (ARM_POWER_LOW);
223   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { SET_RESULT(WARNING, "Low power is not supported"); }
224   else { ASSERT_TRUE(val == ARM_DRIVER_OK); }
225
226   /* Power off */
227   ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
228
229   /* Uninitialize */
230   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
231 }
232
233 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
234 /**
235 \brief  Test case: CAN_Loopback_CheckBitrate
236 \details
237 The test case \b CAN_Loopback_CheckBitrate verifies different bitrates with the sequence:
238  - Initialize
239  - Power on
240  - Change bitrate
241  - Transfer and measure transfer time
242  - Check received data against sent data
243  - Power off
244  - Uninitialize
245 */
246 void CAN_Loopback_CheckBitrate (void) {
247   int32_t val, i;
248   uint32_t bitrate, clock;
249   char str[64];
250
251   ARM_CAN_MSG_INFO tx_data_msg_info;
252   ARM_CAN_MSG_INFO rx_data_msg_info;
253   uint32_t tx_obj_idx = 0xFFFFFFFFU;
254   uint32_t rx_obj_idx = 0xFFFFFFFFU;
255
256   uint32_t ticks_measured;
257   uint32_t ticks_expected;
258   double rate;
259
260   /* Initialize with callback */
261   ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
262
263   /* Power on */
264   ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
265
266   /* Check if loopback is available */
267   capab = drv->GetCapabilities();
268   if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
269     SET_RESULT(FAILED, "Driver does not support loopback mode");
270   } else {
271
272     /* Allocate buffer */
273     buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
274     ASSERT_TRUE(buffer_out != NULL);
275     buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
276     ASSERT_TRUE(buffer_in != NULL);
277
278     /* Find first available object for receive and transmit */
279     for (i = 0U; i < capab.num_objects; i++) {
280       obj_capab = drv->ObjectGetCapabilities (i);
281       if      ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
282       else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
283     }
284
285     /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
286     memset(buffer_out,0x55U,CAN_MSG_SIZE);
287
288     /* Get clock */
289     clock = drv->GetClock();
290
291     for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
292
293       /* Activate initialization mode */
294       ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
295
296       val = ARM_DRIVER_ERROR;
297       if ((clock % (5U*(CAN_BR[bitrate]*1000U))) == 0U) {               // If CAN base clock is divisible by 5 * nominal bitrate without remainder
298         val = drv->SetBitrate   (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
299                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
300                                  ARM_CAN_BIT_PROP_SEG  (2U) |           // Set propagation segment to 2 time quanta
301                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
302                                  ARM_CAN_BIT_PHASE_SEG2(1U) |           // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
303                                  ARM_CAN_BIT_SJW       (1U));           // Resynchronization jump width is same as phase segment 2
304       }
305       if (val != ARM_DRIVER_OK) {                                       // If previous SetBitrate failed try different bit settings
306         if ((clock % (6U*(CAN_BR[bitrate]*1000U))) == 0U) {             // If CAN base clock is divisible by 6 * nominal bitrate without remainder
307           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
308                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
309                                  ARM_CAN_BIT_PROP_SEG  (3U) |           // Set propagation segment to 3 time quanta
310                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
311                                  ARM_CAN_BIT_PHASE_SEG2(1U) |           // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
312                                  ARM_CAN_BIT_SJW       (1U));           // Resynchronization jump width is same as phase segment 2
313         }
314       }
315       if (val != ARM_DRIVER_OK) {                                       // If previous SetBitrate failed try different bit settings
316         if ((clock % (8U*(CAN_BR[bitrate]*1000U))) == 0U) {             // If CAN base clock is divisible by 8 * nominal bitrate without remainder
317           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
318                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
319                                  ARM_CAN_BIT_PROP_SEG  (5U) |           // Set propagation segment to 5 time quanta
320                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
321                                  ARM_CAN_BIT_PHASE_SEG2(1U) |           // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
322                                  ARM_CAN_BIT_SJW       (1U));           // Resynchronization jump width is same as phase segment 2
323         }
324       }
325       if (val != ARM_DRIVER_OK) {                                       // If previous SetBitrate failed try different bit settings
326         if ((clock % (10U*(CAN_BR[bitrate]*1000U))) == 0U) {            // If CAN base clock is divisible by 10 * nominal bitrate without remainder
327           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
328                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
329                                  ARM_CAN_BIT_PROP_SEG  (6U) |           // Set propagation segment to 6 time quanta
330                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
331                                  ARM_CAN_BIT_PHASE_SEG2(2U) |           // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
332                                  ARM_CAN_BIT_SJW       (2U));           // Resynchronization jump width is same as phase segment 2
333         }
334       }
335       if (val != ARM_DRIVER_OK) {
336         sprintf(str,"Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate], clock/1000000U);
337         SET_RESULT(WARNING, str);
338       } else SET_RESULT(PASSED, NULL);
339
340       if (val == ARM_DRIVER_OK) {
341
342         if (capab.external_loopback == 1U) {
343           // Activate loopback external mode
344           ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
345         } else if (capab.internal_loopback == 1U) {
346           // Activate loopback internal mode
347           ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
348         }
349
350         /* ObjectSetFilter add extended exact ID 0x15555555 */
351         ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
352
353         /* ObjectConfigure for tx and rx objects */
354         ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
355         ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
356
357         /* Clear input buffer */
358         memset(buffer_in,0,CAN_MSG_SIZE);
359
360         memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
361         tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
362
363         /* Measure transfer time */
364         ticks_measured = GET_SYSTICK();
365         CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE);
366         ticks_measured = GET_SYSTICK() - ticks_measured;
367         ticks_expected = SYSTICK_MICROSEC((((CAN_MSG_SIZE * 8U) + CAN_EXT_FRAME_BITS) * 1000) / CAN_BR[bitrate]);
368
369         rate = (double)ticks_measured/ticks_expected;
370
371         if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
372           sprintf(str,"At %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate], rate);
373           SET_RESULT(WARNING, str);
374         } else SET_RESULT(PASSED, NULL);
375
376         /* Check received data against sent data*/
377         if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE)!=0) {
378           sprintf(str,"At %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate], CAN_MSG_SIZE);
379           SET_RESULT(FAILED, str);
380         } else SET_RESULT(PASSED, NULL);
381
382         /* ObjectSetFilter remove extended exact ID 0x15555555 */
383         ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
384       }
385     }
386
387     /* Free buffer */
388     free(buffer_out);
389     free(buffer_in);
390   }
391
392   /* Power off and uninitialize*/
393   ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
394   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
395 }
396
397 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
398 /**
399 \brief  Test case: CAN_Loopback_CheckBitrateFD
400 \details
401 The test case \b CAN_Loopback_CheckBitrateFD verifies different bitrates with the sequence:
402  - Initialize
403  - Power on
404  - Change bitrate
405  - Transfer and measure transfer time
406  - Check received data against sent data
407  - Power off
408  - Uninitialize
409 */
410 void CAN_Loopback_CheckBitrateFD (void) {
411   int32_t val, i;
412   uint32_t bitrate, clock;
413   char str[64];
414
415   ARM_CAN_MSG_INFO tx_data_msg_info;
416   ARM_CAN_MSG_INFO rx_data_msg_info;
417   uint32_t tx_obj_idx = 0xFFFFFFFFU;
418   uint32_t rx_obj_idx = 0xFFFFFFFFU;
419
420   uint32_t ticks_measured;
421   uint32_t ticks_expected;
422   double rate;
423
424   /* Initialize with callback */
425   ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
426
427   /* Power on */
428   ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
429
430   /* Test FD mode */
431   capab = drv->GetCapabilities();
432   if (capab.fd_mode == 0U) {
433     SET_RESULT(FAILED, "Driver does not support FD mode");
434   } else {
435
436     /* Check if loopback is available */
437     if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
438       SET_RESULT(FAILED, "Driver does not support loopback mode");
439     } else {
440
441       /* Allocate buffer */
442       buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
443       ASSERT_TRUE(buffer_out != NULL);
444       buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
445       ASSERT_TRUE(buffer_in != NULL);
446
447       /* Find first available object for receive and transmit */
448       for (i = 0U; i < capab.num_objects; i++) {
449         obj_capab = drv->ObjectGetCapabilities (i);
450         if      ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
451         else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
452       }
453
454       /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
455       memset(buffer_out,0x55U,CAN_MSG_SIZE_FD);
456
457       /* Get clock */
458       clock = drv->GetClock();
459
460       for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
461
462         /* Activate initialization mode */
463         ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
464
465         val = ARM_DRIVER_ERROR;
466         if ((clock % (5U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {          // If CAN base clock is divisible by 5 * nominal bitrate without remainder
467           val = drv->SetBitrate   (ARM_CAN_BITRATE_NOMINAL,                             // Set nominal bitrate
468                                    CAN_BR[bitrate]*1000U,                               // Set nominal bitrate to configured constant value
469                                    ARM_CAN_BIT_PROP_SEG  (2U) |                         // Set propagation segment to 2 time quanta
470                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
471                                    ARM_CAN_BIT_PHASE_SEG2(1U) |                         // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
472                                    ARM_CAN_BIT_SJW       (1U));                         // Resynchronization jump width is same as phase segment 2
473           if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,     // Set FD data phase bitrate
474                                    CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO,            // Set FD data phase bitrate to configured constant value
475                                    ARM_CAN_BIT_PROP_SEG  (2U) |                         // Set propagation segment to 2 time quanta
476                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
477                                    ARM_CAN_BIT_PHASE_SEG2(1U) |                         // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
478                                    ARM_CAN_BIT_SJW       (1U));                         // Resynchronization jump width is same as phase segment 2
479         }
480         if (val != ARM_DRIVER_OK) {                                                     // If previous SetBitrate failed try different bit settings
481           if ((clock % (6U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {        // If CAN base clock is divisible by 6 * nominal bitrate without remainder
482             val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                             // Set nominal bitrate
483                                    CAN_BR[bitrate]*1000U,                               // Set nominal bitrate to configured constant value
484                                    ARM_CAN_BIT_PROP_SEG  (3U) |                         // Set propagation segment to 3 time quanta
485                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
486                                    ARM_CAN_BIT_PHASE_SEG2(1U) |                         // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
487                                    ARM_CAN_BIT_SJW       (1U));                         // Resynchronization jump width is same as phase segment 2
488             if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,   // Set FD data phase bitrate
489                                    CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO,            // Set FD data phase bitrate to configured constant value
490                                    ARM_CAN_BIT_PROP_SEG  (3U) |                         // Set propagation segment to 3 time quanta
491                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
492                                    ARM_CAN_BIT_PHASE_SEG2(1U) |                         // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
493                                    ARM_CAN_BIT_SJW       (1U));                         // Resynchronization jump width is same as phase segment 2
494           }
495         }
496         if (val != ARM_DRIVER_OK) {                                                     // If previous SetBitrate failed try different bit settings
497           if ((clock % (8U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {        // If CAN base clock is divisible by 8 * nominal bitrate without remainder
498             val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                             // Set nominal bitrate
499                                    CAN_BR[bitrate]*1000U,                               // Set nominal bitrate to configured constant value
500                                    ARM_CAN_BIT_PROP_SEG  (5U) |                         // Set propagation segment to 5 time quanta
501                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
502                                    ARM_CAN_BIT_PHASE_SEG2(1U) |                         // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
503                                    ARM_CAN_BIT_SJW       (1U));                         // Resynchronization jump width is same as phase segment 2
504             if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,   // Set FD data phase bitrate
505                                    CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO,            // Set FD data phase bitrate to configured constant value
506                                    ARM_CAN_BIT_PROP_SEG  (5U) |                         // Set propagation segment to 5 time quanta
507                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
508                                    ARM_CAN_BIT_PHASE_SEG2(1U) |                         // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
509                                    ARM_CAN_BIT_SJW       (1U));                         // Resynchronization jump width is same as phase segment 2
510           }
511         }
512         if (val != ARM_DRIVER_OK) {                                                     // If previous SetBitrate failed try different bit settings
513           if ((clock % (10U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {// If CAN base clock is divisible by 10 * nominal bitrate without remainder
514             val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                             // Set nominal bitrate
515                                    CAN_BR[bitrate]*1000U,                               // Set nominal bitrate to configured constant value
516                                    ARM_CAN_BIT_PROP_SEG  (6U) |                         // Set propagation segment to 6 time quanta
517                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
518                                    ARM_CAN_BIT_PHASE_SEG2(2U) |                         // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
519                                    ARM_CAN_BIT_SJW       (2U));                         // Resynchronization jump width is same as phase segment 2
520             if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,   // Set FD data phase bitrate
521                                    CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO,            // Set FD data phase bitrate to configured constant value
522                                    ARM_CAN_BIT_PROP_SEG  (6U) |                         // Set propagation segment to 6 time quanta
523                                    ARM_CAN_BIT_PHASE_SEG1(1U) |                         // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
524                                    ARM_CAN_BIT_PHASE_SEG2(2U) |                         // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
525                                    ARM_CAN_BIT_SJW       (2U));                         // Resynchronization jump width is same as phase segment 2
526           }
527         }
528         if (val != ARM_DRIVER_OK) {
529           sprintf(str,"Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, clock/1000000U);
530           SET_RESULT(WARNING, str);
531         } else SET_RESULT(PASSED, NULL);
532
533         if (val == ARM_DRIVER_OK) {
534
535           if (capab.external_loopback == 1U) {
536             // Activate loopback external mode
537             ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
538           } else if (capab.internal_loopback == 1U) {
539             // Activate loopback internal mode
540             ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
541           }
542
543           /* Set FD mode */
544           ASSERT_TRUE(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
545
546           /* ObjectSetFilter add extended exact ID 0x15555555 */
547           ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
548
549           /* ObjectConfigure for tx and rx objects */
550           ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
551           ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
552
553           /* Clear input buffer */
554           memset(buffer_in,0,CAN_MSG_SIZE_FD);
555
556           memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
557           tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
558
559           /* Measure transfer time */
560           ticks_measured = GET_SYSTICK();
561           CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE_FD);
562           ticks_measured = GET_SYSTICK() - ticks_measured;
563           ticks_expected = SYSTICK_MICROSEC((((((CAN_MSG_SIZE_FD * 8U) + CAN_EXT_FRAME_BITS_FD_DATA) * 1000) / (CAN_BR[bitrate] * CAN_DATA_ARB_RATIO)) +
564                                                      (((CAN_EXT_FRAME_BITS_NOMINAL)                         * 1000) /  CAN_BR[bitrate]                      ) ));
565
566           rate = (double)ticks_measured/ticks_expected;
567
568           if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
569             sprintf(str,"At FD bitrate %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, rate);
570             SET_RESULT(WARNING, str);
571           } else SET_RESULT(PASSED, NULL);
572
573           /* Check received data against sent data*/
574           if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE_FD)!=0) {
575             sprintf(str,"At FD bitrate %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, CAN_MSG_SIZE_FD);
576             SET_RESULT(FAILED, str);
577           } else SET_RESULT(PASSED, NULL);
578
579           /* ObjectSetFilter remove extended exact ID 0x15555555 */
580           ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
581         }
582       }
583
584       /* Free buffer */
585       free(buffer_out);
586       free(buffer_in);
587     }
588   }
589
590   /* Power off and uninitialize*/
591   ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
592   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
593 }
594
595 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
596 /**
597 \brief  Test case: CAN_Loopback_Transfer
598 \details
599 The test case \b CAN_Loopback_Transfer verifies the data transfers with the sequence:
600  - Initialize
601  - Power on
602  - Set filter with standard ID
603  - Transfer and check received data against sent data
604  - Check filter with standard ID and remove it
605  - Set filter with extended ID
606  - Transfer and check received data against sent data
607  - Check filter with extended ID and remove it
608  - Power off
609  - Uninitialize
610 */
611 void CAN_Loopback_Transfer (void) {
612   int32_t val;
613   uint32_t i, cnt, clock;
614   char str[64];
615
616   ARM_CAN_MSG_INFO tx_data_msg_info;
617   ARM_CAN_MSG_INFO rx_data_msg_info;
618   uint32_t tx_obj_idx = 0xFFFFFFFFU;
619   uint32_t rx_obj_idx = 0xFFFFFFFFU;
620
621   /* Initialize with callback */
622   ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
623
624   /* Power on */
625   ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
626
627   /* Check if loopback is available */
628   capab = drv->GetCapabilities();
629   if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
630     SET_RESULT(FAILED, "Driver does not support loopback mode");
631   } else {
632
633     /* Allocate buffer */
634     buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
635     ASSERT_TRUE(buffer_out != NULL);
636     buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
637     ASSERT_TRUE(buffer_in != NULL);
638
639     /* Find first available object for receive and transmit */
640     for (i = 0U; i < capab.num_objects; i++) {
641       obj_capab = drv->ObjectGetCapabilities (i);
642       if      ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
643       else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
644     }
645
646     /* Set output buffer with random data */
647     srand(GET_SYSTICK());
648     for (cnt = 0; cnt<CAN_MSG_SIZE; cnt++) {
649       buffer_out[cnt] = rand()%0x100U;
650     }
651
652     /* Activate initialization mode */
653     ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
654
655     if (capab.external_loopback != 0U) {
656       // Activate loopback external mode
657       ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
658     } else if (capab.internal_loopback == 1U) {
659       // Activate loopback internal mode
660       ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
661     }
662
663     /* Get clock */
664     clock = drv->GetClock();
665
666     val = ARM_DRIVER_ERROR;
667     if ((clock % (5U*(CAN_BR[0]*1000U))) == 0U) {                       // If CAN base clock is divisible by 5 * nominal bitrate without remainder
668       val = drv->SetBitrate   (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
669                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
670                                ARM_CAN_BIT_PROP_SEG  (2U) |             // Set propagation segment to 2 time quanta
671                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
672                                ARM_CAN_BIT_PHASE_SEG2(1U) |             // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
673                                ARM_CAN_BIT_SJW       (1U));             // Resynchronization jump width is same as phase segment 2
674     }
675     if (val != ARM_DRIVER_OK) {                                         // If previous SetBitrate failed try different bit settings
676       if ((clock % (6U*(CAN_BR[0]*1000U))) == 0U) {                     // If CAN base clock is divisible by 6 * nominal bitrate without remainder
677         val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
678                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
679                                ARM_CAN_BIT_PROP_SEG  (3U) |             // Set propagation segment to 3 time quanta
680                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
681                                ARM_CAN_BIT_PHASE_SEG2(1U) |             // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
682                                ARM_CAN_BIT_SJW       (1U));             // Resynchronization jump width is same as phase segment 2
683       }
684     }
685     if (val != ARM_DRIVER_OK) {                                         // If previous SetBitrate failed try different bit settings
686       if ((clock % (8U*(CAN_BR[0]*1000U))) == 0U) {                     // If CAN base clock is divisible by 8 * nominal bitrate without remainder
687         val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
688                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
689                                ARM_CAN_BIT_PROP_SEG  (5U) |             // Set propagation segment to 5 time quanta
690                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
691                                ARM_CAN_BIT_PHASE_SEG2(1U) |             // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
692                                ARM_CAN_BIT_SJW       (1U));             // Resynchronization jump width is same as phase segment 2
693       }
694     }
695     if (val != ARM_DRIVER_OK) {                                         // If previous SetBitrate failed try different bit settings
696       if ((clock % (10U*(CAN_BR[0]*1000U))) == 0U) {                    // If CAN base clock is divisible by 10 * nominal bitrate without remainder
697         val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
698                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
699                                ARM_CAN_BIT_PROP_SEG  (6U) |             // Set propagation segment to 6 time quanta
700                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
701                                ARM_CAN_BIT_PHASE_SEG2(2U) |             // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
702                                ARM_CAN_BIT_SJW       (2U));             // Resynchronization jump width is same as phase segment 2
703       }
704     }
705     if (val != ARM_DRIVER_OK) {
706       sprintf(str,"Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[0], clock/1000000U);
707       SET_RESULT(WARNING, str);
708     } else SET_RESULT(PASSED, NULL);
709
710     /* ObjectSetFilter add standard exact ID 0x7FF */
711     ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
712
713     /* ObjectConfigure for tx and rx objects */
714     ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
715     ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
716
717     memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
718     tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
719
720     /* Transfer data chunks */
721     for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
722       /* Clear input buffer */
723       memset(buffer_in,0,CAN_MSG_SIZE);
724       if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
725         sprintf(str,"Fail to transfer block of %d bytes",cnt);
726         SET_RESULT(FAILED, str);
727       } else SET_RESULT(PASSED, NULL);
728       if (memcmp(buffer_in, buffer_out, cnt)!=0) {
729         sprintf(str,"Fail to check block of %d bytes",cnt);
730         SET_RESULT(FAILED, str);
731       } else SET_RESULT(PASSED, NULL);
732     }
733
734     /* Check if a different random ID is filtered */
735     tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
736     memset(buffer_in,0,CAN_MSG_SIZE);
737     ASSERT_TRUE(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
738                                  rx_obj_idx, &rx_data_msg_info, buffer_in,
739                                  CAN_MSG_SIZE) != ARM_DRIVER_OK);
740
741     /* ObjectSetFilter remove standard exact ID 0x7FF */
742     ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
743
744
745     /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
746     ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
747
748     /* ObjectConfigure for tx and rx objects */
749     ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
750     ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
751
752     memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
753     tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
754
755     /* Transfer data chunks */
756     for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
757       /* Clear input buffer */
758       memset(buffer_in,0,CAN_MSG_SIZE);
759       if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
760         sprintf(str,"Fail to transfer block of %d bytes",cnt);
761         SET_RESULT(FAILED, str);
762       } else SET_RESULT(PASSED, NULL);
763       if (memcmp(buffer_in, buffer_out, cnt)!=0) {
764         sprintf(str,"Fail to check block of %d bytes",cnt);
765         SET_RESULT(FAILED, str);
766       } else SET_RESULT(PASSED, NULL);
767     }
768
769     /* Check if a different random ID is filtered */
770     tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
771     memset(buffer_in,0,CAN_MSG_SIZE);
772     ASSERT_TRUE(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
773                                  rx_obj_idx, &rx_data_msg_info, buffer_in,
774                                  CAN_MSG_SIZE) != ARM_DRIVER_OK);
775
776     /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
777     ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
778
779     /* Free buffer */
780     free(buffer_out);
781     free(buffer_in);
782   }
783
784   /* Power off and uninitialize*/
785   ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
786   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
787 }
788
789 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
790 /**
791 \brief  Test case: CAN_Loopback_TransferFD
792 \details
793 The test case \b CAN_Loopback_TransferFD verifies the data transfers with the sequence:
794  - Initialize
795  - Power on
796  - Set filter with standard ID
797  - Transfer and check received data against sent data
798  - Check filter with standard ID and remove it
799  - Set filter with extended ID
800  - Transfer and check received data against sent data
801  - Check filter with extended ID and remove it
802  - Power off
803  - Uninitialize
804 */
805 void CAN_Loopback_TransferFD (void) {
806   int32_t val;
807   uint32_t i, cnt, clock;
808   char str[64];
809
810   ARM_CAN_MSG_INFO tx_data_msg_info;
811   ARM_CAN_MSG_INFO rx_data_msg_info;
812   uint32_t tx_obj_idx = 0xFFFFFFFFU;
813   uint32_t rx_obj_idx = 0xFFFFFFFFU;
814
815   /* Initialize with callback */
816   ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
817
818   /* Power on */
819   ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
820
821   /* Test FD mode */
822   capab = drv->GetCapabilities();
823   if (capab.fd_mode == 0U) {
824     SET_RESULT(FAILED, "Driver does not support FD mode");
825   } else {
826
827     /* Check if loopback is available */
828     if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
829       SET_RESULT(FAILED, "Driver does not support loopback mode");
830     } else {
831
832       /* Allocate buffer */
833       buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
834       ASSERT_TRUE(buffer_out != NULL);
835       buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
836       ASSERT_TRUE(buffer_in != NULL);
837
838       /* Find first available object for receive and transmit */
839       for (i = 0U; i < capab.num_objects; i++) {
840         obj_capab = drv->ObjectGetCapabilities (i);
841         if      ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
842         else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
843       }
844
845       /* Set output buffer with random data */
846       srand(GET_SYSTICK());
847       for (cnt = 0; cnt<CAN_MSG_SIZE_FD; cnt++) {
848         buffer_out[cnt] = rand()%0x100;
849       }
850
851       /* Activate initialization mode */
852       ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
853
854       if (capab.external_loopback != 0U) {
855         // Activate loopback external mode
856         ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
857       } else if (capab.internal_loopback == 1U) {
858         // Activate loopback internal mode
859         ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
860       }
861
862       /* Get clock */
863       clock = drv->GetClock();
864
865       val = ARM_DRIVER_ERROR;
866       if ((clock % (5U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {                  // If CAN base clock is divisible by 5 * nominal bitrate without remainder
867         val = drv->SetBitrate   (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
868                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
869                                  ARM_CAN_BIT_PROP_SEG  (2U) |                           // Set propagation segment to 2 time quanta
870                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
871                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
872                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
873         if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,       // Set FD data phase bitrate
874                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
875                                  ARM_CAN_BIT_PROP_SEG  (2U) |                           // Set propagation segment to 2 time quanta
876                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
877                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
878                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
879       }
880       if (val != ARM_DRIVER_OK) {                                                       // If previous SetBitrate failed try different bit settings
881         if ((clock % (6U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {                // If CAN base clock is divisible by 6 * nominal bitrate without remainder
882           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
883                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
884                                  ARM_CAN_BIT_PROP_SEG  (3U) |                           // Set propagation segment to 3 time quanta
885                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
886                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
887                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
888           if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,     // Set FD data phase bitrate
889                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
890                                  ARM_CAN_BIT_PROP_SEG  (3U) |                           // Set propagation segment to 3 time quanta
891                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
892                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
893                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
894         }
895       }
896       if (val != ARM_DRIVER_OK) {                                                       // If previous SetBitrate failed try different bit settings
897         if ((clock % (8U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {                // If CAN base clock is divisible by 8 * nominal bitrate without remainder
898           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
899                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
900                                  ARM_CAN_BIT_PROP_SEG  (5U) |                           // Set propagation segment to 5 time quanta
901                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
902                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
903                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
904           if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,     // Set FD data phase bitrate
905                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
906                                  ARM_CAN_BIT_PROP_SEG  (5U) |                           // Set propagation segment to 5 time quanta
907                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
908                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
909                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
910         }
911       }
912       if (val != ARM_DRIVER_OK) {                                                       // If previous SetBitrate failed try different bit settings
913         if ((clock % (10U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {               // If CAN base clock is divisible by 10 * nominal bitrate without remainder
914           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
915                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
916                                  ARM_CAN_BIT_PROP_SEG  (6U) |                           // Set propagation segment to 6 time quanta
917                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
918                                  ARM_CAN_BIT_PHASE_SEG2(2U) |                           // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
919                                  ARM_CAN_BIT_SJW       (2U));                           // Resynchronization jump width is same as phase segment 2
920           if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,     // Set FD data phase bitrate
921                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
922                                  ARM_CAN_BIT_PROP_SEG  (6U) |                           // Set propagation segment to 6 time quanta
923                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
924                                  ARM_CAN_BIT_PHASE_SEG2(2U) |                           // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
925                                  ARM_CAN_BIT_SJW       (2U));                           // Resynchronization jump width is same as phase segment 2
926         }
927       }
928       if (val != ARM_DRIVER_OK) {
929         sprintf(str,"Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[0]*CAN_DATA_ARB_RATIO, clock/1000000U);
930         SET_RESULT(WARNING, str);
931       } else SET_RESULT(PASSED, NULL);
932
933       /* Set FD mode */
934       ASSERT_TRUE(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
935
936       /* ObjectSetFilter add standard exact ID 0x7FF */
937       ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
938
939       /* ObjectConfigure for tx and rx objects */
940       ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
941       ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
942
943       memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
944       tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
945
946       /* Transfer data chunks */
947       for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
948         /* Clear input buffer */
949         memset(buffer_in,0,CAN_MSG_SIZE_FD);
950         if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
951           sprintf(str,"Fail to transfer block of %d bytes",cnt);
952           SET_RESULT(FAILED, str);
953         } else SET_RESULT(PASSED, NULL);
954         if (memcmp(buffer_in, buffer_out, cnt)!=0) {
955           sprintf(str,"Fail to check block of %d bytes",cnt);
956           SET_RESULT(FAILED, str);
957         } else SET_RESULT(PASSED, NULL);
958       }
959
960       /* Check if a different random ID is filtered */
961       tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
962       memset(buffer_in,0,CAN_MSG_SIZE_FD);
963       ASSERT_TRUE(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
964                                    rx_obj_idx, &rx_data_msg_info, buffer_in,
965                                    CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
966
967       /* ObjectSetFilter remove standard exact ID 0x7FF */
968       ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
969
970
971       /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
972       ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
973
974       /* ObjectConfigure for tx and rx objects */
975       ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
976       ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
977
978       memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
979       tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
980
981       /* Transfer data chunks */
982       for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
983         /* Clear input buffer */
984         memset(buffer_in,0,CAN_MSG_SIZE_FD);
985         if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
986           sprintf(str,"Fail to transfer block of %d bytes",cnt);
987           SET_RESULT(FAILED, str);
988         } else SET_RESULT(PASSED, NULL);
989         if (memcmp(buffer_in, buffer_out, cnt)!=0) {
990           sprintf(str,"Fail to check block of %d bytes",cnt);
991           SET_RESULT(FAILED, str);
992         } else SET_RESULT(PASSED, NULL);
993       }
994
995       /* Check if a different random ID is filtered */
996       tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
997       memset(buffer_in,0,CAN_MSG_SIZE_FD);
998       ASSERT_TRUE(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
999                                    rx_obj_idx, &rx_data_msg_info, buffer_in,
1000                                    CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
1001
1002       /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
1003       ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
1004
1005       /* Free buffer */
1006       free(buffer_out);
1007       free(buffer_in);
1008     }
1009   }
1010
1011   /* Power off and uninitialize*/
1012   ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
1013   ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
1014 }
1015
1016 /**
1017 @}
1018 */
1019 // end of group can_funcs
1020