From eb0f6582c75f07c2b9b433b469a92faf2409a68b Mon Sep 17 00:00:00 2001 From: Vincent Dupont Date: Fri, 13 Sep 2019 09:37:17 +0200 Subject: [PATCH 1/2] stm32/can: add option to enable deep-sleep per device Deep-sleep was based on using rx pin as external interrupt to be able to wake up from stop mode. If rx pin cannot be used as interrupt or user does not need to wake up from stop from the CAN, an option is now present. If en_deep_sleep_wake_up is set to false, setting the device to sleep simply unblock stop mode. Otherwise the behavior is unchanged. --- cpu/stm32/include/candev_stm32.h | 1 + cpu/stm32/periph/can.c | 36 ++++++++++++++++++++++---------- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/cpu/stm32/include/candev_stm32.h b/cpu/stm32/include/candev_stm32.h index 0d5afe5a7a92..9a8925d3808f 100644 --- a/cpu/stm32/include/candev_stm32.h +++ b/cpu/stm32/include/candev_stm32.h @@ -100,6 +100,7 @@ typedef struct { #ifndef CPU_FAM_STM32F1 gpio_af_t af; /**< Alternate pin function to use */ #endif + bool en_deep_sleep_wake_up; /**< Enable deep-sleep wake-up interrupt */ #if CANDEV_STM32_CHAN_NUMOF > 1 || defined(DOXYGEN) CAN_TypeDef *can_master; /**< Master CAN device */ uint32_t master_rcc_mask; /**< Master device RCC mask */ diff --git a/cpu/stm32/periph/can.c b/cpu/stm32/periph/can.c index 032abb6ae5a7..9862cdb3c802 100644 --- a/cpu/stm32/periph/can.c +++ b/cpu/stm32/periph/can.c @@ -644,8 +644,10 @@ static void turn_off(can_t *dev) #endif } _status[chan] = STATUS_SLEEP; - periph_clk_dis(APB1, dev->conf->rcc_mask); - enable_int(dev, 0); + if (dev->conf->en_deep_sleep_wake_up) { + periph_clk_dis(APB1, dev->conf->rcc_mask); + enable_int(dev, 0); + } } } else { @@ -658,20 +660,26 @@ static void turn_off(can_t *dev) #endif /* Fall through */ case STATUS_NOT_USED: - periph_clk_dis(APB1, dev->conf->master_rcc_mask); + if (dev->conf->en_deep_sleep_wake_up) { + periph_clk_dis(APB1, dev->conf->master_rcc_mask); + } break; } - periph_clk_dis(APB1, dev->conf->rcc_mask); + if (dev->conf->en_deep_sleep_wake_up) { + periph_clk_dis(APB1, dev->conf->rcc_mask); + } if (_status[get_channel(dev->conf->can)] != STATUS_SLEEP) { #ifdef STM32_PM_STOP pm_unblock(STM32_PM_STOP); #endif } _status[get_channel(dev->conf->can)] = STATUS_SLEEP; - if (_status[master_chan] == STATUS_SLEEP) { - enable_int(dev, 1); + if (dev->conf->en_deep_sleep_wake_up) { + if (_status[master_chan] == STATUS_SLEEP) { + enable_int(dev, 1); + } + enable_int(dev, 0); } - enable_int(dev, 0); } #else if (_status[get_channel(dev->conf->can)] != STATUS_SLEEP) { @@ -680,8 +688,10 @@ static void turn_off(can_t *dev) #endif } _status[get_channel(dev->conf->can)] = STATUS_SLEEP; - periph_clk_dis(APB1, dev->conf->rcc_mask); - gpio_init_int(dev->rx_pin, GPIO_IN, GPIO_FALLING, _wkup_cb, dev); + if (dev->conf->en_deep_sleep_wake_up) { + periph_clk_dis(APB1, dev->conf->rcc_mask); + gpio_init_int(dev->rx_pin, GPIO_IN, GPIO_FALLING, _wkup_cb, dev); + } #endif irq_restore(irq); } @@ -697,7 +707,9 @@ static void turn_on(can_t *dev) switch (_status[master_chan]) { case STATUS_SLEEP: _status[master_chan] = STATUS_READY_FOR_SLEEP; - disable_int(dev, 1); + if (dev->conf->en_deep_sleep_wake_up) { + disable_int(dev, 1); + } #ifdef STM32_PM_STOP pm_block(STM32_PM_STOP); #endif @@ -712,7 +724,9 @@ static void turn_on(can_t *dev) #ifdef STM32_PM_STOP pm_block(STM32_PM_STOP); #endif - disable_int(dev, 0); + if (dev->conf->en_deep_sleep_wake_up) { + disable_int(dev, 0); + } periph_clk_en(APB1, dev->conf->rcc_mask); } _status[get_channel(dev->conf->can)] = STATUS_ON; From 2edf37ed5b352a3777ca99f6a942859cef32586b Mon Sep 17 00:00:00 2001 From: Vincent Dupont Date: Tue, 2 Feb 2021 15:39:27 +0100 Subject: [PATCH 2/2] cpu/stm32/can: use en_deep_sleep_wake_up by default Add en_deep_sleep_wake_up = true in default candev_conf in can_params.h --- cpu/stm32/include/can_params.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cpu/stm32/include/can_params.h b/cpu/stm32/include/can_params.h index e0f2408f1447..b6294e599a6b 100644 --- a/cpu/stm32/include/can_params.h +++ b/cpu/stm32/include/can_params.h @@ -65,6 +65,7 @@ static const can_conf_t candev_conf[] = { .rx1_irqn = CAN1_RX1_IRQn, .sce_irqn = CAN1_SCE_IRQn, #endif + .en_deep_sleep_wake_up = true, .ttcm = 0, .abom = 1, .awum = 1, @@ -85,6 +86,7 @@ static const can_conf_t candev_conf[] = { #ifndef CPU_FAM_STM32F1 .af = GPIO_AF9, #endif + .en_deep_sleep_wake_up = true, .tx_irqn = CAN2_TX_IRQn, .rx0_irqn = CAN2_RX0_IRQn, .rx1_irqn = CAN2_RX1_IRQn, @@ -108,6 +110,7 @@ static const can_conf_t candev_conf[] = { .rx_pin = GPIO_PIN(PORT_B, 3), .tx_pin = GPIO_PIN(PORT_B, 4), .af = GPIO_AF11, + .en_deep_sleep_wake_up = true, .tx_irqn = CAN3_TX_IRQn, .rx0_irqn = CAN3_RX0_IRQn, .rx1_irqn = CAN3_RX1_IRQn,