![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Backing up an unused program in case of future need
esp.cpp
- Committer:
- andrewboyson
- Date:
- 2016-04-23
- Revision:
- 3:accba7e07a0d
- Parent:
- 2:06fa34661f19
- Child:
- 4:e076884ef8bd
File content as of revision 3:accba7e07a0d:
#include "mbed.h" #include "log.h" #include "esp.h" #include "io.h" #include "cfg.h" #include "uart.h" #define RECV_TIMEOUT_MS 5000 //State #define LINE_LENGTH 256 #define IDLE 0 #define IN_LINE 1 #define IPD_WAIT_START 2 #define IPD_READ 3 #define SEND_DATA 4 static int state; //Initialised in init //Solicited responses received //============================ #define LINE_LENGTH 256 int EspLineAvailable; //Initialised in init; can be one of the values defined in esp.h char EspLine[LINE_LENGTH]; static char* pLineNext; //Initialised in init to EspLine #define RESP_LENGTH 256 char EspResp[RESP_LENGTH]; static char* pRespNext; //Initialised at each request to EspResp static int addRawCharToBuffer(char* pBuff, char** ppNext, int len, char c) { // if *ppNext is at the last position in pBuff (pBuff+len-1) then we are full and should stop if (*ppNext >= pBuff + len - 1) return -1; // Put the char into *ppNext and NUL into *ppNext + 1. **ppNext = c; ++*ppNext; **ppNext = '\0'; return 0; } static int addCharToBuffer(char* pBuff, char** ppNext, int len, char c, int includeCrLf) { if (!pBuff) return -1; switch (c) { case '\0': if (addRawCharToBuffer(pBuff, ppNext, len, '\\')) return -1; if (addRawCharToBuffer(pBuff, ppNext, len, '0' )) return -1; //This is the character zero '0' not NUL '\0' break; case '\r': case '\n': if (includeCrLf && addRawCharToBuffer(pBuff, ppNext, len, c)) return -1; break; default: if (addRawCharToBuffer(pBuff, ppNext, len, c)) return -1; break; } return 0; } static int addChar(char c) { int r = addCharToBuffer(EspLine, &pLineNext, LINE_LENGTH, c, false); addCharToBuffer(EspResp, &pRespNext, RESP_LENGTH, c, true ); return r; } //Unsolicited ntp or http requests //================================ void *EspIpdBuffer[4]; int EspIpdBufferLen[4]; int EspIpdReserved[4]; int EspIpdLength; int EspIpdId; int EspDataAvailable; //Stuff to send //============= int EspLengthToSend; const void * EspDataToSend; void EspSendStringF(char *fmt, ...) { va_list argptr; va_start(argptr, fmt); int size = vsnprintf(NULL, 0, fmt, argptr); char snd[size + 1]; vsprintf(snd, fmt, argptr); va_end(argptr); EspSendString(snd); } void EspSendString(char* p) { //Reset the response buffer pRespNext = EspResp; *pRespNext = '\0'; //Send the string while(*p) UartSendPush(*p++); } void EspSendData(int length, const void * snd) { const char* p = (char*)snd; const char* e = (char*)snd + length; while (p < e) UartSendPush(*p++); } //Reset ESP8266 zone #define RESET_TIME_MS 250 static DigitalOut espRunOnHighResetOnLow(p26); int reset; //Set to 1 by EspReset (and hence EspInit); set to 0 by EspReleasefromReset void EspResetAndStop() { reset = true; UartReset(); pLineNext = EspLine; *pLineNext = '\0'; pRespNext = EspResp; *pRespNext = '\0'; EspLengthToSend = 0; EspDataToSend = NULL; state = IDLE; } void EspReleaseFromReset(void) { reset = false; } void pulseResetPin() { static Timer resetTimer; if (reset) { resetTimer.stop(); resetTimer.reset(); espRunOnHighResetOnLow = 0; } else { resetTimer.start(); if (resetTimer.read_ms() > RESET_TIME_MS) { resetTimer.stop(); espRunOnHighResetOnLow = 1; } } } //General commands int EspInit() { EspResetAndStop(); UartBaud(CfgBaud); for (int i = 0; i < 4; i++) { EspIpdBuffer[i] = NULL; EspIpdBufferLen[i] = 0; EspIpdReserved[i] = 0; } return 0; } //Main loop zone int handleCharacter(char c) { //Static variables. Initialised on first load. static char ipdHeader[20]; static char * pipdHeader; //Set to ipdHeader when a '+' is received static int bytesRcvd; //Set to 0 when the ':' following the +IPD is received static void * pData; //Set to EspIpdBuffer[EspIpdId] when the ':' following the +IPD is received switch(state) { case IDLE: if (c == '+') { pipdHeader = ipdHeader; *pipdHeader = 0; state = IPD_WAIT_START; } else if (c == '>') { state = SEND_DATA; } else { pLineNext = EspLine; *pLineNext = 0; int r = addChar(c); if (r) { EspLineAvailable = ESP_OVERFLOW; state = IDLE; } else { state = IN_LINE; } } break; case IN_LINE: if (c == '\n') { EspLineAvailable = ESP_AVAILABLE; state = IDLE; } else { int r = addChar(c); if (r) { EspLineAvailable = ESP_OVERFLOW; state = IDLE; } } break; case IPD_WAIT_START: if (pipdHeader == ipdHeader && c != 'I') //If the first character after the '+' is not 'I' then start a line instead { pLineNext = EspLine; addChar('+'); addChar(c); state = IN_LINE; } else { *pipdHeader++ = c; *pipdHeader = 0; if (c == ':') { sscanf(ipdHeader, "IPD,%d,%d:", &EspIpdId, &EspIpdLength); bytesRcvd = 0; pData = EspIpdBuffer[EspIpdId]; state = IPD_READ; } } break; case IPD_READ: bytesRcvd++; if (bytesRcvd <= EspIpdBufferLen[EspIpdId]) { *(char *)pData = c; pData = (char *)pData + 1; } if (bytesRcvd == EspIpdLength) { if (bytesRcvd <= EspIpdBufferLen[EspIpdId]) EspDataAvailable = ESP_AVAILABLE; else EspDataAvailable = ESP_OVERFLOW; state = IDLE; } break; case SEND_DATA: EspSendData(EspLengthToSend, EspDataToSend); state = IDLE; break; default: LogF("Unknown state %d\n\r", state); return -1; } return 0; } int isTimeout() { static Timer receiveTimer; if (state == IDLE) { receiveTimer.stop(); receiveTimer.reset(); } else { receiveTimer.start(); if (receiveTimer.read_ms() > RECV_TIMEOUT_MS) return true; } return false; } int EspMain() { pulseResetPin(); //Reset line availability one shot EspLineAvailable = ESP_IDLE; EspDataAvailable = ESP_IDLE; if (isTimeout()) { if (state == IN_LINE) EspLineAvailable = ESP_TIMEOUT; else EspDataAvailable = ESP_TIMEOUT; state = IDLE; return 0; } //Handle any incoming characters int c = UartRecvPull(); if (c != EOF) { LogPush(c); int r = handleCharacter(c); //This will set the EspAvailable one-shots if (r) return -1; } return 0; }