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;
67 static uint32_t volatile Event;
72 // CAN Signal Unit Event Callback
73 void CAN_SignalUnitEvent (uint32_t event) {
76 case ARM_CAN_EVENT_UNIT_ACTIVE:
78 case ARM_CAN_EVENT_UNIT_WARNING:
80 case ARM_CAN_EVENT_UNIT_PASSIVE:
82 case ARM_CAN_EVENT_UNIT_BUS_OFF:
87 // CAN Signal Object Event Callback
88 void CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event) {
94 int8_t CAN_RunTransfer (uint32_t tx_obj_idx, ARM_CAN_MSG_INFO *tx_msg_info, const uint8_t *tx_data,
95 uint32_t rx_obj_idx, ARM_CAN_MSG_INFO *rx_msg_info, uint8_t *rx_data,
99 Event &= ~ARM_CAN_EVENT_RECEIVE;
100 drv->MessageSend(tx_obj_idx, tx_msg_info, tx_data, size);
102 tick = GET_SYSTICK();
104 if ((Event & ARM_CAN_EVENT_RECEIVE)&&(Obj_idx == rx_obj_idx)) {
105 drv->MessageRead(rx_obj_idx, rx_msg_info, rx_data, size);
109 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(CAN_TRANSFER_TIMEOUT));
114 /*-----------------------------------------------------------------------------
116 *----------------------------------------------------------------------------*/
118 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
120 \defgroup can_funcs CAN Validation
121 \brief CAN test cases
123 The CAN validation test checks the API interface compliance.
127 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
129 \brief Test case: CAN_GetCapabilities
131 The test case \b CAN_GetCapabilities verifies the function \b GetCapabilities.
133 void CAN_GetCapabilities (void) {
134 /* Get CAN capabilities */
135 capab = drv->GetCapabilities();
136 ASSERT_TRUE(&capab != NULL);
137 /* Check number of available objects */
138 if (capab.num_objects < 2U) {
139 SET_RESULT(FAILED, "Driver has less than 2 objects available");
143 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
145 \brief Test case: CAN_Initialization
147 The test case \b CAN_Initialization verifies the CAN functions with the sequence:
148 - Initialize without callback
150 - Initialize with callback
153 void CAN_Initialization (void) {
155 /* Initialize without callback */
156 ASSERT_TRUE(drv->Initialize(NULL, NULL) == ARM_DRIVER_OK);
159 ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
161 /* Initialize with callback */
162 ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
165 ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
168 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
170 \brief Test case: CAN_CheckInvalidInit
172 The test case \b CAN_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
174 - PowerControl with Power off
175 - PowerControl with Power on
177 - PowerControl with Power off
180 void CAN_CheckInvalidInit (void) {
183 ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
186 ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
188 /* Try to power on */
189 ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
191 /* Try to set mode */
192 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) != ARM_DRIVER_OK);
195 ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
198 ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
201 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
203 \brief Test case: CAN_PowerControl
205 The test case \b CAN_PowerControl verifies the \b PowerControl function with the sequence:
212 void CAN_PowerControl (void) {
215 /* Initialize with callback */
216 ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
219 ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
222 val = drv->PowerControl (ARM_POWER_LOW);
223 if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { SET_RESULT(WARNING, "Low power is not supported"); }
224 else { ASSERT_TRUE(val == ARM_DRIVER_OK); }
227 ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
230 ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
233 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
235 \brief Test case: CAN_Loopback_CheckBitrate
237 The test case \b CAN_Loopback_CheckBitrate verifies different bitrates with the sequence:
241 - Transfer and measure transfer time
242 - Check received data against sent data
246 void CAN_Loopback_CheckBitrate (void) {
248 uint32_t bitrate, clock;
251 ARM_CAN_MSG_INFO tx_data_msg_info;
252 ARM_CAN_MSG_INFO rx_data_msg_info;
253 uint32_t tx_obj_idx = 0xFFFFFFFFU;
254 uint32_t rx_obj_idx = 0xFFFFFFFFU;
256 uint32_t ticks_measured;
257 uint32_t ticks_expected;
260 /* Initialize with callback */
261 ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
264 ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
266 /* Check if loopback is available */
267 capab = drv->GetCapabilities();
268 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
269 SET_RESULT(FAILED, "Driver does not support loopback mode");
272 /* Allocate buffer */
273 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
274 ASSERT_TRUE(buffer_out != NULL);
275 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
276 ASSERT_TRUE(buffer_in != NULL);
278 /* Find first available object for receive and transmit */
279 for (i = 0U; i < capab.num_objects; i++) {
280 obj_capab = drv->ObjectGetCapabilities (i);
281 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
282 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
285 /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
286 memset(buffer_out,0x55U,CAN_MSG_SIZE);
289 clock = drv->GetClock();
291 for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
293 /* Activate initialization mode */
294 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
296 val = ARM_DRIVER_ERROR;
297 if ((clock % (5U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
298 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
299 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
300 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
301 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
302 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
303 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
305 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
306 if ((clock % (6U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
307 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
308 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
309 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
310 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
311 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
312 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
315 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
316 if ((clock % (8U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
317 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
318 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
319 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
320 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
321 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
322 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
325 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
326 if ((clock % (10U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
327 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
328 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
329 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
330 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
331 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
332 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
335 if (val != ARM_DRIVER_OK) {
336 sprintf(str,"Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate], clock/1000000U);
337 SET_RESULT(WARNING, str);
338 } else SET_RESULT(PASSED, NULL);
340 if (val == ARM_DRIVER_OK) {
342 if (capab.external_loopback == 1U) {
343 // Activate loopback external mode
344 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
345 } else if (capab.internal_loopback == 1U) {
346 // Activate loopback internal mode
347 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
350 /* ObjectSetFilter add extended exact ID 0x15555555 */
351 ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
353 /* ObjectConfigure for tx and rx objects */
354 ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
355 ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
357 /* Clear input buffer */
358 memset(buffer_in,0,CAN_MSG_SIZE);
360 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
361 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
363 /* Measure transfer time */
364 ticks_measured = GET_SYSTICK();
365 CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE);
366 ticks_measured = GET_SYSTICK() - ticks_measured;
367 ticks_expected = SYSTICK_MICROSEC((((CAN_MSG_SIZE * 8U) + CAN_EXT_FRAME_BITS) * 1000) / CAN_BR[bitrate]);
369 rate = (double)ticks_measured/ticks_expected;
371 if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
372 sprintf(str,"At %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate], rate);
373 SET_RESULT(WARNING, str);
374 } else SET_RESULT(PASSED, NULL);
376 /* Check received data against sent data*/
377 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE)!=0) {
378 sprintf(str,"At %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate], CAN_MSG_SIZE);
379 SET_RESULT(FAILED, str);
380 } else SET_RESULT(PASSED, NULL);
382 /* ObjectSetFilter remove extended exact ID 0x15555555 */
383 ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
392 /* Power off and uninitialize*/
393 ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
394 ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
397 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
399 \brief Test case: CAN_Loopback_CheckBitrateFD
401 The test case \b CAN_Loopback_CheckBitrateFD verifies different bitrates with the sequence:
405 - Transfer and measure transfer time
406 - Check received data against sent data
410 void CAN_Loopback_CheckBitrateFD (void) {
412 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 ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
428 ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
431 capab = drv->GetCapabilities();
432 if (capab.fd_mode == 0U) {
433 SET_RESULT(FAILED, "Driver does not support FD mode");
436 /* Check if loopback is available */
437 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
438 SET_RESULT(FAILED, "Driver does not support loopback mode");
441 /* Allocate buffer */
442 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
443 ASSERT_TRUE(buffer_out != NULL);
444 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
445 ASSERT_TRUE(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 ASSERT_TRUE(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 sprintf(str,"Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, clock/1000000U);
530 SET_RESULT(WARNING, str);
531 } else SET_RESULT(PASSED, NULL);
533 if (val == ARM_DRIVER_OK) {
535 if (capab.external_loopback == 1U) {
536 // Activate loopback external mode
537 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
538 } else if (capab.internal_loopback == 1U) {
539 // Activate loopback internal mode
540 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
544 ASSERT_TRUE(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
546 /* ObjectSetFilter add extended exact ID 0x15555555 */
547 ASSERT_TRUE(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 ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
551 ASSERT_TRUE(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 sprintf(str,"At FD bitrate %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, rate);
570 SET_RESULT(WARNING, str);
571 } else SET_RESULT(PASSED, NULL);
573 /* Check received data against sent data*/
574 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE_FD)!=0) {
575 sprintf(str,"At FD bitrate %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, CAN_MSG_SIZE_FD);
576 SET_RESULT(FAILED, str);
577 } else SET_RESULT(PASSED, NULL);
579 /* ObjectSetFilter remove extended exact ID 0x15555555 */
580 ASSERT_TRUE(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 ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
592 ASSERT_TRUE(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;
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 ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
625 ASSERT_TRUE(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 SET_RESULT(FAILED, "Driver does not support loopback mode");
633 /* Allocate buffer */
634 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
635 ASSERT_TRUE(buffer_out != NULL);
636 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
637 ASSERT_TRUE(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 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
655 if (capab.external_loopback != 0U) {
656 // Activate loopback external mode
657 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
658 } else if (capab.internal_loopback == 1U) {
659 // Activate loopback internal mode
660 ASSERT_TRUE(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 sprintf(str,"Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[0], clock/1000000U);
707 SET_RESULT(WARNING, str);
708 } else SET_RESULT(PASSED, NULL);
710 /* ObjectSetFilter add standard exact ID 0x7FF */
711 ASSERT_TRUE(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 ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
715 ASSERT_TRUE(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 sprintf(str,"Fail to transfer block of %d bytes",cnt);
726 SET_RESULT(FAILED, str);
727 } else SET_RESULT(PASSED, NULL);
728 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
729 sprintf(str,"Fail to check block of %d bytes",cnt);
730 SET_RESULT(FAILED, str);
731 } else SET_RESULT(PASSED, NULL);
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 ASSERT_TRUE(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 ASSERT_TRUE(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 ASSERT_TRUE(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 ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
750 ASSERT_TRUE(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 sprintf(str,"Fail to transfer block of %d bytes",cnt);
761 SET_RESULT(FAILED, str);
762 } else SET_RESULT(PASSED, NULL);
763 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
764 sprintf(str,"Fail to check block of %d bytes",cnt);
765 SET_RESULT(FAILED, str);
766 } else SET_RESULT(PASSED, NULL);
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 ASSERT_TRUE(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 ASSERT_TRUE(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 ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
786 ASSERT_TRUE(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;
810 ARM_CAN_MSG_INFO tx_data_msg_info;
811 ARM_CAN_MSG_INFO rx_data_msg_info;
812 uint32_t tx_obj_idx = 0xFFFFFFFFU;
813 uint32_t rx_obj_idx = 0xFFFFFFFFU;
815 /* Initialize with callback */
816 ASSERT_TRUE(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
819 ASSERT_TRUE(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
822 capab = drv->GetCapabilities();
823 if (capab.fd_mode == 0U) {
824 SET_RESULT(FAILED, "Driver does not support FD mode");
827 /* Check if loopback is available */
828 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
829 SET_RESULT(FAILED, "Driver does not support loopback mode");
832 /* Allocate buffer */
833 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
834 ASSERT_TRUE(buffer_out != NULL);
835 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
836 ASSERT_TRUE(buffer_in != NULL);
838 /* Find first available object for receive and transmit */
839 for (i = 0U; i < capab.num_objects; i++) {
840 obj_capab = drv->ObjectGetCapabilities (i);
841 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
842 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
845 /* Set output buffer with random data */
846 srand(GET_SYSTICK());
847 for (cnt = 0; cnt<CAN_MSG_SIZE_FD; cnt++) {
848 buffer_out[cnt] = rand()%0x100;
851 /* Activate initialization mode */
852 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
854 if (capab.external_loopback != 0U) {
855 // Activate loopback external mode
856 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
857 } else if (capab.internal_loopback == 1U) {
858 // Activate loopback internal mode
859 ASSERT_TRUE(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
863 clock = drv->GetClock();
865 val = ARM_DRIVER_ERROR;
866 if ((clock % (5U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
867 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
868 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
869 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
870 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
871 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
872 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
873 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
874 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
875 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
876 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
877 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
878 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
880 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
881 if ((clock % (6U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
882 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
883 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
884 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
885 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
886 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
887 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
888 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
889 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
890 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
891 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
892 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
893 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
896 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
897 if ((clock % (8U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
898 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
899 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
900 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
901 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
902 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
903 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
904 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
905 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
906 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
907 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
908 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
909 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
912 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
913 if ((clock % (10U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
914 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
915 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
916 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
917 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
918 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
919 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
920 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
921 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
922 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
923 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
924 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
925 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
928 if (val != ARM_DRIVER_OK) {
929 sprintf(str,"Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[0]*CAN_DATA_ARB_RATIO, clock/1000000U);
930 SET_RESULT(WARNING, str);
931 } else SET_RESULT(PASSED, NULL);
934 ASSERT_TRUE(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
936 /* ObjectSetFilter add standard exact ID 0x7FF */
937 ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
939 /* ObjectConfigure for tx and rx objects */
940 ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
941 ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
943 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
944 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
946 /* Transfer data chunks */
947 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
948 /* Clear input buffer */
949 memset(buffer_in,0,CAN_MSG_SIZE_FD);
950 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) {
951 sprintf(str,"Fail to transfer block of %d bytes",cnt);
952 SET_RESULT(FAILED, str);
953 } else SET_RESULT(PASSED, NULL);
954 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
955 sprintf(str,"Fail to check block of %d bytes",cnt);
956 SET_RESULT(FAILED, str);
957 } else SET_RESULT(PASSED, NULL);
960 /* Check if a different random ID is filtered */
961 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
962 memset(buffer_in,0,CAN_MSG_SIZE_FD);
963 ASSERT_TRUE(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
964 rx_obj_idx, &rx_data_msg_info, buffer_in,
965 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
967 /* ObjectSetFilter remove standard exact ID 0x7FF */
968 ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
971 /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
972 ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
974 /* ObjectConfigure for tx and rx objects */
975 ASSERT_TRUE(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
976 ASSERT_TRUE(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
978 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
979 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
981 /* Transfer data chunks */
982 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
983 /* Clear input buffer */
984 memset(buffer_in,0,CAN_MSG_SIZE_FD);
985 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) {
986 sprintf(str,"Fail to transfer block of %d bytes",cnt);
987 SET_RESULT(FAILED, str);
988 } else SET_RESULT(PASSED, NULL);
989 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
990 sprintf(str,"Fail to check block of %d bytes",cnt);
991 SET_RESULT(FAILED, str);
992 } else SET_RESULT(PASSED, NULL);
995 /* Check if a different random ID is filtered */
996 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
997 memset(buffer_in,0,CAN_MSG_SIZE_FD);
998 ASSERT_TRUE(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
999 rx_obj_idx, &rx_data_msg_info, buffer_in,
1000 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
1002 /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
1003 ASSERT_TRUE(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
1011 /* Power off and uninitialize*/
1012 ASSERT_TRUE(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
1013 ASSERT_TRUE(drv->Uninitialize() == ARM_DRIVER_OK);
1019 // end of group can_funcs