mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-16 10:03: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:
parent
3c026569f6
commit
f05fc0c70f
@ -82,6 +82,7 @@ struct candev {
|
|||||||
enum can_state state; /**< device state */
|
enum can_state state; /**< device state */
|
||||||
#ifdef MODULE_FDCAN
|
#ifdef MODULE_FDCAN
|
||||||
struct can_bittiming fd_data_bittiming;/**< device bittimings for FD CAN only */
|
struct can_bittiming fd_data_bittiming;/**< device bittimings for FD CAN only */
|
||||||
|
uint16_t loop_delay; /**< CAN FD transceiver loop delay */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
menu "System"
|
menu "System"
|
||||||
|
|
||||||
rsource "auto_init/Kconfig"
|
rsource "auto_init/Kconfig"
|
||||||
|
rsource "can/Kconfig"
|
||||||
rsource "chunked_ringbuffer/Kconfig"
|
rsource "chunked_ringbuffer/Kconfig"
|
||||||
rsource "congure/Kconfig"
|
rsource "congure/Kconfig"
|
||||||
rsource "debug_irq_disable/Kconfig"
|
rsource "debug_irq_disable/Kconfig"
|
||||||
|
|||||||
@ -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].rx_inactivity_timeout = candev_params[i].rx_inactivity_timeout;
|
||||||
candev_dev[i].tx_wakeup_timeout = candev_params[i].tx_wakeup_timeout;
|
candev_dev[i].tx_wakeup_timeout = candev_params[i].tx_wakeup_timeout;
|
||||||
#endif
|
#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,
|
can_device_init(_can_stacks[i], CANDEV_STACKSIZE, CANDEV_BASE_PRIORITY + i,
|
||||||
candev_params[i].name, &candev_dev[i]);
|
candev_params[i].name, &candev_dev[i]);
|
||||||
|
|||||||
36
sys/can/Kconfig
Normal file
36
sys/can/Kconfig
Normal 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
|
||||||
@ -35,6 +35,16 @@
|
|||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
#include "debug.h"
|
#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
|
#ifndef CAN_DEVICE_MSG_QUEUE_SIZE
|
||||||
#define CAN_DEVICE_MSG_QUEUE_SIZE 64
|
#define CAN_DEVICE_MSG_QUEUE_SIZE 64
|
||||||
#endif
|
#endif
|
||||||
@ -236,6 +246,13 @@ static void *_can_device_thread(void *args)
|
|||||||
|
|
||||||
candev_dev->ifnum = can_dll_register_candev(candev_dev);
|
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);
|
dev->driver->init(dev);
|
||||||
power_up(candev_dev);
|
power_up(candev_dev);
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,9 @@ typedef struct candev_params {
|
|||||||
#if defined(MODULE_CAN_TRX) || defined(DOXYGEN)
|
#if defined(MODULE_CAN_TRX) || defined(DOXYGEN)
|
||||||
can_trx_t *trx; /**< transceiver to set */
|
can_trx_t *trx; /**< transceiver to set */
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(MODULE_FDCAN)
|
||||||
|
uint16_t loop_delay; /**< CAN FD transceiver loop delay */
|
||||||
|
#endif
|
||||||
#if defined(MODULE_CAN_PM) || defined(DOXYGEN)
|
#if defined(MODULE_CAN_PM) || defined(DOXYGEN)
|
||||||
uint32_t rx_inactivity_timeout; /**< power management rx timeout value */
|
uint32_t rx_inactivity_timeout; /**< power management rx timeout value */
|
||||||
uint32_t tx_wakeup_timeout; /**< power management tx wake up 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)
|
#if defined(MODULE_CAN_TRX) || defined(DOXYGEN)
|
||||||
can_trx_t *trx; /**< transceiver attached to the device */
|
can_trx_t *trx; /**< transceiver attached to the device */
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(MODULE_FDCAN)
|
||||||
|
uint16_t loop_delay; /**< CAN FD transceiver loop delay */
|
||||||
|
#endif
|
||||||
#if defined(MODULE_CAN_PM) || defined(DOXYGEN)
|
#if defined(MODULE_CAN_PM) || defined(DOXYGEN)
|
||||||
uint32_t rx_inactivity_timeout; /**< Min timeout loaded when a frame is received */
|
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 */
|
uint32_t tx_wakeup_timeout; /**< Min timeout loaded when a frame is sent */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user