1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-15 09:33:50 +01:00

can: introduce loop_delay

During the data phase of a FDCAN transmission only one node is
transmitting, all others are receivers. The length of the bus line has
no impact.
When transmitting via pin FDCAN_TX the protocol controller receives the
transmitted data from its local CAN transceiver via pin FDCAN_RX. The
received data is delayed by the CAN transceiver loop delay.
If this delay is greater than TSEG1 (time segment before sample point),
a bit error is detected. Without transceiver delay compensation, the bit
rate in the data phase of a FDCAN frame is limited by the transceiver's
loop delay.

Since this parameter is related to the transceiver used, there cannot be
a default value, and it must be explicitly defined with the
configuration variable CONFIG_FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY.

Signed-off-by: Gilles DOFFE <gilles.doffe@rtone.fr>
This commit is contained in:
Gilles DOFFE 2024-02-23 22:50:43 +01:00
parent 3c026569f6
commit f05fc0c70f
6 changed files with 64 additions and 0 deletions

View File

@ -82,6 +82,7 @@ struct candev {
enum can_state state; /**< device state */
#ifdef MODULE_FDCAN
struct can_bittiming fd_data_bittiming;/**< device bittimings for FD CAN only */
uint16_t loop_delay; /**< CAN FD transceiver loop delay */
#endif
};

View File

@ -7,6 +7,7 @@
menu "System"
rsource "auto_init/Kconfig"
rsource "can/Kconfig"
rsource "chunked_ringbuffer/Kconfig"
rsource "congure/Kconfig"
rsource "debug_irq_disable/Kconfig"

View File

@ -48,6 +48,9 @@ void auto_init_periph_can(void) {
candev_dev[i].rx_inactivity_timeout = candev_params[i].rx_inactivity_timeout;
candev_dev[i].tx_wakeup_timeout = candev_params[i].tx_wakeup_timeout;
#endif
#ifdef MODULE_FDCAN
candev_dev[i].loop_delay = candev_params[i].loop_delay;
#endif
can_device_init(_can_stacks[i], CANDEV_STACKSIZE, CANDEV_BASE_PRIORITY + i,
candev_params[i].name, &candev_dev[i]);

36
sys/can/Kconfig Normal file
View File

@ -0,0 +1,36 @@
menu "CAN"
depends on USEMODULE_CAN || USEMODULE_FDCAN
menu "FD CAN"
config FDCAN_DEVICE_SET_TRANSCEIVER_LOOP_DELAY
depends on USEMODULE_FDCAN
bool "FD CAN transceiver loop delay"
default n
help
Allow to set FD CAN Transceiver loop delay.
config FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY
depends on FDCAN_DEVICE_SET_TRANSCEIVER_LOOP_DELAY
int "FD CAN transceiver loop delay value"
range 0 1000
default 0
help
This parameter defines the loop delay introduced by the CAN transceiver
during transmission. The loop delay represents the time taken for the
transmitted signal to be looped back to the CAN controller. This delay
is introduced by the physical transceiver circuitry and may vary
depending on the transceiver model and other physical factors.
The value is typically measured in nanoseconds and should be set
according to the specifications provided by the transceiver manufacturer.
A higher loop delay can affect the timing of CAN message transmissions
and may need to be adjusted in systems with tight timing requirements.
If unsure, leave this value as 0 or refer to the hardware documentation
for the correct delay value.
endmenu # FD CAN
endmenu # CAN

View File

@ -35,6 +35,16 @@
#define ENABLE_DEBUG 0
#include "debug.h"
#ifdef MODULE_FDCAN
/**
* The loop delay in CAN, especially in CAN FD with bitrate switching, affects synchronization due to increased data rates.
* The unit is nanoseconds.
*/
#ifndef CONFIG_FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY
#error "CONFIG_FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY must be defined. This property can be found in the datasheet of the CAN transceiver in use. The unit is nanoseconds."
#endif /* CONFIG_FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY */
#endif /* MODULE_FDCAN */
#ifndef CAN_DEVICE_MSG_QUEUE_SIZE
#define CAN_DEVICE_MSG_QUEUE_SIZE 64
#endif
@ -236,6 +246,13 @@ static void *_can_device_thread(void *args)
candev_dev->ifnum = can_dll_register_candev(candev_dev);
#if defined(MODULE_FDCAN)
if (candev_dev->loop_delay == 0) {
candev_dev->loop_delay = CONFIG_FDCAN_DEVICE_TRANSCEIVER_LOOP_DELAY;
}
dev->loop_delay = candev_dev->loop_delay;
#endif
dev->driver->init(dev);
power_up(candev_dev);

View File

@ -57,6 +57,9 @@ typedef struct candev_params {
#if defined(MODULE_CAN_TRX) || defined(DOXYGEN)
can_trx_t *trx; /**< transceiver to set */
#endif
#if defined(MODULE_FDCAN)
uint16_t loop_delay; /**< CAN FD transceiver loop delay */
#endif
#if defined(MODULE_CAN_PM) || defined(DOXYGEN)
uint32_t rx_inactivity_timeout; /**< power management rx timeout value */
uint32_t tx_wakeup_timeout; /**< power management tx wake up value */
@ -74,6 +77,9 @@ typedef struct candev_dev {
#if defined(MODULE_CAN_TRX) || defined(DOXYGEN)
can_trx_t *trx; /**< transceiver attached to the device */
#endif
#if defined(MODULE_FDCAN)
uint16_t loop_delay; /**< CAN FD transceiver loop delay */
#endif
#if defined(MODULE_CAN_PM) || defined(DOXYGEN)
uint32_t rx_inactivity_timeout; /**< Min timeout loaded when a frame is received */
uint32_t tx_wakeup_timeout; /**< Min timeout loaded when a frame is sent */