@@ -97,92 +97,35 @@ void QUECTEL_BG96::set_ready_cb(Callback<void()> callback)
9797 _at->set_urc_handler (DEVICE_READY_URC, callback);
9898}
9999
100- nsapi_error_t QUECTEL_BG96::hard_power_on ()
101- {
102- if (_pwr.is_connected ()) {
103- tr_info (" Modem power on" );
104- ThisThread::sleep_for (250 );
105- _pwr = !_active_high;
106- ThisThread::sleep_for (250 ); // BG96_Hardware_Design_V1.1 says 100 ms, but 250 ms seems to be more robust
107- _pwr = _active_high;
108- ThisThread::sleep_for (500 );
109- }
110-
111- return NSAPI_ERROR_OK;
112- }
113-
114100nsapi_error_t QUECTEL_BG96::soft_power_on ()
115- {
116- if (!_rst.is_connected ()) {
117- return NSAPI_ERROR_OK;
118- }
119-
120- tr_info (" Reset modem" );
121- _rst = !_active_high;
122- ThisThread::sleep_for (100 );
123- _rst = _active_high;
124- ThisThread::sleep_for (150 + 460 ); // RESET_N timeout from BG96_Hardware_Design_V1.1
125- _rst = !_active_high;
126- ThisThread::sleep_for (500 );
127-
128- // wait for RDY
129- _at->lock ();
130- _at->set_at_timeout (10 * 1000 );
131- _at->resp_start ();
132- _at->set_stop_tag (" RDY" );
133- bool rdy = _at->consume_to_stop_tag ();
134- _at->set_stop_tag (OK);
135- _at->restore_at_timeout ();
136-
137- if (!rdy) {
138- // check if modem was silently powered on
139- _at->clear_error ();
140- _at->set_at_timeout (100 );
141- _at->at_cmd_discard (" " , " " ); // Send AT
142- _at->restore_at_timeout ();
143- }
144- return _at->unlock_return_error ();
145- }
146-
147- nsapi_error_t QUECTEL_BG96::hard_power_off ()
148101{
149102 if (_pwr.is_connected ()) {
150- tr_info (" Modem power off" );
151- _pwr = _active_high;
152- ThisThread::sleep_for (650 ); // from BG96_Hardware_Design_V1.1
153- _pwr = !_active_high;
103+ tr_info (" QUECTEL_BG96::soft_power_on" );
104+ // check if modem was powered on already
105+ if (wake_up ()) {
106+ return NSAPI_ERROR_OK;
107+ }
108+ if (!wake_up (true )) {
109+ tr_error (" Modem not responding" );
110+ soft_power_off ();
111+ return NSAPI_ERROR_DEVICE_ERROR;
112+ }
154113 }
155114
156115 return NSAPI_ERROR_OK;
157116}
158117
159- nsapi_error_t QUECTEL_BG96::init ()
118+ nsapi_error_t QUECTEL_BG96::soft_power_off ()
160119{
161- setup_at_handler ();
162-
163- int retry = 0 ;
164-
165120 _at->lock ();
166- _at->flush ();
167- _at->at_cmd_discard (" E0" , " " ); // echo off
168-
169- _at->at_cmd_discard (" +CMEE" , " =1" ); // verbose responses
170-
121+ _at->cmd_start (" AT+QPOWD" );
122+ _at->cmd_stop_read_resp ();
171123 if (_at->get_last_error () != NSAPI_ERROR_OK) {
172- return _at->unlock_return_error ();
173- }
174-
175- do {
176- _at->clear_error ();
177- _at->at_cmd_discard (" +CFUN" , " =1" ); // set full functionality
178- if (_at->get_last_error () == NSAPI_ERROR_OK) {
179- break ;
124+ tr_warn (" Force modem off" );
125+ if (_pwr.is_connected ()) {
126+ press_button (_pwr, 650 ); // BG96_Hardware_Design_V1.1: Power off signal at least 650 ms
180127 }
181- // wait some time that modem gets ready for CFUN command, and try again
182- retry++;
183- ThisThread::sleep_for (64 ); // experimental value
184- } while (retry < 3 );
185-
128+ }
186129 return _at->unlock_return_error ();
187130}
188131
@@ -215,3 +158,52 @@ void QUECTEL_BG96::urc_pdpdeact()
215158 }
216159 send_disconnect_to_context (cid);
217160}
161+
162+ void QUECTEL_BG96::press_button (DigitalOut &button, uint32_t timeout)
163+ {
164+ if (!button.is_connected ()) {
165+ return ;
166+ }
167+ button = _active_high;
168+ ThisThread::sleep_for (timeout);
169+ button = !_active_high;
170+ }
171+
172+ bool QUECTEL_BG96::wake_up (bool reset)
173+ {
174+ // check if modem is already ready
175+ _at->lock ();
176+ _at->flush ();
177+ _at->set_at_timeout (30 );
178+ _at->cmd_start (" AT" );
179+ _at->cmd_stop_read_resp ();
180+ nsapi_error_t err = _at->get_last_error ();
181+ _at->restore_at_timeout ();
182+ _at->unlock ();
183+ // modem is not responding, power it on
184+ if (err != NSAPI_ERROR_OK) {
185+ if (!reset) {
186+ // BG96_Hardware_Design_V1.1 requires VBAT to be stable over 30 ms, that's handled above
187+ tr_info (" Power on modem" );
188+ press_button (_pwr, 250 ); // BG96_Hardware_Design_V1.1 requires time 100 ms, but 250 ms seems to be more robust
189+ } else {
190+ tr_warn (" Reset modem" );
191+ press_button (_rst, 150 ); // BG96_Hardware_Design_V1.1 requires RESET_N timeout at least 150 ms
192+ }
193+ _at->lock ();
194+ // According to BG96_Hardware_Design_V1.1 USB is active after 4.2s, but it seems to take over 5s
195+ _at->set_at_timeout (6000 );
196+ _at->resp_start ();
197+ _at->set_stop_tag (" RDY" );
198+ bool rdy = _at->consume_to_stop_tag ();
199+ _at->set_stop_tag (OK);
200+ _at->restore_at_timeout ();
201+ _at->unlock ();
202+ if (!rdy) {
203+ return false ;
204+ }
205+ }
206+
207+ // sync to check that AT is really responsive and to clear garbage
208+ return _at->sync (500 );
209+ }
0 commit comments