1 /*-----------------------------------------------------------------------------
3 * Purpose: CAN test cases
4 *----------------------------------------------------------------------------
5 * Copyright(c) KEIL - An ARM Company
6 *----------------------------------------------------------------------------*/
10 #include "DV_Framework.h"
11 #include "Driver_CAN.h"
16 #define CAN_MSG_SIZE 8U // CAN data size bytes
17 #define CAN_MSG_SIZE_FD 64U // CAN FD data size bytes
19 // CAN frame format according to BOSCH "CAN with Flexible Data-Rate" Specification Version 1.0
20 // released April 17th 2012
22 // CAN extended frame format bits (without datafield)
23 // SOF BASEID SRR IDE IDEXT RTR r1 r0 DLC DATA CRC CRCDEL ACK EOF
24 #define CAN_EXT_FRAME_BITS ( 1 +11 +1 +1 +18 +1 +1 +1 +4 +21 +1 +2 +7 )
26 // CAN FD extended frame format bits sent at NOMINAL bitrate
27 // SOF BASEID SRR IDE IDEXT r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
28 #define CAN_EXT_FRAME_BITS_NOMINAL ( 1 +11 +1 +1 +18 +1 +1 +1 +1 +2 +7 )
30 // CAN FD extended frame format bits sent at FD_DATA bitrate (without datafield)
31 // SOF BASEID SRR IDE IDEXT r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
32 #define CAN_EXT_FRAME_BITS_FD_DATA ( +1 +4 +21 +1 )
34 // CAN buffer pointers
35 static uint8_t *buffer_out;
36 static uint8_t *buffer_in;
39 const uint32_t CAN_BR[] = {
59 const uint32_t CAN_BR_NUM = ARRAY_SIZE(CAN_BR);
61 // Register Driver_CAN#
62 extern ARM_DRIVER_CAN CREATE_SYMBOL(Driver_CAN, DRV_CAN);
63 static ARM_DRIVER_CAN *drv = &CREATE_SYMBOL(Driver_CAN, DRV_CAN);
64 static ARM_CAN_CAPABILITIES capab;
65 static ARM_CAN_OBJ_CAPABILITIES obj_capab;
70 static uint32_t volatile Event;
75 // CAN Signal Unit Event Callback
76 void CAN_SignalUnitEvent (uint32_t event) {
79 case ARM_CAN_EVENT_UNIT_ACTIVE:
81 case ARM_CAN_EVENT_UNIT_WARNING:
83 case ARM_CAN_EVENT_UNIT_PASSIVE:
85 case ARM_CAN_EVENT_UNIT_BUS_OFF:
90 // CAN Signal Object Event Callback
91 void CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event) {
97 int8_t CAN_RunTransfer (uint32_t tx_obj_idx, ARM_CAN_MSG_INFO *tx_msg_info, const uint8_t *tx_data,
98 uint32_t rx_obj_idx, ARM_CAN_MSG_INFO *rx_msg_info, uint8_t *rx_data,
102 Event &= ~ARM_CAN_EVENT_RECEIVE;
103 drv->MessageSend(tx_obj_idx, tx_msg_info, tx_data, size);
105 tick = GET_SYSTICK();
107 if ((Event & ARM_CAN_EVENT_RECEIVE)&&(Obj_idx == rx_obj_idx)) {
108 drv->MessageRead(rx_obj_idx, rx_msg_info, rx_data, size);
112 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(CAN_TRANSFER_TIMEOUT));
117 /*-----------------------------------------------------------------------------
119 *----------------------------------------------------------------------------*/
121 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
123 \defgroup can_funcs CAN Validation
124 \brief CAN test cases
126 The CAN validation test checks the API interface compliance.
130 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
132 \brief Test case: CAN_GetCapabilities
134 The test case \b CAN_GetCapabilities verifies the function \b GetCapabilities.
136 void CAN_GetCapabilities (void) {
137 /* Get CAN capabilities */
138 capab = drv->GetCapabilities();
139 TEST_ASSERT(&capab != NULL);
140 /* Check number of available objects */
141 if (capab.num_objects < 2U) {
142 TEST_FAIL_MESSAGE("[FAILED] Driver has less than 2 objects available");
146 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
148 \brief Test case: CAN_Initialization
150 The test case \b CAN_Initialization verifies the CAN functions with the sequence:
151 - Initialize without callback
153 - Initialize with callback
156 void CAN_Initialization (void) {
158 /* Initialize without callback */
159 TEST_ASSERT(drv->Initialize(NULL, NULL) == ARM_DRIVER_OK);
162 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
164 /* Initialize with callback */
165 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
168 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
171 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
173 \brief Test case: CAN_CheckInvalidInit
175 The test case \b CAN_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
177 - PowerControl with Power off
178 - PowerControl with Power on
180 - PowerControl with Power off
183 void CAN_CheckInvalidInit (void) {
186 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
189 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
191 /* Try to power on */
192 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
194 /* Try to set mode */
195 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) != ARM_DRIVER_OK);
198 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
201 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
204 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
206 \brief Test case: CAN_PowerControl
208 The test case \b CAN_PowerControl verifies the \b PowerControl function with the sequence:
215 void CAN_PowerControl (void) {
218 /* Initialize with callback */
219 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
222 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
225 val = drv->PowerControl (ARM_POWER_LOW);
226 if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
227 else { TEST_ASSERT(val == ARM_DRIVER_OK); }
230 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
233 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
236 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
238 \brief Test case: CAN_Loopback_CheckBitrate
240 The test case \b CAN_Loopback_CheckBitrate verifies different bitrates with the sequence:
244 - Transfer and measure transfer time
245 - Check received data against sent data
249 void CAN_Loopback_CheckBitrate (void) {
251 uint32_t bitrate, clock;
253 ARM_CAN_MSG_INFO tx_data_msg_info;
254 ARM_CAN_MSG_INFO rx_data_msg_info;
255 uint32_t tx_obj_idx = 0xFFFFFFFFU;
256 uint32_t rx_obj_idx = 0xFFFFFFFFU;
258 uint32_t ticks_measured;
259 uint32_t ticks_expected;
262 /* Initialize with callback */
263 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
266 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
268 /* Check if loopback is available */
269 capab = drv->GetCapabilities();
270 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
271 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
274 /* Allocate buffer */
275 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
276 TEST_ASSERT(buffer_out != NULL);
277 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
278 TEST_ASSERT(buffer_in != NULL);
280 /* Find first available object for receive and transmit */
281 for (i = 0U; i < capab.num_objects; i++) {
282 obj_capab = drv->ObjectGetCapabilities (i);
283 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
284 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
287 /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
288 memset(buffer_out,0x55U,CAN_MSG_SIZE);
291 clock = drv->GetClock();
293 for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
295 /* Activate initialization mode */
296 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
298 val = ARM_DRIVER_ERROR;
299 if ((clock % (5U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
300 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
301 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
302 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
303 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
304 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
305 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
307 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
308 if ((clock % (6U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
309 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
310 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
311 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
312 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
313 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
314 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
317 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
318 if ((clock % (8U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
319 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
320 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
321 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
322 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
323 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
324 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
327 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
328 if ((clock % (10U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
329 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
330 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
331 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
332 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
333 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
334 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
337 if (val != ARM_DRIVER_OK) {
338 snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate], clock/1000000U);
342 if (val == ARM_DRIVER_OK) {
344 if (capab.external_loopback == 1U) {
345 // Activate loopback external mode
346 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
347 } else if (capab.internal_loopback == 1U) {
348 // Activate loopback internal mode
349 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
352 /* ObjectSetFilter add extended exact ID 0x15555555 */
353 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
355 /* ObjectConfigure for tx and rx objects */
356 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
357 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
359 /* Clear input buffer */
360 memset(buffer_in,0,CAN_MSG_SIZE);
362 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
363 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
365 /* Measure transfer time */
366 ticks_measured = GET_SYSTICK();
367 CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE);
368 ticks_measured = GET_SYSTICK() - ticks_measured;
369 ticks_expected = SYSTICK_MICROSEC((((CAN_MSG_SIZE * 8U) + CAN_EXT_FRAME_BITS) * 1000) / CAN_BR[bitrate]);
371 rate = (double)ticks_measured/ticks_expected;
373 if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
374 snprintf(str,sizeof(str),"[WARNING] At %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate], rate);
378 /* Check received data against sent data*/
379 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE)!=0) {
380 snprintf(str,sizeof(str),"[FAILED] At %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate], CAN_MSG_SIZE);
381 TEST_FAIL_MESSAGE(str);
384 /* ObjectSetFilter remove extended exact ID 0x15555555 */
385 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
394 /* Power off and uninitialize*/
395 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
396 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
399 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
401 \brief Test case: CAN_Loopback_CheckBitrateFD
403 The test case \b CAN_Loopback_CheckBitrateFD verifies different bitrates with the sequence:
407 - Transfer and measure transfer time
408 - Check received data against sent data
412 void CAN_Loopback_CheckBitrateFD (void) {
414 uint32_t bitrate, clock;
416 ARM_CAN_MSG_INFO tx_data_msg_info;
417 ARM_CAN_MSG_INFO rx_data_msg_info;
418 uint32_t tx_obj_idx = 0xFFFFFFFFU;
419 uint32_t rx_obj_idx = 0xFFFFFFFFU;
421 uint32_t ticks_measured;
422 uint32_t ticks_expected;
425 /* Initialize with callback */
426 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
429 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
432 capab = drv->GetCapabilities();
433 if (capab.fd_mode == 0U) {
434 TEST_FAIL_MESSAGE("[FAILED] Driver does not support FD mode");
437 /* Check if loopback is available */
438 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
439 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
442 /* Allocate buffer */
443 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
444 TEST_ASSERT(buffer_out != NULL);
445 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
446 TEST_ASSERT(buffer_in != NULL);
448 /* Find first available object for receive and transmit */
449 for (i = 0U; i < capab.num_objects; i++) {
450 obj_capab = drv->ObjectGetCapabilities (i);
451 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
452 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
455 /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
456 memset(buffer_out,0x55U,CAN_MSG_SIZE_FD);
459 clock = drv->GetClock();
461 for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
463 /* Activate initialization mode */
464 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
466 val = ARM_DRIVER_ERROR;
467 if ((clock % (5U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
468 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
469 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
470 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
471 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
472 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
473 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
474 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
475 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
476 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
477 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
478 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
479 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
481 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
482 if ((clock % (6U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
483 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
484 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
485 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
486 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
487 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
488 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
489 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
490 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
491 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
492 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
493 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
494 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
497 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
498 if ((clock % (8U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
499 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
500 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
501 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
502 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
503 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
504 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
505 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
506 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
507 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
508 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
509 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
510 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
513 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
514 if ((clock % (10U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {// If CAN base clock is divisible by 10 * nominal bitrate without remainder
515 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
516 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
517 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
518 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
519 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
520 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
521 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
522 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
523 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
524 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
525 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
526 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
529 if (val != ARM_DRIVER_OK) {
530 snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, clock/1000000U);
534 if (val == ARM_DRIVER_OK) {
536 if (capab.external_loopback == 1U) {
537 // Activate loopback external mode
538 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
539 } else if (capab.internal_loopback == 1U) {
540 // Activate loopback internal mode
541 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
545 TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
547 /* ObjectSetFilter add extended exact ID 0x15555555 */
548 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
550 /* ObjectConfigure for tx and rx objects */
551 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
552 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
554 /* Clear input buffer */
555 memset(buffer_in,0,CAN_MSG_SIZE_FD);
557 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
558 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
560 /* Measure transfer time */
561 ticks_measured = GET_SYSTICK();
562 CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE_FD);
563 ticks_measured = GET_SYSTICK() - ticks_measured;
564 ticks_expected = SYSTICK_MICROSEC((((((CAN_MSG_SIZE_FD * 8U) + CAN_EXT_FRAME_BITS_FD_DATA) * 1000) / (CAN_BR[bitrate] * CAN_DATA_ARB_RATIO)) +
565 (((CAN_EXT_FRAME_BITS_NOMINAL) * 1000) / CAN_BR[bitrate] ) ));
567 rate = (double)ticks_measured/ticks_expected;
569 if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
570 snprintf(str,sizeof(str),"[WARNING] At FD bitrate %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, rate);
574 /* Check received data against sent data*/
575 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE_FD)!=0) {
576 snprintf(str,sizeof(str),"[FAILED] At FD bitrate %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, CAN_MSG_SIZE_FD);
577 TEST_FAIL_MESSAGE(str);
580 /* ObjectSetFilter remove extended exact ID 0x15555555 */
581 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
591 /* Power off and uninitialize*/
592 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
593 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
596 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
598 \brief Test case: CAN_Loopback_Transfer
600 The test case \b CAN_Loopback_Transfer verifies the data transfers with the sequence:
603 - Set filter with standard ID
604 - Transfer and check received data against sent data
605 - Check filter with standard ID and remove it
606 - Set filter with extended ID
607 - Transfer and check received data against sent data
608 - Check filter with extended ID and remove it
612 void CAN_Loopback_Transfer (void) {
614 uint32_t i, cnt, clock;
616 ARM_CAN_MSG_INFO tx_data_msg_info;
617 ARM_CAN_MSG_INFO rx_data_msg_info;
618 uint32_t tx_obj_idx = 0xFFFFFFFFU;
619 uint32_t rx_obj_idx = 0xFFFFFFFFU;
621 /* Initialize with callback */
622 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
625 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
627 /* Check if loopback is available */
628 capab = drv->GetCapabilities();
629 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
630 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
633 /* Allocate buffer */
634 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
635 TEST_ASSERT(buffer_out != NULL);
636 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
637 TEST_ASSERT(buffer_in != NULL);
639 /* Find first available object for receive and transmit */
640 for (i = 0U; i < capab.num_objects; i++) {
641 obj_capab = drv->ObjectGetCapabilities (i);
642 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
643 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
646 /* Set output buffer with random data */
647 srand(GET_SYSTICK());
648 for (cnt = 0; cnt<CAN_MSG_SIZE; cnt++) {
649 buffer_out[cnt] = rand()%0x100U;
652 /* Activate initialization mode */
653 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
655 if (capab.external_loopback != 0U) {
656 // Activate loopback external mode
657 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
658 } else if (capab.internal_loopback == 1U) {
659 // Activate loopback internal mode
660 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
664 clock = drv->GetClock();
666 val = ARM_DRIVER_ERROR;
667 if ((clock % (5U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
668 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
669 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
670 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
671 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
672 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
673 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
675 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
676 if ((clock % (6U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
677 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
678 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
679 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
680 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
681 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
682 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
685 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
686 if ((clock % (8U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
687 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
688 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
689 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
690 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
691 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
692 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
695 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
696 if ((clock % (10U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
697 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
698 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
699 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
700 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
701 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
702 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
705 if (val != ARM_DRIVER_OK) {
706 snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[0], clock/1000000U);
710 /* ObjectSetFilter add standard exact ID 0x7FF */
711 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
713 /* ObjectConfigure for tx and rx objects */
714 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
715 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
717 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
718 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
720 /* Transfer data chunks */
721 for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
722 /* Clear input buffer */
723 memset(buffer_in,0,CAN_MSG_SIZE);
724 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
725 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
726 TEST_FAIL_MESSAGE(str);
728 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
729 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
730 TEST_FAIL_MESSAGE(str);
734 /* Check if a different random ID is filtered */
735 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
736 memset(buffer_in,0,CAN_MSG_SIZE);
737 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
738 rx_obj_idx, &rx_data_msg_info, buffer_in,
739 CAN_MSG_SIZE) != ARM_DRIVER_OK);
741 /* ObjectSetFilter remove standard exact ID 0x7FF */
742 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
745 /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
746 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
748 /* ObjectConfigure for tx and rx objects */
749 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
750 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
752 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
753 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
755 /* Transfer data chunks */
756 for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
757 /* Clear input buffer */
758 memset(buffer_in,0,CAN_MSG_SIZE);
759 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
760 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
761 TEST_FAIL_MESSAGE(str);
763 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
764 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
765 TEST_FAIL_MESSAGE(str);
769 /* Check if a different random ID is filtered */
770 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
771 memset(buffer_in,0,CAN_MSG_SIZE);
772 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
773 rx_obj_idx, &rx_data_msg_info, buffer_in,
774 CAN_MSG_SIZE) != ARM_DRIVER_OK);
776 /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
777 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
784 /* Power off and uninitialize*/
785 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
786 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
789 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
791 \brief Test case: CAN_Loopback_TransferFD
793 The test case \b CAN_Loopback_TransferFD verifies the data transfers with the sequence:
796 - Set filter with standard ID
797 - Transfer and check received data against sent data
798 - Check filter with standard ID and remove it
799 - Set filter with extended ID
800 - Transfer and check received data against sent data
801 - Check filter with extended ID and remove it
805 void CAN_Loopback_TransferFD (void) {
807 uint32_t i, cnt, clock;
809 ARM_CAN_MSG_INFO tx_data_msg_info;
810 ARM_CAN_MSG_INFO rx_data_msg_info;
811 uint32_t tx_obj_idx = 0xFFFFFFFFU;
812 uint32_t rx_obj_idx = 0xFFFFFFFFU;
814 /* Initialize with callback */
815 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
818 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
821 capab = drv->GetCapabilities();
822 if (capab.fd_mode == 0U) {
823 TEST_FAIL_MESSAGE("[FAILED] Driver does not support FD mode");
826 /* Check if loopback is available */
827 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
828 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
831 /* Allocate buffer */
832 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
833 TEST_ASSERT(buffer_out != NULL);
834 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
835 TEST_ASSERT(buffer_in != NULL);
837 /* Find first available object for receive and transmit */
838 for (i = 0U; i < capab.num_objects; i++) {
839 obj_capab = drv->ObjectGetCapabilities (i);
840 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
841 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
844 /* Set output buffer with random data */
845 srand(GET_SYSTICK());
846 for (cnt = 0; cnt<CAN_MSG_SIZE_FD; cnt++) {
847 buffer_out[cnt] = rand()%0x100;
850 /* Activate initialization mode */
851 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
853 if (capab.external_loopback != 0U) {
854 // Activate loopback external mode
855 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
856 } else if (capab.internal_loopback == 1U) {
857 // Activate loopback internal mode
858 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
862 clock = drv->GetClock();
864 val = ARM_DRIVER_ERROR;
865 if ((clock % (5U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
866 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
867 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
868 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
869 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
870 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
871 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
872 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
873 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
874 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
875 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
876 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
877 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
879 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
880 if ((clock % (6U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
881 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
882 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
883 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
884 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
885 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
886 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
887 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
888 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
889 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
890 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
891 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
892 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
895 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
896 if ((clock % (8U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
897 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
898 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
899 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
900 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
901 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
902 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
903 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
904 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
905 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
906 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
907 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
908 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
911 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
912 if ((clock % (10U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
913 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
914 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
915 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
916 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
917 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
918 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
919 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
920 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
921 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
922 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
923 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
924 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
927 if (val != ARM_DRIVER_OK) {
928 snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[0]*CAN_DATA_ARB_RATIO, clock/1000000U);
933 TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
935 /* ObjectSetFilter add standard exact ID 0x7FF */
936 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
938 /* ObjectConfigure for tx and rx objects */
939 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
940 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
942 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
943 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
945 /* Transfer data chunks */
946 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
947 /* Clear input buffer */
948 memset(buffer_in,0,CAN_MSG_SIZE_FD);
949 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
950 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
951 TEST_FAIL_MESSAGE(str);
953 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
954 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
955 TEST_FAIL_MESSAGE(str);
959 /* Check if a different random ID is filtered */
960 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
961 memset(buffer_in,0,CAN_MSG_SIZE_FD);
962 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
963 rx_obj_idx, &rx_data_msg_info, buffer_in,
964 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
966 /* ObjectSetFilter remove standard exact ID 0x7FF */
967 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
970 /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
971 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
973 /* ObjectConfigure for tx and rx objects */
974 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
975 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
977 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
978 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
980 /* Transfer data chunks */
981 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
982 /* Clear input buffer */
983 memset(buffer_in,0,CAN_MSG_SIZE_FD);
984 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
985 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
986 TEST_FAIL_MESSAGE(str);
988 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
989 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
990 TEST_FAIL_MESSAGE(str);
994 /* Check if a different random ID is filtered */
995 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
996 memset(buffer_in,0,CAN_MSG_SIZE_FD);
997 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
998 rx_obj_idx, &rx_data_msg_info, buffer_in,
999 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
1001 /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
1002 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
1010 /* Power off and uninitialize*/
1011 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
1012 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
1018 // end of group can_funcs