@@ -29,6 +29,7 @@ using namespace mbed;
2929
3030ONBOARD_SARA4_PPP::ONBOARD_SARA4_PPP (FileHandle *fh) : SARA4_PPP(fh)
3131{
32+ initialized = 0 ;
3233}
3334
3435nsapi_error_t ONBOARD_SARA4_PPP::hard_power_on ()
@@ -45,6 +46,8 @@ nsapi_error_t ONBOARD_SARA4_PPP::hard_power_off()
4546
4647nsapi_error_t ONBOARD_SARA4_PPP::soft_power_on ()
4748{
49+ // See base function description. This function is for power on but reset too.
50+ onboard_modem_power_down ();
4851 onboard_modem_power_up ();
4952 return NSAPI_ERROR_OK;
5053}
@@ -80,55 +83,105 @@ void ONBOARD_SARA4_PPP::onboard_modem_init()
8083{
8184 gpio_t gpio;
8285
83- // Take us out of reset
86+ // Enable radio power regulator and buffer, configure RESET_N and PWR_ON.
8487 gpio_init_inout (&gpio, RADIO_PWR, PIN_OUTPUT, PushPullNoPull, 1 );
8588 gpio_init_inout (&gpio, BUF_EN, PIN_OUTPUT, OpenDrainNoPull, 0 );
8689 gpio_init_out_ex (&gpio, MDMRST, 0 );
8790 gpio_init_out_ex (&gpio, MDMPWRON, 0 );
8891 gpio_init_inout (&gpio, RADIO_DTR, PIN_OUTPUT, OpenDrainNoPull, 0 );
92+ initialized = 1 ;
8993}
9094
9195void ONBOARD_SARA4_PPP::onboard_modem_deinit ()
9296{
97+ // Make sure to power down before removing power!
9398 onboard_modem_power_down ();
9499 gpio_t gpio;
95100
96- // Back into reset
97- gpio_init_out_ex (&gpio, MDMRST, 1 );
98- gpio_init_out_ex (&gpio, MDMPWRON, 1 );
99- gpio_init_inout (&gpio, BUF_EN, PIN_OUTPUT, OpenDrainNoPull, 1 );
100- gpio_init_inout (&gpio, RADIO_PWR, PIN_OUTPUT, PushPullNoPull, 0 );
101- gpio_init_inout (&gpio, RADIO_DTR, PIN_OUTPUT, OpenDrainNoPull, 1 );
101+ // Set all to input no pull. Let pull resistors do their thing. Allows for lowest power draw.
102+ // Disable radio power regulator and buffer.
103+ gpio_init_inout (&gpio, MDMRST, PIN_INPUT, PullNone, 1 );
104+ gpio_init_inout (&gpio, MDMPWRON, PIN_INPUT, PullNone, 1 );
105+ gpio_init_inout (&gpio, BUF_EN, PIN_INPUT, PullNone, 1 );
106+ gpio_init_inout (&gpio, RADIO_PWR, PIN_INPUT, PullNone, 0 );
107+ gpio_init_inout (&gpio, RADIO_DTR, PIN_INPUT, PullNone, 1 );
108+ initialized = 0 ;
102109}
103110
104111void ONBOARD_SARA4_PPP::onboard_modem_power_up ()
105112{
106- onboard_modem_init ();
113+ // Make sure the radio is initialized so it can be powered on.
114+ if (!initialized){
115+ onboard_modem_init ();
116+ }
107117
108- gpio_t gpio;
109- gpio_init_in (&gpio, MON_1V8);
110-
111- if (gpio_is_connected (&gpio) && !gpio_read (&gpio)) {
112- unsigned int i = 0 ;
113- while (i < 3 )
114- {
115- press_power_button (150000 );
116- thread_sleep_for (250 );
117-
118- if (gpio_read (&gpio))
119- {
120- break ;
121- }
122- i++;
123- }
118+ gpio_t radioOn;
119+ gpio_init_in (&radioOn, MON_1V8);
120+
121+ // Need volatile so 1.8v check is not optimized out.
122+ volatile int v1_8 = gpio_read (&radioOn);
123+
124+ // If radio is on, do nothing.
125+ if (v1_8) {
126+ return ;
124127 }
128+
129+ uint8_t retries = 5 ;
130+ do {
131+ // If it hasn't turned on after multiple tries, exit and return.
132+ if (0 == retries--) {
133+ return ;
134+ }
135+ // Activate PWR_ON for 150ms-3.2s to switch on. Reference ublox SARA-R4 data sheet.
136+ press_power_button (160000 );
137+ v1_8 = gpio_read (&radioOn);
138+ } while (!v1_8);
139+ // Takes ~4.5s to power on. Reference SARA-R4 system integration manual... module power-on.
140+ // Pad a few more seconds to be sure.
141+ thread_sleep_for (8000 );
125142}
126143
127144void ONBOARD_SARA4_PPP::onboard_modem_power_down ()
128145{
129- /* Activate PWR_ON for 1.5s to switch off */
130- press_power_button (1500000 );
131- // check for 1.8v low if not, take reset low for 10s
146+ gpio_t radioOn;
147+ gpio_init_in (&radioOn, MON_1V8);
148+ // Need volatile so 1.8v check is not optimized out.
149+ volatile int v1_8 = gpio_read (&radioOn);
150+ // Do nothing if it's already off.
151+ if (!v1_8) {
152+ return ;
153+ }
154+
155+ // Make sure the I/O are properly initialized.
156+ if (!initialized){
157+ onboard_modem_init ();
158+ }
159+ // Activate PWR_ON for at least 1.5s to switch off. Reference ublox SARA-R4 data sheet.
160+ press_power_button (1600000 );
161+
162+ // wait a max of 40s for 1.8v to go low. Reference AT command guide +CPWROFF estimated response.
163+ uint8_t timeout = 40 ;
164+ do {
165+ thread_sleep_for (1000 );
166+ v1_8 = gpio_read (&radioOn);
167+ } while (v1_8 && timeout--);
168+
169+ // hold RESET_N low (inverted) at least 10s to power down the radio.
170+ if (v1_8) {
171+ gpio_t gpio;
172+ gpio_init_out_ex (&gpio, RADIO_RESET, 1 );
173+ thread_sleep_for (11000 );
174+ gpio_write (&gpio, 0 );
175+ }
176+
177+ v1_8 = gpio_read (&radioOn);
178+ // Cut power to the radio if it's still not powered off.
179+ if (v1_8) {
180+ gpio_t gpio;
181+ gpio_init_inout (&gpio, RADIO_PWR, PIN_INPUT, PullNone, 0 );
182+ thread_sleep_for (1000 );
183+ initialized = 0 ;
184+ }
132185}
133186
134187#endif // MBED_CONF_NSAPI_PRESENT
0 commit comments