Backing up an unused program in case of future need

Dependencies:   mbed

Committer:
andrewboyson
Date:
Sat Apr 23 20:00:04 2016 +0000
Revision:
3:accba7e07a0d
Parent:
2:06fa34661f19
Child:
4:e076884ef8bd
Separated serial queues into a generic uart module.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 0:09f915e6f9f6 1 #include "mbed.h"
andrewboyson 2:06fa34661f19 2 #include "log.h"
andrewboyson 2:06fa34661f19 3 #include "esp.h"
andrewboyson 2:06fa34661f19 4 #include "io.h"
andrewboyson 2:06fa34661f19 5 #include "cfg.h"
andrewboyson 3:accba7e07a0d 6 #include "uart.h"
andrewboyson 0:09f915e6f9f6 7
andrewboyson 0:09f915e6f9f6 8 #define RECV_TIMEOUT_MS 5000
andrewboyson 0:09f915e6f9f6 9
andrewboyson 0:09f915e6f9f6 10 //State
andrewboyson 0:09f915e6f9f6 11 #define LINE_LENGTH 256
andrewboyson 0:09f915e6f9f6 12 #define IDLE 0
andrewboyson 0:09f915e6f9f6 13 #define IN_LINE 1
andrewboyson 0:09f915e6f9f6 14 #define IPD_WAIT_START 2
andrewboyson 0:09f915e6f9f6 15 #define IPD_READ 3
andrewboyson 0:09f915e6f9f6 16 #define SEND_DATA 4
andrewboyson 0:09f915e6f9f6 17 static int state; //Initialised in init
andrewboyson 0:09f915e6f9f6 18
andrewboyson 0:09f915e6f9f6 19 //Solicited responses received
andrewboyson 0:09f915e6f9f6 20 //============================
andrewboyson 0:09f915e6f9f6 21 #define LINE_LENGTH 256
andrewboyson 0:09f915e6f9f6 22 int EspLineAvailable; //Initialised in init; can be one of the values defined in esp.h
andrewboyson 0:09f915e6f9f6 23 char EspLine[LINE_LENGTH];
andrewboyson 2:06fa34661f19 24 static char* pLineNext; //Initialised in init to EspLine
andrewboyson 2:06fa34661f19 25
andrewboyson 2:06fa34661f19 26 #define RESP_LENGTH 256
andrewboyson 2:06fa34661f19 27 char EspResp[RESP_LENGTH];
andrewboyson 2:06fa34661f19 28 static char* pRespNext; //Initialised at each request to EspResp
andrewboyson 2:06fa34661f19 29 static int addRawCharToBuffer(char* pBuff, char** ppNext, int len, char c)
andrewboyson 0:09f915e6f9f6 30 {
andrewboyson 2:06fa34661f19 31
andrewboyson 2:06fa34661f19 32 // if *ppNext is at the last position in pBuff (pBuff+len-1) then we are full and should stop
andrewboyson 2:06fa34661f19 33 if (*ppNext >= pBuff + len - 1) return -1;
andrewboyson 2:06fa34661f19 34
andrewboyson 2:06fa34661f19 35 // Put the char into *ppNext and NUL into *ppNext + 1.
andrewboyson 2:06fa34661f19 36 **ppNext = c;
andrewboyson 2:06fa34661f19 37 ++*ppNext;
andrewboyson 2:06fa34661f19 38 **ppNext = '\0';
andrewboyson 2:06fa34661f19 39
andrewboyson 2:06fa34661f19 40 return 0;
andrewboyson 2:06fa34661f19 41 }
andrewboyson 2:06fa34661f19 42 static int addCharToBuffer(char* pBuff, char** ppNext, int len, char c, int includeCrLf)
andrewboyson 2:06fa34661f19 43 {
andrewboyson 2:06fa34661f19 44 if (!pBuff) return -1;
andrewboyson 0:09f915e6f9f6 45 switch (c)
andrewboyson 0:09f915e6f9f6 46 {
andrewboyson 2:06fa34661f19 47 case '\0':
andrewboyson 2:06fa34661f19 48 if (addRawCharToBuffer(pBuff, ppNext, len, '\\')) return -1;
andrewboyson 2:06fa34661f19 49 if (addRawCharToBuffer(pBuff, ppNext, len, '0' )) return -1; //This is the character zero '0' not NUL '\0'
andrewboyson 0:09f915e6f9f6 50 break;
andrewboyson 0:09f915e6f9f6 51 case '\r':
andrewboyson 0:09f915e6f9f6 52 case '\n':
andrewboyson 2:06fa34661f19 53 if (includeCrLf && addRawCharToBuffer(pBuff, ppNext, len, c)) return -1;
andrewboyson 0:09f915e6f9f6 54 break;
andrewboyson 0:09f915e6f9f6 55 default:
andrewboyson 2:06fa34661f19 56 if (addRawCharToBuffer(pBuff, ppNext, len, c)) return -1;
andrewboyson 0:09f915e6f9f6 57 break;
andrewboyson 0:09f915e6f9f6 58 }
andrewboyson 0:09f915e6f9f6 59 return 0;
andrewboyson 0:09f915e6f9f6 60 }
andrewboyson 2:06fa34661f19 61 static int addChar(char c)
andrewboyson 2:06fa34661f19 62 {
andrewboyson 2:06fa34661f19 63 int r = addCharToBuffer(EspLine, &pLineNext, LINE_LENGTH, c, false);
andrewboyson 2:06fa34661f19 64 addCharToBuffer(EspResp, &pRespNext, RESP_LENGTH, c, true );
andrewboyson 2:06fa34661f19 65 return r;
andrewboyson 2:06fa34661f19 66 }
andrewboyson 0:09f915e6f9f6 67 //Unsolicited ntp or http requests
andrewboyson 0:09f915e6f9f6 68 //================================
andrewboyson 0:09f915e6f9f6 69 void *EspIpdBuffer[4];
andrewboyson 0:09f915e6f9f6 70 int EspIpdBufferLen[4];
andrewboyson 0:09f915e6f9f6 71 int EspIpdReserved[4];
andrewboyson 0:09f915e6f9f6 72 int EspIpdLength;
andrewboyson 0:09f915e6f9f6 73 int EspIpdId;
andrewboyson 0:09f915e6f9f6 74 int EspDataAvailable;
andrewboyson 0:09f915e6f9f6 75
andrewboyson 0:09f915e6f9f6 76
andrewboyson 0:09f915e6f9f6 77 //Stuff to send
andrewboyson 0:09f915e6f9f6 78 //=============
andrewboyson 0:09f915e6f9f6 79 int EspLengthToSend;
andrewboyson 0:09f915e6f9f6 80 const void * EspDataToSend;
andrewboyson 0:09f915e6f9f6 81
andrewboyson 0:09f915e6f9f6 82 void EspSendStringF(char *fmt, ...)
andrewboyson 0:09f915e6f9f6 83 {
andrewboyson 0:09f915e6f9f6 84 va_list argptr;
andrewboyson 0:09f915e6f9f6 85 va_start(argptr, fmt);
andrewboyson 0:09f915e6f9f6 86 int size = vsnprintf(NULL, 0, fmt, argptr);
andrewboyson 0:09f915e6f9f6 87 char snd[size + 1];
andrewboyson 0:09f915e6f9f6 88 vsprintf(snd, fmt, argptr);
andrewboyson 0:09f915e6f9f6 89 va_end(argptr);
andrewboyson 0:09f915e6f9f6 90 EspSendString(snd);
andrewboyson 0:09f915e6f9f6 91 }
andrewboyson 0:09f915e6f9f6 92 void EspSendString(char* p)
andrewboyson 0:09f915e6f9f6 93 {
andrewboyson 3:accba7e07a0d 94 //Reset the response buffer
andrewboyson 3:accba7e07a0d 95 pRespNext = EspResp;
andrewboyson 2:06fa34661f19 96 *pRespNext = '\0';
andrewboyson 3:accba7e07a0d 97
andrewboyson 3:accba7e07a0d 98 //Send the string
andrewboyson 3:accba7e07a0d 99 while(*p) UartSendPush(*p++);
andrewboyson 0:09f915e6f9f6 100 }
andrewboyson 0:09f915e6f9f6 101 void EspSendData(int length, const void * snd)
andrewboyson 0:09f915e6f9f6 102 {
andrewboyson 0:09f915e6f9f6 103 const char* p = (char*)snd;
andrewboyson 0:09f915e6f9f6 104 const char* e = (char*)snd + length;
andrewboyson 3:accba7e07a0d 105 while (p < e) UartSendPush(*p++);
andrewboyson 0:09f915e6f9f6 106 }
andrewboyson 0:09f915e6f9f6 107
andrewboyson 0:09f915e6f9f6 108
andrewboyson 0:09f915e6f9f6 109 //Reset ESP8266 zone
andrewboyson 0:09f915e6f9f6 110 #define RESET_TIME_MS 250
andrewboyson 0:09f915e6f9f6 111 static DigitalOut espRunOnHighResetOnLow(p26);
andrewboyson 0:09f915e6f9f6 112 int reset; //Set to 1 by EspReset (and hence EspInit); set to 0 by EspReleasefromReset
andrewboyson 0:09f915e6f9f6 113 void EspResetAndStop()
andrewboyson 0:09f915e6f9f6 114 {
andrewboyson 0:09f915e6f9f6 115 reset = true;
andrewboyson 3:accba7e07a0d 116 UartReset();
andrewboyson 0:09f915e6f9f6 117 pLineNext = EspLine;
andrewboyson 2:06fa34661f19 118 *pLineNext = '\0';
andrewboyson 2:06fa34661f19 119 pRespNext = EspResp;
andrewboyson 2:06fa34661f19 120 *pRespNext = '\0';
andrewboyson 0:09f915e6f9f6 121 EspLengthToSend = 0;
andrewboyson 0:09f915e6f9f6 122 EspDataToSend = NULL;
andrewboyson 0:09f915e6f9f6 123 state = IDLE;
andrewboyson 0:09f915e6f9f6 124 }
andrewboyson 0:09f915e6f9f6 125 void EspReleaseFromReset(void)
andrewboyson 0:09f915e6f9f6 126 {
andrewboyson 0:09f915e6f9f6 127 reset = false;
andrewboyson 0:09f915e6f9f6 128 }
andrewboyson 0:09f915e6f9f6 129 void pulseResetPin()
andrewboyson 0:09f915e6f9f6 130 {
andrewboyson 0:09f915e6f9f6 131 static Timer resetTimer;
andrewboyson 0:09f915e6f9f6 132
andrewboyson 0:09f915e6f9f6 133 if (reset)
andrewboyson 0:09f915e6f9f6 134 {
andrewboyson 0:09f915e6f9f6 135 resetTimer.stop();
andrewboyson 0:09f915e6f9f6 136 resetTimer.reset();
andrewboyson 0:09f915e6f9f6 137 espRunOnHighResetOnLow = 0;
andrewboyson 0:09f915e6f9f6 138 }
andrewboyson 0:09f915e6f9f6 139 else
andrewboyson 0:09f915e6f9f6 140 {
andrewboyson 0:09f915e6f9f6 141 resetTimer.start();
andrewboyson 0:09f915e6f9f6 142 if (resetTimer.read_ms() > RESET_TIME_MS)
andrewboyson 0:09f915e6f9f6 143 {
andrewboyson 0:09f915e6f9f6 144 resetTimer.stop();
andrewboyson 0:09f915e6f9f6 145 espRunOnHighResetOnLow = 1;
andrewboyson 0:09f915e6f9f6 146 }
andrewboyson 0:09f915e6f9f6 147 }
andrewboyson 0:09f915e6f9f6 148 }
andrewboyson 0:09f915e6f9f6 149 //General commands
andrewboyson 2:06fa34661f19 150 int EspInit()
andrewboyson 0:09f915e6f9f6 151 {
andrewboyson 0:09f915e6f9f6 152 EspResetAndStop();
andrewboyson 3:accba7e07a0d 153 UartBaud(CfgBaud);
andrewboyson 0:09f915e6f9f6 154 for (int i = 0; i < 4; i++)
andrewboyson 0:09f915e6f9f6 155 {
andrewboyson 0:09f915e6f9f6 156 EspIpdBuffer[i] = NULL;
andrewboyson 0:09f915e6f9f6 157 EspIpdBufferLen[i] = 0;
andrewboyson 0:09f915e6f9f6 158 EspIpdReserved[i] = 0;
andrewboyson 0:09f915e6f9f6 159 }
andrewboyson 2:06fa34661f19 160 return 0;
andrewboyson 0:09f915e6f9f6 161 }
andrewboyson 0:09f915e6f9f6 162
andrewboyson 0:09f915e6f9f6 163 //Main loop zone
andrewboyson 0:09f915e6f9f6 164 int handleCharacter(char c)
andrewboyson 0:09f915e6f9f6 165 {
andrewboyson 0:09f915e6f9f6 166 //Static variables. Initialised on first load.
andrewboyson 0:09f915e6f9f6 167 static char ipdHeader[20];
andrewboyson 0:09f915e6f9f6 168 static char * pipdHeader; //Set to ipdHeader when a '+' is received
andrewboyson 0:09f915e6f9f6 169 static int bytesRcvd; //Set to 0 when the ':' following the +IPD is received
andrewboyson 0:09f915e6f9f6 170 static void * pData; //Set to EspIpdBuffer[EspIpdId] when the ':' following the +IPD is received
andrewboyson 0:09f915e6f9f6 171
andrewboyson 0:09f915e6f9f6 172 switch(state)
andrewboyson 0:09f915e6f9f6 173 {
andrewboyson 0:09f915e6f9f6 174 case IDLE:
andrewboyson 0:09f915e6f9f6 175 if (c == '+')
andrewboyson 0:09f915e6f9f6 176 {
andrewboyson 0:09f915e6f9f6 177 pipdHeader = ipdHeader;
andrewboyson 0:09f915e6f9f6 178 *pipdHeader = 0;
andrewboyson 0:09f915e6f9f6 179 state = IPD_WAIT_START;
andrewboyson 0:09f915e6f9f6 180 }
andrewboyson 0:09f915e6f9f6 181 else if (c == '>')
andrewboyson 0:09f915e6f9f6 182 {
andrewboyson 0:09f915e6f9f6 183 state = SEND_DATA;
andrewboyson 0:09f915e6f9f6 184 }
andrewboyson 0:09f915e6f9f6 185 else
andrewboyson 0:09f915e6f9f6 186 {
andrewboyson 0:09f915e6f9f6 187 pLineNext = EspLine;
andrewboyson 0:09f915e6f9f6 188 *pLineNext = 0;
andrewboyson 2:06fa34661f19 189 int r = addChar(c);
andrewboyson 0:09f915e6f9f6 190 if (r)
andrewboyson 0:09f915e6f9f6 191 {
andrewboyson 0:09f915e6f9f6 192 EspLineAvailable = ESP_OVERFLOW;
andrewboyson 0:09f915e6f9f6 193 state = IDLE;
andrewboyson 0:09f915e6f9f6 194 }
andrewboyson 0:09f915e6f9f6 195 else
andrewboyson 0:09f915e6f9f6 196 {
andrewboyson 0:09f915e6f9f6 197 state = IN_LINE;
andrewboyson 0:09f915e6f9f6 198 }
andrewboyson 0:09f915e6f9f6 199 }
andrewboyson 0:09f915e6f9f6 200 break;
andrewboyson 0:09f915e6f9f6 201 case IN_LINE:
andrewboyson 0:09f915e6f9f6 202 if (c == '\n')
andrewboyson 0:09f915e6f9f6 203 {
andrewboyson 0:09f915e6f9f6 204 EspLineAvailable = ESP_AVAILABLE;
andrewboyson 0:09f915e6f9f6 205 state = IDLE;
andrewboyson 0:09f915e6f9f6 206 }
andrewboyson 0:09f915e6f9f6 207 else
andrewboyson 0:09f915e6f9f6 208 {
andrewboyson 2:06fa34661f19 209 int r = addChar(c);
andrewboyson 0:09f915e6f9f6 210 if (r)
andrewboyson 0:09f915e6f9f6 211 {
andrewboyson 0:09f915e6f9f6 212 EspLineAvailable = ESP_OVERFLOW;
andrewboyson 0:09f915e6f9f6 213 state = IDLE;
andrewboyson 0:09f915e6f9f6 214 }
andrewboyson 0:09f915e6f9f6 215 }
andrewboyson 0:09f915e6f9f6 216 break;
andrewboyson 0:09f915e6f9f6 217 case IPD_WAIT_START:
andrewboyson 0:09f915e6f9f6 218 if (pipdHeader == ipdHeader && c != 'I') //If the first character after the '+' is not 'I' then start a line instead
andrewboyson 0:09f915e6f9f6 219 {
andrewboyson 0:09f915e6f9f6 220 pLineNext = EspLine;
andrewboyson 2:06fa34661f19 221 addChar('+');
andrewboyson 2:06fa34661f19 222 addChar(c);
andrewboyson 0:09f915e6f9f6 223 state = IN_LINE;
andrewboyson 0:09f915e6f9f6 224 }
andrewboyson 0:09f915e6f9f6 225 else
andrewboyson 0:09f915e6f9f6 226 {
andrewboyson 0:09f915e6f9f6 227 *pipdHeader++ = c;
andrewboyson 0:09f915e6f9f6 228 *pipdHeader = 0;
andrewboyson 0:09f915e6f9f6 229 if (c == ':')
andrewboyson 0:09f915e6f9f6 230 {
andrewboyson 0:09f915e6f9f6 231 sscanf(ipdHeader, "IPD,%d,%d:", &EspIpdId, &EspIpdLength);
andrewboyson 0:09f915e6f9f6 232 bytesRcvd = 0;
andrewboyson 0:09f915e6f9f6 233 pData = EspIpdBuffer[EspIpdId];
andrewboyson 0:09f915e6f9f6 234 state = IPD_READ;
andrewboyson 0:09f915e6f9f6 235 }
andrewboyson 0:09f915e6f9f6 236 }
andrewboyson 0:09f915e6f9f6 237 break;
andrewboyson 0:09f915e6f9f6 238 case IPD_READ:
andrewboyson 0:09f915e6f9f6 239 bytesRcvd++;
andrewboyson 0:09f915e6f9f6 240 if (bytesRcvd <= EspIpdBufferLen[EspIpdId])
andrewboyson 0:09f915e6f9f6 241 {
andrewboyson 0:09f915e6f9f6 242 *(char *)pData = c;
andrewboyson 0:09f915e6f9f6 243 pData = (char *)pData + 1;
andrewboyson 0:09f915e6f9f6 244 }
andrewboyson 0:09f915e6f9f6 245 if (bytesRcvd == EspIpdLength)
andrewboyson 0:09f915e6f9f6 246 {
andrewboyson 0:09f915e6f9f6 247 if (bytesRcvd <= EspIpdBufferLen[EspIpdId]) EspDataAvailable = ESP_AVAILABLE;
andrewboyson 0:09f915e6f9f6 248 else EspDataAvailable = ESP_OVERFLOW;
andrewboyson 0:09f915e6f9f6 249 state = IDLE;
andrewboyson 0:09f915e6f9f6 250 }
andrewboyson 0:09f915e6f9f6 251 break;
andrewboyson 0:09f915e6f9f6 252 case SEND_DATA:
andrewboyson 0:09f915e6f9f6 253 EspSendData(EspLengthToSend, EspDataToSend);
andrewboyson 0:09f915e6f9f6 254 state = IDLE;
andrewboyson 0:09f915e6f9f6 255 break;
andrewboyson 0:09f915e6f9f6 256 default:
andrewboyson 0:09f915e6f9f6 257 LogF("Unknown state %d\n\r", state);
andrewboyson 0:09f915e6f9f6 258 return -1;
andrewboyson 0:09f915e6f9f6 259 }
andrewboyson 0:09f915e6f9f6 260 return 0;
andrewboyson 0:09f915e6f9f6 261 }
andrewboyson 0:09f915e6f9f6 262 int isTimeout()
andrewboyson 0:09f915e6f9f6 263 {
andrewboyson 0:09f915e6f9f6 264 static Timer receiveTimer;
andrewboyson 0:09f915e6f9f6 265
andrewboyson 0:09f915e6f9f6 266 if (state == IDLE)
andrewboyson 0:09f915e6f9f6 267 {
andrewboyson 0:09f915e6f9f6 268 receiveTimer.stop();
andrewboyson 0:09f915e6f9f6 269 receiveTimer.reset();
andrewboyson 0:09f915e6f9f6 270 }
andrewboyson 0:09f915e6f9f6 271 else
andrewboyson 0:09f915e6f9f6 272 {
andrewboyson 0:09f915e6f9f6 273 receiveTimer.start();
andrewboyson 0:09f915e6f9f6 274 if (receiveTimer.read_ms() > RECV_TIMEOUT_MS) return true;
andrewboyson 0:09f915e6f9f6 275 }
andrewboyson 0:09f915e6f9f6 276 return false;
andrewboyson 0:09f915e6f9f6 277 }
andrewboyson 0:09f915e6f9f6 278 int EspMain()
andrewboyson 0:09f915e6f9f6 279 {
andrewboyson 0:09f915e6f9f6 280
andrewboyson 0:09f915e6f9f6 281 pulseResetPin();
andrewboyson 0:09f915e6f9f6 282
andrewboyson 0:09f915e6f9f6 283 //Reset line availability one shot
andrewboyson 0:09f915e6f9f6 284 EspLineAvailable = ESP_IDLE;
andrewboyson 0:09f915e6f9f6 285 EspDataAvailable = ESP_IDLE;
andrewboyson 0:09f915e6f9f6 286
andrewboyson 0:09f915e6f9f6 287 if (isTimeout())
andrewboyson 0:09f915e6f9f6 288 {
andrewboyson 0:09f915e6f9f6 289 if (state == IN_LINE) EspLineAvailable = ESP_TIMEOUT;
andrewboyson 0:09f915e6f9f6 290 else EspDataAvailable = ESP_TIMEOUT;
andrewboyson 0:09f915e6f9f6 291 state = IDLE;
andrewboyson 0:09f915e6f9f6 292 return 0;
andrewboyson 0:09f915e6f9f6 293 }
andrewboyson 0:09f915e6f9f6 294
andrewboyson 0:09f915e6f9f6 295 //Handle any incoming characters
andrewboyson 3:accba7e07a0d 296 int c = UartRecvPull();
andrewboyson 0:09f915e6f9f6 297 if (c != EOF)
andrewboyson 0:09f915e6f9f6 298 {
andrewboyson 0:09f915e6f9f6 299 LogPush(c);
andrewboyson 0:09f915e6f9f6 300 int r = handleCharacter(c); //This will set the EspAvailable one-shots
andrewboyson 0:09f915e6f9f6 301 if (r) return -1;
andrewboyson 0:09f915e6f9f6 302 }
andrewboyson 0:09f915e6f9f6 303
andrewboyson 0:09f915e6f9f6 304 return 0;
andrewboyson 0:09f915e6f9f6 305 }
andrewboyson 0:09f915e6f9f6 306
andrewboyson 0:09f915e6f9f6 307
andrewboyson 0:09f915e6f9f6 308