void sc_extint_clear(ioportid_t port, uint8_t pin) { uint8_t need_stop = 1; uint8_t i; EXTChannelConfig cfg; (void)port; chMtxLock(&cfg_mtx); chDbgAssert(pin < EXT_MAX_CHANNELS , "EXT pin number outside range"); chDbgAssert(extcfg.channels[pin].cb != NULL, "EXT pin cb not registered"); // FIXME: should check that port matches as well? cfg.cb = NULL; cfg.mode = EXT_CH_MODE_DISABLED; extSetChannelMode(&EXTD1, pin, &cfg); for (i = 0; i < EXT_MAX_CHANNELS; ++i) { if (extcfg.channels[pin].cb != NULL) { need_stop = 0; break; } } if (need_stop) { extStop(&EXTD1); } chMtxUnlock(&cfg_mtx); }
void sc_pwr_rtc_sleep(int timeout_sec) { EXTChannelConfig cfg; EXTConfig extcfg; DEBUG_TOGGLE(1, true); // Allow RTC write RTC->WPR = 0xCA; RTC->WPR = 0x53; while (!(RTC->ISR & RTC_ISR_WUTWF)){ RTC->CR &= ~RTC_CR_WUTE; } DEBUG_TOGGLE(2, true); RTC->CR &= (~7); // Clear WUCKSEL RTC->CR |= 4; // Wakeup clock = ck_spre (1Hz) RTC->WUTR = timeout_sec; DEBUG_TOGGLE(3, true); // Start the wakeup timer PWR->CR |= PWR_CR_CWUF; RTC->ISR &= ~RTC_ISR_WUTF; RTC->CR |= RTC_CR_WUTE | RTC_CR_WUTIE; DEBUG_TOGGLE(4, true); bzero(&cfg, sizeof(cfg)); bzero(&extcfg, sizeof(extcfg)); cfg.mode = EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART; cfg.cb = _empty_cb; extStart(&EXTD1, &extcfg); extSetChannelMode(&EXTD1, 22, &cfg); DEBUG_TOGGLE(5, true); SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; PWR->CR |= (PWR_CR_LPDS/* | PWR_CR_FPDS*/ | PWR_CR_CSBF | PWR_CR_CWUF); PWR->CR &= ~PWR_CR_PDDS; __WFI(); SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; stm32_clock_init(); DEBUG_TOGGLE(6, true); extChannelDisable(&EXTD1, 22); extStop(&EXTD1); RTC->CR &= ~RTC_CR_WUTE; RTC->ISR &= ~RTC_ISR_WUTF; RTC->WPR = 0; // Relock registers }
void sc_extint_set_isr_cb(ioportid_t port, uint8_t pin, SC_EXTINT_EDGE mode, extcallback_t cb) { uint8_t need_start = 1; uint8_t i; uint32_t ext_mode; EXTChannelConfig cfg; chDbgAssert(pin < EXT_MAX_CHANNELS , "EXT pin number outside range"); chDbgAssert(mode == EXT_CH_MODE_RISING_EDGE || mode == EXT_CH_MODE_FALLING_EDGE || mode == EXT_CH_MODE_BOTH_EDGES, "Invalid edge mode"); chMtxLock(&cfg_mtx); chDbgAssert(extcfg.channels[pin].cb == NULL, "EXT pin already registered"); for (i = 0; i < EXT_MAX_CHANNELS; ++i) { if (extcfg.channels[pin].cb != NULL) { need_start = 0; break; } } ext_mode = (mode | EXT_CH_MODE_AUTOSTART | _get_ext_from_port(port)); cfg.cb = cb; cfg.mode = ext_mode; if (need_start) { extStart(&EXTD1, &extcfg); } extSetChannelMode(&EXTD1, pin, &cfg); chMtxUnlock(&cfg_mtx); }