Rick McConney
/
AvnetATT_shape_hackathon
This program simply connects to a HTS221 I2C device to proximity sensor
Embed:
(wiki syntax)
Show/hide line numbers
Wnc.cpp
00001 #include "Wnc.h" 00002 #include "mbed.h" 00003 #include <cctype> 00004 #include <string> 00005 #include "config_me.h" 00006 #include "SerialBuffered.h" 00007 00008 00009 extern Serial pc; 00010 00011 DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot 00012 DigitalOut mdm_power_on(PTB9); // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem) 00013 DigitalInOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield 00014 00015 DigitalOut mdm_reset(PTC12); // active high 00016 00017 DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active 00018 DigitalOut mdm_uart1_cts(PTD0); 00019 00020 SerialBuffered mdm(PTD3, PTD2, 512); 00021 00022 bool powerSave = false; 00023 bool firstWake = false; 00024 00025 Wnc::Wnc(void) 00026 { 00027 } 00028 00029 void Wnc::checkPassthrough() 00030 { 00031 if(pc.readable()) 00032 { 00033 if(pc.getc() == '~') 00034 passthrough(); 00035 } 00036 } 00037 00038 00039 void Wnc::passthrough() 00040 { 00041 pc.printf(">>\r\n"); 00042 while(1) 00043 { 00044 char c; 00045 if(pc.readable()) 00046 { 00047 c = pc.getc(); 00048 pc.putc(c); 00049 if(c == '~') 00050 { 00051 pc.printf("exit\r\n"); 00052 break; 00053 } 00054 else if(c == '<') 00055 { 00056 00057 mdm_wakeup_in = 0; 00058 pc.printf("sleep\r\n"); 00059 } 00060 else if(c == '>') 00061 { 00062 mdm_wakeup_in = 1; 00063 pc.printf("wake\r\n"); 00064 } 00065 else if(c == '}') 00066 { 00067 mdm_uart2_rx_boot_mode_sel = 1; 00068 pc.printf("rx hi\r\n"); 00069 } 00070 else if(c == '{') 00071 { 00072 mdm_uart2_rx_boot_mode_sel = 0; 00073 pc.printf("rx low\r\n"); 00074 } 00075 00076 else if(c == '^') 00077 { 00078 pc.printf("reboot\r\n"); 00079 NVIC_SystemReset(); 00080 } 00081 else 00082 { 00083 00084 mdm.putc(c); 00085 } 00086 } 00087 if(mdm.readable()) 00088 pc.putc(mdm.getc()); 00089 } 00090 } 00091 00092 bool Wnc::isPowerSaveOn() 00093 { 00094 return powerSave; 00095 } 00096 00097 void Wnc::resumePowerSave() 00098 { 00099 mdm_wakeup_in = 0; 00100 } 00101 00102 char* Wnc::read(int timeout_ms) 00103 { 00104 static char response[3200]; 00105 int len = 0; 00106 00107 if(timeout_ms > 0) // read until timeout or OK 00108 { 00109 Timer timer; 00110 timer.start(); 00111 while ((len < (3200-1)) && (timer.read_ms() < timeout_ms)) { 00112 if (mdm.readable()) { 00113 response[len++] = mdm.getc(); 00114 if(len>1 && response[len-2] == 'O' && response[len-1] == 'K') 00115 break; 00116 } 00117 } 00118 } 00119 00120 response[len] = (char)NULL; 00121 pc.printf("{%s}\r\n",response); 00122 return response; 00123 } 00124 00125 char* Wnc::send(const char *cmd, int timeout_ms) 00126 { 00127 char* reply; 00128 00129 while (mdm.readable()) { 00130 mdm.getc(); 00131 } 00132 00133 int tries = 4; 00134 while(tries > 0) 00135 { 00136 tries--; 00137 pc.printf("\r\n<%s>",cmd); 00138 const char *pt = cmd; 00139 size_t n = strlen(cmd); 00140 while (n--) { 00141 mdm.putc(*pt++); 00142 }; 00143 mdm.putc('\r'); 00144 mdm.putc('\n'); 00145 reply = read(timeout_ms); 00146 if(strlen(reply) > 0 && strstr(reply,"OK") !=0) 00147 break; 00148 checkPassthrough(); 00149 } 00150 return reply; 00151 } 00152 00153 bool Wnc::isModemResponding() 00154 { 00155 char *reply = send("AT",WNC_WAIT_TIME_MS); 00156 if(strlen(reply) > 0 && strstr(reply,"OK") !=0) 00157 return true; 00158 return false; 00159 } 00160 00161 void Wnc::setIn() 00162 { 00163 mdm_wakeup_in.input(); 00164 } 00165 00166 void Wnc::toggleWake() 00167 { 00168 mdm_wakeup_in = 0; 00169 wait_ms(2000); 00170 mdm_wakeup_in = 0; 00171 } 00172 00173 int Wnc::init(void) { 00174 mdm_wakeup_in.output(); 00175 // disable signal level translator (necessary 00176 // for the modem to boot properly) 00177 shield_3v3_1v8_sig_trans_ena = 0; 00178 00179 // Hard reset the modem (doesn't go through 00180 // the signal level translator) 00181 mdm_reset = 1; 00182 00183 // wait a moment for the modem to react 00184 wait_ms(10); 00185 00186 // Let modem boot 00187 mdm_reset = 0; 00188 00189 // wait a moment for the modem to react 00190 wait(1.0); 00191 00192 // power modem on //off 00193 mdm_power_on = 0; //1; 00194 00195 // insure modem boots into normal operating mode 00196 // and does not go to sleep when powered on 00197 mdm_uart2_rx_boot_mode_sel = 1; 00198 mdm_wakeup_in = 1; 00199 00200 // initialze comm with the modem 00201 mdm.baud(115200); 00202 // clear out potential garbage 00203 while (mdm.readable()) 00204 mdm.getc(); 00205 00206 mdm_uart1_cts = 0; 00207 00208 // wait a moment for the modem to react to signal 00209 // conditions while the level translator is disabled 00210 // (sorry, don't have enough information to know 00211 // what exactly the modem is doing with the current 00212 // pin settings) 00213 wait(1.0); 00214 00215 // enable the signal level translator to start 00216 // modem reset process (modem will be powered down) 00217 shield_3v3_1v8_sig_trans_ena = 1; 00218 00219 // Give the modem 60 secons to start responding by 00220 // sending simple 'AT' commands to modem once per second. 00221 Timer timer; 00222 timer.start(); 00223 while (timer.read() < 60) { 00224 SetLedColor(0x1); //red 00225 if(isModemResponding()) 00226 { 00227 SetLedColor(0); 00228 return true; 00229 } 00230 SetLedColor(0); //off 00231 wait_ms(1000 - (timer.read_ms() % 1000)); 00232 pc.printf("\r%d",timer.read_ms()/1000); 00233 00234 } 00235 return false; 00236 } 00237 int Wnc::secToTau(int time) 00238 { 00239 /* 00240 0 - value is incremented in multiples of 10 minutes 00241 1 - value is incremented in multiples of 1 hour 00242 2 - value is incremented in multiples of 10 hours 00243 3 - value is incremented in multiples of 2 seconds 00244 4 - value is incremented in multiples of 30 seconds 00245 5 - value is incremented in multiples of 1 minute 00246 */ 00247 if(time/2 < 32) 00248 { 00249 return (0x3<<5)+time/2; 00250 } 00251 else if(time/30 < 32) 00252 { 00253 return (0x4<<5)+time/30; 00254 } 00255 else if(time/60 < 32) 00256 { 00257 return (0x5<<5)+time/60; 00258 } 00259 else if(time/3600 < 32) 00260 { 00261 return (0x1<<5)+time/3600; 00262 } 00263 else if(time/36000 < 32) 00264 { 00265 return (0x2<<5)+time/36000; 00266 } 00267 else 00268 return (0x7<<5); 00269 00270 00271 } 00272 int Wnc::secToActivity(int time) 00273 { 00274 /* 00275 0 - value is incremented in multiples of 2 seconds 00276 1 - value is incremented in multiples of 1 minute 00277 2 - value is incremented in multiples of decihours 00278 7 - value indicates that the timer is deactivated. 00279 */ 00280 if(time/2 < 32) 00281 { 00282 return (0x0<<5)+time/2; 00283 } 00284 else if(time/60 < 32) 00285 { 00286 return (0x1<<5)+time/60; 00287 } 00288 else if(time/36000 < 32) 00289 { 00290 return (0x2<<5)+time/36000; 00291 } 00292 else 00293 return (0x7<<5); 00294 00295 } 00296 void Wnc::setPowerSave(bool on,int t3412,int t3324) 00297 { 00298 if(on) 00299 { 00300 int tau = secToTau(t3412); 00301 int activity = secToActivity(t3324); 00302 mdm_wakeup_in = 0; //allow power sleep mode 00303 powerSave = true; 00304 char cmd[32]; 00305 sprintf(cmd,"AT+CPSMS=1,,,%d,%d",tau,activity); 00306 send(cmd, WNC_WAIT_TIME_MS); 00307 } 00308 else 00309 { 00310 mdm_wakeup_in = 1; //disallow power sleep mode 00311 powerSave = false; 00312 send("AT+CPSMS=0", WNC_WAIT_TIME_MS); 00313 } 00314 } 00315 00316 char* Wnc::getIccid() 00317 { 00318 static char iccidBuf[32]; 00319 iccidBuf[0] = NULL; 00320 char* reply = send("AT%CCID",500); 00321 int index = 0; 00322 int begin = -1; 00323 int i = 0; 00324 00325 while (reply[index]) { // While there are more characters to process... 00326 if (begin == -1 && isdigit(reply[index])) { // Upon finding a digit, ... 00327 begin = index; 00328 } 00329 if(begin != -1) 00330 { 00331 if(isdigit(reply[index])) 00332 { 00333 iccidBuf[i++] = reply[index]; 00334 } 00335 else 00336 { 00337 iccidBuf[i++] = NULL; 00338 return iccidBuf; 00339 } 00340 } 00341 index++; 00342 } 00343 return iccidBuf; 00344 } 00345 00346 void Wnc::wakeFromPowerSave() 00347 { 00348 char *reply; 00349 mdm_wakeup_in = 1; 00350 pc.printf("wake from power save\r\n"); 00351 firstWake = true; 00352 // reply = send("AT+CFUN=1", WNC_WAIT_TIME_MS); 00353 // reply = send("AT%CMATT=1", WNC_WAIT_TIME_MS); 00354 // wait(5); // wait to attach 00355 // reply = send("AT+CREG?", WNC_WAIT_TIME_MS); 00356 // reply = send("AT@INTERNET=1", WNC_WAIT_TIME_MS); // Internet services enabled 00357 // reply = send("AT@SOCKDIAL=1", WNC_WAIT_TIME_MS); 00358 00359 00360 } 00361 00362 void Wnc::startInternet() 00363 { 00364 char *reply; 00365 reply = send("ATE1",WNC_WAIT_TIME_MS); // Echo ON 00366 char apn [32]; 00367 sprintf(apn,"AT%%PDNSET=1,%s,IP",MY_APN_STR); 00368 00369 reply = send(apn, 2*WNC_WAIT_TIME_MS); // Set APN, cmd seems to take a little longer sometimes 00370 reply = send("AT+CREG?", WNC_WAIT_TIME_MS); 00371 reply = send("AT@INTERNET=1", WNC_WAIT_TIME_MS); // Internet services enabled 00372 reply = send("AT@SOCKDIAL=1", WNC_WAIT_TIME_MS); 00373 } 00374 00375 char* Wnc::ping(char* ip) 00376 { 00377 char cmd[32]; 00378 sprintf(cmd,"AT@PINGREQ=\"%s\"",ip); 00379 return send(cmd,WNC_WAIT_TIME_MS); 00380 } 00381 // AT@SOCKCONN=1,"108.244.165.22",5005 00382 bool Wnc::connect(char* ip, int port) 00383 { 00384 char *reply; 00385 00386 if(isModemResponding()) 00387 { 00388 reply = send("AT@SOCKCREAT=1", WNC_WAIT_TIME_MS); 00389 if(strlen(reply) == 0 || strstr(reply,"OK") ==0) 00390 return false; 00391 } 00392 00393 00394 char cmd[32]; 00395 if(isModemResponding()) 00396 { 00397 sprintf(cmd,"AT@SOCKCONN=1,\"%s\",%d",ip,port); 00398 reply = send(cmd,WNC_WAIT_TIME_MS); 00399 if(firstWake) 00400 { 00401 for(int i = 0;i<10;i++) 00402 { 00403 pc.printf("%d",i); 00404 send("AT", WNC_WAIT_TIME_MS); 00405 reply = send("AT+CREG?",WNC_WAIT_TIME_MS); 00406 if(strlen(reply) > 0 && strstr(reply,"2,1") != 0) 00407 { 00408 pc.printf("connected %s",reply); 00409 break; 00410 } 00411 else 00412 { 00413 pc.printf("Unconnected %s",reply); 00414 } 00415 wait(1); 00416 } 00417 } 00418 firstWake = false; 00419 reply = send(cmd,WNC_WAIT_TIME_MS); 00420 00421 if(strlen(reply) == 0 || strstr(reply,"OK") ==0) 00422 return false; 00423 } 00424 return true; 00425 } 00426 00427 void Wnc::disconnect() 00428 { 00429 send("AT@SOCKCLOSE=1", WNC_WAIT_TIME_MS); 00430 } 00431 00432 char* Wnc::encode(int value, char* result, int base) 00433 { 00434 // check that the base if valid 00435 if ( base < 2 || base > 36 ) { 00436 *result = '\0'; 00437 return result; 00438 } 00439 00440 char* ptr = result, *ptr1 = result, tmp_char; 00441 int tmp_value; 00442 00443 do { 00444 tmp_value = value; 00445 value /= base; 00446 *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; 00447 } while ( value ); 00448 00449 // Apply negative sign 00450 if ( tmp_value < 0 ) 00451 *ptr++ = '-'; 00452 *ptr-- = '\0'; 00453 00454 while ( ptr1 < ptr ) { 00455 tmp_char = *ptr; 00456 *ptr-- = *ptr1; 00457 *ptr1++ = tmp_char; 00458 } 00459 return result; 00460 } 00461 00462 char* Wnc::writeSocket(const char * s) 00463 { 00464 00465 char *reply; 00466 char num2str[6]; 00467 size_t sLen = strlen(s); 00468 if (sLen <= 99999) 00469 { 00470 00471 string cmd_str("AT@SOCKWRITE=1,"); 00472 encode(sLen, num2str, 10); 00473 cmd_str += num2str; 00474 cmd_str += ",\""; 00475 while(*s != '\0') 00476 { 00477 encode((int)*s++, num2str, 16); 00478 // Always 2-digit ascii hex: 00479 if (strlen(num2str) == 1) 00480 { 00481 num2str[2] = '\0'; 00482 num2str[1] = num2str[0]; 00483 num2str[0] = '0'; 00484 } 00485 cmd_str += num2str; 00486 } 00487 cmd_str += "\""; 00488 reply = send(cmd_str.c_str(), WNC_WAIT_TIME_MS); 00489 } 00490 else 00491 pc.puts("sockwrite Err, string to long\r\n"); 00492 return NULL; 00493 } 00494 00495 int Wnc::hex_to_int(char c){ 00496 if(c >=97) 00497 c=c-32; 00498 int first = c / 16 - 3; 00499 int second = c % 16; 00500 int result = first*10 + second; 00501 if(result > 9) result--; 00502 return result; 00503 } 00504 00505 int Wnc::hex_to_ascii(char h, char l){ 00506 int high = hex_to_int(h) * 16; 00507 int low = hex_to_int(l); 00508 return high+low; 00509 } 00510 00511 int Wnc::indexOf(char* str, char c) 00512 { 00513 int index = 0; 00514 while(str[index] != 0) 00515 { 00516 if(str[index] == c) 00517 return index; 00518 index++; 00519 } 00520 return -1; 00521 } 00522 00523 char* Wnc::readSocket() 00524 { 00525 00526 static char data[1000]; 00527 int i = 0; 00528 char *reply; 00529 reply = send("AT@SOCKREAD=1,1024",1000); 00530 if(strlen(reply) > 0) 00531 { 00532 int pos_start = indexOf(reply,'"'); 00533 00534 if(pos_start > 0) 00535 { 00536 pos_start+=1; 00537 int length = indexOf(&reply[pos_start],'"'); 00538 00539 if(length > 0) 00540 { 00541 char hi; 00542 char low; 00543 for(i = 0; i < length; i++){ 00544 if(i % 2 != 0){ 00545 low = reply[pos_start++]; 00546 data[i/2] = (char) hex_to_ascii(hi,low); 00547 }else{ 00548 hi = reply[pos_start++]; 00549 } 00550 } 00551 } 00552 } 00553 } 00554 data[i] = NULL; 00555 return data; 00556 }
Generated on Tue Jul 12 2022 19:39:23 by 1.7.2