]> begriffs open source - cmsis-driver-validation/blob - Source/DV_CAN.c
Merge branch 'develop'
[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 static char str[128];
67
68 // Event flags
69 static uint32_t volatile Event;
70
71 // Object index
72 uint32_t Obj_idx;
73
74 // CAN Signal Unit Event Callback
75 void CAN_SignalUnitEvent (uint32_t event) {
76
77   switch (event) {
78     case ARM_CAN_EVENT_UNIT_ACTIVE:
79       break;
80     case ARM_CAN_EVENT_UNIT_WARNING:
81       break;
82     case ARM_CAN_EVENT_UNIT_PASSIVE:
83       break;
84     case ARM_CAN_EVENT_UNIT_BUS_OFF:
85       break;
86   }
87 }
88
89 // CAN Signal Object Event Callback
90 void CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event) {
91   Obj_idx = obj_idx;
92   Event = event;
93 }
94
95 // CAN transfer
96 int8_t CAN_RunTransfer (uint32_t tx_obj_idx, ARM_CAN_MSG_INFO *tx_msg_info, const uint8_t *tx_data,
97                         uint32_t rx_obj_idx, ARM_CAN_MSG_INFO *rx_msg_info, uint8_t *rx_data,
98                         uint8_t size) {
99   uint32_t tick;
100
101   Event &= ~ARM_CAN_EVENT_RECEIVE;
102   drv->MessageSend(tx_obj_idx, tx_msg_info, tx_data, size);
103
104   tick = GET_SYSTICK();
105   do {
106     if ((Event & ARM_CAN_EVENT_RECEIVE)&&(Obj_idx == rx_obj_idx)) {
107       drv->MessageRead(rx_obj_idx, rx_msg_info, rx_data, size);
108       return 0;
109     }
110   }
111   while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(CAN_TRANSFER_TIMEOUT));
112   return -1;
113 }
114
115
116 /*-----------------------------------------------------------------------------
117  *      Test cases
118  *----------------------------------------------------------------------------*/
119
120 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
121 /**
122 \defgroup can_funcs CAN Validation
123 \brief CAN test cases
124 \details
125 The CAN validation test checks the API interface compliance.
126 @{
127 */
128
129 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
130 /**
131 \brief Test case: CAN_GetCapabilities
132 \details
133 The test case \b CAN_GetCapabilities verifies the function \b GetCapabilities.
134 */
135 void CAN_GetCapabilities (void) {
136   /* Get CAN capabilities */
137   capab = drv->GetCapabilities();
138   TEST_ASSERT(&capab != NULL);
139   /* Check number of available objects */
140   if (capab.num_objects < 2U) {
141     TEST_FAIL_MESSAGE("[FAILED] Driver has less than 2 objects available");
142   }
143 }
144
145 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
146 /**
147 \brief  Test case: CAN_Initialization
148 \details
149 The test case \b CAN_Initialization verifies the CAN functions with the sequence:
150   - Initialize  without callback
151   - Uninitialize
152   - Initialize with callback
153   - Uninitialize
154 */
155 void CAN_Initialization (void) {
156
157   /* Initialize without callback */
158   TEST_ASSERT(drv->Initialize(NULL, NULL) == ARM_DRIVER_OK);
159
160   /* Uninitialize */
161   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
162
163   /* Initialize with callback */
164   TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
165
166   /* Uninitialize */
167   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
168 }
169
170 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
171 /**
172 \brief  Test case: CAN_CheckInvalidInit
173 \details
174 The test case \b CAN_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
175   - Uninitialize
176   - PowerControl with Power off
177   - PowerControl with Power on
178   - Set Mode
179   - PowerControl with Power off
180   - Uninitialize
181 */
182 void CAN_CheckInvalidInit (void) {
183
184   /* Uninitialize */
185   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
186
187   /* Power off */
188   TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
189
190   /* Try to power on */
191   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
192
193   /* Try to set mode */
194   TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) != ARM_DRIVER_OK);
195
196   /* Power off */
197   TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
198
199   /* Uninitialize */
200   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
201 }
202
203 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
204 /**
205 \brief  Test case: CAN_PowerControl
206 \details
207 The test case \b CAN_PowerControl verifies the \b PowerControl function with the sequence:
208  - Initialize
209  - Power on
210  - Power low
211  - Power off
212  - Uninitialize
213 */
214 void CAN_PowerControl (void) {
215   int32_t val;
216
217   /* Initialize with callback */
218   TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
219
220   /* Power on */
221   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
222
223   /* Power low */
224   val = drv->PowerControl (ARM_POWER_LOW);
225   if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
226   else { TEST_ASSERT(val == ARM_DRIVER_OK); }
227
228   /* Power off */
229   TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
230
231   /* Uninitialize */
232   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
233 }
234
235 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
236 /**
237 \brief  Test case: CAN_Loopback_CheckBitrate
238 \details
239 The test case \b CAN_Loopback_CheckBitrate verifies different bitrates with the sequence:
240  - Initialize
241  - Power on
242  - Change bitrate
243  - Transfer and measure transfer time
244  - Check received data against sent data
245  - Power off
246  - Uninitialize
247 */
248 void CAN_Loopback_CheckBitrate (void) {
249   int32_t val, i;
250   uint32_t bitrate, clock;
251
252   ARM_CAN_MSG_INFO tx_data_msg_info;
253   ARM_CAN_MSG_INFO rx_data_msg_info;
254   uint32_t tx_obj_idx = 0xFFFFFFFFU;
255   uint32_t rx_obj_idx = 0xFFFFFFFFU;
256
257   uint32_t ticks_measured;
258   uint32_t ticks_expected;
259   double rate;
260
261   /* Initialize with callback */
262   TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
263
264   /* Power on */
265   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
266
267   /* Check if loopback is available */
268   capab = drv->GetCapabilities();
269   if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
270     TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
271   } else {
272
273     /* Allocate buffer */
274     buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
275     TEST_ASSERT(buffer_out != NULL);
276     buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
277     TEST_ASSERT(buffer_in != NULL);
278
279     /* Find first available object for receive and transmit */
280     for (i = 0U; i < capab.num_objects; i++) {
281       obj_capab = drv->ObjectGetCapabilities (i);
282       if      ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
283       else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
284     }
285
286     /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
287     memset(buffer_out,0x55U,CAN_MSG_SIZE);
288
289     /* Get clock */
290     clock = drv->GetClock();
291
292     for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
293
294       /* Activate initialization mode */
295       TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
296
297       val = ARM_DRIVER_ERROR;
298       if ((clock % (5U*(CAN_BR[bitrate]*1000U))) == 0U) {               // If CAN base clock is divisible by 5 * nominal bitrate without remainder
299         val = drv->SetBitrate   (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
300                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
301                                  ARM_CAN_BIT_PROP_SEG  (2U) |           // Set propagation segment to 2 time quanta
302                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
303                                  ARM_CAN_BIT_PHASE_SEG2(1U) |           // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
304                                  ARM_CAN_BIT_SJW       (1U));           // Resynchronization jump width is same as phase segment 2
305       }
306       if (val != ARM_DRIVER_OK) {                                       // If previous SetBitrate failed try different bit settings
307         if ((clock % (6U*(CAN_BR[bitrate]*1000U))) == 0U) {             // If CAN base clock is divisible by 6 * nominal bitrate without remainder
308           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
309                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
310                                  ARM_CAN_BIT_PROP_SEG  (3U) |           // Set propagation segment to 3 time quanta
311                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
312                                  ARM_CAN_BIT_PHASE_SEG2(1U) |           // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
313                                  ARM_CAN_BIT_SJW       (1U));           // Resynchronization jump width is same as phase segment 2
314         }
315       }
316       if (val != ARM_DRIVER_OK) {                                       // If previous SetBitrate failed try different bit settings
317         if ((clock % (8U*(CAN_BR[bitrate]*1000U))) == 0U) {             // If CAN base clock is divisible by 8 * nominal bitrate without remainder
318           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
319                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
320                                  ARM_CAN_BIT_PROP_SEG  (5U) |           // Set propagation segment to 5 time quanta
321                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
322                                  ARM_CAN_BIT_PHASE_SEG2(1U) |           // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
323                                  ARM_CAN_BIT_SJW       (1U));           // Resynchronization jump width is same as phase segment 2
324         }
325       }
326       if (val != ARM_DRIVER_OK) {                                       // If previous SetBitrate failed try different bit settings
327         if ((clock % (10U*(CAN_BR[bitrate]*1000U))) == 0U) {            // If CAN base clock is divisible by 10 * nominal bitrate without remainder
328           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,               // Set nominal bitrate
329                                  CAN_BR[bitrate]*1000U,                 // Set nominal bitrate to configured constant value
330                                  ARM_CAN_BIT_PROP_SEG  (6U) |           // Set propagation segment to 6 time quanta
331                                  ARM_CAN_BIT_PHASE_SEG1(1U) |           // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
332                                  ARM_CAN_BIT_PHASE_SEG2(2U) |           // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
333                                  ARM_CAN_BIT_SJW       (2U));           // Resynchronization jump width is same as phase segment 2
334         }
335       }
336       if (val != ARM_DRIVER_OK) {
337         snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate], clock/1000000U);
338         TEST_MESSAGE(str);
339       } else TEST_PASS();
340
341       if (val == ARM_DRIVER_OK) {
342
343         if (capab.external_loopback == 1U) {
344           // Activate loopback external mode
345           TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
346         } else if (capab.internal_loopback == 1U) {
347           // Activate loopback internal mode
348           TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
349         }
350
351         /* ObjectSetFilter add extended exact ID 0x15555555 */
352         TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
353
354         /* ObjectConfigure for tx and rx objects */
355         TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
356         TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
357
358         /* Clear input buffer */
359         memset(buffer_in,0,CAN_MSG_SIZE);
360
361         memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
362         tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
363
364         /* Measure transfer time */
365         ticks_measured = GET_SYSTICK();
366         CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE);
367         ticks_measured = GET_SYSTICK() - ticks_measured;
368         ticks_expected = SYSTICK_MICROSEC((((CAN_MSG_SIZE * 8U) + CAN_EXT_FRAME_BITS) * 1000) / CAN_BR[bitrate]);
369
370         rate = (double)ticks_measured/ticks_expected;
371
372         if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
373           snprintf(str,sizeof(str),"[WARNING] At %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate], rate);
374           TEST_MESSAGE(str);
375         } else TEST_PASS();
376
377         /* Check received data against sent data*/
378         if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE)!=0) {
379           snprintf(str,sizeof(str),"[FAILED] At %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate], CAN_MSG_SIZE);
380           TEST_FAIL_MESSAGE(str);
381         } else TEST_PASS();
382
383         /* ObjectSetFilter remove extended exact ID 0x15555555 */
384         TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
385       }
386     }
387
388     /* Free buffer */
389     free(buffer_out);
390     free(buffer_in);
391   }
392
393   /* Power off and uninitialize*/
394   TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
395   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
396 }
397
398 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
399 /**
400 \brief  Test case: CAN_Loopback_CheckBitrateFD
401 \details
402 The test case \b CAN_Loopback_CheckBitrateFD verifies different bitrates with the sequence:
403  - Initialize
404  - Power on
405  - Change bitrate
406  - Transfer and measure transfer time
407  - Check received data against sent data
408  - Power off
409  - Uninitialize
410 */
411 void CAN_Loopback_CheckBitrateFD (void) {
412   int32_t val, i;
413   uint32_t bitrate, clock;
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   TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
426
427   /* Power on */
428   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
429
430   /* Test FD mode */
431   capab = drv->GetCapabilities();
432   if (capab.fd_mode == 0U) {
433     TEST_FAIL_MESSAGE("[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       TEST_FAIL_MESSAGE("[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       TEST_ASSERT(buffer_out != NULL);
444       buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
445       TEST_ASSERT(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         TEST_ASSERT(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           snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, clock/1000000U);
530           TEST_MESSAGE(str);
531         } else TEST_PASS();
532
533         if (val == ARM_DRIVER_OK) {
534
535           if (capab.external_loopback == 1U) {
536             // Activate loopback external mode
537             TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
538           } else if (capab.internal_loopback == 1U) {
539             // Activate loopback internal mode
540             TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
541           }
542
543           /* Set FD mode */
544           TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
545
546           /* ObjectSetFilter add extended exact ID 0x15555555 */
547           TEST_ASSERT(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           TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
551           TEST_ASSERT(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             snprintf(str,sizeof(str),"[WARNING] At FD bitrate %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, rate);
570             TEST_MESSAGE(str);
571           } else TEST_PASS();
572
573           /* Check received data against sent data*/
574           if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE_FD)!=0) {
575             snprintf(str,sizeof(str),"[FAILED] At FD bitrate %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, CAN_MSG_SIZE_FD);
576             TEST_FAIL_MESSAGE(str);
577           } else TEST_PASS();
578
579           /* ObjectSetFilter remove extended exact ID 0x15555555 */
580           TEST_ASSERT(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   TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
592   TEST_ASSERT(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
615   ARM_CAN_MSG_INFO tx_data_msg_info;
616   ARM_CAN_MSG_INFO rx_data_msg_info;
617   uint32_t tx_obj_idx = 0xFFFFFFFFU;
618   uint32_t rx_obj_idx = 0xFFFFFFFFU;
619
620   /* Initialize with callback */
621   TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
622
623   /* Power on */
624   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
625
626   /* Check if loopback is available */
627   capab = drv->GetCapabilities();
628   if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
629     TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
630   } else {
631
632     /* Allocate buffer */
633     buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
634     TEST_ASSERT(buffer_out != NULL);
635     buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
636     TEST_ASSERT(buffer_in != NULL);
637
638     /* Find first available object for receive and transmit */
639     for (i = 0U; i < capab.num_objects; i++) {
640       obj_capab = drv->ObjectGetCapabilities (i);
641       if      ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
642       else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
643     }
644
645     /* Set output buffer with random data */
646     srand(GET_SYSTICK());
647     for (cnt = 0; cnt<CAN_MSG_SIZE; cnt++) {
648       buffer_out[cnt] = rand()%0x100U;
649     }
650
651     /* Activate initialization mode */
652     TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
653
654     if (capab.external_loopback != 0U) {
655       // Activate loopback external mode
656       TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
657     } else if (capab.internal_loopback == 1U) {
658       // Activate loopback internal mode
659       TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
660     }
661
662     /* Get clock */
663     clock = drv->GetClock();
664
665     val = ARM_DRIVER_ERROR;
666     if ((clock % (5U*(CAN_BR[0]*1000U))) == 0U) {                       // If CAN base clock is divisible by 5 * nominal bitrate without remainder
667       val = drv->SetBitrate   (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
668                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
669                                ARM_CAN_BIT_PROP_SEG  (2U) |             // Set propagation segment to 2 time quanta
670                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
671                                ARM_CAN_BIT_PHASE_SEG2(1U) |             // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
672                                ARM_CAN_BIT_SJW       (1U));             // Resynchronization jump width is same as phase segment 2
673     }
674     if (val != ARM_DRIVER_OK) {                                         // If previous SetBitrate failed try different bit settings
675       if ((clock % (6U*(CAN_BR[0]*1000U))) == 0U) {                     // If CAN base clock is divisible by 6 * nominal bitrate without remainder
676         val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
677                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
678                                ARM_CAN_BIT_PROP_SEG  (3U) |             // Set propagation segment to 3 time quanta
679                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
680                                ARM_CAN_BIT_PHASE_SEG2(1U) |             // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
681                                ARM_CAN_BIT_SJW       (1U));             // Resynchronization jump width is same as phase segment 2
682       }
683     }
684     if (val != ARM_DRIVER_OK) {                                         // If previous SetBitrate failed try different bit settings
685       if ((clock % (8U*(CAN_BR[0]*1000U))) == 0U) {                     // If CAN base clock is divisible by 8 * nominal bitrate without remainder
686         val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
687                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
688                                ARM_CAN_BIT_PROP_SEG  (5U) |             // Set propagation segment to 5 time quanta
689                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
690                                ARM_CAN_BIT_PHASE_SEG2(1U) |             // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
691                                ARM_CAN_BIT_SJW       (1U));             // Resynchronization jump width is same as phase segment 2
692       }
693     }
694     if (val != ARM_DRIVER_OK) {                                         // If previous SetBitrate failed try different bit settings
695       if ((clock % (10U*(CAN_BR[0]*1000U))) == 0U) {                    // If CAN base clock is divisible by 10 * nominal bitrate without remainder
696         val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                 // Set nominal bitrate
697                                CAN_BR[0]*1000U,                         // Set nominal bitrate to configured constant value
698                                ARM_CAN_BIT_PROP_SEG  (6U) |             // Set propagation segment to 6 time quanta
699                                ARM_CAN_BIT_PHASE_SEG1(1U) |             // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
700                                ARM_CAN_BIT_PHASE_SEG2(2U) |             // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
701                                ARM_CAN_BIT_SJW       (2U));             // Resynchronization jump width is same as phase segment 2
702       }
703     }
704     if (val != ARM_DRIVER_OK) {
705       snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[0], clock/1000000U);
706       TEST_MESSAGE(str);
707     } else TEST_PASS();
708
709     /* ObjectSetFilter add standard exact ID 0x7FF */
710     TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
711
712     /* ObjectConfigure for tx and rx objects */
713     TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
714     TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
715
716     memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
717     tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
718
719     /* Transfer data chunks */
720     for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
721       /* Clear input buffer */
722       memset(buffer_in,0,CAN_MSG_SIZE);
723       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) {
724         snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
725         TEST_FAIL_MESSAGE(str);
726       } else TEST_PASS();
727       if (memcmp(buffer_in, buffer_out, cnt)!=0) {
728         snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
729         TEST_FAIL_MESSAGE(str);
730       } else TEST_PASS();
731     }
732
733     /* Check if a different random ID is filtered */
734     tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
735     memset(buffer_in,0,CAN_MSG_SIZE);
736     TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
737                                  rx_obj_idx, &rx_data_msg_info, buffer_in,
738                                  CAN_MSG_SIZE) != ARM_DRIVER_OK);
739
740     /* ObjectSetFilter remove standard exact ID 0x7FF */
741     TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
742
743
744     /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
745     TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
746
747     /* ObjectConfigure for tx and rx objects */
748     TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
749     TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
750
751     memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
752     tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
753
754     /* Transfer data chunks */
755     for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
756       /* Clear input buffer */
757       memset(buffer_in,0,CAN_MSG_SIZE);
758       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) {
759         snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
760         TEST_FAIL_MESSAGE(str);
761       } else TEST_PASS();
762       if (memcmp(buffer_in, buffer_out, cnt)!=0) {
763         snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
764         TEST_FAIL_MESSAGE(str);
765       } else TEST_PASS();
766     }
767
768     /* Check if a different random ID is filtered */
769     tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
770     memset(buffer_in,0,CAN_MSG_SIZE);
771     TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
772                                  rx_obj_idx, &rx_data_msg_info, buffer_in,
773                                  CAN_MSG_SIZE) != ARM_DRIVER_OK);
774
775     /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
776     TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
777
778     /* Free buffer */
779     free(buffer_out);
780     free(buffer_in);
781   }
782
783   /* Power off and uninitialize*/
784   TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
785   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
786 }
787
788 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
789 /**
790 \brief  Test case: CAN_Loopback_TransferFD
791 \details
792 The test case \b CAN_Loopback_TransferFD verifies the data transfers with the sequence:
793  - Initialize
794  - Power on
795  - Set filter with standard ID
796  - Transfer and check received data against sent data
797  - Check filter with standard ID and remove it
798  - Set filter with extended ID
799  - Transfer and check received data against sent data
800  - Check filter with extended ID and remove it
801  - Power off
802  - Uninitialize
803 */
804 void CAN_Loopback_TransferFD (void) {
805   int32_t val;
806   uint32_t i, cnt, clock;
807
808   ARM_CAN_MSG_INFO tx_data_msg_info;
809   ARM_CAN_MSG_INFO rx_data_msg_info;
810   uint32_t tx_obj_idx = 0xFFFFFFFFU;
811   uint32_t rx_obj_idx = 0xFFFFFFFFU;
812
813   /* Initialize with callback */
814   TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
815
816   /* Power on */
817   TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
818
819   /* Test FD mode */
820   capab = drv->GetCapabilities();
821   if (capab.fd_mode == 0U) {
822     TEST_FAIL_MESSAGE("[FAILED] Driver does not support FD mode");
823   } else {
824
825     /* Check if loopback is available */
826     if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
827       TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
828     } else {
829
830       /* Allocate buffer */
831       buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
832       TEST_ASSERT(buffer_out != NULL);
833       buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
834       TEST_ASSERT(buffer_in != NULL);
835
836       /* Find first available object for receive and transmit */
837       for (i = 0U; i < capab.num_objects; i++) {
838         obj_capab = drv->ObjectGetCapabilities (i);
839         if      ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
840         else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
841       }
842
843       /* Set output buffer with random data */
844       srand(GET_SYSTICK());
845       for (cnt = 0; cnt<CAN_MSG_SIZE_FD; cnt++) {
846         buffer_out[cnt] = rand()%0x100;
847       }
848
849       /* Activate initialization mode */
850       TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
851
852       if (capab.external_loopback != 0U) {
853         // Activate loopback external mode
854         TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
855       } else if (capab.internal_loopback == 1U) {
856         // Activate loopback internal mode
857         TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
858       }
859
860       /* Get clock */
861       clock = drv->GetClock();
862
863       val = ARM_DRIVER_ERROR;
864       if ((clock % (5U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {                  // If CAN base clock is divisible by 5 * nominal bitrate without remainder
865         val = drv->SetBitrate   (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
866                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
867                                  ARM_CAN_BIT_PROP_SEG  (2U) |                           // Set propagation segment to 2 time quanta
868                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
869                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
870                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
871         if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,       // Set FD data phase bitrate
872                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
873                                  ARM_CAN_BIT_PROP_SEG  (2U) |                           // Set propagation segment to 2 time quanta
874                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
875                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
876                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
877       }
878       if (val != ARM_DRIVER_OK) {                                                       // If previous SetBitrate failed try different bit settings
879         if ((clock % (6U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {                // If CAN base clock is divisible by 6 * nominal bitrate without remainder
880           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
881                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
882                                  ARM_CAN_BIT_PROP_SEG  (3U) |                           // Set propagation segment to 3 time quanta
883                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
884                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
885                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
886           if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,     // Set FD data phase bitrate
887                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
888                                  ARM_CAN_BIT_PROP_SEG  (3U) |                           // Set propagation segment to 3 time quanta
889                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
890                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
891                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
892         }
893       }
894       if (val != ARM_DRIVER_OK) {                                                       // If previous SetBitrate failed try different bit settings
895         if ((clock % (8U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {                // If CAN base clock is divisible by 8 * nominal bitrate without remainder
896           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
897                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
898                                  ARM_CAN_BIT_PROP_SEG  (5U) |                           // Set propagation segment to 5 time quanta
899                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
900                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
901                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
902           if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,     // Set FD data phase bitrate
903                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
904                                  ARM_CAN_BIT_PROP_SEG  (5U) |                           // Set propagation segment to 5 time quanta
905                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
906                                  ARM_CAN_BIT_PHASE_SEG2(1U) |                           // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
907                                  ARM_CAN_BIT_SJW       (1U));                           // Resynchronization jump width is same as phase segment 2
908         }
909       }
910       if (val != ARM_DRIVER_OK) {                                                       // If previous SetBitrate failed try different bit settings
911         if ((clock % (10U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {               // If CAN base clock is divisible by 10 * nominal bitrate without remainder
912           val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL,                               // Set nominal bitrate
913                                  CAN_BR[0]*1000U,                                       // Set nominal bitrate to configured constant value
914                                  ARM_CAN_BIT_PROP_SEG  (6U) |                           // Set propagation segment to 6 time quanta
915                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
916                                  ARM_CAN_BIT_PHASE_SEG2(2U) |                           // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
917                                  ARM_CAN_BIT_SJW       (2U));                           // Resynchronization jump width is same as phase segment 2
918           if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA,     // Set FD data phase bitrate
919                                  CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO,                    // Set FD data phase bitrate to configured constant value
920                                  ARM_CAN_BIT_PROP_SEG  (6U) |                           // Set propagation segment to 6 time quanta
921                                  ARM_CAN_BIT_PHASE_SEG1(1U) |                           // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
922                                  ARM_CAN_BIT_PHASE_SEG2(2U) |                           // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
923                                  ARM_CAN_BIT_SJW       (2U));                           // Resynchronization jump width is same as phase segment 2
924         }
925       }
926       if (val != ARM_DRIVER_OK) {
927         snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[0]*CAN_DATA_ARB_RATIO, clock/1000000U);
928         TEST_MESSAGE(str);
929       } else TEST_PASS();
930
931       /* Set FD mode */
932       TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
933
934       /* ObjectSetFilter add standard exact ID 0x7FF */
935       TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
936
937       /* ObjectConfigure for tx and rx objects */
938       TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
939       TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
940
941       memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
942       tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
943
944       /* Transfer data chunks */
945       for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
946         /* Clear input buffer */
947         memset(buffer_in,0,CAN_MSG_SIZE_FD);
948         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) {
949           snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
950           TEST_FAIL_MESSAGE(str);
951         } else TEST_PASS();
952         if (memcmp(buffer_in, buffer_out, cnt)!=0) {
953           snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
954           TEST_FAIL_MESSAGE(str);
955         } else TEST_PASS();
956       }
957
958       /* Check if a different random ID is filtered */
959       tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
960       memset(buffer_in,0,CAN_MSG_SIZE_FD);
961       TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
962                                    rx_obj_idx, &rx_data_msg_info, buffer_in,
963                                    CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
964
965       /* ObjectSetFilter remove standard exact ID 0x7FF */
966       TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
967
968
969       /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
970       TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
971
972       /* ObjectConfigure for tx and rx objects */
973       TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
974       TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
975
976       memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
977       tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
978
979       /* Transfer data chunks */
980       for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
981         /* Clear input buffer */
982         memset(buffer_in,0,CAN_MSG_SIZE_FD);
983         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) {
984           snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
985           TEST_FAIL_MESSAGE(str);
986         } else TEST_PASS();
987         if (memcmp(buffer_in, buffer_out, cnt)!=0) {
988           snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
989           TEST_FAIL_MESSAGE(str);
990         } else TEST_PASS();
991       }
992
993       /* Check if a different random ID is filtered */
994       tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
995       memset(buffer_in,0,CAN_MSG_SIZE_FD);
996       TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
997                                    rx_obj_idx, &rx_data_msg_info, buffer_in,
998                                    CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
999
1000       /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
1001       TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
1002
1003       /* Free buffer */
1004       free(buffer_out);
1005       free(buffer_in);
1006     }
1007   }
1008
1009   /* Power off and uninitialize*/
1010   TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
1011   TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
1012 }
1013
1014 /**
1015 @}
1016 */
1017 // end of group can_funcs
1018