Extending the X_NUCLEO_IDW01M1 to allow configuration of the board as an access point

Dependents:   X_NUCLEO_IDW01M1_AP_Test

Fork of X_NUCLEO_IDW01M1 by ST

Revision:
1:bd9db471d47d
Parent:
0:dc55f40eb04f
Child:
5:c83ffd44f40a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Spwf_API/SpwfSADevice.cpp	Thu Apr 14 06:14:14 2016 +0000
@@ -0,0 +1,398 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2013 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.
+*/
+ 
+/**
+  ******************************************************************************
+  * @file    SpwfSADevice.cpp 
+  * @author  STMicroelectronics
+  * @brief   Implementation of SpwfSADevice class for Wi-Fi mbed
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
+  ******************************************************************************
+  */ 
+  
+
+#include "SpwfSADevice.h" 
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  
+void Rx_irq_handler(void);
+void Wifi_scheduler(void);
+void Wifi_ticker(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+extern void setSpwfSADevice(SpwfSADevice * dev);
+
+SpwfSADevice::SpwfSADevice(PinName tx, PinName rx, PinName rst, PinName wkup, PinName rts):
+    uart_(tx,rx), 
+    term_(SERIAL_TX, SERIAL_RX),
+    wakeup_(wkup, PIN_INPUT, PullNone, 0),
+    rst_(rst, PIN_INPUT, PullNone, 1),     
+    rts_(rts, PIN_INPUT, PullUp, 0)
+{
+    setSpwfSADevice(this);
+    sync_wait_signal = false;
+}
+
+SpwfSADevice::~SpwfSADevice(void)
+{
+    //de-constructor
+}
+
+int32_t SpwfSADevice::init(void) 
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+    Timer timer;
+    
+    timer.start();    
+    rst_.output();
+    wakeup_.output();
+    rts_.output();
+    
+    term_.baud(9600);
+    term_.format(8, SerialBase::None, 1);
+  
+    uart_.baud(115200);
+    uart_.format(8, SerialBase::None, 1);
+    uart_.set_flow_control(SerialBase::RTS, PA_12, NC);//RTSCTS
+    uart_.attach(Rx_irq_handler, SerialBase::RxIrq);
+
+    config.power=wifi_active;
+    config.power_level=high;
+    config.dhcp=on;//use DHCP IP address
+    
+    /*Initialize the tickers*/
+    wifi_isr.attach_us(Wifi_ticker, 1000); //decreasing the time period to 1ms may be causing overrun issue with UART?\
+                                                //UART error not evident but characters are sometimes missing in pipeline(ring_buffer)\
+                                                //specifically in the +WIND:25:WiFi Association with 'STM' successful WIND (why specifically this?)
+    
+    wifi_callback.attach_us(Wifi_scheduler, 2000);//How low can we go?
+        
+    sync_wait_signal = false;
+    status = wifi_init(&config);
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return -1;
+    }
+    
+    while(!sync_wait_signal)
+    {
+        if (timer.read_ms() > _timeout) {
+            return -1;
+        }
+        __NOP();
+    }
+    
+    return 0;
+}
+
+int32_t SpwfSADevice::connect(char * ssid, char * sec_key, WiFi_Priv_Mode priv_mode) 
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+    Timer timer;
+    
+    timer.start();
+    sync_wait_signal = false;
+    status = wifi_connect(ssid, sec_key, priv_mode);
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return -1;
+    }        
+    
+    while(!sync_wait_signal)
+    {
+        if (timer.read_ms() > _timeout) {
+            return -1;
+        }
+        __NOP();
+    } 
+    
+    return 0;
+}
+
+int32_t SpwfSADevice::disconnect()
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+
+    status = wifi_disconnect();//will set to Idle Mode
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return -1;
+    }
+    
+    return 0;
+}
+
+const char *SpwfSADevice::getIPAddress()
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+
+    status = WiFi_Get_IP_Address((uint8_t *)_ip_buffer);
+    
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return NULL;
+    } else 
+        return _ip_buffer;
+}
+
+const char *SpwfSADevice::getMACAddress()
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+
+    status = WiFi_Get_MAC_Address((uint8_t *)_mac_buffer);
+    
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return NULL;
+    } else 
+        return _mac_buffer;
+}
+
+int32_t SpwfSADevice::socket_client_open(uint8_t * hostname, uint32_t port_number, uint8_t * protocol, uint8_t * sock_id)
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+
+    //Timeout of synchronous functions?
+    status = wifi_socket_client_open(hostname, port_number, protocol, sock_id);
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        *sock_id = 9;//make sure socket id is not set(set to out of bounds of SPWFSA_SOCKET_COUNT range)
+        return -1;
+    }
+    
+    return 0;
+}
+
+
+int32_t SpwfSADevice::socket_client_write(uint8_t sock_id, uint16_t DataLength,char * pData)
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+
+    status = wifi_socket_client_write(sock_id, DataLength, pData);
+    //map error to enum ns_error_t 
+    
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return -1;
+    }
+    return 0;
+}
+
+
+int32_t SpwfSADevice::socket_client_recv(uint8_t sock_id, uint16_t RecvLength,char * pData)
+{
+    Timer timer;
+    
+    timer.start();
+    bytes_to_read = RecvLength;
+
+    __disable_irq();
+    bytes_read=0;
+    sync_wait_signal = false;
+    recv_buff = (uint8_t*)pData;
+    __enable_irq();
+    
+    while(!sync_wait_signal)
+    {
+      if (timer.read_ms() > _timeout) {
+            //debug_print("\r\n SpwfSADevice:: Timeout!\r\n");
+            sync_wait_signal = true;            
+            //if(bytes_read==0) return -1;//return error if no bytes are read!
+            return bytes_read;//return amount of data arrived so far
+            //when do we return NS_ERROR_WOULD_BLOCK??
+        }
+      __NOP();
+    }
+
+    return bytes_read;
+    
+}
+
+void SpwfSADevice::network_scan(wifi_scan *scan_result, uint16_t max_scan_number)
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+    
+    status = wifi_network_scan(scan_result, max_scan_number);
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return;
+    }
+}
+
+void SpwfSADevice::http_get(uint8_t * hostname, uint8_t * path, uint32_t port_number)
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+    
+    status = wifi_http_get((uint8_t *)hostname, (uint8_t *)path, port_number);
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return;
+    }    
+}
+
+void SpwfSADevice::http_post(uint8_t * url_path)
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+    
+    status = wifi_http_post(url_path);
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return;
+    }    
+}
+
+void SpwfSADevice::signal_data_receive(uint8_t socket_id, uint8_t * data_ptr, uint32_t message_size, uint32_t chunk_size)
+{
+    char debug_str[10];
+    //Data will be copied or returned to user only if there is a pending request
+    //Copy data to pData
+    if(recv_buff && !sync_wait_signal)
+    {
+        if((bytes_read + message_size)<= bytes_to_read)
+        {
+            memcpy(recv_buff + bytes_read, data_ptr, message_size);//only copy bytes_to_read asked by user//rest of the data is lost!!
+            bytes_read += message_size;
+        }
+        else
+            {
+                uint32_t x_size = (bytes_read + message_size) - bytes_to_read;
+                memcpy(recv_buff + bytes_read, data_ptr, message_size-x_size);
+                bytes_read += (message_size-x_size);
+            }          
+        
+        if(bytes_read >= bytes_to_read)
+        {
+            __disable_irq();
+            sync_wait_signal = true;
+            __enable_irq();
+        }
+    }
+    else
+    {
+        debug_print("\r\n Socket:: Data Dropped: ");
+        sprintf((char*)debug_str,"%d\r\n",message_size); 
+        debug_print(debug_str);
+        __disable_irq();
+        sync_wait_signal = true;
+        __enable_irq();
+    }
+    
+}
+
+void SpwfSADevice::signal_synch_wait(WiFi_Status_t code)
+{
+    if(code == WiFi_DISASSOCIATION)
+    {
+        //do nothing
+    } 
+    else
+    {
+        __disable_irq();
+        sync_wait_signal = true;
+        __enable_irq();
+    }
+}
+
+int32_t SpwfSADevice::socket_client_close(uint8_t sock_close_id)
+{
+    WiFi_Status_t status = WiFi_MODULE_SUCCESS;
+
+    status = wifi_socket_client_close(sock_close_id);
+    //map error to enum ns_error_t 
+    if(status!=WiFi_MODULE_SUCCESS)
+    {
+        return -1;
+    }    
+    
+    return 0;
+}
+
+
+void SpwfSADevice::spwf_attach_irq(wifi_bool attach) 
+{
+    if(attach)
+    {
+        uart_.attach(Rx_irq_handler, SerialBase::RxIrq);
+    }
+    else
+    {
+        uart_.attach(NULL, SerialBase::RxIrq);
+    }
+}
+
+void SpwfSADevice::spwf_send(const char * cmd, uint16_t size) 
+{
+    Timer timer;
+    int i;
+    //timer.start();
+    
+    //uart_.puts(cmd);//string may contain '\0' character in between hence not used
+    
+    for(i=0;i<size;i++)
+    {
+        uart_.putc(cmd[i]);        
+        //if (timer.read_ms() > _timeout) {
+            //return -1;
+        //}
+    }
+}
+
+char SpwfSADevice::spwf_get(void) 
+{
+    return(uart_.getc());
+}
+
+void SpwfSADevice::spwf_wakeup(int wake)
+{
+    wakeup_.write(wake);
+}
+
+void SpwfSADevice::spwf_reset(int reset)
+{
+    rst_.write(reset);
+}
+
+void SpwfSADevice::spwf_rts(int rts)
+{
+    rts_.write(rts);
+}
+
+int SpwfSADevice::spwf_read_rts()
+{
+    return(rts_.read());
+}
+
+void SpwfSADevice::debug_print(const char * string)
+{
+    term_.puts(string);
+}
+