A library to operate the ESP8266

Dependents:   ESP8266_MDM_LIB

ESP8266_mdm.cpp

Committer:
epgmdm
Date:
2017-05-23
Revision:
0:011fdf85bfc8

File content as of revision 0:011fdf85bfc8:

/**
 *@section DESCRIPTION
 * ESP8266_mdm  Library
 * This sets up the ESP8266 as a server or client.
 * It detect \r\n sequence from the ESP8266 to chunk the response into lines. This then drives a state machine.
 *@section LICENSE
 * Copyright (c) 2016, Malcolm McCulloch
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * @file "ESP8266_mdm.cpp"
 */
#include "ESP8266_mdm.h"

// *********************
// * Protected variables: *
// *********************
char* ESP8266_mdm::startCmnds[10]= {
    "AT",
    "AT",
    "AT",
    "AT+RST",
    "AT+CWMODE=1",
    "AT+CWJAP=\"epgmdm\",\"3F7540BC59\"",
    "AT+CIFSR",
    "AT+CIPMUX=1",
    "AT+CIPSERVER=1,8080",
    "AT+CIPSEND=0,"
};
char* ESP8266_mdm::startResp[10]= {
    "OK",
    "OK",
    "OK",
    "OK",
    "WIFI GOT IP",
    "OK",
    "OK",
    "+CIFSR:STAIP",
    "OK",
    "+IPD"
};

int ESP8266_mdm::startMaxState=7;

// *********************
// * Public functions: *
// *********************

ESP8266_mdm::ESP8266_mdm(RawSerial *esp, int server, RawSerial *pc, PinName rstPn):esp(esp),server(server),pc(pc),rstPn(rstPn)
{
    reset = new DigitalOut(rstPn,1);
    esp->baud(115200);
    esp->attach(callback(this, &ESP8266_mdm::dev_recv));
    reset->write(0);
    // Init variables
    buffer=(char *)calloc(BUFF_SIZE,1);
    bufferPnt=0;
    ready=0;
    state=0;
    // Create hardware
    last = new Timer();
       

    //esp->attach(this,&ESP8266_mdm::dev_recv, Serial::RxIrq);
    //
    // Setting up interrupts
    //
    INFO("Reseting");
    wait(1.5);
    reset->write(1);
    pc->printf("Start up\n\r");
    wait(2.0);
    esp->printf("AT\r\n");

    INFO("Starting up v5");

    // Startup
    command = startCmnds;
    responseRequired = startResp;
    maxState = startMaxState;
    timeOut=11;
    DBG("Start Do Loop");
    doLoop(0);
    DBG ("DONE");
    while(1);

}

// *********************
// * Protected functions: *
// *********************

/**
* Device has received a byte
*/
void ESP8266_mdm::dev_recv()
{
    char c;
    if(bufferPnt==0) {
        memset(buffer,0,BUFF_SIZE);
    }
    while(esp->readable()) {
        c = (char)esp->getc();
//if (state>=maxState){
        pc->putc(c);
//  }

        buffer[bufferPnt]=c;
        bufferPnt++;
        if (bufferPnt>1024) {
            ready=1;
        }
        if ((c==0x0a)||(c==0x0d)) {
            ready=1;
        } else if (c==0x0a) {
            if (bufferPnt>1) {
                if (buffer[bufferPnt -2]==0x0d) {
                    ready=1;
                    break;
                }
            }
        }
        if (!esp->readable()) {
            wait_us(100);
        }
    }
}

/**
* Checks if pattern is in test. Returns 1 for true, 0 for no. -1 if busy. -2 ERROR
*
*/
int ESP8266_mdm::OKResponse(char *test, const char *pattern)
{

    char *p= strstr(test,pattern);
    if (p!=NULL) {
        return 1;
    }
    p= strstr(test,"busy");
    if (p!=NULL) {
        return -1;
    }
    p= strstr(test,"ERROR");
    if (p!=NULL) {
        return -2;
    }
    return 0;
}
/**
* Loops through until state = maxState;
*/
void ESP8266_mdm::doLoop(int initState)
{
    int resp;
    state = initState;
//   last->reset();
//  last->start();
    DBG("[%d] next %s : Waiting for %s",state,command[state],responseRequired[state]);

    while (1) {
        //   printf(" {t %d}", *last);
        // Timeout code
        /*  if ((*last)>timeOut){
              WARN("Timeout on [%d] next %s : Waiting for %s",state,command[state],responseRequired[state]);
              last->reset();
              if (state>0) {
                  esp->printf("%s\r\n",command[state-1]);
              } else {
                  esp->printf("%s\r\n",command[state]);
              }

          }
          */
        if (ready) {
            ready=0;
            last->reset();
            bufferPnt=0;
            printf("<%s>\r\n",buffer);
            DBG("[%d] next %s : Waiting for %s",state,command[state],responseRequired[state]);
            resp=OKResponse(buffer,responseRequired[state]);
            switch (resp) {
                case 0: { // not yet
                    break;
                }
                case 1: { //Yes
                    esp->printf("%s\r\n",command[state]);
                    state++;
                    break;
                }
                case -1: { // busy
                    if (state>0) {
                        esp->printf("%s\r\n",command[state-1]);
                    } else {
                        esp->printf("%s\r\n",command[state]);
                    }
                    break;
                }
                case -2: { //ERROR
                    esp->printf("AT\r\n");
                    wait(1);
                    if (state>0) {
                        esp->printf("%s\r\n",command[state-1]);
                    } else {
                        esp->printf("%s\r\n",command[state]);
                    }
                    break;
                }
            } // switch
        } // if
    } // while
    last->stop();
}