AT Parser and bufferedSerial based SPWF library

Dependencies:   ATParser

Dependents:   X_NUCLEO_IDW01M1v2

Fork of SPWF01SA by ST Expansion SW Team

Files at this revision

API Documentation at this revision

Comitter:
mridup
Date:
Thu Jun 30 06:04:46 2016 +0000
Child:
1:becf69a794fb
Commit message:
first version of AT parser based SPWF library.

Changed in this revision

ATParser.lib Show annotated file Show diff for this revision Revisions of this file
SPWFSA01.cpp Show annotated file Show diff for this revision Revisions of this file
SPWFSA01.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ATParser.lib	Thu Jun 30 06:04:46 2016 +0000
@@ -0,0 +1,1 @@
+https://developer.mbed.org/teams/components/code/ATParser/#6b8190f55d83
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SPWFSA01.cpp	Thu Jun 30 06:04:46 2016 +0000
@@ -0,0 +1,297 @@
+/* SPWFInterface 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 "SPWFSA01.h"
+
+#define SPWFSA01_CONNECT_TIMEOUT 15000
+#define SPWFSA01_SEND_TIMEOUT    500
+#define SPWFSA01_RECV_TIMEOUT    1000//some commands like AT&F/W takes some time to get the result back!
+#define SPWFSA01_MISC_TIMEOUT    500
+
+SPWFSA01::SPWFSA01(PinName tx, PinName rx, bool debug)
+    : _serial(tx, rx, 1024), _parser(_serial),
+      _wakeup(PC_8, PIN_INPUT, PullNone, 0), _reset(PC_12, PIN_INPUT, PullNone, 1)
+      //Pin PC_8 is wakeup pin
+      //Pin PA_12 is reset pin
+{
+    _serial.baud(115200);
+    _reset.output();
+    _wakeup.output();
+    _parser.debugOn(debug);
+}
+
+bool SPWFSA01::startup(int mode)
+{
+    setTimeout(SPWFSA01_RECV_TIMEOUT);
+    
+    /*Test module before reset*/
+    waitSPWFReady();
+    /*Reset module*/
+    reset();
+     
+    /*set local echo to 0*/
+    if(!(_parser.send("AT+S.SCFG=localecho1,%d", 0) && _parser.recv("OK"))) 
+        {
+            printf("\r\nerror local echo set\n");
+            return false;
+        }   
+    /*reset factory settings*/
+    if(!(_parser.send("AT&F") && _parser.recv("OK"))) 
+        {
+            printf("\r\nerror AT&F\n");
+            return false;
+        }
+
+    /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
+    if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", mode) && _parser.recv("OK")))
+        {
+            printf("\r\nerror wifi mode set\n");
+            return false;
+        } 
+
+    /* save current setting in flash */
+    if(!(_parser.send("AT&W") && _parser.recv("OK")))
+        {
+            printf("\r\nerror AT&W\n");
+            return false;
+        }
+        
+    /*reset again and send AT command and check for result (AT->OK)*/
+    reset();
+        
+    return true;    
+}
+
+bool SPWFSA01::hw_reset(void)
+{    
+    /* reset the pin PC12 */  
+    _reset.write(0);
+    wait_ms(200);
+    _reset.write(1); 
+    wait_ms(100);
+    return 1;
+}
+
+bool SPWFSA01::reset(void)
+{
+    if(!_parser.send("AT+CFUN=1")) return false;
+    while(1) {
+        if (_parser.recv("+WIND:32:WiFi Hardware Started")) {
+            return true;
+        }
+    }
+}
+
+void SPWFSA01::waitSPWFReady(void)
+{
+    //wait_ms(200);
+    while(1) 
+        if(_parser.send("AT") && _parser.recv("OK"))
+            //till we get OK from AT command
+            //printf("\r\nwaiting for reset to complete..\n");
+            return;
+                
+}
+
+/* Security Mode
+    None          = 0, 
+    WEP           = 1,
+    WPA_Personal  = 2,
+*/
+bool SPWFSA01::connect(const char *ap, const char *passPhrase, int securityMode)
+{
+    uint32_t n1, n2, n3, n4;
+    
+    //AT+S.SCFG=wifi_wpa_psk_text,%s\r
+    if(!(_parser.send("AT+S.SCFG=wifi_wpa_psk_text,%s", passPhrase) && _parser.recv("OK"))) 
+        {
+            printf("\r\nerror pass set\n");
+            return false;
+        } 
+    //AT+S.SSIDTXT=%s\r
+    if(!(_parser.send("AT+S.SSIDTXT=%s", ap) && _parser.recv("OK"))) 
+        {
+            printf("\r\nerror ssid set\n");
+            return false;
+        }
+    //AT+S.SCFG=wifi_priv_mode,%d\r
+    if(!(_parser.send("AT+S.SCFG=wifi_priv_mode,%d", securityMode) && _parser.recv("OK"))) 
+        {
+            printf("\r\nerror security mode set\n");
+            return false;
+        } 
+    //"AT+S.SCFG=wifi_mode,%d\r"
+    /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
+    if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 1) && _parser.recv("OK")))
+        {
+            printf("\r\nerror wifi mode set\n");
+            return false;
+        }
+    //AT&W
+    /* save current setting in flash */
+    if(!(_parser.send("AT&W") && _parser.recv("OK")))
+        {
+            printf("\r\nerror AT&W\n");
+            return false;
+        }
+    //reset module
+    reset();
+    
+    while(1)
+        if((_parser.recv("+WIND:24:WiFi Up:%u.%u.%u.%u",&n1, &n2, &n3, &n4)))
+        //if((_parser.recv("+WIND:24:WiFi Up:%[^\\r]",_ip_buffer)))
+            {
+                break;
+            }
+            
+    printf("\r\nip address:%u.%u.%u.%u\n",n1, n2, n3, n4);
+        
+    return true;
+}
+
+bool SPWFSA01::disconnect(void)
+{
+    //"AT+S.SCFG=wifi_mode,%d\r"
+    /*set idle mode (0->idle, 1->STA,3->miniAP, 2->IBSS)*/
+    if(!(_parser.send("AT+S.SCFG=wifi_mode,%d\r", 0) && _parser.recv("OK")))
+        {
+            printf("\r\nerror wifi mode set\n");
+            return false;
+        }
+    //AT&W
+    /* save current setting in flash */
+    if(!(_parser.send("AT&W") && _parser.recv("OK")))
+        {
+            printf("\r\nerror AT&W\n");
+            return false;
+        }
+    //reset module
+    reset();
+    return true;
+}
+
+bool SPWFSA01::dhcp(bool enabled, int mode)
+{
+    //only 3 valid modes
+    if(mode < 0 || mode > 2) {
+        return false;
+    }
+
+    return _parser.send("AT+CWDHCP=%d,%d", enabled?1:0, mode)
+        && _parser.recv("OK");
+}
+
+
+const char *SPWFSA01::getIPAddress(void)
+{
+    uint32_t n1, n2, n3, n4;
+    
+    if (!(_parser.send("AT+S.STS=ip_ipaddr")
+        && _parser.recv("ip_ipaddr = %u.%u.%u.%u", &n1, &n2, &n3, &n4)
+        && _parser.recv("OK"))) {
+            printf("\r\ngetIPAddress error\n");
+        return 0;
+    }
+    printf("\r\nip address:%u.%u.%u.%u\n",n1, n2, n3, n4);
+    sprintf((char*)_ip_buffer,"%u.%u.%u.%u", n1, n2, n3, n4);
+
+    return _ip_buffer;
+}
+
+const char *SPWFSA01::getMACAddress(void)
+{
+    if (!(_parser.send("AT+CIFSR")
+        && _parser.recv("+CIFSR:STAMAC,\"%[^\"]\"", _mac_buffer)
+        && _parser.recv("OK"))) {
+        return 0;
+    }
+
+    return _mac_buffer;
+}
+
+bool SPWFSA01::isConnected(void)
+{
+    return getIPAddress() != 0;
+}
+
+bool SPWFSA01::open(const char *type, int id, const char* addr, int port)
+{
+    //IDs only 0-4
+    if(id > 4) {
+        return false;
+    }
+
+    return _parser.send("AT+CIPSTART=%d,\"%s\",\"%s\",%d", id, type, addr, port)
+        && _parser.recv("OK");
+}
+
+bool SPWFSA01::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+CIPSEND=%d,%d", id, amount)
+            && _parser.recv(">")
+            && _parser.write((char*)data, (int)amount) >= 0) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+int32_t SPWFSA01::recv(int id, void *data, uint32_t amount)
+{
+    uint32_t recv_amount;
+    int recv_id;
+
+    if (!(_parser.recv("+IPD,%d,%d:", &recv_id, &recv_amount)
+        && recv_id == id
+        && recv_amount <= amount
+        && _parser.read((char*)data, recv_amount)
+        && _parser.recv("OK"))) {
+        return -1;
+    }
+
+    return recv_amount;
+}
+
+bool SPWFSA01::close(int id)
+{
+    //May take a second try if device is busy
+    for (unsigned i = 0; i < 2; i++) {
+        if (_parser.send("AT+CIPCLOSE=%d", id)
+            && _parser.recv("OK")) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void SPWFSA01::setTimeout(uint32_t timeout_ms)
+{
+    _parser.setTimeout(timeout_ms);
+}
+
+bool SPWFSA01::readable()
+{
+    return _serial.readable();
+}
+
+bool SPWFSA01::writeable()
+{
+    return _serial.writeable();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SPWFSA01.h	Thu Jun 30 06:04:46 2016 +0000
@@ -0,0 +1,161 @@
+/* SPWFInterface 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.
+ */
+ 
+#ifndef SPWFSA01_H
+#define SPWFSA01_H
+ 
+#include "ATParser.h"
+ 
+/** SPWFSA01Interface class.
+    This is an interface to a SPWFSA01 module.
+ */
+class SPWFSA01
+{
+public:
+    SPWFSA01(PinName tx, PinName rx, bool debug=false);
+ 
+    /**
+    * Init the SPWFSA01
+    *
+    * @param mode mode in which to startup
+    * @return true only if SPWFSA01 has started up correctly
+    */
+    bool startup(int mode);
+ 
+    void waitSPWFReady(void);
+    /**
+    * Reset SPWFSA01
+    *
+    * @return true only if SPWFSA01 resets successfully
+    */
+    bool reset(void);
+    
+    bool hw_reset(void);
+ 
+    /**
+    * Enable/Disable DHCP
+    *
+    * @param enabled DHCP enabled when true
+    * @param mode mode of DHCP 0-softAP, 1-station, 2-both
+    * @return true only if SPWFSA01 enables/disables DHCP successfully
+    */
+    bool dhcp(bool enabled, int mode);
+ 
+    /**
+    * Connect SPWFSA01 to AP
+    *
+    * @param ap the name of the AP
+    * @param passPhrase the password of AP
+    * @param securityMode the security mode of AP (WPA/WPA2, WEP, Open)
+    * @return true only if SPWFSA01 is connected successfully
+    */
+    bool connect(const char *ap, const char *passPhrase, int securityMode);
+ 
+    /**
+    * Disconnect SPWFSA01 from AP
+    *
+    * @return true only if SPWFSA01 is disconnected successfully
+    */
+    bool disconnect(void);
+ 
+    /**
+    * Get the IP address of SPWFSA01
+    *
+    * @return null-teriminated IP address or null if no IP address is assigned
+    */
+    const char *getIPAddress(void);
+ 
+    /**
+    * Get the MAC address of SPWFSA01
+    *
+    * @return null-terminated MAC address or null if no MAC address is assigned
+    */
+    const char *getMACAddress(void);
+ 
+    /**
+    * Check if SPWFSA01 is conenected
+    *
+    * @return true only if the chip has an IP address
+    */
+    bool isConnected(void);
+ 
+    /**
+    * Open a socketed connection
+    *
+    * @param type the type of socket to open "UDP" or "TCP"
+    * @param id id to give the new socket, valid 0-4
+    * @param port port to open connection with
+    * @param addr the IP address of the destination
+    * @return true only if socket opened successfully
+    */
+    bool open(const char *type, int id, const char* addr, int port);
+ 
+    /**
+    * Sends data to an open socket
+    *
+    * @param id id of socket to send to
+    * @param data data to be sent
+    * @param amount amount of data to be sent - max 1024
+    * @return true only if data sent successfully
+    */
+    bool send(int id, const void *data, uint32_t amount);
+ 
+    /**
+    * Receives data from an open socket
+    *
+    * @param id id to receive from
+    * @param data placeholder for returned information
+    * @param amount number of bytes to be received
+    * @return the number of bytes received
+    */
+    int32_t recv(int id, void *data, uint32_t amount);
+ 
+    /**
+    * Closes a socket
+    *
+    * @param id id of socket to close, valid only 0-4
+    * @return true only if socket is closed successfully
+    */
+    bool close(int id);
+ 
+    /**
+    * Allows timeout to be changed between commands
+    *
+    * @param timeout_ms timeout of the connection
+    */
+    void setTimeout(uint32_t timeout_ms);
+ 
+    /**
+    * Checks if data is available
+    */
+    bool readable();
+ 
+    /**
+    * Checks if data can be written
+    */
+    bool writeable();
+ 
+private:
+    BufferedSerial _serial;
+    ATParser _parser;
+    DigitalInOut _wakeup;
+    DigitalInOut _reset;
+ 
+    char _ip_buffer[16];
+    char _mac_buffer[18];
+};
+ 
+#endif  //SPWFSA01_H
\ No newline at end of file