![](/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-13
- Revision:
- 0:09f915e6f9f6
- Child:
- 2:06fa34661f19
File content as of revision 0:09f915e6f9f6:
#include "mbed.h" #include "log.h" #include "esp.h" #include "io.h" #include <stdarg.h> #define RECV_TIMEOUT_MS 5000 static RawSerial esp(p9, p10); // tx, rx //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 int addToLine(char c) { if (pLineNext >= EspLine + LINE_LENGTH) return -1; switch (c) { case 0: *pLineNext = '\\'; pLineNext++; *pLineNext = '0'; pLineNext++; break; case '\r': case '\n': break; default: *pLineNext = c; pLineNext++; break; } *pLineNext = 0; return 0; } //Unsolicited ntp or http requests //================================ void *EspIpdBuffer[4]; int EspIpdBufferLen[4]; int EspIpdReserved[4]; int EspIpdLength; int EspIpdId; int EspDataAvailable; //Wrap around buffers //=================== #define RECV_BUFFER_LENGTH 1024 #define SEND_BUFFER_LENGTH 1024 static char recvbuffer[RECV_BUFFER_LENGTH]; static char sendbuffer[SEND_BUFFER_LENGTH]; static char* pRecvPush; //Initialised in init static char* pRecvPull; //Initialised in init static char* pSendPush; //Initialised in init static char* pSendPull; //Initialised in init static void incrementPushPullPointer(char** pp, char* buffer, int bufferLength) { (*pp)++; //increment the pointer by one if (*pp == buffer + bufferLength) *pp = buffer; //if the pointer is now beyond the end then point it back to the start } static void recvpush(void) //Called by the esp data received interrupt { while (esp.readable()) { int c = esp.getc(); *pRecvPush = c; incrementPushPullPointer(&pRecvPush, recvbuffer, RECV_BUFFER_LENGTH); } } static int recvpull(void) //Called every scan. Returns the next byte or EOF if no more are available { if (pRecvPull == pRecvPush) return EOF; char c = *pRecvPull; incrementPushPullPointer(&pRecvPull, recvbuffer, RECV_BUFFER_LENGTH); return c; } static void sendpush(char c) //Called whenever something needs to be sent { *pSendPush = c; incrementPushPullPointer(&pSendPush, sendbuffer, SEND_BUFFER_LENGTH); } static int sendpull(void) //Called every scan. Returns the next byte or EOF if no more are available { if (pSendPull == pSendPush) return EOF; char c = *pSendPull; incrementPushPullPointer(&pSendPull, sendbuffer, SEND_BUFFER_LENGTH); return c; } //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) { while(*p) sendpush(*p++); } void EspSendData(int length, const void * snd) { const char* p = (char*)snd; const char* e = (char*)snd + length; while (p < e) sendpush(*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; pRecvPush = recvbuffer; pRecvPull = recvbuffer; pSendPush = sendbuffer; pSendPull = sendbuffer; pLineNext = EspLine; *pLineNext = 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 void EspInit() { EspResetAndStop(); esp.attach(&recvpush, Serial::RxIrq); esp.baud(BAUD); for (int i = 0; i < 4; i++) { EspIpdBuffer[i] = NULL; EspIpdBufferLen[i] = 0; EspIpdReserved[i] = 0; } } void EspBaud(int baud) { esp.baud(baud); } //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 = addToLine(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 = addToLine(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; addToLine('+'); addToLine(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; } void sendAnyData() { while(esp.writeable()) { int c = sendpull(); if (c == EOF) break; esp.putc(c); } } 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() { sendAnyData(); 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 = recvpull(); if (c != EOF) { LogPush(c); int r = handleCharacter(c); //This will set the EspAvailable one-shots if (r) return -1; } return 0; }