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