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