This program simply connects to a HTS221 I2C device to proximity sensor

Dependencies:   FXOS8700CQ mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Wnc.cpp Source File

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 }