grove_esp8266

Revision:
0:0ac7892e440f
diff -r 000000000000 -r 0ac7892e440f grove_esp8266.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/grove_esp8266.cpp	Tue Jun 09 10:18:06 2015 +0000
@@ -0,0 +1,346 @@
+
+
+#include "suli2.h"
+#include "grove_esp8266.h"
+
+
+
+//local functions
+static void _uart_rx_callback(void);
+static bool esp8266_send_cmd(UART_T *uart, char *command, char *content, unsigned int timeout);
+__weak static void esp8266_callback(char *msg, unsigned int len);
+
+
+//local variables
+static char content_buffer[CONTENT_BUF_LEN];
+static char rx_buf[RX_BUF_LEN];
+static unsigned int rx_buf_ptr = 0;//point to the next unused char of rx_buf
+static char cmd[70];
+static char cmd_buf[70];
+static char *WaitForAnswer_cmd_Buffer;
+static char *WaitForAnswer_ans_Buffer;
+static char *WaitForAnswer_data_Buffer;
+static ESP8266_RecvStateMachine recv_machine = RECV_DATA;
+static bool flag_recved_cmd = false;
+static bool flag_recved_end = false;
+static bool flag_send_ok = false;
+
+static UART_T *_uart;
+static user_cb_fun_ptr user_cb_fun;
+EVENT_T event_esp8266;
+
+void grove_esp8266_init(UART_T *uart, int pintx, int pinrx)
+{
+    suli_uart_init(uart, pintx, pinrx, 115200);
+}
+
+bool grove_esp8266_write_setup(UART_T *uart)
+{
+    memset((void *)rx_buf, 0, RX_BUF_LEN);
+    memset((void *)content_buffer, 0, CONTENT_BUF_LEN);
+    _uart = uart;
+    suli_uart_rx_event_attach(uart, (cb_fun_ptr)&_uart_rx_callback);
+    grove_esp8266_write_setcbfun(esp8266_callback);
+    
+    return true;
+}
+
+void grove_esp8266_write_setcbfun(user_cb_fun_ptr fun)
+{
+    user_cb_fun = fun;
+}
+
+bool grove_esp8266_attach_event_handler(CALLBACK_T handler)
+{
+    suli_event_init(&event_esp8266, handler);
+//    pinMode(13, INPUT_PULLUP);
+//    attachInterrupt(13, _trigger, FALLING);
+    return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+bool grove_esp8266_read_getversion(UART_T *uart)
+{
+    //read version information
+    while(esp8266_send_cmd(uart, (char*)"AT+GMR", content_buffer, 200) != true)
+    {
+        printf("try again\r\n");
+        wait(0.5);
+    }
+    printf("Version: %s\r\n", content_buffer);
+    
+    return true;
+}
+
+bool grove_esp8266_write_joinwifi(UART_T *uart, char *ssid, char *pwd)
+{
+    //set to station mode
+    printf("set mode to STATION\r\n");
+    wait(0.1);
+    while(esp8266_send_cmd(uart, (char*)"AT+CWMODE=1", content_buffer, 200) != true)
+    {
+        printf("try again\r\n");
+        wait(0.5);
+    }
+    printf("OK\r\n\r\n");
+    
+    //join router
+    printf("joining specified router\r\n");
+    wait(0.1);
+    while(esp8266_send_cmd(uart, (char*)"AT+CWJAP=\"stu.se.private\",\"depot0510se\"", content_buffer, 5000) != true)
+    {
+        printf("try again\r\n");
+        wait(0.5);
+    }
+    printf("joined\r\n");
+    wait(0.1);
+    while(esp8266_send_cmd(uart, (char*)"AT+CWJAP?", content_buffer, 1000) != true)
+    {
+        printf("try again\r\n");
+        wait(0.5);
+    }
+    printf("joined indeed\r\n\r\n");
+    
+    return true;
+}
+
+bool grove_esp8266_write_socketasclient(UART_T *uart, char *ip, unsigned int port)
+{
+    //enable mux connection
+    printf("enable mux connection\r\n");
+    wait(0.1);
+    while(esp8266_send_cmd(uart, (char*)"AT+CIPMUX=1", content_buffer, 200) != true)
+    {
+        printf("try again\r\n");
+        wait(0.5);
+    }
+    printf("OK\r\n\r\n");
+    
+    //connect to tcp server
+    printf("connect to tcp server\r\n");
+    wait(0.1);
+    while(esp8266_send_cmd(uart, (char*)"AT+CIPSTART=4,\"TCP\",\"192.168.21.159\",6320", content_buffer, 2000) != true)
+    {
+        printf("try again\r\n");
+        wait(0.5);
+    }
+    printf("OK\r\n\r\n");
+    
+    return true;
+}
+
+bool grove_esp8266_read_aplist(UART_T *uart)
+{
+    //list all AP
+    printf("list all AP around\r\n");
+    wait(0.1);
+    while(esp8266_send_cmd(uart, (char*)"AT+CWLAP", content_buffer, 10000) != true)
+    {
+        printf("try again\r\n");
+        wait(0.5);
+    }
+    printf("%s\r\n", content_buffer);
+    
+    return true;
+}
+
+/*
+function: internal function, uart callback
+*/
+static void _uart_rx_callback(void)
+{
+    unsigned int payload_len, header_len;
+    unsigned int port;
+    int res;
+    char *payload_str;
+    
+    while(suli_uart_readable(_uart))
+    {
+        if(rx_buf_ptr < RX_BUF_LEN - 2)
+        {
+            rx_buf[rx_buf_ptr++] = suli_uart_read(_uart);
+        }
+    }
+    //receiving state machine after recved all data for now
+    switch(recv_machine)
+    {
+        case RECV_DATA:
+            WaitForAnswer_data_Buffer = strstr(rx_buf, "\r\n+IPD");//check the "+IPD" response
+            if(WaitForAnswer_data_Buffer != NULL)//user data recved
+            {
+                res = sscanf(rx_buf,"\r\n+IPD,%d,%d:", &port, &payload_len);
+                payload_str = strtok(rx_buf, ":");
+                header_len = strlen(payload_str) + 1;
+                if((res == 2) && (payload_len == rx_buf_ptr - header_len))
+                {
+                    memcpy(content_buffer, rx_buf + header_len, payload_len);
+                    user_cb_fun(content_buffer, payload_len);
+                    memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv
+                    rx_buf_ptr = 0;
+                }
+            }
+            break;
+        case RECV_CMD:
+            WaitForAnswer_cmd_Buffer = strstr(rx_buf, cmd_buf);//check the cmd
+            if(WaitForAnswer_cmd_Buffer != NULL)//right cmd
+            {
+                flag_recved_cmd = true;
+                recv_machine = RECV_END;
+            }
+            break;
+        case RECV_END:
+            //check the "OK" response
+            WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nOK\r\n");
+            if(WaitForAnswer_ans_Buffer != NULL)//"OK"recved
+            {
+                //recv cmd response
+                flag_recved_end = true;
+            }
+            //check the "ERROR" response
+            WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nERROR\r\n");
+            if(WaitForAnswer_ans_Buffer != NULL)//"ERROR"recved
+            {
+                flag_recved_end = true;
+            }
+            //check the "SEND OK" response
+            WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nSEND OK\r\n");
+            if(WaitForAnswer_ans_Buffer != NULL)//"SEND OK"recved
+            {
+                flag_send_ok = true;
+            }
+            break;
+        default:
+            break;
+    }
+}
+
+/*
+function: send data through ESP8266
+const char *command: AT command to be send
+char *content: returned data from ESP8266
+unsigned int timeout: timeout
+*/
+static bool esp8266_send_cmd(UART_T *uart, char *command, char *content, unsigned int timeout)
+{
+    volatile uint32_t TxWaitForResponse_TimeStmp;
+    unsigned int len;
+    
+    //reset flags and state machine
+    recv_machine = RECV_CMD;
+    flag_recved_cmd = false;
+    flag_recved_end = false;
+    //clear the buffer
+    memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv
+    rx_buf_ptr = 0;
+    //save the cmd just sent
+    strcpy(cmd_buf, command);
+    sprintf(cmd, "%s\r\n", command);
+    //send cmd
+    suli_uart_write_bytes(_uart, (uint8_t*)cmd, strlen(cmd));
+    
+    //wait for response
+    TxWaitForResponse_TimeStmp = millis();
+    while(millis() - TxWaitForResponse_TimeStmp < timeout)//timeout control
+    {
+        if(flag_recved_cmd == true)
+        {
+            if(flag_recved_end == true)
+            {
+                WaitForAnswer_ans_Buffer = strstr(WaitForAnswer_cmd_Buffer, "\r\nOK\r\n");//check the "OK" response
+                if(WaitForAnswer_ans_Buffer != NULL)
+                {
+                    len = WaitForAnswer_ans_Buffer - WaitForAnswer_cmd_Buffer - strlen(cmd_buf) - 3;
+                    memset(content, 0, CONTENT_BUF_LEN);
+                    memcpy(content, WaitForAnswer_ans_Buffer - len, len);
+                    memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv
+                    rx_buf_ptr = 0;
+                    recv_machine = RECV_DATA;
+                    return true;
+                }
+            }
+        }
+        wait(0.1);
+    }
+    memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv
+    rx_buf_ptr = 0;
+    recv_machine = RECV_DATA;
+    return false;
+}
+
+/*
+function: send data through ESP8266
+char *data: data will be send
+unsigned int len: data length in byte
+*/
+bool grove_esp8266_write_msg(UART_T *uart, char *msg, unsigned int len)
+{
+    volatile uint32_t TxWaitForResponse_TimeStmp;
+    unsigned ptr = 0;
+    
+    if(len > 2048)
+        return false;
+    
+    //send cmd
+    sprintf(cmd, "AT+CIPSEND=4,%d", len);
+    if(esp8266_send_cmd(uart, cmd, content_buffer, 200) != true)
+    {
+        return false;
+    }
+    //send user data
+    while(len--)
+    {
+        suli_uart_write(uart, msg[ptr++]);
+    }
+    
+    //reset flags and state machine
+    recv_machine = RECV_END;
+    flag_recved_cmd = false;
+    flag_recved_end = false;
+    flag_send_ok = false;
+    
+    //wait for response
+    TxWaitForResponse_TimeStmp = millis();
+    while(millis() - TxWaitForResponse_TimeStmp < 500)//timeout control
+    {
+        if(flag_send_ok == true)
+        {
+            memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv
+            rx_buf_ptr = 0;
+            recv_machine = RECV_DATA;
+            return true;
+        }
+        wait(0.01);
+    }
+    memset(rx_buf, 0, rx_buf_ptr);//clear the buffer for next recv
+    rx_buf_ptr = 0;
+    recv_machine = RECV_DATA;
+    return false;
+}
+
+/*
+callback function when a piece of message arrived
+this is a WEAK declaration
+*/
+__weak static void esp8266_callback(char *msg, unsigned int len)
+{
+    msg[len] = '\0';
+    printf("esp8266 driver recv%3d bytes: %s\r\n", len, msg);
+    printf("user can add his own callback function instead\r\n");
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+