EMW3162 driver for NSAPI

Dependents:   HelloEMW3162

Fork of emw3162-driver by Maggie Mei

Revision:
0:2d5090e1ceb4
Child:
2:fb6251306b21
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emw3162/EMW3162.cpp	Tue Nov 01 02:18:18 2016 +0000
@@ -0,0 +1,240 @@
+/* ESP8266 Example
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EMW3162.h"
+
+ESP8266::ESP8266(PinName tx, PinName rx, bool debug)
+    : _serial(tx, rx, 1024), _parser(_serial)
+    , _packets(0), _packets_end(&_packets)
+{
+    _serial.baud(115200);
+    _parser.debugOn(debug);
+}
+
+bool ESP8266::startup(void)
+{
+    bool success = reset("FACTORY");
+
+    _parser.oob("+EVENT=SOCKET", this, &ESP8266::_packet_handler);
+
+    return success;
+}
+
+bool ESP8266::reset(const char *reset)
+{
+    for (int i = 0; i < 2; i++) {
+        if (_parser.send("AT+%s", reset)
+            && _parser.recv("+OK")) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool ESP8266::dhcp(bool enabled)
+{
+    return _parser.send("AT+DHCP=%s", enabled ? "ON":"OFF")
+        && _parser.recv("+OK");
+}
+
+bool ESP8266::connect(const char *ap, const char *passPhrase)
+{
+    return _parser.send("AT+WSTA=%s,%s", ap, passPhrase)
+        && _parser.recv("+OK")
+        && _parser.send("AT+EVENT=ON")
+        && _parser.recv("+OK")
+        && _parser.recv("+EVENT=WIFI_LINK,STATION_UP");
+}
+
+bool ESP8266::disconnect(void)
+{
+    
+    return _parser.send("AT+WLANF=STA,OFF")
+        && _parser.recv("+OK")
+        && _parser.recv("+EVENT=WIFI_LINK,STATION_DOWN")
+        && _parser.send("AT+EVENT=OFF")
+        && _parser.recv("+OK");
+}
+
+const char *ESP8266::getIPAddress(void)
+{
+    if (!(_parser.send("AT+IPCONFIG")
+        && _parser.recv("%*[^,],%*[^,],%*[^,],%[^,]%*[^#]#", _ip_buffer))) {
+        return 0;
+    }
+
+    return _ip_buffer;
+}
+
+const char *ESP8266::getMACAddress(void)
+{
+    if (!(_parser.send("AT+WMAC")
+        && _parser.recv("%*[^=]=%[^#]#", _mac_buffer))) {
+        return 0;
+    }
+
+    return _mac_buffer;
+}
+
+bool ESP8266::isConnected(void)
+{
+    return getIPAddress() != 0;
+}
+
+int ESP8266::open(const char *type, int id, const char* addr, int port)
+{
+    int state1 = 0, state2 = 0;
+    state1 = _parser.send("AT+CON1=%s,%d,%d,%s", type, id, port, addr)
+        && _parser.recv("+OK")
+        && _parser.send("AT+SAVE")
+        && _parser.recv("+OK")
+        && reset("REBOOT")
+        && _parser.recv("+EVENT=REBOOT");
+    
+    wait(3);
+    char conType[10];       // UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST
+    int socketId;           // UDP/TCP socket id
+    
+    // Receive wifi connect event
+    state2 = _parser.recv("+EVENT=WIFI_LINK,STATION_UP")
+        && _parser.recv("+EVENT=%[^,],CONNECT,%d", conType, &socketId);
+    
+    if (state1 && state2)
+        return socketId;
+    else
+        return -1;
+}
+
+bool ESP8266::send(int id, const void *data, uint32_t amount)
+{
+    //May take a second try if device is busy
+    for (unsigned i = 0; i < 2; i++) {
+        if (_parser.send("AT+SSEND=%d,%d", id, amount)
+            && _parser.recv(">")
+            && _parser.write((char*)data, (int)amount) >= 0
+            && _parser.recv("+OK")) {
+            //wait(3);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void ESP8266::_packet_handler()
+{
+    int id;
+    uint32_t amount;
+
+    // parse out the packet
+    if (!_parser.recv(",%d,%d,", &id, &amount)) {
+        return;
+    }
+
+    struct packet *packet = (struct packet*)malloc(
+            sizeof(struct packet) + amount);
+    if (!packet) {
+        return;
+    }
+
+    packet->id = id;
+    packet->len = amount;
+    packet->next = 0;
+
+    if (!(_parser.read((char*)(packet + 1), amount))) {
+        free(packet);
+        return;
+    }
+
+    // append to packet list
+    *_packets_end = packet;
+    _packets_end = &packet->next;
+}
+
+int32_t ESP8266::recv(int id, void *data, uint32_t amount)
+{
+    while (true) {
+        // check if any packets are ready for us
+        for (struct packet **p = &_packets; *p; p = &(*p)->next) {
+            if ((*p)->id == id) {
+                struct packet *q = *p;
+
+                if (q->len <= amount) { // Return and remove full packet
+                    memcpy(data, q+1, q->len);
+
+                    if (_packets_end == &(*p)->next) {
+                        _packets_end = p;
+                    }
+                    *p = (*p)->next;
+
+                    uint32_t len = q->len;
+                    free(q);
+                    return len;
+                } else { // return only partial packet
+                    memcpy(data, q+1, amount);
+
+                    q->len -= amount;
+                    memmove(q+1, (uint8_t*)(q+1) + amount, q->len);
+
+                    return amount;
+                }
+            }
+        }
+
+        // Wait for inbound packet
+        if (!_parser.recv("#")) {
+            return -1;
+        }
+    }
+}
+
+bool ESP8266::close(int id)
+{
+    //May take a second try if device is busy
+    for (unsigned i = 0; i < 2; i++) {
+        if (_parser.send("AT+CONF=1,OFF")
+            && _parser.recv("+OK")) {
+            char conType[10];  // Used for UDP/TCP connection type: SERVER, CLIENT, BROADCAST, UNICAST
+            int socketId;      // Used for UDP/TCP socket id
+            
+            _parser.recv("+EVENT=%[^,],DISCONNECT,%d", conType, &socketId);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void ESP8266::setTimeout(uint32_t timeout_ms)
+{
+    _parser.setTimeout(timeout_ms);
+}
+
+bool ESP8266::readable()
+{
+    return _serial.readable();
+}
+
+bool ESP8266::writeable()
+{
+    return _serial.writeable();
+}
+
+void ESP8266::attach(Callback<void()> func)
+{
+    _serial.attach(func);
+}