Rick McConney
/
stripReader
Proximity strip reader
Fork of StarterKit by
Wnc.cpp
- Committer:
- elmkom
- Date:
- 2016-11-30
- Revision:
- 45:fe90f1fcb4e0
- Parent:
- 44:60008ebffdd4
File content as of revision 45:fe90f1fcb4e0:
#include "Wnc.h" #include "mbed.h" #include <cctype> #include "config_me.h" #include "SerialBuffered.h" extern Serial pc; DigitalOut mdm_uart2_rx_boot_mode_sel(PTC17); // on powerup, 0 = boot mode, 1 = normal boot DigitalOut mdm_power_on(PTB9); // 0 = turn modem on, 1 = turn modem off (should be held high for >5 seconds to cycle modem) DigitalInOut mdm_wakeup_in(PTC2); // 0 = let modem sleep, 1 = keep modem awake -- Note: pulled high on shield DigitalOut mdm_reset(PTC12); // active high DigitalOut shield_3v3_1v8_sig_trans_ena(PTC4); // 0 = disabled (all signals high impedence, 1 = translation active DigitalOut mdm_uart1_cts(PTD0); DigitalOut uart1Rts(PTD1); SerialBuffered mdm(PTD3, PTD2, 512); int t3412Timer = 4*60*60; int t3324Timer = 20; bool powerSave = false; Wnc::Wnc(void) { } void Wnc::checkPassthrough() { if(pc.readable()) { if(pc.getc() == '~') passthrough(); } } void Wnc::passthrough() { pc.printf(">>\r\n"); while(1) { char c; if(pc.readable()) { c = pc.getc(); pc.putc(c); if(c == '~') { pc.printf("exit\r\n"); break; } else if(c == '<') { mdm_wakeup_in = 0; pc.printf("sleep\r\n"); } else if(c == '>') { mdm_wakeup_in = 1; pc.printf("wake\r\n"); } else if(c == '}') { mdm_uart2_rx_boot_mode_sel = 1; pc.printf("rx hi\r\n"); } else if(c == '{') { mdm_uart2_rx_boot_mode_sel = 0; pc.printf("rx low\r\n"); } else if(c == '^') { pc.printf("reboot\r\n"); NVIC_SystemReset(); } else { mdm.putc(c); } } if(mdm.readable()) pc.putc(mdm.getc()); } } bool Wnc::isPowerSaveOn() { return powerSave; } void Wnc::resumePowerSave() { mdm_wakeup_in = 0; } int Wnc::gett3412Timer() { return t3412Timer; } int Wnc::gett3324Timer() { return t3324Timer; } char* Wnc::read(int timeout_ms) { static char response[3200]; int len = 0; char c; if(timeout_ms > 0) // read until timeout or OK { Timer timer; timer.start(); while ((len < (3200-1)) && (timer.read_ms() < timeout_ms)) { if (mdm.readable()) { c = mdm.getc(); // replace \r\n to make debug messages more compact if(c == '\r') c = ' '; if(c == '\n') c = ' '; response[len++] = c; if(len>1 && response[len-2] == 'O' && response[len-1] == 'K') break; } } } response[len] = (char)NULL; pc.printf("{%d %s}\r\n",len,response); return response; } char* Wnc::send(const char *cmd, int timeout_ms) { char *reply; while (mdm.readable()) { mdm.getc(); } int tries = 4; while(tries > 0) { tries--; pc.printf("\r\n<%s>",cmd); const char *pt = cmd; size_t n = strlen(cmd); while (n--) { mdm.putc(*pt++); }; mdm.putc('\r'); mdm.putc('\n'); reply = read(timeout_ms); if(strlen(reply) > 0 && strstr(reply,"OK") !=0) break; checkPassthrough(); } return reply; } bool Wnc::isModemResponding() { char *reply = send("AT",WNC_WAIT_TIME_MS); if(strlen(reply) > 0 && strstr(reply,"OK") !=0) return true; return false; } void Wnc::setIn() { mdm_wakeup_in.input(); } void Wnc::toggleWake() { mdm_wakeup_in = 0; wait_ms(2000); mdm_wakeup_in = 0; } bool Wnc::init(void) { uart1Rts = 0; mdm_wakeup_in.output(); // disable signal level translator (necessary // for the modem to boot properly) shield_3v3_1v8_sig_trans_ena = 0; // Hard reset the modem (doesn't go through // the signal level translator) mdm_reset = 1; // wait a moment for the modem to react wait_ms(10); // Let modem boot mdm_reset = 0; // wait a moment for the modem to react wait(1.0); // power modem on //off mdm_power_on = 0; //1; // insure modem boots into normal operating mode // and does not go to sleep when powered on mdm_uart2_rx_boot_mode_sel = 1; mdm_wakeup_in = 1; // initialze comm with the modem mdm.baud(115200); // clear out potential garbage while (mdm.readable()) mdm.getc(); mdm_uart1_cts = 0; // wait a moment for the modem to react to signal // conditions while the level translator is disabled // (sorry, don't have enough information to know // what exactly the modem is doing with the current // pin settings) wait(1.0); // enable the signal level translator to start // modem reset process (modem will be powered down) shield_3v3_1v8_sig_trans_ena = 1; // Give the modem 60 secons to start responding by // sending simple 'AT' commands to modem once per second. Timer timer; timer.start(); while (timer.read() < 60) { SetLedColor(0x1); //red if(isModemResponding()) { SetLedColor(0); //mdm_uart2_rx_boot_mode_sel = 0; return true; } SetLedColor(0); //off wait_ms(1000 - (timer.read_ms() % 1000)); pc.printf("\r%d",timer.read_ms()/1000); } return false; } int Wnc::secToTau(int time) { /* 0 - value is incremented in multiples of 10 minutes 1 - value is incremented in multiples of 1 hour 2 - value is incremented in multiples of 10 hours 3 - value is incremented in multiples of 2 seconds 4 - value is incremented in multiples of 30 seconds 5 - value is incremented in multiples of 1 minute */ if(time/2 < 32) { return (0x3<<5)+time/2; } else if(time/30 < 32) { return (0x4<<5)+time/30; } else if(time/60 < 32) { return (0x5<<5)+time/60; } else if(time/3600 < 32) { return (0x1<<5)+time/3600; } else if(time/36000 < 32) { return (0x2<<5)+time/36000; } else return (0x7<<5); } int Wnc::secToActivity(int time) { /* 0 - value is incremented in multiples of 2 seconds 1 - value is incremented in multiples of 1 minute 2 - value is incremented in multiples of decihours 7 - value indicates that the timer is deactivated. */ if(time/2 < 32) { return (0x0<<5)+time/2; } else if(time/60 < 32) { return (0x1<<5)+time/60; } else if(time/36000 < 32) { return (0x2<<5)+time/36000; } else return (0x7<<5); } void Wnc::setPowerSave(bool on,int t3412,int t3324) { if(on) { t3412Timer = t3412; t3324Timer = t3324; int tau = secToTau(t3412); int activity = secToActivity(t3324); mdm_wakeup_in = 0; //allow power sleep mode powerSave = true; char cmd[32]; snprintf(cmd,sizeof(cmd),"AT+CPSMS=1,,,%d,%d",tau,activity); send(cmd, WNC_WAIT_TIME_MS); } else { mdm_wakeup_in = 1; //disallow power sleep mode powerSave = false; send("AT+CPSMS=0", WNC_WAIT_TIME_MS); } } char* Wnc::getIccid() { static char iccidBuf[32]; iccidBuf[0] = NULL; char* reply = send("AT%CCID",500); int index = 0; int begin = -1; int i = 0; while (reply[index]) { // While there are more characters to process... if (begin == -1 && isdigit(reply[index])) { // Upon finding a digit, ... begin = index; } if(begin != -1) { if(isdigit(reply[index])) { iccidBuf[i++] = reply[index]; } else { iccidBuf[i++] = NULL; return iccidBuf; } } index++; } return iccidBuf; } void Wnc::wakeFromPowerSave() { mdm_wakeup_in = 1; pc.printf("wake from power save\r\n"); } bool Wnc::cmdFailed(char* reply,char* msg) { if(strstr(reply,"OK") > 0) return false; pc.printf("%s\r\n",msg); return true; } bool Wnc::startInternet() { char *reply; reply = send("ATE1",WNC_WAIT_TIME_MS); // Echo ON char apn [32]; snprintf(apn,sizeof(apn),"AT%%PDNSET=1,%s,IP",MY_APN_STR); reply = send(apn, 2*WNC_WAIT_TIME_MS); // Set APN, cmd seems to take a little longer sometimes if(cmdFailed(reply,"Failed to set APN")) return false; reply = send("AT%PDNSET?", WNC_WAIT_TIME_MS); // pc.printf("Wiating ...\r\n"); // wait(10); reply = send("AT@INTERNET=1", WNC_WAIT_TIME_MS); // Internet services enabled if(cmdFailed(reply,"Failed to start INTERNET")) { return false; } reply = send("AT@SOCKDIAL=1", WNC_WAIT_TIME_MS); if(cmdFailed(reply,"SOCKDIAL Failed")) { // passthrough(); return false; } return true; } char* Wnc::ping(char* ip) { char cmd[32]; snprintf(cmd,sizeof(cmd),"AT@PINGREQ=\"%s\"",ip); return send(cmd,WNC_WAIT_TIME_MS); } bool Wnc::connect(char* ip, int port) { char *reply; for(int i = 0;i<2;i++) { if(isModemResponding()) break; wait(0.5); } if(isModemResponding()) { reply = send("AT@SOCKCREAT=1", WNC_WAIT_TIME_MS); if(cmdFailed(reply,"Socket Create Failed")) return false; } else { pc.printf("Error Modem not responding\r\n"); return false; } char cmd[64]; snprintf(cmd,sizeof(cmd),"AT@SOCKCONN=1,\"%s\",%d",ip,port); reply = send(cmd,12*WNC_WAIT_TIME_MS); if(cmdFailed(reply,"Socket Connect Failed")) return false; for(int i = 0;i<10;i++) { reply = send("AT+CREG?",WNC_WAIT_TIME_MS); if(strlen(reply) > 0 && strstr(reply,"2,1") != 0) { pc.printf("Connected %s\r\n",reply); return true; } else { pc.printf("Unconnected %s\r\n",reply); } wait(1); } return false; } void Wnc::disconnect() { send("AT@SOCKCLOSE=1", WNC_WAIT_TIME_MS); } char* Wnc::encode(int value, char* result, int base) { // check that the base if valid if ( base < 2 || base > 36 ) { *result = '\0'; return result; } char* ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= base; *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)]; } while ( value ); // Apply negative sign if ( tmp_value < 0 ) *ptr++ = '-'; *ptr-- = '\0'; while ( ptr1 < ptr ) { tmp_char = *ptr; *ptr-- = *ptr1; *ptr1++ = tmp_char; } return result; } bool Wnc::writeSocket(const char * s) { char num2str[6]; size_t sLen = strlen(s); if (sLen <= 99999) { char cmd[sLen*2+32]; int index = snprintf(cmd,sizeof(cmd),"AT@SOCKWRITE=1,%d,\"",sLen); while(*s != '\0') { encode((int)*s++, num2str, 16); // Always 2-digit ascii hex: if (strlen(num2str) == 1) { num2str[2] = '\0'; num2str[1] = num2str[0]; num2str[0] = '0'; } cmd[index++] = num2str[0]; cmd[index++] = num2str[1]; } cmd[index++] = '"'; cmd[index] = '\0'; char* reply = send(cmd, WNC_WAIT_TIME_MS); if(cmdFailed(reply,"Send Failed")) return false; return true; } else { pc.puts("sockwrite Err, string to long\r\n"); return false; } } int Wnc::hex_to_int(char A) { return (A > '9')? (A &~ 0x20) - 'A' + 10: (A - '0'); } int Wnc::hex_to_ascii(char h, char l) { return hex_to_int(h) * 16 + hex_to_int(l); } int Wnc::indexOf(char* str, char c) { int index = 0; while(str[index] != 0) { if(str[index] == c) return index; index++; } return -1; } char* Wnc::readSocket() { static char data[1000]; int i = 0; char *reply; reply = send("AT@SOCKREAD=1,1024",1000); if(strlen(reply) > 0) { int pos_start = indexOf(reply,'"'); if(pos_start > 0) { pos_start+=1; int length = indexOf(&reply[pos_start],'"'); if(length > 0) { char hi; char low; for(i = 0; i < length; i++){ if(i % 2 != 0){ low = reply[pos_start++]; data[i/2] = (char) hex_to_ascii(hi,low); }else{ hi = reply[pos_start++]; } } data[length/2] = NULL; } } } data[i] = NULL; return data; } char* Wnc::resolveDn(const char* name) { char cmd[64]; snprintf(cmd,sizeof(cmd),"AT@DNSRESVDON=\"%s\"",name); char* reply = send(cmd,12*WNC_WAIT_TIME_MS); static char ipBuf[32]; ipBuf[0] = NULL; int index = 0; int begin = -1; int i = 0; while (reply[index]) { // While there are more characters to process... if (begin == -1 && isdigit(reply[index])) { // Upon finding a digit, ... begin = index; } if(begin != -1) { if(isdigit(reply[index]) || reply[index] == '.') { ipBuf[i++] = reply[index]; } else { ipBuf[i++] = NULL; return ipBuf; } } index++; } return ipBuf; }