From 01b60c20a1c7adc9d31c87ff0b75f5c2ddbb5bed Mon Sep 17 00:00:00 2001 From: Leon Date: Thu, 19 Nov 2020 18:09:06 -0600 Subject: [PATCH] Update Dragonfly Nano(MTQN) power on/off so soft_power_on() performs a reset --- .../ONBOARD_SARA4_PPP.cpp | 109 +++++++++++++----- .../ONBOARD_SARA4_PPP.h | 2 + 2 files changed, 83 insertions(+), 28 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.cpp b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.cpp index d4f7f851f3..d09ef1cc8e 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.cpp +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.cpp @@ -29,6 +29,7 @@ using namespace mbed; ONBOARD_SARA4_PPP::ONBOARD_SARA4_PPP(FileHandle *fh) : SARA4_PPP(fh) { + initialized = 0; } nsapi_error_t ONBOARD_SARA4_PPP::hard_power_on() @@ -45,6 +46,8 @@ nsapi_error_t ONBOARD_SARA4_PPP::hard_power_off() nsapi_error_t ONBOARD_SARA4_PPP::soft_power_on() { + // See base function description. This function is for power on but reset too. + onboard_modem_power_down(); onboard_modem_power_up(); return NSAPI_ERROR_OK; } @@ -80,55 +83,105 @@ void ONBOARD_SARA4_PPP::onboard_modem_init() { gpio_t gpio; - // Take us out of reset + // Enable radio power regulator and buffer, configure RESET_N and PWR_ON. gpio_init_inout(&gpio, RADIO_PWR, PIN_OUTPUT, PushPullNoPull, 1); gpio_init_inout(&gpio, BUF_EN, PIN_OUTPUT, OpenDrainNoPull, 0); gpio_init_out_ex(&gpio, MDMRST, 0); gpio_init_out_ex(&gpio, MDMPWRON, 0); gpio_init_inout(&gpio, RADIO_DTR, PIN_OUTPUT, OpenDrainNoPull, 0); + initialized = 1; } void ONBOARD_SARA4_PPP::onboard_modem_deinit() { + // Make sure to power down before removing power! onboard_modem_power_down(); gpio_t gpio; - // Back into reset - gpio_init_out_ex(&gpio, MDMRST, 1); - gpio_init_out_ex(&gpio, MDMPWRON, 1); - gpio_init_inout(&gpio, BUF_EN, PIN_OUTPUT, OpenDrainNoPull, 1); - gpio_init_inout(&gpio, RADIO_PWR, PIN_OUTPUT, PushPullNoPull, 0); - gpio_init_inout(&gpio, RADIO_DTR, PIN_OUTPUT, OpenDrainNoPull, 1); + // Set all to input no pull. Let pull resistors do their thing. Allows for lowest power draw. + // Disable radio power regulator and buffer. + gpio_init_inout(&gpio, MDMRST, PIN_INPUT, PullNone, 1); + gpio_init_inout(&gpio, MDMPWRON, PIN_INPUT, PullNone, 1); + gpio_init_inout(&gpio, BUF_EN, PIN_INPUT, PullNone, 1); + gpio_init_inout(&gpio, RADIO_PWR, PIN_INPUT, PullNone, 0); + gpio_init_inout(&gpio, RADIO_DTR, PIN_INPUT, PullNone, 1); + initialized = 0; } void ONBOARD_SARA4_PPP::onboard_modem_power_up() { - onboard_modem_init(); - - gpio_t gpio; - gpio_init_in(&gpio, MON_1V8); - - if(gpio_is_connected(&gpio) && !gpio_read(&gpio)) { - unsigned int i = 0; - while(i < 3) - { - press_power_button(150000); - thread_sleep_for(250); - - if(gpio_read(&gpio)) - { - break; - } - i++; - } + // Make sure the radio is initialized so it can be powered on. + if (!initialized){ + onboard_modem_init(); } + + gpio_t radioOn; + gpio_init_in(&radioOn, MON_1V8); + + // Need volatile so 1.8v check is not optimized out. + volatile int v1_8 = gpio_read(&radioOn); + + // If radio is on, do nothing. + if (v1_8) { + return; + } + + uint8_t retries = 5; + do { + // If it hasn't turned on after multiple tries, exit and return. + if(0 == retries--) { + return; + } + // Activate PWR_ON for 150ms-3.2s to switch on. Reference ublox SARA-R4 data sheet. + press_power_button(160000); + v1_8 = gpio_read(&radioOn); + } while (!v1_8); + // Takes ~4.5s to power on. Reference SARA-R4 system integration manual... module power-on. + // Pad a few more seconds to be sure. + thread_sleep_for(8000); } void ONBOARD_SARA4_PPP::onboard_modem_power_down() { - /* Activate PWR_ON for 1.5s to switch off */ - press_power_button(1500000); - // check for 1.8v low if not, take reset low for 10s + gpio_t radioOn; + gpio_init_in(&radioOn, MON_1V8); + // Need volatile so 1.8v check is not optimized out. + volatile int v1_8 = gpio_read(&radioOn); + // Do nothing if it's already off. + if (!v1_8) { + return; + } + + // Make sure the I/O are properly initialized. + if (!initialized){ + onboard_modem_init(); + } + // Activate PWR_ON for at least 1.5s to switch off. Reference ublox SARA-R4 data sheet. + press_power_button(1600000); + + // wait a max of 40s for 1.8v to go low. Reference AT command guide +CPWROFF estimated response. + uint8_t timeout = 40; + do { + thread_sleep_for(1000); + v1_8 = gpio_read(&radioOn); + } while (v1_8 && timeout--); + + // hold RESET_N low (inverted) at least 10s to power down the radio. + if (v1_8) { + gpio_t gpio; + gpio_init_out_ex(&gpio, RADIO_RESET, 1); + thread_sleep_for(11000); + gpio_write(&gpio, 0); + } + + v1_8 = gpio_read(&radioOn); + // Cut power to the radio if it's still not powered off. + if (v1_8) { + gpio_t gpio; + gpio_init_inout(&gpio, RADIO_PWR, PIN_INPUT, PullNone, 0); + thread_sleep_for(1000); + initialized = 0; + } } #endif // MBED_CONF_NSAPI_PRESENT diff --git a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.h b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.h index 7b63276b12..05652a19f7 100644 --- a/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.h +++ b/targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L471xG/TARGET_MTS_DRAGONFLY_L471QG/ONBOARD_SARA4_PPP.h @@ -32,6 +32,8 @@ public: virtual nsapi_error_t soft_power_off(); private: + uint8_t initialized; + void press_power_button(int time_ms); void onboard_modem_init();