Eric Jung
/
WIZnet-IoTShield-BG96-PSM
BG96 Cat.M1 PSM setting sample for WIZnet IoT Shield
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 /* WIZnet IoT Shield Cat.M1 Sample code for Arm MBED 00002 * Copyright (c) 2019 WIZnet Co., Ltd. 00003 * SPDX-License-Identifier: Apache-2.0 00004 */ 00005 00006 /* 00007 * Licensed under the Apache License, Version 2.0 (the "License"); 00008 * you may not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, 00015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * 00017 * See the License for the specific language governing permissions and 00018 * limitations under the License. 00019 * 00020 */ 00021 00022 00023 #include <string> 00024 #include "mbed.h" 00025 00026 #define RET_OK 1 00027 #define RET_NOK -1 00028 #define DEBUG_ENABLE 1 00029 #define DEBUG_DISABLE 0 00030 #define ON 1 00031 #define OFF 0 00032 00033 #define MAX_BUF_SIZE 1024 00034 00035 #define BG96_APN_PROTOCOL_IPv4 1 00036 #define BG96_APN_PROTOCOL_IPv6 2 00037 #define BG96_DEFAULT_TIMEOUT 1000 00038 #define BG96_CONNECT_TIMEOUT 15000 00039 #define BG96_SEND_TIMEOUT 500 00040 #define BG96_RECV_TIMEOUT 500 00041 00042 #define BG96_APN_PROTOCOL BG96_APN_PROTOCOL_IPv6 00043 #define BG96_DEFAULT_BAUD_RATE 115200 00044 #define BG96_PARSER_DELIMITER "\r\n" 00045 00046 #define CATM1_APN_SKT "lte-internet.sktelecom.com" 00047 00048 #define CATM1_DEVICE_NAME_BG96 "BG96" 00049 #define DEVNAME CATM1_DEVICE_NAME_BG96 00050 00051 #define devlog(f_, ...) if(CATM1_DEVICE_DEBUG == DEBUG_ENABLE) { pc.printf("\r\n[%s] ", DEVNAME); pc.printf((f_), ##__VA_ARGS__); } 00052 #define myprintf(f_, ...) {pc.printf("\r\n[MAIN] "); pc.printf((f_), ##__VA_ARGS__);} 00053 00054 /* Pin configuraiton */ 00055 // Cat.M1 00056 #define MBED_CONF_IOTSHIELD_CATM1_TX D8 00057 #define MBED_CONF_IOTSHIELD_CATM1_RX D2 00058 #define MBED_CONF_IOTSHIELD_CATM1_RESET D7 00059 #define MBED_CONF_IOTSHIELD_CATM1_PWRKEY D9 00060 00061 // Sensors 00062 #define MBED_CONF_IOTSHIELD_SENSOR_CDS A0 00063 #define MBED_CONF_IOTSHIELD_SENSOR_TEMP A1 00064 00065 /* Debug message settings */ 00066 #define BG96_PARSER_DEBUG DEBUG_DISABLE 00067 #define CATM1_DEVICE_DEBUG DEBUG_ENABLE 00068 00069 00070 // Functions: Module Status 00071 void waitCatM1Ready(void); 00072 int8_t setEchoStatus_BG96(bool onoff); 00073 int8_t getUsimStatus_BG96(void); 00074 int8_t getNetworkStatus_BG96(void); 00075 int8_t checknSetApn_BG96(const char * apn); 00076 int8_t getFirmwareVersion_BG96(char * version); 00077 00078 // Functions: PSM (Power Saving Mode) 00079 int8_t setPsmActivate_BG96(char * Requested_Periodic_TAU, char * Requested_Active_Time); 00080 int8_t setPsmDeactivate_BG96(void); 00081 int8_t getPsmSetting_BG96(bool * enable, int * Requested_Periodic_TAU, int * Requested_Active_Time); 00082 00083 // Functions: Network time 00084 int8_t getNetworkTimeGMT_BG96(char * timestr); 00085 int8_t getNetworkTimeLocal_BG96(char * timestr); 00086 void setFlagGettime(void); 00087 void clearFlagGettime(void); 00088 00089 00090 Serial pc(USBTX, USBRX); // USB debug 00091 00092 UARTSerial *_serial; // Cat.M1 module 00093 ATCmdParser *_parser; 00094 00095 DigitalOut _RESET_BG96(MBED_CONF_IOTSHIELD_CATM1_RESET); 00096 DigitalOut _PWRKEY_BG96(MBED_CONF_IOTSHIELD_CATM1_PWRKEY); 00097 00098 Ticker flip; 00099 bool flag_gettime = false; 00100 00101 void serialPcInit(void) 00102 { 00103 pc.baud(115200); 00104 pc.format(8, Serial::None, 1); 00105 } 00106 00107 void serialDeviceInit(PinName tx, PinName rx, int baudrate) 00108 { 00109 _serial = new UARTSerial(tx, rx, baudrate); 00110 } 00111 00112 void serialAtParserInit(const char *delimiter, bool debug_en) 00113 { 00114 _parser = new ATCmdParser(_serial); 00115 _parser->debug_on(debug_en); 00116 _parser->set_delimiter(delimiter); 00117 _parser->set_timeout(BG96_DEFAULT_TIMEOUT); 00118 } 00119 00120 void catm1DeviceInit(void) 00121 { 00122 serialDeviceInit( MBED_CONF_IOTSHIELD_CATM1_TX, 00123 MBED_CONF_IOTSHIELD_CATM1_RX, 00124 BG96_DEFAULT_BAUD_RATE); 00125 00126 serialAtParserInit( BG96_PARSER_DELIMITER, 00127 BG96_PARSER_DEBUG); 00128 } 00129 00130 void catm1DeviceReset_BG96(void) 00131 { 00132 _RESET_BG96 = 1; 00133 _PWRKEY_BG96 = 1; 00134 wait_ms(300); 00135 00136 _RESET_BG96 = 0; 00137 _PWRKEY_BG96 = 0; 00138 wait_ms(400); 00139 00140 _RESET_BG96 = 1; 00141 wait_ms(1000); 00142 } 00143 00144 00145 // ---------------------------------------------------------------- 00146 // Main routine 00147 // ---------------------------------------------------------------- 00148 00149 int main() 00150 { 00151 serialPcInit(); 00152 catm1DeviceInit(); 00153 00154 myprintf("Waiting for Cat.M1 Module Ready...\r\n"); 00155 00156 catm1DeviceReset_BG96(); 00157 00158 waitCatM1Ready(); 00159 00160 wait_ms(5000); 00161 00162 myprintf("System Init Complete\r\n"); 00163 00164 myprintf("WIZnet IoT Shield for Arm MBED"); 00165 myprintf("LTE Cat.M1 Version"); 00166 myprintf("================================================="); 00167 myprintf(">> Target Board: WIoT-QC01 (Quectel BG96)"); 00168 myprintf(">> Sample Code: PSM (Power Saving Mode)"); 00169 myprintf("=================================================\r\n"); 00170 00171 setEchoStatus_BG96(OFF); 00172 00173 getUsimStatus_BG96(); 00174 00175 getNetworkStatus_BG96(); 00176 00177 checknSetApn_BG96(CATM1_APN_SKT); 00178 00179 Timer t; 00180 float elapsed_time_sec = 0; 00181 bool psm_en = false; 00182 int psm_tau = 0; 00183 int psm_active = 0; 00184 00185 // PSM enable 00186 #if 0 00187 setPsmDeactivate_BG96(); 00188 #endif 00189 if(getPsmSetting_BG96(&psm_en, &psm_tau, &psm_active) == RET_OK) { 00190 if(psm_en != true) { 00191 if(setPsmActivate_BG96("10100101", "00100100") == RET_OK) { 00192 myprintf("Cat.M1 PSM enable, Device reboot"); 00193 00194 // Cat.M1 reboot 00195 catm1DeviceReset_BG96(); 00196 waitCatM1Ready(); 00197 } else { 00198 myprintf("Cat.M1 PSM enable failed"); 00199 } 00200 } 00201 } 00202 00203 myprintf("Cat.M1 PSM Config: %s, TAU time: %dsec, Active time: %dsec", psm_en?"Enabled":"Disabled", psm_tau, psm_active); 00204 00205 // Timer event callback 00206 flip.attach(callback(&setFlagGettime), 1.0); 00207 00208 while(1) 00209 { 00210 if(flag_gettime) { 00211 char nettime[30] = {0, }; 00212 if(getNetworkTimeLocal_BG96(nettime) == RET_OK) { 00213 if(elapsed_time_sec > 0) { 00214 t.stop(); 00215 myprintf("Cat.M1 Active, Sleep time: %.2fsec", elapsed_time_sec); 00216 elapsed_time_sec = 0; 00217 } 00218 myprintf("%s", nettime); 00219 } else { 00220 if(elapsed_time_sec == 0) { 00221 t.start(); 00222 myprintf("%s", "Sleep Start"); 00223 } 00224 elapsed_time_sec = t.read(); 00225 myprintf("Cat.M1 PSM, %.2f", elapsed_time_sec); 00226 } 00227 clearFlagGettime(); 00228 } 00229 } 00230 00231 /* 00232 // Set HTTP request URL 00233 if(setHttpRequest_BG96(request_url, strlen(request_url)-1) != RET_OK) { 00234 myprintf("[HTTP] setHttpRequest failed\r\n"); 00235 while(1){;} 00236 } 00237 00238 int http_response_code = 0; 00239 int http_response_len = 0; 00240 00241 if(sendHttpRequest_BG96(20, &http_response_code, &http_response_len)) { 00242 if(http_response_code == HTTP_STATUS_CODE_OK) { 00243 myprintf("[HTTP] 200 OK, Response content length: %d\r\n", http_response_len); 00244 00245 char * http_buf; 00246 http_buf = (char*)calloc(http_response_len+2, sizeof(char)); // memory allocation 00247 00248 if(getHttpResponse_BG96(20, http_buf, http_response_len+2)) { 00249 dumpHttpRespones_BG96(http_buf); 00250 } 00251 00252 free(http_buf); // release 00253 00254 myprintf("[HTTP] getHttpResponse success\r\n"); 00255 } else { 00256 myprintf("[HTTP] sendHttpRequest failed - HTTP response code: %d\r\n", http_response_code); 00257 } 00258 } 00259 */ 00260 } 00261 00262 00263 // ---------------------------------------------------------------- 00264 // Functions: Cat.M1 Status 00265 // ---------------------------------------------------------------- 00266 00267 void waitCatM1Ready(void) 00268 { 00269 while(1) 00270 { 00271 if(_parser->recv("RDY")) 00272 { 00273 myprintf("BG96 ready\r\n"); 00274 return ; 00275 } 00276 else if(_parser->send("AT") && _parser->recv("OK")) 00277 { 00278 myprintf("BG96 already available\r\n"); 00279 return ; 00280 } 00281 } 00282 } 00283 00284 int8_t setEchoStatus_BG96(bool onoff) 00285 { 00286 int8_t ret = RET_NOK; 00287 char _buf[10]; 00288 00289 sprintf((char *)_buf, "ATE%d", onoff); 00290 00291 if(_parser->send(_buf) && _parser->recv("OK")) { 00292 devlog("Turn Echo %s success\r\n", onoff?"ON":"OFF"); 00293 ret = RET_OK; 00294 } else { 00295 devlog("Turn Echo %s failed\r\n", onoff?"ON":"OFF"); 00296 } 00297 return ret; 00298 } 00299 00300 int8_t getUsimStatus_BG96(void) 00301 { 00302 int8_t ret = RET_NOK; 00303 00304 _parser->send("AT+CPIN?"); 00305 if(_parser->recv("+CPIN: READY") && _parser->recv("OK")) { 00306 devlog("USIM Status: READY\r\n"); 00307 ret = RET_OK; 00308 } else { 00309 devlog("Retrieving USIM Status failed\r\n"); 00310 } 00311 return ret; 00312 } 00313 00314 int8_t getNetworkStatus_BG96(void) 00315 { 00316 int8_t ret = RET_NOK; 00317 00318 if(_parser->send("AT+QCDS") && _parser->recv("+QCDS: \"SRV\"") && _parser->recv("OK")) { 00319 devlog("Network Status: attached\r\n"); 00320 ret = RET_OK; 00321 } else if (_parser->send("AT+QCDS") && _parser->recv("+QCDS: \"LIMITED\"") && _parser->recv("OK")) { 00322 devlog("Network Status: limited\r\n"); 00323 ret = RET_OK; 00324 } else { 00325 devlog("Network Status: Error\r\n"); 00326 } 00327 return ret; 00328 } 00329 00330 int8_t checknSetApn_BG96(const char * apn) // Configure Parameters of a TCP/IP Context 00331 { 00332 char resp_str[100]; 00333 00334 uint16_t i = 0; 00335 char * search_pt; 00336 00337 memset(resp_str, 0, sizeof(resp_str)); 00338 00339 devlog("Checking APN...\r\n"); 00340 00341 _parser->send("AT+QICSGP=1"); 00342 00343 while(1) 00344 { 00345 _parser->read(&resp_str[i++], 1); 00346 search_pt = strstr(resp_str, "OK\r\n"); 00347 if (search_pt != 0) 00348 { 00349 break; 00350 } 00351 } 00352 00353 search_pt = strstr(resp_str, apn); 00354 if (search_pt == 0) 00355 { 00356 devlog("Mismatched APN: %s\r\n", resp_str); 00357 devlog("Storing APN %s...\r\n", apn); 00358 if(!(_parser->send("AT+QICSGP=1,%d,\"%s\",\"\",\"\",0", BG96_APN_PROTOCOL, apn) && _parser->recv("OK"))) 00359 { 00360 return RET_NOK; // failed 00361 } 00362 } 00363 devlog("APN Check Done\r\n"); 00364 00365 return RET_OK; 00366 } 00367 00368 int8_t getFirmwareVersion_BG96(char * version) 00369 { 00370 int8_t ret = RET_NOK; 00371 00372 if(_parser->send("AT+QGMR") && _parser->recv("%s\n", version) && _parser->recv("OK")) 00373 { 00374 ret = RET_OK; 00375 } 00376 return ret; 00377 } 00378 00379 int8_t getImeiNumber_BG96(char * imei) 00380 { 00381 int8_t ret = RET_NOK; 00382 00383 if(_parser->send("AT+CGSN") && _parser->recv("%s\n", imei) && _parser->recv("OK")) 00384 { 00385 ret = RET_OK; 00386 } 00387 return ret; 00388 } 00389 00390 // ---------------------------------------------------------------- 00391 // Functions: Cat.M1 PSM activate / deactivate 00392 // ---------------------------------------------------------------- 00393 00394 int8_t setPsmActivate_BG96(char *Requested_Periodic_TAU, char *Requested_Active_Time) 00395 { 00396 int8_t ret = RET_NOK; 00397 00398 if (_parser->send("AT+CPSMS=1,,,\"%s\",\"%s\"", Requested_Periodic_TAU, Requested_Active_Time) 00399 && _parser->recv("OK")) 00400 { 00401 devlog("PSM activate success\r\n"); 00402 ret = RET_OK; 00403 } 00404 return ret; 00405 } 00406 00407 int8_t setPsmDeactivate_BG96(void) 00408 { 00409 int8_t ret = RET_NOK; 00410 00411 if (_parser->send("AT+CPSMS=0") && _parser->recv("OK")) { 00412 devlog("PSM deactivate success\r\n"); 00413 } 00414 return ret; 00415 } 00416 00417 int8_t getPsmSetting_BG96(bool * enable, int * Requested_Periodic_TAU, int * Requested_Active_Time) 00418 { 00419 int8_t ret = RET_NOK; 00420 int en = 0; 00421 00422 if (_parser->send("AT+QPSMS?") // BG96 only 00423 && _parser->recv("+QPSMS: %d,,,\"%d\",\"%d\"", &en, Requested_Periodic_TAU, Requested_Active_Time) 00424 && _parser->recv("OK")) 00425 { 00426 if(en != 0) 00427 *enable = true; 00428 else 00429 *enable = false; 00430 00431 devlog("Get PSM setting success\r\n"); 00432 ret = RET_OK; 00433 } 00434 return ret; 00435 } 00436 00437 00438 // ---------------------------------------------------------------- 00439 // Functions: Cat.M1 Network time 00440 // ---------------------------------------------------------------- 00441 00442 int8_t getNetworkTimeGMT_BG96(char * timestr) 00443 { 00444 int8_t ret = RET_NOK; 00445 if (_parser->send("AT+QLTS=1") 00446 && _parser->recv("+QLTS: \"%[^\"]\"", timestr) 00447 && _parser->recv("OK")) 00448 { 00449 //devlog("Get current GMT time success\r\n"); 00450 ret = RET_OK; 00451 } 00452 return ret; 00453 } 00454 00455 int8_t getNetworkTimeLocal_BG96(char * timestr) 00456 { 00457 int8_t ret = RET_NOK; 00458 if (_parser->send("AT+QLTS=2") 00459 && _parser->recv("+QLTS: \"%[^\"]\"", timestr) 00460 && _parser->recv("OK")) 00461 { 00462 //devlog("Get current local time success\r\n"); 00463 ret = RET_OK; 00464 } 00465 return ret; 00466 } 00467 00468 void setFlagGettime(void) 00469 { 00470 flag_gettime = true; 00471 } 00472 00473 void clearFlagGettime(void) 00474 { 00475 flag_gettime = false; 00476 } 00477 00478 // ---------------------------------------------------------------- 00479 // Functions: Cat.M1 HTTP send & recv 00480 // ---------------------------------------------------------------- 00481 /* 00482 int8_t setHttpRequest_BG96(char * req, int len) 00483 { 00484 int8_t ret = RET_NOK; 00485 bool done = false; 00486 00487 _parser->set_timeout(BG96_CONNECT_TIMEOUT); 00488 00489 _parser->send("AT+QHTTPURL=%d,%d", len, 5); 00490 if( !done && _parser->recv("CONNECT\r\n") ) 00491 done = (_parser->write(req, len) <= 0); 00492 00493 if( !done ) { 00494 done = (_parser->recv("OK")); 00495 if(done) { 00496 devlog("Set HTTP request URL success: %s\r\n", req); 00497 ret = RET_OK; 00498 } 00499 } 00500 _parser->set_timeout(BG96_DEFAULT_TIMEOUT); 00501 00502 return ret; 00503 } 00504 00505 00506 00507 int8_t sendHttpRequest_BG96(int timeout, int * rsp_code, int * content_len) 00508 { 00509 int8_t ret = RET_NOK; 00510 int err; 00511 00512 _parser->set_timeout(BG96_DEFAULT_TIMEOUT + (timeout * 1000)); 00513 00514 if( _parser->send("AT+QHTTPGET=%d", timeout) 00515 && _parser->recv("+QHTTPGET: %d,%d,%d\r\n", &err, rsp_code, content_len) 00516 && (err == 0)) 00517 { 00518 devlog("The HTTP request is sent and the response is successful\r\n"); 00519 ret = RET_OK; 00520 } 00521 _parser->set_timeout(BG96_DEFAULT_TIMEOUT); 00522 00523 return ret; 00524 } 00525 00526 00527 int8_t getHttpResponse_BG96(int timeout, char * buf, int len) 00528 { 00529 int8_t ret = RET_NOK; 00530 bool done = false; 00531 00532 if( _parser->send("AT+QHTTPREAD=%d", timeout) && _parser->recv("CONNECT\r\n")) { 00533 done = _parser->read(buf, len); 00534 } 00535 00536 if(done) { 00537 if( _parser->recv("OK") && _parser->recv("+QHTTPREAD: 0")) { 00538 ret = RET_OK; 00539 } 00540 } 00541 return ret; 00542 } 00543 00544 void dumpHttpRespones_BG96(char * buf) 00545 { 00546 myprintf("%s", buf); 00547 } 00548 */
Generated on Mon Jul 25 2022 19:36:44 by 1.7.2