A simple WIP that logs data from a Grove sensor, and can send and receive information over USB and SMS.

Dependencies:   DHT DS_1337 SDFileSystem USBDevice mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers GprsHandler.cpp Source File

GprsHandler.cpp

00001 #ifdef ENABLE_GPRS_TESTING
00002 #include "GprsHandler.h"
00003 #include "mbed.h"
00004 #include "config.h"
00005 #include "UsbComms.h"
00006 #include "circbuff.h"
00007 #define TX_GSM P1_27
00008 #define RX_GSM P1_26
00009 
00010 // declare led3 to display GPRS handler state
00011 extern DigitalOut myled3;
00012 
00013 /*
00014  * PINPWR to low on Q10 drives 3V3 to Q7, which drives Q5 to ground, which powers VBAT_900, with
00015  * either VCC_BUCK or VCC_BAT
00016  */
00017 #define PINPWR                  P1_2
00018 #define PINONOFF                P1_7
00019 
00020 #define REQ_SEND_SMS     0b00000001
00021 
00022 #define USB_BUFF_SIZE 256
00023 
00024 #define SIM900_SERIAL_TIMEOUT 10000
00025 
00026 GprsHandler::GprsHandler(MyTimers * _timer, UsbComms *_usb) : AbstractHandler(_timer)
00027 {
00028     m_serial = new Serial(TX_GSM, RX_GSM);  // create object for UART comms
00029     mode = gprs_Start;      // initialise state machine
00030 
00031     m_sim900_pwr = new DigitalOut(PINPWR);      // create pin out for
00032     m_sim900_on  = new DigitalOut(PINONOFF);
00033     m_reqReg = 0;
00034 
00035     m_usb = _usb;
00036     m_rxBuff = new CircBuff(USB_BUFF_SIZE);
00037 
00038     m_atReq = atreq_Test;
00039 }
00040 
00041 GprsHandler::~GprsHandler()
00042 {
00043     // TODO Auto-generated destructor stub
00044     delete m_serial;
00045     delete m_rxBuff;
00046     delete m_sim900_pwr;
00047     delete m_sim900_on;
00048 }
00049 
00050 void GprsHandler::run()
00051 {
00052     switch(mode)
00053     {
00054     case gprs_Start:
00055 
00056         mode = gprs_PowerOff;
00057         break;
00058 
00059 
00060         // POWER HANDLERS
00061 
00062     case gprs_PowerOff:
00063         m_sim900_pwr->write(1);             // turn power supply off
00064         m_sim900_on->write(1);
00065         m_timer->SetTimer(MyTimers::tmr_GprsPower, 500);    // wait to settle
00066         mode = gprs_PowerOffWait;
00067         break;
00068 
00069     case gprs_PowerOffWait:
00070         if (!m_timer->GetTimer(MyTimers::tmr_GprsPower))
00071         {
00072             mode = gprs_PowerSupplyOn;      // timer has elapsed
00073         }
00074         break;
00075 
00076     case gprs_PowerSupplyOn:
00077         m_sim900_pwr->write(0);     // turn power supply on
00078         m_sim900_on->write(0);      // from the ref: "drive the PWRKEY to a low level for 1 second then release."
00079 
00080 
00081         m_timer->SetTimer(MyTimers::tmr_GprsPower, 1000);   // wait for one second
00082         mode = gprs_PowerSupplyOnWait;                      // go to wait state
00083         break;
00084 
00085     case gprs_PowerSupplyOnWait:
00086         if (!m_timer->GetTimer(MyTimers::tmr_GprsPower))
00087         {
00088             mode = gprs_PowerSwitchOn;      // timer has elapsed
00089         }
00090         break;
00091 
00092     case gprs_PowerSwitchOn:
00093         m_sim900_on->write(1);      // release power key
00094         m_timer->SetTimer(MyTimers::tmr_GprsPower, 500);    // wait to settle
00095         mode = gprs_PowerSwitchOnWait;
00096         break;
00097 
00098     case gprs_PowerSwitchOnWait:
00099         if (!m_timer->GetTimer(MyTimers::tmr_GprsPower))
00100         {
00101             mode = gprs_CheckATReqs;        // timer has elapsed
00102         }
00103         break;
00104 
00105 
00106         // REQUEST HANDLERS
00107 
00108     case gprs_CheckATReqs:
00109         switch (m_atReq) {
00110         case atreq_Test:
00111             sprintf((char*)txBuf, "AT\r\n");
00112             txBufLen = 4;
00113             mode = gprs_PostTx;
00114             break;
00115 
00116         case atreq_CheckSMS:
00117             sprintf((char*)txBuf, "AT+CMGL=\"ALL\"");
00118             txBufLen = 13;
00119             mode = gprs_PostTx;
00120             break;
00121 
00122         default:
00123             m_atReq = atreq_Test;
00124         }
00125         break;
00126 
00127 
00128         // TX/RX HANDLERS
00129 
00130     case gprs_PostTx:
00131         // use putc, other write functions in serial don't really seem to work
00132         for (int i = 0; i < txBufLen; i++) {
00133             m_serial->putc(txBuf[i]);
00134         }
00135 
00136         // make sure buffer is null terminated before printing to USB
00137         txBuf[txBufLen+1] = 0;
00138         m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, txBuf);
00139 
00140         // clear the buffer
00141         txBufLen = 0;
00142 
00143         // set timeout
00144         m_timer->SetTimer(MyTimers::tmr_GprsRxTx, SIM900_SERIAL_TIMEOUT);
00145 
00146         // wait for a response
00147         mode = gprs_WaitRx;
00148         break;
00149 
00150     case gprs_WaitRx:
00151         if (m_timer->GetTimer(MyTimers::tmr_GprsRxTx))
00152         {
00153             // we have not timed out yet
00154             // we need a generic rx handler here.
00155             while (m_serial->readable())
00156             {
00157                 char ch = m_serial->getc();
00158 
00159                 // save this to our rx circular buffer
00160                 m_rxBuff->putc(ch);
00161 
00162                 mode = gprs_CheckRx;
00163                 wait(0.1);
00164             }
00165             // we have not timed out, and have not got anything back yet
00166             // keep waiting in this state
00167         }
00168         else {
00169             m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"SIM900 TIMEOUT!");
00170             mode = gprs_RxTimeout;
00171         }
00172         break;
00173 
00174     case gprs_CheckRx:
00175         if (m_rxBuff->dataAvailable()) {
00176 
00177             // read out
00178             unsigned char s[50];
00179             uint16_t len = m_rxBuff->read(s, 50);
00180 
00181             // write to USB
00182             m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s);
00183 
00184             // process the reply
00185             switch(m_atReq) {
00186             case atreq_Test:
00187                 // should have just gotten an ok back
00188                 bool bOk = false;
00189                 for (int i = 0; i < (len - 1); i++) {
00190                     if ((s[i] == 'O') && (s[i+1] == 'K')) {
00191                         bOk = true;
00192                     }
00193                 }
00194 
00195                 if (bOk) {
00196                     myled3 = 1;
00197                     // so we know that comms are definitely OK.
00198                     // now check to see what requests need to get fulfilled
00199 
00200                     if (m_reqReg&REQ_SEND_SMS) {
00201                         // we want to check what sms is
00202                         m_atReq = atreq_SendSMS;
00203 
00204                         m_reqReg &= ~REQ_SEND_SMS;
00205                     }
00206                     else {
00207                         // no requests, but see if there are any received SMSs
00208                         m_atReq = atreq_CheckSMS;
00209                     }
00210                 }
00211                 else {
00212                     // did not get the reply we were hoping for.
00213                 }
00214                 break;
00215 
00216             default:
00217                 // todo: handle replies for checking/sending SMSs
00218                 m_atReq = atreq_Test;
00219                 break;
00220             }
00221         }
00222         else {
00223 
00224         }
00225         m_timer->SetTimer(MyTimers::tmr_GprsRxTx, 2000);
00226         // now that we're done here, go check what needs to get sent to the SIM900 next
00227         mode = gprs_WaitUntilNextRequest;
00228         break;
00229         
00230     case gprs_WaitUntilNextRequest:
00231         if (!m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) {
00232             mode = gprs_CheckATReqs;
00233         }
00234         break;
00235     case gprs_RxTimeout:
00236     case gprs_RxError:
00237     default:
00238         mode = gprs_Start;
00239         break;
00240 
00241 
00242     }
00243 }
00244 
00245 void GprsHandler::setRequest(int request, void *data)
00246 {
00247     m_lastRequest = (request_t )request;
00248     switch(request) {
00249     case gprsreq_SmsSend:
00250         GprsRequest *req = (GprsRequest*)data;
00251 
00252         // make a copy
00253         m_lastMessage = *req;     // there are strings, do i have to copy these manually?
00254 
00255         // set the request
00256         m_reqReg |= REQ_SEND_SMS;
00257         break;
00258     }
00259 }
00260 #endif