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.
This commit is contained in:
Vincent Dupont 2019-09-13 09:37:17 +02:00
parent 0903952564
commit eb0f6582c7
2 changed files with 26 additions and 11 deletions

View File

@ -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 */

View File

@ -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;