Backing up an unused program in case of future need

Dependencies:   mbed

Revision:
0:09f915e6f9f6
Child:
2:06fa34661f19
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/esp.cpp	Wed Apr 13 09:21:02 2016 +0000
@@ -0,0 +1,344 @@
+#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;
+}
+
+
+