1 /*-----------------------------------------------------------------------------
3 * Purpose: CAN test cases
4 *----------------------------------------------------------------------------
5 * Copyright(c) KEIL - An ARM Company
6 *----------------------------------------------------------------------------*/
9 #include "DV_Framework.h"
10 #include "Driver_CAN.h"
15 #define CAN_MSG_SIZE 8U // CAN data size bytes
16 #define CAN_MSG_SIZE_FD 64U // CAN FD data size bytes
18 // CAN frame format according to BOSCH "CAN with Flexible Data-Rate" Specification Version 1.0
19 // released April 17th 2012
21 // CAN extended frame format bits (without datafield)
22 // SOF BASEID SRR IDE IDEXT RTR r1 r0 DLC DATA CRC CRCDEL ACK EOF
23 #define CAN_EXT_FRAME_BITS ( 1 +11 +1 +1 +18 +1 +1 +1 +4 +21 +1 +2 +7 )
25 // CAN FD extended frame format bits sent at NOMINAL bitrate
26 // SOF BASEID SRR IDE IDEXT r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
27 #define CAN_EXT_FRAME_BITS_NOMINAL ( 1 +11 +1 +1 +18 +1 +1 +1 +1 +2 +7 )
29 // CAN FD extended frame format bits sent at FD_DATA bitrate (without datafield)
30 // SOF BASEID SRR IDE IDEXT r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
31 #define CAN_EXT_FRAME_BITS_FD_DATA ( +1 +4 +21 +1 )
33 // CAN buffer pointers
34 static uint8_t *buffer_out;
35 static uint8_t *buffer_in;
38 const uint32_t CAN_BR[] = {
58 const uint32_t CAN_BR_NUM = ARRAY_SIZE(CAN_BR);
60 // Register Driver_CAN#
61 extern ARM_DRIVER_CAN CREATE_SYMBOL(Driver_CAN, DRV_CAN);
62 static ARM_DRIVER_CAN *drv = &CREATE_SYMBOL(Driver_CAN, DRV_CAN);
63 static ARM_CAN_CAPABILITIES capab;
64 static ARM_CAN_OBJ_CAPABILITIES obj_capab;
69 static uint32_t volatile Event;
74 // CAN Signal Unit Event Callback
75 void CAN_SignalUnitEvent (uint32_t event) {
78 case ARM_CAN_EVENT_UNIT_ACTIVE:
80 case ARM_CAN_EVENT_UNIT_WARNING:
82 case ARM_CAN_EVENT_UNIT_PASSIVE:
84 case ARM_CAN_EVENT_UNIT_BUS_OFF:
89 // CAN Signal Object Event Callback
90 void CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event) {
96 int8_t CAN_RunTransfer (uint32_t tx_obj_idx, ARM_CAN_MSG_INFO *tx_msg_info, const uint8_t *tx_data,
97 uint32_t rx_obj_idx, ARM_CAN_MSG_INFO *rx_msg_info, uint8_t *rx_data,
101 Event &= ~ARM_CAN_EVENT_RECEIVE;
102 drv->MessageSend(tx_obj_idx, tx_msg_info, tx_data, size);
104 tick = GET_SYSTICK();
106 if ((Event & ARM_CAN_EVENT_RECEIVE)&&(Obj_idx == rx_obj_idx)) {
107 drv->MessageRead(rx_obj_idx, rx_msg_info, rx_data, size);
111 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(CAN_TRANSFER_TIMEOUT));
116 /*-----------------------------------------------------------------------------
118 *----------------------------------------------------------------------------*/
120 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
122 \defgroup can_funcs CAN Validation
123 \brief CAN test cases
125 The CAN validation test checks the API interface compliance.
129 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
131 \brief Test case: CAN_GetCapabilities
133 The test case \b CAN_GetCapabilities verifies the function \b GetCapabilities.
135 void CAN_GetCapabilities (void) {
136 /* Get CAN capabilities */
137 capab = drv->GetCapabilities();
138 TEST_ASSERT(&capab != NULL);
139 /* Check number of available objects */
140 if (capab.num_objects < 2U) {
141 TEST_FAIL_MESSAGE("[FAILED] Driver has less than 2 objects available");
145 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
147 \brief Test case: CAN_Initialization
149 The test case \b CAN_Initialization verifies the CAN functions with the sequence:
150 - Initialize without callback
152 - Initialize with callback
155 void CAN_Initialization (void) {
157 /* Initialize without callback */
158 TEST_ASSERT(drv->Initialize(NULL, NULL) == ARM_DRIVER_OK);
161 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
163 /* Initialize with callback */
164 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
167 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
170 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
172 \brief Test case: CAN_CheckInvalidInit
174 The test case \b CAN_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
176 - PowerControl with Power off
177 - PowerControl with Power on
179 - PowerControl with Power off
182 void CAN_CheckInvalidInit (void) {
185 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
188 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
190 /* Try to power on */
191 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
193 /* Try to set mode */
194 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) != ARM_DRIVER_OK);
197 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
200 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
203 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
205 \brief Test case: CAN_PowerControl
207 The test case \b CAN_PowerControl verifies the \b PowerControl function with the sequence:
214 void CAN_PowerControl (void) {
217 /* Initialize with callback */
218 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
221 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
224 val = drv->PowerControl (ARM_POWER_LOW);
225 if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
226 else { TEST_ASSERT(val == ARM_DRIVER_OK); }
229 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
232 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
235 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
237 \brief Test case: CAN_Loopback_CheckBitrate
239 The test case \b CAN_Loopback_CheckBitrate verifies different bitrates with the sequence:
243 - Transfer and measure transfer time
244 - Check received data against sent data
248 void CAN_Loopback_CheckBitrate (void) {
250 uint32_t bitrate, clock;
252 ARM_CAN_MSG_INFO tx_data_msg_info;
253 ARM_CAN_MSG_INFO rx_data_msg_info;
254 uint32_t tx_obj_idx = 0xFFFFFFFFU;
255 uint32_t rx_obj_idx = 0xFFFFFFFFU;
257 uint32_t ticks_measured;
258 uint32_t ticks_expected;
261 /* Initialize with callback */
262 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
265 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
267 /* Check if loopback is available */
268 capab = drv->GetCapabilities();
269 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
270 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
273 /* Allocate buffer */
274 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
275 TEST_ASSERT(buffer_out != NULL);
276 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
277 TEST_ASSERT(buffer_in != NULL);
279 /* Find first available object for receive and transmit */
280 for (i = 0U; i < capab.num_objects; i++) {
281 obj_capab = drv->ObjectGetCapabilities (i);
282 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
283 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
286 /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
287 memset(buffer_out,0x55U,CAN_MSG_SIZE);
290 clock = drv->GetClock();
292 for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
294 /* Activate initialization mode */
295 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
297 val = ARM_DRIVER_ERROR;
298 if ((clock % (5U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
299 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
300 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
301 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
302 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
303 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
304 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
306 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
307 if ((clock % (6U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
308 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
309 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
310 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
311 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
312 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
313 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
316 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
317 if ((clock % (8U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
318 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
319 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
320 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
321 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
322 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
323 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
326 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
327 if ((clock % (10U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
328 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
329 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
330 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
331 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
332 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
333 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
336 if (val != ARM_DRIVER_OK) {
337 snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate], clock/1000000U);
341 if (val == ARM_DRIVER_OK) {
343 if (capab.external_loopback == 1U) {
344 // Activate loopback external mode
345 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
346 } else if (capab.internal_loopback == 1U) {
347 // Activate loopback internal mode
348 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
351 /* ObjectSetFilter add extended exact ID 0x15555555 */
352 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
354 /* ObjectConfigure for tx and rx objects */
355 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
356 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
358 /* Clear input buffer */
359 memset(buffer_in,0,CAN_MSG_SIZE);
361 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
362 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
364 /* Measure transfer time */
365 ticks_measured = GET_SYSTICK();
366 CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE);
367 ticks_measured = GET_SYSTICK() - ticks_measured;
368 ticks_expected = SYSTICK_MICROSEC((((CAN_MSG_SIZE * 8U) + CAN_EXT_FRAME_BITS) * 1000) / CAN_BR[bitrate]);
370 rate = (double)ticks_measured/ticks_expected;
372 if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
373 snprintf(str,sizeof(str),"[WARNING] At %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate], rate);
377 /* Check received data against sent data*/
378 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE)!=0) {
379 snprintf(str,sizeof(str),"[FAILED] At %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate], CAN_MSG_SIZE);
380 TEST_FAIL_MESSAGE(str);
383 /* ObjectSetFilter remove extended exact ID 0x15555555 */
384 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
393 /* Power off and uninitialize*/
394 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
395 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
398 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
400 \brief Test case: CAN_Loopback_CheckBitrateFD
402 The test case \b CAN_Loopback_CheckBitrateFD verifies different bitrates with the sequence:
406 - Transfer and measure transfer time
407 - Check received data against sent data
411 void CAN_Loopback_CheckBitrateFD (void) {
413 uint32_t bitrate, clock;
415 ARM_CAN_MSG_INFO tx_data_msg_info;
416 ARM_CAN_MSG_INFO rx_data_msg_info;
417 uint32_t tx_obj_idx = 0xFFFFFFFFU;
418 uint32_t rx_obj_idx = 0xFFFFFFFFU;
420 uint32_t ticks_measured;
421 uint32_t ticks_expected;
424 /* Initialize with callback */
425 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
428 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
431 capab = drv->GetCapabilities();
432 if (capab.fd_mode == 0U) {
433 TEST_FAIL_MESSAGE("[FAILED] Driver does not support FD mode");
436 /* Check if loopback is available */
437 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
438 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
441 /* Allocate buffer */
442 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
443 TEST_ASSERT(buffer_out != NULL);
444 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
445 TEST_ASSERT(buffer_in != NULL);
447 /* Find first available object for receive and transmit */
448 for (i = 0U; i < capab.num_objects; i++) {
449 obj_capab = drv->ObjectGetCapabilities (i);
450 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
451 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
454 /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
455 memset(buffer_out,0x55U,CAN_MSG_SIZE_FD);
458 clock = drv->GetClock();
460 for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
462 /* Activate initialization mode */
463 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
465 val = ARM_DRIVER_ERROR;
466 if ((clock % (5U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
467 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
468 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
469 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
470 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
471 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
472 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
473 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
474 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
475 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
476 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
477 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
478 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
480 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
481 if ((clock % (6U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
482 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
483 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
484 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
485 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
486 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
487 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
488 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
489 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
490 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
491 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
492 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
493 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
496 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
497 if ((clock % (8U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
498 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
499 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
500 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
501 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
502 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
503 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
504 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
505 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
506 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
507 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
508 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
509 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
512 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
513 if ((clock % (10U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {// If CAN base clock is divisible by 10 * nominal bitrate without remainder
514 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
515 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
516 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
517 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
518 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
519 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
520 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
521 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
522 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
523 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
524 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
525 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
528 if (val != ARM_DRIVER_OK) {
529 snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, clock/1000000U);
533 if (val == ARM_DRIVER_OK) {
535 if (capab.external_loopback == 1U) {
536 // Activate loopback external mode
537 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
538 } else if (capab.internal_loopback == 1U) {
539 // Activate loopback internal mode
540 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
544 TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
546 /* ObjectSetFilter add extended exact ID 0x15555555 */
547 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
549 /* ObjectConfigure for tx and rx objects */
550 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
551 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
553 /* Clear input buffer */
554 memset(buffer_in,0,CAN_MSG_SIZE_FD);
556 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
557 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
559 /* Measure transfer time */
560 ticks_measured = GET_SYSTICK();
561 CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE_FD);
562 ticks_measured = GET_SYSTICK() - ticks_measured;
563 ticks_expected = SYSTICK_MICROSEC((((((CAN_MSG_SIZE_FD * 8U) + CAN_EXT_FRAME_BITS_FD_DATA) * 1000) / (CAN_BR[bitrate] * CAN_DATA_ARB_RATIO)) +
564 (((CAN_EXT_FRAME_BITS_NOMINAL) * 1000) / CAN_BR[bitrate] ) ));
566 rate = (double)ticks_measured/ticks_expected;
568 if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
569 snprintf(str,sizeof(str),"[WARNING] At FD bitrate %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, rate);
573 /* Check received data against sent data*/
574 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE_FD)!=0) {
575 snprintf(str,sizeof(str),"[FAILED] At FD bitrate %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, CAN_MSG_SIZE_FD);
576 TEST_FAIL_MESSAGE(str);
579 /* ObjectSetFilter remove extended exact ID 0x15555555 */
580 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
590 /* Power off and uninitialize*/
591 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
592 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
595 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
597 \brief Test case: CAN_Loopback_Transfer
599 The test case \b CAN_Loopback_Transfer verifies the data transfers with the sequence:
602 - Set filter with standard ID
603 - Transfer and check received data against sent data
604 - Check filter with standard ID and remove it
605 - Set filter with extended ID
606 - Transfer and check received data against sent data
607 - Check filter with extended ID and remove it
611 void CAN_Loopback_Transfer (void) {
613 uint32_t i, cnt, clock;
615 ARM_CAN_MSG_INFO tx_data_msg_info;
616 ARM_CAN_MSG_INFO rx_data_msg_info;
617 uint32_t tx_obj_idx = 0xFFFFFFFFU;
618 uint32_t rx_obj_idx = 0xFFFFFFFFU;
620 /* Initialize with callback */
621 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
624 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
626 /* Check if loopback is available */
627 capab = drv->GetCapabilities();
628 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
629 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
632 /* Allocate buffer */
633 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
634 TEST_ASSERT(buffer_out != NULL);
635 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
636 TEST_ASSERT(buffer_in != NULL);
638 /* Find first available object for receive and transmit */
639 for (i = 0U; i < capab.num_objects; i++) {
640 obj_capab = drv->ObjectGetCapabilities (i);
641 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
642 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
645 /* Set output buffer with random data */
646 srand(GET_SYSTICK());
647 for (cnt = 0; cnt<CAN_MSG_SIZE; cnt++) {
648 buffer_out[cnt] = rand()%0x100U;
651 /* Activate initialization mode */
652 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
654 if (capab.external_loopback != 0U) {
655 // Activate loopback external mode
656 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
657 } else if (capab.internal_loopback == 1U) {
658 // Activate loopback internal mode
659 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
663 clock = drv->GetClock();
665 val = ARM_DRIVER_ERROR;
666 if ((clock % (5U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
667 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
668 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
669 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
670 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
671 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
672 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
674 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
675 if ((clock % (6U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
676 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
677 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
678 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
679 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
680 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
681 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
684 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
685 if ((clock % (8U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
686 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
687 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
688 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
689 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
690 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
691 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
694 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
695 if ((clock % (10U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
696 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
697 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
698 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
699 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
700 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
701 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
704 if (val != ARM_DRIVER_OK) {
705 snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[0], clock/1000000U);
709 /* ObjectSetFilter add standard exact ID 0x7FF */
710 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
712 /* ObjectConfigure for tx and rx objects */
713 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
714 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
716 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
717 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
719 /* Transfer data chunks */
720 for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
721 /* Clear input buffer */
722 memset(buffer_in,0,CAN_MSG_SIZE);
723 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
724 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
725 TEST_FAIL_MESSAGE(str);
727 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
728 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
729 TEST_FAIL_MESSAGE(str);
733 /* Check if a different random ID is filtered */
734 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
735 memset(buffer_in,0,CAN_MSG_SIZE);
736 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
737 rx_obj_idx, &rx_data_msg_info, buffer_in,
738 CAN_MSG_SIZE) != ARM_DRIVER_OK);
740 /* ObjectSetFilter remove standard exact ID 0x7FF */
741 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
744 /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
745 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
747 /* ObjectConfigure for tx and rx objects */
748 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
749 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
751 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
752 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
754 /* Transfer data chunks */
755 for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
756 /* Clear input buffer */
757 memset(buffer_in,0,CAN_MSG_SIZE);
758 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
759 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
760 TEST_FAIL_MESSAGE(str);
762 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
763 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
764 TEST_FAIL_MESSAGE(str);
768 /* Check if a different random ID is filtered */
769 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
770 memset(buffer_in,0,CAN_MSG_SIZE);
771 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
772 rx_obj_idx, &rx_data_msg_info, buffer_in,
773 CAN_MSG_SIZE) != ARM_DRIVER_OK);
775 /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
776 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
783 /* Power off and uninitialize*/
784 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
785 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
788 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
790 \brief Test case: CAN_Loopback_TransferFD
792 The test case \b CAN_Loopback_TransferFD verifies the data transfers with the sequence:
795 - Set filter with standard ID
796 - Transfer and check received data against sent data
797 - Check filter with standard ID and remove it
798 - Set filter with extended ID
799 - Transfer and check received data against sent data
800 - Check filter with extended ID and remove it
804 void CAN_Loopback_TransferFD (void) {
806 uint32_t i, cnt, clock;
808 ARM_CAN_MSG_INFO tx_data_msg_info;
809 ARM_CAN_MSG_INFO rx_data_msg_info;
810 uint32_t tx_obj_idx = 0xFFFFFFFFU;
811 uint32_t rx_obj_idx = 0xFFFFFFFFU;
813 /* Initialize with callback */
814 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
817 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
820 capab = drv->GetCapabilities();
821 if (capab.fd_mode == 0U) {
822 TEST_FAIL_MESSAGE("[FAILED] Driver does not support FD mode");
825 /* Check if loopback is available */
826 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
827 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
830 /* Allocate buffer */
831 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
832 TEST_ASSERT(buffer_out != NULL);
833 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
834 TEST_ASSERT(buffer_in != NULL);
836 /* Find first available object for receive and transmit */
837 for (i = 0U; i < capab.num_objects; i++) {
838 obj_capab = drv->ObjectGetCapabilities (i);
839 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
840 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
843 /* Set output buffer with random data */
844 srand(GET_SYSTICK());
845 for (cnt = 0; cnt<CAN_MSG_SIZE_FD; cnt++) {
846 buffer_out[cnt] = rand()%0x100;
849 /* Activate initialization mode */
850 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
852 if (capab.external_loopback != 0U) {
853 // Activate loopback external mode
854 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
855 } else if (capab.internal_loopback == 1U) {
856 // Activate loopback internal mode
857 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
861 clock = drv->GetClock();
863 val = ARM_DRIVER_ERROR;
864 if ((clock % (5U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
865 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
866 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
867 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
868 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
869 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
870 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
871 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
872 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
873 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
874 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
875 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
876 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
878 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
879 if ((clock % (6U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
880 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
881 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
882 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
883 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
884 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
885 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
886 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
887 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
888 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
889 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
890 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
891 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
894 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
895 if ((clock % (8U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
896 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
897 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
898 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
899 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
900 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
901 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
902 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
903 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
904 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
905 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
906 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
907 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
910 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
911 if ((clock % (10U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
912 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
913 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
914 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
915 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
916 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
917 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
918 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
919 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
920 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
921 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
922 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
923 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
926 if (val != ARM_DRIVER_OK) {
927 snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[0]*CAN_DATA_ARB_RATIO, clock/1000000U);
932 TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
934 /* ObjectSetFilter add standard exact ID 0x7FF */
935 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
937 /* ObjectConfigure for tx and rx objects */
938 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
939 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
941 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
942 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
944 /* Transfer data chunks */
945 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
946 /* Clear input buffer */
947 memset(buffer_in,0,CAN_MSG_SIZE_FD);
948 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
949 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
950 TEST_FAIL_MESSAGE(str);
952 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
953 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
954 TEST_FAIL_MESSAGE(str);
958 /* Check if a different random ID is filtered */
959 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
960 memset(buffer_in,0,CAN_MSG_SIZE_FD);
961 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
962 rx_obj_idx, &rx_data_msg_info, buffer_in,
963 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
965 /* ObjectSetFilter remove standard exact ID 0x7FF */
966 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
969 /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
970 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
972 /* ObjectConfigure for tx and rx objects */
973 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
974 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
976 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
977 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
979 /* Transfer data chunks */
980 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
981 /* Clear input buffer */
982 memset(buffer_in,0,CAN_MSG_SIZE_FD);
983 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
984 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
985 TEST_FAIL_MESSAGE(str);
987 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
988 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
989 TEST_FAIL_MESSAGE(str);
993 /* Check if a different random ID is filtered */
994 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
995 memset(buffer_in,0,CAN_MSG_SIZE_FD);
996 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
997 rx_obj_idx, &rx_data_msg_info, buffer_in,
998 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
1000 /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
1001 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
1009 /* Power off and uninitialize*/
1010 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
1011 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
1017 // end of group can_funcs