AT Parser and bufferedSerial based SPWF library
Dependencies: ATParser
Dependents: X_NUCLEO_IDW01M1v2
Fork of SPWF01SA by
Revision 0:9e5d98ceea74, committed 2016-06-30
- 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
--- /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
