2 * Copyright (c) 2015-2020 Arm Limited. All rights reserved.
4 * SPDX-License-Identifier: Apache-2.0
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 * -----------------------------------------------------------------------------
20 * Project: CMSIS-Driver Validation
21 * Title: Controller Area Network (CAN) Driver Validation tests
23 * -----------------------------------------------------------------------------
28 #include "DV_CAN_Config.h"
29 #include "DV_Framework.h"
30 #include "Driver_CAN.h"
35 #define CAN_MSG_SIZE 8U // CAN data size bytes
36 #define CAN_MSG_SIZE_FD 64U // CAN FD data size bytes
38 // CAN frame format according to BOSCH "CAN with Flexible Data-Rate" Specification Version 1.0
39 // released April 17th 2012
41 // CAN extended frame format bits (without datafield)
42 // SOF BASEID SRR IDE IDEXT RTR r1 r0 DLC DATA CRC CRCDEL ACK EOF
43 #define CAN_EXT_FRAME_BITS ( 1 +11 +1 +1 +18 +1 +1 +1 +4 +21 +1 +2 +7 )
45 // CAN FD extended frame format bits sent at NOMINAL bitrate
46 // SOF BASEID SRR IDE IDEXT r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
47 #define CAN_EXT_FRAME_BITS_NOMINAL ( 1 +11 +1 +1 +18 +1 +1 +1 +1 +2 +7 )
49 // CAN FD extended frame format bits sent at FD_DATA bitrate (without datafield)
50 // SOF BASEID SRR IDE IDEXT r1 EDL r0 BRS ESI DLC DATA CRC CRCDEL ACK EOF
51 #define CAN_EXT_FRAME_BITS_FD_DATA ( +1 +4 +21 +1 )
53 // CAN buffer pointers
54 static uint8_t *buffer_out;
55 static uint8_t *buffer_in;
58 const uint32_t CAN_BR[] = {
78 const uint32_t CAN_BR_NUM = ARRAY_SIZE(CAN_BR);
80 // Register Driver_CAN#
81 extern ARM_DRIVER_CAN CREATE_SYMBOL(Driver_CAN, DRV_CAN);
82 static ARM_DRIVER_CAN *drv = &CREATE_SYMBOL(Driver_CAN, DRV_CAN);
83 static ARM_CAN_CAPABILITIES capab;
84 static ARM_CAN_OBJ_CAPABILITIES obj_capab;
89 static uint32_t volatile Event;
94 // CAN Signal Unit Event Callback
95 void CAN_SignalUnitEvent (uint32_t event) {
98 case ARM_CAN_EVENT_UNIT_ACTIVE:
100 case ARM_CAN_EVENT_UNIT_WARNING:
102 case ARM_CAN_EVENT_UNIT_PASSIVE:
104 case ARM_CAN_EVENT_UNIT_BUS_OFF:
109 // CAN Signal Object Event Callback
110 void CAN_SignalObjectEvent (uint32_t obj_idx, uint32_t event) {
116 int8_t CAN_RunTransfer (uint32_t tx_obj_idx, ARM_CAN_MSG_INFO *tx_msg_info, const uint8_t *tx_data,
117 uint32_t rx_obj_idx, ARM_CAN_MSG_INFO *rx_msg_info, uint8_t *rx_data,
121 Event &= ~ARM_CAN_EVENT_RECEIVE;
122 drv->MessageSend(tx_obj_idx, tx_msg_info, tx_data, size);
124 tick = GET_SYSTICK();
126 if ((Event & ARM_CAN_EVENT_RECEIVE)&&(Obj_idx == rx_obj_idx)) {
127 drv->MessageRead(rx_obj_idx, rx_msg_info, rx_data, size);
131 while ((GET_SYSTICK() - tick) < SYSTICK_MICROSEC(CAN_TRANSFER_TIMEOUT));
136 /*-----------------------------------------------------------------------------
138 *----------------------------------------------------------------------------*/
140 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
142 \defgroup dv_can CAN Validation
143 \brief CAN driver validation
145 The CAN validation test checks the API interface compliance.
147 \defgroup can_tests Tests
153 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
155 \brief Function: CAN_GetCapabilities
157 The test function \b CAN_GetCapabilities verifies the function \b GetCapabilities.
159 void CAN_GetCapabilities (void) {
160 /* Get CAN capabilities */
161 capab = drv->GetCapabilities();
162 TEST_ASSERT(&capab != NULL);
163 /* Check number of available objects */
164 if (capab.num_objects < 2U) {
165 TEST_FAIL_MESSAGE("[FAILED] Driver has less than 2 objects available");
169 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
171 \brief Function: CAN_Initialization
173 The test function \b CAN_Initialization verifies the CAN functions with the sequence:
174 - Initialize without callback
176 - Initialize with callback
179 void CAN_Initialization (void) {
181 /* Initialize without callback */
182 TEST_ASSERT(drv->Initialize(NULL, NULL) == ARM_DRIVER_OK);
185 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
187 /* Initialize with callback */
188 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
191 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
194 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
196 \brief Function: CAN_CheckInvalidInit
198 The test function \b CAN_CheckInvalidInit verifies the driver behaviour when receiving an invalid initialization sequence:
200 - PowerControl with Power off
201 - PowerControl with Power on
203 - PowerControl with Power off
206 void CAN_CheckInvalidInit (void) {
209 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
212 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
214 /* Try to power on */
215 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) != ARM_DRIVER_OK);
217 /* Try to set mode */
218 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) != ARM_DRIVER_OK);
221 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
224 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
227 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
229 \brief Function: CAN_PowerControl
231 The test function \b CAN_PowerControl verifies the \b PowerControl function with the sequence:
238 void CAN_PowerControl (void) {
241 /* Initialize with callback */
242 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
245 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
248 val = drv->PowerControl (ARM_POWER_LOW);
249 if (val == ARM_DRIVER_ERROR_UNSUPPORTED) { TEST_MESSAGE("[WARNING] Low power is not supported"); }
250 else { TEST_ASSERT(val == ARM_DRIVER_OK); }
253 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
256 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
259 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
261 \brief Function: CAN_Loopback_CheckBitrate
263 The test function \b CAN_Loopback_CheckBitrate verifies different bitrates with the sequence:
267 - Transfer and measure transfer time
268 - Check received data against sent data
272 void CAN_Loopback_CheckBitrate (void) {
274 uint32_t bitrate, clock;
276 ARM_CAN_MSG_INFO tx_data_msg_info;
277 ARM_CAN_MSG_INFO rx_data_msg_info;
278 uint32_t tx_obj_idx = 0xFFFFFFFFU;
279 uint32_t rx_obj_idx = 0xFFFFFFFFU;
281 uint32_t ticks_measured;
282 uint32_t ticks_expected;
285 /* Initialize with callback */
286 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
289 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
291 /* Check if loopback is available */
292 capab = drv->GetCapabilities();
293 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
294 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
297 /* Allocate buffer */
298 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
299 TEST_ASSERT(buffer_out != NULL);
300 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
301 TEST_ASSERT(buffer_in != NULL);
303 /* Find first available object for receive and transmit */
304 for (i = 0U; i < capab.num_objects; i++) {
305 obj_capab = drv->ObjectGetCapabilities (i);
306 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
307 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
310 /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
311 memset(buffer_out,0x55U,CAN_MSG_SIZE);
314 clock = drv->GetClock();
316 for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
318 /* Activate initialization mode */
319 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
321 val = ARM_DRIVER_ERROR;
322 if ((clock % (5U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
323 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
324 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
325 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
326 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
327 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
328 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
330 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
331 if ((clock % (6U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
332 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
333 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
334 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
335 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
336 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
337 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
340 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
341 if ((clock % (8U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
342 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
343 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
344 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
345 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
346 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
347 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
350 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
351 if ((clock % (10U*(CAN_BR[bitrate]*1000U))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
352 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
353 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
354 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
355 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
356 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
357 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
360 if (val != ARM_DRIVER_OK) {
361 snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate], clock/1000000U);
365 if (val == ARM_DRIVER_OK) {
367 if (capab.external_loopback == 1U) {
368 // Activate loopback external mode
369 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
370 } else if (capab.internal_loopback == 1U) {
371 // Activate loopback internal mode
372 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
375 /* ObjectSetFilter add extended exact ID 0x15555555 */
376 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
378 /* ObjectConfigure for tx and rx objects */
379 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
380 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
382 /* Clear input buffer */
383 memset(buffer_in,0,CAN_MSG_SIZE);
385 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
386 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
388 /* Measure transfer time */
389 ticks_measured = GET_SYSTICK();
390 CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE);
391 ticks_measured = GET_SYSTICK() - ticks_measured;
392 ticks_expected = SYSTICK_MICROSEC((((CAN_MSG_SIZE * 8U) + CAN_EXT_FRAME_BITS) * 1000) / CAN_BR[bitrate]);
394 rate = (double)ticks_measured/ticks_expected;
396 if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
397 snprintf(str,sizeof(str),"[WARNING] At %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate], rate);
401 /* Check received data against sent data*/
402 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE)!=0) {
403 snprintf(str,sizeof(str),"[FAILED] At %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate], CAN_MSG_SIZE);
404 TEST_FAIL_MESSAGE(str);
407 /* ObjectSetFilter remove extended exact ID 0x15555555 */
408 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
417 /* Power off and uninitialize*/
418 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
419 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
422 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
424 \brief Function: CAN_Loopback_CheckBitrateFD
426 The test function \b CAN_Loopback_CheckBitrateFD verifies different bitrates with the sequence:
430 - Transfer and measure transfer time
431 - Check received data against sent data
435 void CAN_Loopback_CheckBitrateFD (void) {
437 uint32_t bitrate, clock;
439 ARM_CAN_MSG_INFO tx_data_msg_info;
440 ARM_CAN_MSG_INFO rx_data_msg_info;
441 uint32_t tx_obj_idx = 0xFFFFFFFFU;
442 uint32_t rx_obj_idx = 0xFFFFFFFFU;
444 uint32_t ticks_measured;
445 uint32_t ticks_expected;
448 /* Initialize with callback */
449 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
452 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
455 capab = drv->GetCapabilities();
456 if (capab.fd_mode == 0U) {
457 TEST_FAIL_MESSAGE("[FAILED] Driver does not support FD mode");
460 /* Check if loopback is available */
461 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
462 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
465 /* Allocate buffer */
466 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
467 TEST_ASSERT(buffer_out != NULL);
468 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
469 TEST_ASSERT(buffer_in != NULL);
471 /* Find first available object for receive and transmit */
472 for (i = 0U; i < capab.num_objects; i++) {
473 obj_capab = drv->ObjectGetCapabilities (i);
474 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
475 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
478 /* Set output buffer with all data = 0x55 to avoid CAN bit stuffing */
479 memset(buffer_out,0x55U,CAN_MSG_SIZE_FD);
482 clock = drv->GetClock();
484 for (bitrate=0; bitrate<CAN_BR_NUM; bitrate++) {
486 /* Activate initialization mode */
487 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
489 val = ARM_DRIVER_ERROR;
490 if ((clock % (5U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
491 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
492 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
493 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
494 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
495 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
496 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
497 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
498 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
499 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
500 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
501 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
502 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
504 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
505 if ((clock % (6U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
506 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
507 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
508 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
509 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
510 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
511 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
512 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
513 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
514 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
515 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
516 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
517 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
520 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
521 if ((clock % (8U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
522 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
523 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
524 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
525 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
526 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
527 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
528 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
529 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
530 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
531 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
532 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
533 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
536 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
537 if ((clock % (10U*(CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO))) == 0U) {// If CAN base clock is divisible by 10 * nominal bitrate without remainder
538 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
539 CAN_BR[bitrate]*1000U, // Set nominal bitrate to configured constant value
540 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
541 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
542 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
543 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
544 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
545 CAN_BR[bitrate]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
546 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
547 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
548 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
549 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
552 if (val != ARM_DRIVER_OK) {
553 snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, clock/1000000U);
557 if (val == ARM_DRIVER_OK) {
559 if (capab.external_loopback == 1U) {
560 // Activate loopback external mode
561 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
562 } else if (capab.internal_loopback == 1U) {
563 // Activate loopback internal mode
564 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
568 TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
570 /* ObjectSetFilter add extended exact ID 0x15555555 */
571 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
573 /* ObjectConfigure for tx and rx objects */
574 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
575 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
577 /* Clear input buffer */
578 memset(buffer_in,0,CAN_MSG_SIZE_FD);
580 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
581 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x15555555U);
583 /* Measure transfer time */
584 ticks_measured = GET_SYSTICK();
585 CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, CAN_MSG_SIZE_FD);
586 ticks_measured = GET_SYSTICK() - ticks_measured;
587 ticks_expected = SYSTICK_MICROSEC((((((CAN_MSG_SIZE_FD * 8U) + CAN_EXT_FRAME_BITS_FD_DATA) * 1000) / (CAN_BR[bitrate] * CAN_DATA_ARB_RATIO)) +
588 (((CAN_EXT_FRAME_BITS_NOMINAL) * 1000) / CAN_BR[bitrate] ) ));
590 rate = (double)ticks_measured/ticks_expected;
592 if ((rate>(1.0+(double)MIN_BITRATE/100))||(rate<(1.0-(double)MIN_BITRATE/100))) {
593 snprintf(str,sizeof(str),"[WARNING] At FD bitrate %dkbit/s: measured time is %f x expected time", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, rate);
597 /* Check received data against sent data*/
598 if (memcmp(buffer_in, buffer_out, CAN_MSG_SIZE_FD)!=0) {
599 snprintf(str,sizeof(str),"[FAILED] At FD bitrate %dkbit/s: fail to check block of %d bytes", CAN_BR[bitrate]*CAN_DATA_ARB_RATIO, CAN_MSG_SIZE_FD);
600 TEST_FAIL_MESSAGE(str);
603 /* ObjectSetFilter remove extended exact ID 0x15555555 */
604 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x15555555U), 0U) == ARM_DRIVER_OK );
614 /* Power off and uninitialize*/
615 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
616 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
619 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
621 \brief Function: CAN_Loopback_Transfer
623 The test function \b CAN_Loopback_Transfer verifies the data transfers with the sequence:
626 - Set filter with standard ID
627 - Transfer and check received data against sent data
628 - Check filter with standard ID and remove it
629 - Set filter with extended ID
630 - Transfer and check received data against sent data
631 - Check filter with extended ID and remove it
635 void CAN_Loopback_Transfer (void) {
637 uint32_t i, cnt, clock;
639 ARM_CAN_MSG_INFO tx_data_msg_info;
640 ARM_CAN_MSG_INFO rx_data_msg_info;
641 uint32_t tx_obj_idx = 0xFFFFFFFFU;
642 uint32_t rx_obj_idx = 0xFFFFFFFFU;
644 /* Initialize with callback */
645 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
648 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
650 /* Check if loopback is available */
651 capab = drv->GetCapabilities();
652 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
653 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
656 /* Allocate buffer */
657 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
658 TEST_ASSERT(buffer_out != NULL);
659 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE*sizeof(uint8_t));
660 TEST_ASSERT(buffer_in != NULL);
662 /* Find first available object for receive and transmit */
663 for (i = 0U; i < capab.num_objects; i++) {
664 obj_capab = drv->ObjectGetCapabilities (i);
665 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
666 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
669 /* Set output buffer with random data */
670 srand(GET_SYSTICK());
671 for (cnt = 0; cnt<CAN_MSG_SIZE; cnt++) {
672 buffer_out[cnt] = rand()%0x100U;
675 /* Activate initialization mode */
676 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
678 if (capab.external_loopback != 0U) {
679 // Activate loopback external mode
680 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
681 } else if (capab.internal_loopback == 1U) {
682 // Activate loopback internal mode
683 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
687 clock = drv->GetClock();
689 val = ARM_DRIVER_ERROR;
690 if ((clock % (5U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
691 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
692 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
693 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
694 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
695 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
696 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
698 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
699 if ((clock % (6U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
700 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
701 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
702 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
703 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
704 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
705 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
708 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
709 if ((clock % (8U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
710 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
711 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
712 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
713 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
714 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
715 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
718 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
719 if ((clock % (10U*(CAN_BR[0]*1000U))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
720 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
721 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
722 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
723 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
724 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
725 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
728 if (val != ARM_DRIVER_OK) {
729 snprintf(str,sizeof(str),"[WARNING] Invalid bitrate: %dkbit/s, clock %dMHz", CAN_BR[0], clock/1000000U);
733 /* ObjectSetFilter add standard exact ID 0x7FF */
734 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
736 /* ObjectConfigure for tx and rx objects */
737 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
738 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
740 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
741 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
743 /* Transfer data chunks */
744 for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
745 /* Clear input buffer */
746 memset(buffer_in,0,CAN_MSG_SIZE);
747 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
748 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
749 TEST_FAIL_MESSAGE(str);
751 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
752 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
753 TEST_FAIL_MESSAGE(str);
757 /* Check if a different random ID is filtered */
758 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
759 memset(buffer_in,0,CAN_MSG_SIZE);
760 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
761 rx_obj_idx, &rx_data_msg_info, buffer_in,
762 CAN_MSG_SIZE) != ARM_DRIVER_OK);
764 /* ObjectSetFilter remove standard exact ID 0x7FF */
765 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
768 /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
769 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
771 /* ObjectConfigure for tx and rx objects */
772 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
773 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
775 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
776 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
778 /* Transfer data chunks */
779 for (cnt = 1; cnt <= CAN_MSG_SIZE; cnt++) {
780 /* Clear input buffer */
781 memset(buffer_in,0,CAN_MSG_SIZE);
782 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
783 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
784 TEST_FAIL_MESSAGE(str);
786 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
787 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
788 TEST_FAIL_MESSAGE(str);
792 /* Check if a different random ID is filtered */
793 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
794 memset(buffer_in,0,CAN_MSG_SIZE);
795 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
796 rx_obj_idx, &rx_data_msg_info, buffer_in,
797 CAN_MSG_SIZE) != ARM_DRIVER_OK);
799 /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
800 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
807 /* Power off and uninitialize*/
808 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
809 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
812 /*=======0=========1=========2=========3=========4=========5=========6=========7=========8=========9=========0=========1====*/
814 \brief Function: CAN_Loopback_TransferFD
816 The test function \b CAN_Loopback_TransferFD verifies the data transfers with the sequence:
819 - Set filter with standard ID
820 - Transfer and check received data against sent data
821 - Check filter with standard ID and remove it
822 - Set filter with extended ID
823 - Transfer and check received data against sent data
824 - Check filter with extended ID and remove it
828 void CAN_Loopback_TransferFD (void) {
830 uint32_t i, cnt, clock;
832 ARM_CAN_MSG_INFO tx_data_msg_info;
833 ARM_CAN_MSG_INFO rx_data_msg_info;
834 uint32_t tx_obj_idx = 0xFFFFFFFFU;
835 uint32_t rx_obj_idx = 0xFFFFFFFFU;
837 /* Initialize with callback */
838 TEST_ASSERT(drv->Initialize(CAN_SignalUnitEvent, CAN_SignalObjectEvent) == ARM_DRIVER_OK);
841 TEST_ASSERT(drv->PowerControl (ARM_POWER_FULL) == ARM_DRIVER_OK);
844 capab = drv->GetCapabilities();
845 if (capab.fd_mode == 0U) {
846 TEST_FAIL_MESSAGE("[FAILED] Driver does not support FD mode");
849 /* Check if loopback is available */
850 if ((capab.external_loopback == 0U) && (capab.internal_loopback == 0U)) {
851 TEST_FAIL_MESSAGE("[FAILED] Driver does not support loopback mode");
854 /* Allocate buffer */
855 buffer_out = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
856 TEST_ASSERT(buffer_out != NULL);
857 buffer_in = (uint8_t*) malloc(CAN_MSG_SIZE_FD*sizeof(uint8_t));
858 TEST_ASSERT(buffer_in != NULL);
860 /* Find first available object for receive and transmit */
861 for (i = 0U; i < capab.num_objects; i++) {
862 obj_capab = drv->ObjectGetCapabilities (i);
863 if ((tx_obj_idx == 0xFFFFFFFFU) && (obj_capab.tx == 1U)) { tx_obj_idx = i; }
864 else if ((rx_obj_idx == 0xFFFFFFFFU) && (obj_capab.rx == 1U)) { rx_obj_idx = i; }
867 /* Set output buffer with random data */
868 srand(GET_SYSTICK());
869 for (cnt = 0; cnt<CAN_MSG_SIZE_FD; cnt++) {
870 buffer_out[cnt] = rand()%0x100;
873 /* Activate initialization mode */
874 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_INITIALIZATION) == ARM_DRIVER_OK);
876 if (capab.external_loopback != 0U) {
877 // Activate loopback external mode
878 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_EXTERNAL) == ARM_DRIVER_OK );
879 } else if (capab.internal_loopback == 1U) {
880 // Activate loopback internal mode
881 TEST_ASSERT(drv->SetMode (ARM_CAN_MODE_LOOPBACK_INTERNAL) == ARM_DRIVER_OK );
885 clock = drv->GetClock();
887 val = ARM_DRIVER_ERROR;
888 if ((clock % (5U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 5 * nominal bitrate without remainder
889 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
890 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
891 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
892 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
893 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
894 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
895 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
896 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
897 ARM_CAN_BIT_PROP_SEG (2U) | // Set propagation segment to 2 time quanta
898 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 80% of bit time)
899 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 5 time quanta long)
900 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
902 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
903 if ((clock % (6U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 6 * nominal bitrate without remainder
904 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
905 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
906 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
907 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
908 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
909 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
910 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
911 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
912 ARM_CAN_BIT_PROP_SEG (3U) | // Set propagation segment to 3 time quanta
913 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 83.3% of bit time)
914 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 6 time quanta long)
915 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
918 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
919 if ((clock % (8U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 8 * nominal bitrate without remainder
920 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
921 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
922 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
923 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
924 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
925 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
926 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
927 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
928 ARM_CAN_BIT_PROP_SEG (5U) | // Set propagation segment to 5 time quanta
929 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 87.5% of bit time)
930 ARM_CAN_BIT_PHASE_SEG2(1U) | // Set phase segment 2 to 1 time quantum (total bit is 8 time quanta long)
931 ARM_CAN_BIT_SJW (1U)); // Resynchronization jump width is same as phase segment 2
934 if (val != ARM_DRIVER_OK) { // If previous SetBitrate failed try different bit settings
935 if ((clock % (10U*(CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO))) == 0U) { // If CAN base clock is divisible by 10 * nominal bitrate without remainder
936 val = drv->SetBitrate (ARM_CAN_BITRATE_NOMINAL, // Set nominal bitrate
937 CAN_BR[0]*1000U, // Set nominal bitrate to configured constant value
938 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
939 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
940 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
941 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
942 if (val == ARM_DRIVER_OK) val = drv->SetBitrate (ARM_CAN_BITRATE_FD_DATA, // Set FD data phase bitrate
943 CAN_BR[0]*1000U*CAN_DATA_ARB_RATIO, // Set FD data phase bitrate to configured constant value
944 ARM_CAN_BIT_PROP_SEG (6U) | // Set propagation segment to 6 time quanta
945 ARM_CAN_BIT_PHASE_SEG1(1U) | // Set phase segment 1 to 1 time quantum (sample point at 70% of bit time)
946 ARM_CAN_BIT_PHASE_SEG2(2U) | // Set phase segment 2 to 2 time quantum (total bit is 10 time quanta long)
947 ARM_CAN_BIT_SJW (2U)); // Resynchronization jump width is same as phase segment 2
950 if (val != ARM_DRIVER_OK) {
951 snprintf(str,sizeof(str),"[WARNING] Invalid FD bitrate: %dkbit/s, clock %dMHz", CAN_BR[0]*CAN_DATA_ARB_RATIO, clock/1000000U);
956 TEST_ASSERT(drv->Control (ARM_CAN_SET_FD_MODE, 1) == ARM_DRIVER_OK);
958 /* ObjectSetFilter add standard exact ID 0x7FF */
959 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
961 /* ObjectConfigure for tx and rx objects */
962 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
963 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
965 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
966 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(0x7FFU);
968 /* Transfer data chunks */
969 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
970 /* Clear input buffer */
971 memset(buffer_in,0,CAN_MSG_SIZE_FD);
972 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
973 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
974 TEST_FAIL_MESSAGE(str);
976 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
977 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
978 TEST_FAIL_MESSAGE(str);
982 /* Check if a different random ID is filtered */
983 tx_data_msg_info.id = ARM_CAN_STANDARD_ID(rand()%0x7FFU);
984 memset(buffer_in,0,CAN_MSG_SIZE_FD);
985 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
986 rx_obj_idx, &rx_data_msg_info, buffer_in,
987 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
989 /* ObjectSetFilter remove standard exact ID 0x7FF */
990 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_STANDARD_ID(0x7FFU), 0U) == ARM_DRIVER_OK );
993 /* ObjectSetFilter add extended exact ID 0x1FFFFFFF */
994 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
996 /* ObjectConfigure for tx and rx objects */
997 TEST_ASSERT(drv->ObjectConfigure(tx_obj_idx, ARM_CAN_OBJ_TX) == ARM_DRIVER_OK );
998 TEST_ASSERT(drv->ObjectConfigure(rx_obj_idx, ARM_CAN_OBJ_RX) == ARM_DRIVER_OK );
1000 memset(&tx_data_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO));
1001 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(0x1FFFFFFFU);
1003 /* Transfer data chunks */
1004 for (cnt = 1; cnt <= CAN_MSG_SIZE_FD; cnt++) {
1005 /* Clear input buffer */
1006 memset(buffer_in,0,CAN_MSG_SIZE_FD);
1007 if (CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out, rx_obj_idx, &rx_data_msg_info, buffer_in, cnt) != ARM_DRIVER_OK) {
1008 snprintf(str,sizeof(str),"[FAILED] Fail to transfer block of %d bytes",cnt);
1009 TEST_FAIL_MESSAGE(str);
1011 if (memcmp(buffer_in, buffer_out, cnt)!=0) {
1012 snprintf(str,sizeof(str),"[FAILED] Fail to check block of %d bytes",cnt);
1013 TEST_FAIL_MESSAGE(str);
1017 /* Check if a different random ID is filtered */
1018 tx_data_msg_info.id = ARM_CAN_EXTENDED_ID(rand()%0x1FFFFFFFU);
1019 memset(buffer_in,0,CAN_MSG_SIZE_FD);
1020 TEST_ASSERT(CAN_RunTransfer (tx_obj_idx, &tx_data_msg_info, buffer_out,
1021 rx_obj_idx, &rx_data_msg_info, buffer_in,
1022 CAN_MSG_SIZE_FD) != ARM_DRIVER_OK);
1024 /* ObjectSetFilter remove extended exact ID 0x1FFFFFFF */
1025 TEST_ASSERT(drv->ObjectSetFilter(rx_obj_idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ARM_CAN_EXTENDED_ID(0x1FFFFFFFU), 0U) == ARM_DRIVER_OK );
1033 /* Power off and uninitialize*/
1034 TEST_ASSERT(drv->PowerControl (ARM_POWER_OFF) == ARM_DRIVER_OK);
1035 TEST_ASSERT(drv->Uninitialize() == ARM_DRIVER_OK);
1041 // end of group dv_can