diff --git a/boards/nucleo-f722ze/Kconfig b/boards/nucleo-f722ze/Kconfig index 8e5fcd5f5e..a6d9b19328 100644 --- a/boards/nucleo-f722ze/Kconfig +++ b/boards/nucleo-f722ze/Kconfig @@ -21,6 +21,7 @@ config BOARD_NUCLEO_F722ZE select HAS_PERIPH_TIMER select HAS_PERIPH_UART select HAS_PERIPH_USBDEV + select HAS_PERIPH_CAN # Put other features for this board (in alphabetical order) select HAS_RIOTBOOT diff --git a/boards/nucleo-f722ze/Makefile.features b/boards/nucleo-f722ze/Makefile.features index 346aa6ff29..87f80e5c15 100644 --- a/boards/nucleo-f722ze/Makefile.features +++ b/boards/nucleo-f722ze/Makefile.features @@ -8,6 +8,7 @@ FEATURES_PROVIDED += periph_rtt FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_uart FEATURES_PROVIDED += periph_usbdev +FEATURES_PROVIDED += periph_can # Put other features for this board (in alphabetical order) FEATURES_PROVIDED += riotboot diff --git a/cpu/stm32/include/can_params.h b/cpu/stm32/include/can_params.h index b6294e599a..d1c0e26912 100644 --- a/cpu/stm32/include/can_params.h +++ b/cpu/stm32/include/can_params.h @@ -43,11 +43,13 @@ static const can_conf_t candev_conf[] = { .rcc_mask = RCC_APB1ENR1_CAN1EN, #else .rcc_mask = RCC_APB1ENR_CAN1EN, +#if CANDEV_STM32_CHAN_NUMOF > 1 .can_master = CAN1, .master_rcc_mask = RCC_APB1ENR_CAN1EN, .first_filter = 0, .nb_filters = 14, #endif +#endif #if defined(CPU_FAM_STM32F1) .rx_pin = GPIO_PIN(PORT_A, 11), .tx_pin = GPIO_PIN(PORT_A, 12), diff --git a/cpu/stm32/include/candev_stm32.h b/cpu/stm32/include/candev_stm32.h index 9a8925d380..c87467ea9a 100644 --- a/cpu/stm32/include/candev_stm32.h +++ b/cpu/stm32/include/candev_stm32.h @@ -42,7 +42,7 @@ extern "C" { #elif defined(CPU_FAM_STM32F1) || defined(CPU_FAM_STM32F2) || defined(CPU_FAM_STM32F4) #define CANDEV_STM32_CHAN_NUMOF 2 #elif defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32F3) || \ - defined(CPU_FAM_STM32L4) || DOXYGEN + defined(CPU_FAM_STM32L4) || defined(CPU_LINE_STM32F722xx) || DOXYGEN /** Number of channels in the device (up to 3) */ #define CANDEV_STM32_CHAN_NUMOF 1 #else @@ -137,7 +137,6 @@ typedef struct { /** The number of receive FIFO */ #define CAN_STM32_RX_MAILBOXES 2 - #ifndef CAN_STM32_RX_MAIL_FIFO /** This is the maximum number of frame the driver can receive simultaneously */ #define CAN_STM32_RX_MAIL_FIFO 12 diff --git a/cpu/stm32/periph/can.c b/cpu/stm32/periph/can.c index 9862cdb3c8..0376319f9d 100644 --- a/cpu/stm32/periph/can.c +++ b/cpu/stm32/periph/can.c @@ -805,6 +805,12 @@ static int _set(candev_t *candev, canopt_t opt, void *value, size_t value_len) can->BTR |= CAN_BTR_SILM; res += set_mode(can, mode); break; + case CANOPT_STATE_LOOPBACK: + DEBUG("candev_stm32 %p: Loopback\n", (void *)dev); + res = set_mode(can, MODE_INIT); + can->BTR |= CAN_BTR_LBKM; + res += set_mode(can, MODE_NORMAL); + break; } } break; diff --git a/sys/include/can/common.h b/sys/include/can/common.h index ea255c0802..80babfa4e0 100644 --- a/sys/include/can/common.h +++ b/sys/include/can/common.h @@ -63,9 +63,9 @@ typedef enum { CANOPT_STATE_SLEEP, /**< sleep mode */ CANOPT_STATE_LISTEN_ONLY, /**< listen only mode */ CANOPT_STATE_ON, /**< power on, rx / tx mode */ + CANOPT_STATE_LOOPBACK, /**< loopback mode */ } canopt_state_t; - /** * @brief Structure to pass a CAN option */ diff --git a/tests/candev/main.c b/tests/candev/main.c index 1a795b5962..42e796be00 100644 --- a/tests/candev/main.c +++ b/tests/candev/main.c @@ -48,6 +48,11 @@ static candev_mcp2515_t mcp2515_dev; /* add includes for other candev drivers here */ #endif +/* Default is not using loopback test mode */ +#ifndef CONFIG_USE_LOOPBACK_MODE +#define CONFIG_USE_LOOPBACK_MODE 0 +#endif + #define RX_RINGBUFFER_SIZE 128 /* Needs to be a power of 2! */ static isrpipe_t rxbuf; static uint8_t rx_ringbuf[RX_RINGBUFFER_SIZE]; @@ -222,6 +227,18 @@ int main(void) candev->driver->init(candev); +if (IS_ACTIVE(CONFIG_USE_LOOPBACK_MODE)) { + puts("Switching to loopback mode"); + /* set to loopback test mode */ + canopt_state_t mode = CANOPT_STATE_LOOPBACK; + candev->driver->set(candev, CANOPT_STATE, &mode, sizeof(mode)); + + /* do not care, receive all message id */ + struct can_filter filter; + filter.can_mask = 0; + candev->driver->set_filter(candev, &filter); +} + char line_buf[SHELL_DEFAULT_BUFSIZE]; shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);