Rick McConney
/
stripReader
Proximity strip reader
Fork of StarterKit by
Wnc.cpp
- Committer:
- elmkom
- Date:
- 2016-10-10
- Revision:
- 43:3979ea0a2df3
- Parent:
- 42:8500f0cb2ea5
- Child:
- 44:60008ebffdd4
File content as of revision 43:3979ea0a2df3:
#include "Wnc.h" #include "mbed.h" #include <cctype> #include <string> #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); SerialBuffered mdm(PTD3, PTD2, 512); bool powerSave = false; bool firstWake = 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; } char* Wnc::read(int timeout_ms) { static char response[3200]; int len = 0; 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()) { response[len++] = mdm.getc(); if(len>1 && response[len-2] == 'O' && response[len-1] == 'K') break; } } } response[len] = (char)NULL; pc.printf("{%s}\r\n",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; } int Wnc::init(void) { 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); 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) { int tau = secToTau(t3412); int activity = secToActivity(t3324); mdm_wakeup_in = 0; //allow power sleep mode powerSave = true; char cmd[32]; sprintf(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() { char *reply; mdm_wakeup_in = 1; pc.printf("wake from power save\r\n"); firstWake = true; // reply = send("AT+CFUN=1", WNC_WAIT_TIME_MS); // reply = send("AT%CMATT=1", WNC_WAIT_TIME_MS); // wait(5); // wait to attach // reply = send("AT+CREG?", WNC_WAIT_TIME_MS); // reply = send("AT@INTERNET=1", WNC_WAIT_TIME_MS); // Internet services enabled // reply = send("AT@SOCKDIAL=1", WNC_WAIT_TIME_MS); } void Wnc::startInternet() { char *reply; reply = send("ATE1",WNC_WAIT_TIME_MS); // Echo ON char apn [32]; sprintf(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 reply = send("AT+CREG?", WNC_WAIT_TIME_MS); reply = send("AT@INTERNET=1", WNC_WAIT_TIME_MS); // Internet services enabled reply = send("AT@SOCKDIAL=1", WNC_WAIT_TIME_MS); } char* Wnc::ping(char* ip) { char cmd[32]; sprintf(cmd,"AT@PINGREQ=\"%s\"",ip); return send(cmd,WNC_WAIT_TIME_MS); } // AT@SOCKCONN=1,"108.244.165.22",5005 bool Wnc::connect(char* ip, int port) { char *reply; if(isModemResponding()) { reply = send("AT@SOCKCREAT=1", WNC_WAIT_TIME_MS); if(strlen(reply) == 0 || strstr(reply,"OK") ==0) return false; } char cmd[32]; if(isModemResponding()) { sprintf(cmd,"AT@SOCKCONN=1,\"%s\",%d",ip,port); reply = send(cmd,WNC_WAIT_TIME_MS); if(firstWake) { for(int i = 0;i<10;i++) { pc.printf("%d",i); send("AT", WNC_WAIT_TIME_MS); reply = send("AT+CREG?",WNC_WAIT_TIME_MS); if(strlen(reply) > 0 && strstr(reply,"2,1") != 0) { pc.printf("connected %s",reply); break; } else { pc.printf("Unconnected %s",reply); } wait(1); } } firstWake = false; reply = send(cmd,WNC_WAIT_TIME_MS); if(strlen(reply) == 0 || strstr(reply,"OK") ==0) return false; } return true; } 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; } char* Wnc::writeSocket(const char * s) { char *reply; char num2str[6]; size_t sLen = strlen(s); if (sLen <= 99999) { string cmd_str("AT@SOCKWRITE=1,"); encode(sLen, num2str, 10); cmd_str += num2str; cmd_str += ",\""; 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_str += num2str; } cmd_str += "\""; reply = send(cmd_str.c_str(), WNC_WAIT_TIME_MS); } else pc.puts("sockwrite Err, string to long\r\n"); return NULL; } int Wnc::hex_to_int(char c){ if(c >=97) c=c-32; int first = c / 16 - 3; int second = c % 16; int result = first*10 + second; if(result > 9) result--; return result; } int Wnc::hex_to_ascii(char h, char l){ int high = hex_to_int(h) * 16; int low = hex_to_int(l); return high+low; } 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[i] = NULL; return data; }