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
Handlers/GprsHandler.cpp@0:2df78a4443cd, 2016-04-10 (annotated)
- Committer:
- Joseph Radford
- Date:
- Sun Apr 10 15:47:33 2016 +1000
- Revision:
- 0:2df78a4443cd
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Joseph Radford |
0:2df78a4443cd | 1 | #ifdef ENABLE_GPRS_TESTING |
Joseph Radford |
0:2df78a4443cd | 2 | #include "GprsHandler.h" |
Joseph Radford |
0:2df78a4443cd | 3 | #include "mbed.h" |
Joseph Radford |
0:2df78a4443cd | 4 | #include "config.h" |
Joseph Radford |
0:2df78a4443cd | 5 | #include "UsbComms.h" |
Joseph Radford |
0:2df78a4443cd | 6 | #include "circbuff.h" |
Joseph Radford |
0:2df78a4443cd | 7 | #define TX_GSM P1_27 |
Joseph Radford |
0:2df78a4443cd | 8 | #define RX_GSM P1_26 |
Joseph Radford |
0:2df78a4443cd | 9 | |
Joseph Radford |
0:2df78a4443cd | 10 | // declare led3 to display GPRS handler state |
Joseph Radford |
0:2df78a4443cd | 11 | extern DigitalOut myled3; |
Joseph Radford |
0:2df78a4443cd | 12 | |
Joseph Radford |
0:2df78a4443cd | 13 | /* |
Joseph Radford |
0:2df78a4443cd | 14 | * PINPWR to low on Q10 drives 3V3 to Q7, which drives Q5 to ground, which powers VBAT_900, with |
Joseph Radford |
0:2df78a4443cd | 15 | * either VCC_BUCK or VCC_BAT |
Joseph Radford |
0:2df78a4443cd | 16 | */ |
Joseph Radford |
0:2df78a4443cd | 17 | #define PINPWR P1_2 |
Joseph Radford |
0:2df78a4443cd | 18 | #define PINONOFF P1_7 |
Joseph Radford |
0:2df78a4443cd | 19 | |
Joseph Radford |
0:2df78a4443cd | 20 | #define REQ_SEND_SMS 0b00000001 |
Joseph Radford |
0:2df78a4443cd | 21 | |
Joseph Radford |
0:2df78a4443cd | 22 | #define USB_BUFF_SIZE 256 |
Joseph Radford |
0:2df78a4443cd | 23 | |
Joseph Radford |
0:2df78a4443cd | 24 | #define SIM900_SERIAL_TIMEOUT 10000 |
Joseph Radford |
0:2df78a4443cd | 25 | |
Joseph Radford |
0:2df78a4443cd | 26 | GprsHandler::GprsHandler(MyTimers * _timer, UsbComms *_usb) : AbstractHandler(_timer) |
Joseph Radford |
0:2df78a4443cd | 27 | { |
Joseph Radford |
0:2df78a4443cd | 28 | m_serial = new Serial(TX_GSM, RX_GSM); // create object for UART comms |
Joseph Radford |
0:2df78a4443cd | 29 | mode = gprs_Start; // initialise state machine |
Joseph Radford |
0:2df78a4443cd | 30 | |
Joseph Radford |
0:2df78a4443cd | 31 | m_sim900_pwr = new DigitalOut(PINPWR); // create pin out for |
Joseph Radford |
0:2df78a4443cd | 32 | m_sim900_on = new DigitalOut(PINONOFF); |
Joseph Radford |
0:2df78a4443cd | 33 | m_reqReg = 0; |
Joseph Radford |
0:2df78a4443cd | 34 | |
Joseph Radford |
0:2df78a4443cd | 35 | m_usb = _usb; |
Joseph Radford |
0:2df78a4443cd | 36 | m_rxBuff = new CircBuff(USB_BUFF_SIZE); |
Joseph Radford |
0:2df78a4443cd | 37 | |
Joseph Radford |
0:2df78a4443cd | 38 | m_atReq = atreq_Test; |
Joseph Radford |
0:2df78a4443cd | 39 | } |
Joseph Radford |
0:2df78a4443cd | 40 | |
Joseph Radford |
0:2df78a4443cd | 41 | GprsHandler::~GprsHandler() |
Joseph Radford |
0:2df78a4443cd | 42 | { |
Joseph Radford |
0:2df78a4443cd | 43 | // TODO Auto-generated destructor stub |
Joseph Radford |
0:2df78a4443cd | 44 | delete m_serial; |
Joseph Radford |
0:2df78a4443cd | 45 | delete m_rxBuff; |
Joseph Radford |
0:2df78a4443cd | 46 | delete m_sim900_pwr; |
Joseph Radford |
0:2df78a4443cd | 47 | delete m_sim900_on; |
Joseph Radford |
0:2df78a4443cd | 48 | } |
Joseph Radford |
0:2df78a4443cd | 49 | |
Joseph Radford |
0:2df78a4443cd | 50 | void GprsHandler::run() |
Joseph Radford |
0:2df78a4443cd | 51 | { |
Joseph Radford |
0:2df78a4443cd | 52 | switch(mode) |
Joseph Radford |
0:2df78a4443cd | 53 | { |
Joseph Radford |
0:2df78a4443cd | 54 | case gprs_Start: |
Joseph Radford |
0:2df78a4443cd | 55 | |
Joseph Radford |
0:2df78a4443cd | 56 | mode = gprs_PowerOff; |
Joseph Radford |
0:2df78a4443cd | 57 | break; |
Joseph Radford |
0:2df78a4443cd | 58 | |
Joseph Radford |
0:2df78a4443cd | 59 | |
Joseph Radford |
0:2df78a4443cd | 60 | // POWER HANDLERS |
Joseph Radford |
0:2df78a4443cd | 61 | |
Joseph Radford |
0:2df78a4443cd | 62 | case gprs_PowerOff: |
Joseph Radford |
0:2df78a4443cd | 63 | m_sim900_pwr->write(1); // turn power supply off |
Joseph Radford |
0:2df78a4443cd | 64 | m_sim900_on->write(1); |
Joseph Radford |
0:2df78a4443cd | 65 | m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle |
Joseph Radford |
0:2df78a4443cd | 66 | mode = gprs_PowerOffWait; |
Joseph Radford |
0:2df78a4443cd | 67 | break; |
Joseph Radford |
0:2df78a4443cd | 68 | |
Joseph Radford |
0:2df78a4443cd | 69 | case gprs_PowerOffWait: |
Joseph Radford |
0:2df78a4443cd | 70 | if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) |
Joseph Radford |
0:2df78a4443cd | 71 | { |
Joseph Radford |
0:2df78a4443cd | 72 | mode = gprs_PowerSupplyOn; // timer has elapsed |
Joseph Radford |
0:2df78a4443cd | 73 | } |
Joseph Radford |
0:2df78a4443cd | 74 | break; |
Joseph Radford |
0:2df78a4443cd | 75 | |
Joseph Radford |
0:2df78a4443cd | 76 | case gprs_PowerSupplyOn: |
Joseph Radford |
0:2df78a4443cd | 77 | m_sim900_pwr->write(0); // turn power supply on |
Joseph Radford |
0:2df78a4443cd | 78 | m_sim900_on->write(0); // from the ref: "drive the PWRKEY to a low level for 1 second then release." |
Joseph Radford |
0:2df78a4443cd | 79 | |
Joseph Radford |
0:2df78a4443cd | 80 | |
Joseph Radford |
0:2df78a4443cd | 81 | m_timer->SetTimer(MyTimers::tmr_GprsPower, 1000); // wait for one second |
Joseph Radford |
0:2df78a4443cd | 82 | mode = gprs_PowerSupplyOnWait; // go to wait state |
Joseph Radford |
0:2df78a4443cd | 83 | break; |
Joseph Radford |
0:2df78a4443cd | 84 | |
Joseph Radford |
0:2df78a4443cd | 85 | case gprs_PowerSupplyOnWait: |
Joseph Radford |
0:2df78a4443cd | 86 | if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) |
Joseph Radford |
0:2df78a4443cd | 87 | { |
Joseph Radford |
0:2df78a4443cd | 88 | mode = gprs_PowerSwitchOn; // timer has elapsed |
Joseph Radford |
0:2df78a4443cd | 89 | } |
Joseph Radford |
0:2df78a4443cd | 90 | break; |
Joseph Radford |
0:2df78a4443cd | 91 | |
Joseph Radford |
0:2df78a4443cd | 92 | case gprs_PowerSwitchOn: |
Joseph Radford |
0:2df78a4443cd | 93 | m_sim900_on->write(1); // release power key |
Joseph Radford |
0:2df78a4443cd | 94 | m_timer->SetTimer(MyTimers::tmr_GprsPower, 500); // wait to settle |
Joseph Radford |
0:2df78a4443cd | 95 | mode = gprs_PowerSwitchOnWait; |
Joseph Radford |
0:2df78a4443cd | 96 | break; |
Joseph Radford |
0:2df78a4443cd | 97 | |
Joseph Radford |
0:2df78a4443cd | 98 | case gprs_PowerSwitchOnWait: |
Joseph Radford |
0:2df78a4443cd | 99 | if (!m_timer->GetTimer(MyTimers::tmr_GprsPower)) |
Joseph Radford |
0:2df78a4443cd | 100 | { |
Joseph Radford |
0:2df78a4443cd | 101 | mode = gprs_CheckATReqs; // timer has elapsed |
Joseph Radford |
0:2df78a4443cd | 102 | } |
Joseph Radford |
0:2df78a4443cd | 103 | break; |
Joseph Radford |
0:2df78a4443cd | 104 | |
Joseph Radford |
0:2df78a4443cd | 105 | |
Joseph Radford |
0:2df78a4443cd | 106 | // REQUEST HANDLERS |
Joseph Radford |
0:2df78a4443cd | 107 | |
Joseph Radford |
0:2df78a4443cd | 108 | case gprs_CheckATReqs: |
Joseph Radford |
0:2df78a4443cd | 109 | switch (m_atReq) { |
Joseph Radford |
0:2df78a4443cd | 110 | case atreq_Test: |
Joseph Radford |
0:2df78a4443cd | 111 | sprintf((char*)txBuf, "AT\r\n"); |
Joseph Radford |
0:2df78a4443cd | 112 | txBufLen = 4; |
Joseph Radford |
0:2df78a4443cd | 113 | mode = gprs_PostTx; |
Joseph Radford |
0:2df78a4443cd | 114 | break; |
Joseph Radford |
0:2df78a4443cd | 115 | |
Joseph Radford |
0:2df78a4443cd | 116 | case atreq_CheckSMS: |
Joseph Radford |
0:2df78a4443cd | 117 | sprintf((char*)txBuf, "AT+CMGL=\"ALL\""); |
Joseph Radford |
0:2df78a4443cd | 118 | txBufLen = 13; |
Joseph Radford |
0:2df78a4443cd | 119 | mode = gprs_PostTx; |
Joseph Radford |
0:2df78a4443cd | 120 | break; |
Joseph Radford |
0:2df78a4443cd | 121 | |
Joseph Radford |
0:2df78a4443cd | 122 | default: |
Joseph Radford |
0:2df78a4443cd | 123 | m_atReq = atreq_Test; |
Joseph Radford |
0:2df78a4443cd | 124 | } |
Joseph Radford |
0:2df78a4443cd | 125 | break; |
Joseph Radford |
0:2df78a4443cd | 126 | |
Joseph Radford |
0:2df78a4443cd | 127 | |
Joseph Radford |
0:2df78a4443cd | 128 | // TX/RX HANDLERS |
Joseph Radford |
0:2df78a4443cd | 129 | |
Joseph Radford |
0:2df78a4443cd | 130 | case gprs_PostTx: |
Joseph Radford |
0:2df78a4443cd | 131 | // use putc, other write functions in serial don't really seem to work |
Joseph Radford |
0:2df78a4443cd | 132 | for (int i = 0; i < txBufLen; i++) { |
Joseph Radford |
0:2df78a4443cd | 133 | m_serial->putc(txBuf[i]); |
Joseph Radford |
0:2df78a4443cd | 134 | } |
Joseph Radford |
0:2df78a4443cd | 135 | |
Joseph Radford |
0:2df78a4443cd | 136 | // make sure buffer is null terminated before printing to USB |
Joseph Radford |
0:2df78a4443cd | 137 | txBuf[txBufLen+1] = 0; |
Joseph Radford |
0:2df78a4443cd | 138 | m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, txBuf); |
Joseph Radford |
0:2df78a4443cd | 139 | |
Joseph Radford |
0:2df78a4443cd | 140 | // clear the buffer |
Joseph Radford |
0:2df78a4443cd | 141 | txBufLen = 0; |
Joseph Radford |
0:2df78a4443cd | 142 | |
Joseph Radford |
0:2df78a4443cd | 143 | // set timeout |
Joseph Radford |
0:2df78a4443cd | 144 | m_timer->SetTimer(MyTimers::tmr_GprsRxTx, SIM900_SERIAL_TIMEOUT); |
Joseph Radford |
0:2df78a4443cd | 145 | |
Joseph Radford |
0:2df78a4443cd | 146 | // wait for a response |
Joseph Radford |
0:2df78a4443cd | 147 | mode = gprs_WaitRx; |
Joseph Radford |
0:2df78a4443cd | 148 | break; |
Joseph Radford |
0:2df78a4443cd | 149 | |
Joseph Radford |
0:2df78a4443cd | 150 | case gprs_WaitRx: |
Joseph Radford |
0:2df78a4443cd | 151 | if (m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) |
Joseph Radford |
0:2df78a4443cd | 152 | { |
Joseph Radford |
0:2df78a4443cd | 153 | // we have not timed out yet |
Joseph Radford |
0:2df78a4443cd | 154 | // we need a generic rx handler here. |
Joseph Radford |
0:2df78a4443cd | 155 | while (m_serial->readable()) |
Joseph Radford |
0:2df78a4443cd | 156 | { |
Joseph Radford |
0:2df78a4443cd | 157 | char ch = m_serial->getc(); |
Joseph Radford |
0:2df78a4443cd | 158 | |
Joseph Radford |
0:2df78a4443cd | 159 | // save this to our rx circular buffer |
Joseph Radford |
0:2df78a4443cd | 160 | m_rxBuff->putc(ch); |
Joseph Radford |
0:2df78a4443cd | 161 | |
Joseph Radford |
0:2df78a4443cd | 162 | mode = gprs_CheckRx; |
Joseph Radford |
0:2df78a4443cd | 163 | wait(0.1); |
Joseph Radford |
0:2df78a4443cd | 164 | } |
Joseph Radford |
0:2df78a4443cd | 165 | // we have not timed out, and have not got anything back yet |
Joseph Radford |
0:2df78a4443cd | 166 | // keep waiting in this state |
Joseph Radford |
0:2df78a4443cd | 167 | } |
Joseph Radford |
0:2df78a4443cd | 168 | else { |
Joseph Radford |
0:2df78a4443cd | 169 | m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, (char*)"SIM900 TIMEOUT!"); |
Joseph Radford |
0:2df78a4443cd | 170 | mode = gprs_RxTimeout; |
Joseph Radford |
0:2df78a4443cd | 171 | } |
Joseph Radford |
0:2df78a4443cd | 172 | break; |
Joseph Radford |
0:2df78a4443cd | 173 | |
Joseph Radford |
0:2df78a4443cd | 174 | case gprs_CheckRx: |
Joseph Radford |
0:2df78a4443cd | 175 | if (m_rxBuff->dataAvailable()) { |
Joseph Radford |
0:2df78a4443cd | 176 | |
Joseph Radford |
0:2df78a4443cd | 177 | // read out |
Joseph Radford |
0:2df78a4443cd | 178 | unsigned char s[50]; |
Joseph Radford |
0:2df78a4443cd | 179 | uint16_t len = m_rxBuff->read(s, 50); |
Joseph Radford |
0:2df78a4443cd | 180 | |
Joseph Radford |
0:2df78a4443cd | 181 | // write to USB |
Joseph Radford |
0:2df78a4443cd | 182 | m_usb->setRequest(UsbComms::usbreq_PrintToTerminalTimestamp, s); |
Joseph Radford |
0:2df78a4443cd | 183 | |
Joseph Radford |
0:2df78a4443cd | 184 | // process the reply |
Joseph Radford |
0:2df78a4443cd | 185 | switch(m_atReq) { |
Joseph Radford |
0:2df78a4443cd | 186 | case atreq_Test: |
Joseph Radford |
0:2df78a4443cd | 187 | // should have just gotten an ok back |
Joseph Radford |
0:2df78a4443cd | 188 | bool bOk = false; |
Joseph Radford |
0:2df78a4443cd | 189 | for (int i = 0; i < (len - 1); i++) { |
Joseph Radford |
0:2df78a4443cd | 190 | if ((s[i] == 'O') && (s[i+1] == 'K')) { |
Joseph Radford |
0:2df78a4443cd | 191 | bOk = true; |
Joseph Radford |
0:2df78a4443cd | 192 | } |
Joseph Radford |
0:2df78a4443cd | 193 | } |
Joseph Radford |
0:2df78a4443cd | 194 | |
Joseph Radford |
0:2df78a4443cd | 195 | if (bOk) { |
Joseph Radford |
0:2df78a4443cd | 196 | myled3 = 1; |
Joseph Radford |
0:2df78a4443cd | 197 | // so we know that comms are definitely OK. |
Joseph Radford |
0:2df78a4443cd | 198 | // now check to see what requests need to get fulfilled |
Joseph Radford |
0:2df78a4443cd | 199 | |
Joseph Radford |
0:2df78a4443cd | 200 | if (m_reqReg&REQ_SEND_SMS) { |
Joseph Radford |
0:2df78a4443cd | 201 | // we want to check what sms is |
Joseph Radford |
0:2df78a4443cd | 202 | m_atReq = atreq_SendSMS; |
Joseph Radford |
0:2df78a4443cd | 203 | |
Joseph Radford |
0:2df78a4443cd | 204 | m_reqReg &= ~REQ_SEND_SMS; |
Joseph Radford |
0:2df78a4443cd | 205 | } |
Joseph Radford |
0:2df78a4443cd | 206 | else { |
Joseph Radford |
0:2df78a4443cd | 207 | // no requests, but see if there are any received SMSs |
Joseph Radford |
0:2df78a4443cd | 208 | m_atReq = atreq_CheckSMS; |
Joseph Radford |
0:2df78a4443cd | 209 | } |
Joseph Radford |
0:2df78a4443cd | 210 | } |
Joseph Radford |
0:2df78a4443cd | 211 | else { |
Joseph Radford |
0:2df78a4443cd | 212 | // did not get the reply we were hoping for. |
Joseph Radford |
0:2df78a4443cd | 213 | } |
Joseph Radford |
0:2df78a4443cd | 214 | break; |
Joseph Radford |
0:2df78a4443cd | 215 | |
Joseph Radford |
0:2df78a4443cd | 216 | default: |
Joseph Radford |
0:2df78a4443cd | 217 | // todo: handle replies for checking/sending SMSs |
Joseph Radford |
0:2df78a4443cd | 218 | m_atReq = atreq_Test; |
Joseph Radford |
0:2df78a4443cd | 219 | break; |
Joseph Radford |
0:2df78a4443cd | 220 | } |
Joseph Radford |
0:2df78a4443cd | 221 | } |
Joseph Radford |
0:2df78a4443cd | 222 | else { |
Joseph Radford |
0:2df78a4443cd | 223 | |
Joseph Radford |
0:2df78a4443cd | 224 | } |
Joseph Radford |
0:2df78a4443cd | 225 | m_timer->SetTimer(MyTimers::tmr_GprsRxTx, 2000); |
Joseph Radford |
0:2df78a4443cd | 226 | // now that we're done here, go check what needs to get sent to the SIM900 next |
Joseph Radford |
0:2df78a4443cd | 227 | mode = gprs_WaitUntilNextRequest; |
Joseph Radford |
0:2df78a4443cd | 228 | break; |
Joseph Radford |
0:2df78a4443cd | 229 | |
Joseph Radford |
0:2df78a4443cd | 230 | case gprs_WaitUntilNextRequest: |
Joseph Radford |
0:2df78a4443cd | 231 | if (!m_timer->GetTimer(MyTimers::tmr_GprsRxTx)) { |
Joseph Radford |
0:2df78a4443cd | 232 | mode = gprs_CheckATReqs; |
Joseph Radford |
0:2df78a4443cd | 233 | } |
Joseph Radford |
0:2df78a4443cd | 234 | break; |
Joseph Radford |
0:2df78a4443cd | 235 | case gprs_RxTimeout: |
Joseph Radford |
0:2df78a4443cd | 236 | case gprs_RxError: |
Joseph Radford |
0:2df78a4443cd | 237 | default: |
Joseph Radford |
0:2df78a4443cd | 238 | mode = gprs_Start; |
Joseph Radford |
0:2df78a4443cd | 239 | break; |
Joseph Radford |
0:2df78a4443cd | 240 | |
Joseph Radford |
0:2df78a4443cd | 241 | |
Joseph Radford |
0:2df78a4443cd | 242 | } |
Joseph Radford |
0:2df78a4443cd | 243 | } |
Joseph Radford |
0:2df78a4443cd | 244 | |
Joseph Radford |
0:2df78a4443cd | 245 | void GprsHandler::setRequest(int request, void *data) |
Joseph Radford |
0:2df78a4443cd | 246 | { |
Joseph Radford |
0:2df78a4443cd | 247 | m_lastRequest = (request_t)request; |
Joseph Radford |
0:2df78a4443cd | 248 | switch(request) { |
Joseph Radford |
0:2df78a4443cd | 249 | case gprsreq_SmsSend: |
Joseph Radford |
0:2df78a4443cd | 250 | GprsRequest *req = (GprsRequest*)data; |
Joseph Radford |
0:2df78a4443cd | 251 | |
Joseph Radford |
0:2df78a4443cd | 252 | // make a copy |
Joseph Radford |
0:2df78a4443cd | 253 | m_lastMessage = *req; // there are strings, do i have to copy these manually? |
Joseph Radford |
0:2df78a4443cd | 254 | |
Joseph Radford |
0:2df78a4443cd | 255 | // set the request |
Joseph Radford |
0:2df78a4443cd | 256 | m_reqReg |= REQ_SEND_SMS; |
Joseph Radford |
0:2df78a4443cd | 257 | break; |
Joseph Radford |
0:2df78a4443cd | 258 | } |
Joseph Radford |
0:2df78a4443cd | 259 | } |
Joseph Radford |
0:2df78a4443cd | 260 | #endif |