Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: SpwfInterface_NSAPI_Tests HelloWorld_IDW01M1
Fork of X_NUCLEO_IDW01M1 by
SpwfSADevice.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 20015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 /** 00018 ****************************************************************************** 00019 * @file SpwfSADevice.cpp 00020 * @author STMicroelectronics 00021 * @brief Implementation of SpwfSADevice class for Wi-Fi mbed 00022 ****************************************************************************** 00023 * @copy 00024 * 00025 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS 00026 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE 00027 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY 00028 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING 00029 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE 00030 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. 00031 * 00032 * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2> 00033 ****************************************************************************** 00034 */ 00035 00036 00037 #include "SpwfSADevice.h" 00038 00039 00040 #ifdef __cplusplus 00041 extern "C" { 00042 #endif 00043 00044 void Rx_irq_handler(void); 00045 void Wifi_scheduler(void); 00046 void Wifi_ticker(void); 00047 00048 #ifdef __cplusplus 00049 } 00050 #endif 00051 00052 extern void setSpwfSADevice(SpwfSADevice * dev); 00053 00054 /** 00055 * @brief SpwfSADevice constructor 00056 * @param tx: Pin USART TX 00057 * rx: Pin USART RX 00058 * rst: reset pin for Spwf module 00059 * wkup: reset pin for Spwf module 00060 * rts: Pin USART RTS 00061 * @retval none 00062 */ 00063 SpwfSADevice::SpwfSADevice(PinName tx, PinName rx, PinName rst, PinName wkup, PinName rts): 00064 uart_(tx,rx), 00065 term_(SERIAL_TX, SERIAL_RX), 00066 wakeup_(wkup, PIN_INPUT, PullNone, 0), 00067 rst_(rst, PIN_INPUT, PullNone, 1), 00068 rts_(rts, PIN_INPUT, PullUp, 0) 00069 { 00070 setSpwfSADevice(this); 00071 sync_wait_signal = false; 00072 wait_for_incoming_client = false; 00073 wait_for_socket_data = false; 00074 } 00075 00076 /** 00077 * @brief SpwfSADevice destructor 00078 * @param none 00079 * @retval none 00080 */ 00081 SpwfSADevice::~SpwfSADevice(void) 00082 { 00083 //de-constructor 00084 } 00085 00086 /** 00087 * @brief init function 00088 initializes timers, gpios, uart 00089 * @param none 00090 * @retval error value 00091 */ 00092 int SpwfSADevice::init(void) 00093 { 00094 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00095 Timer timer; 00096 00097 timer.start(); 00098 rst_.output(); 00099 wakeup_.output(); 00100 rts_.output(); 00101 00102 term_.baud(9600); 00103 term_.format(8, SerialBase::None, 1); 00104 00105 uart_.baud(115200); 00106 uart_.format(8, SerialBase::None, 1); 00107 uart_.set_flow_control(SerialBase::RTS, PA_12, NC);//RTSCTS 00108 uart_.attach(Rx_irq_handler, SerialBase::RxIrq); 00109 00110 config.power=wifi_active; 00111 config.power_level=high; 00112 config.dhcp=on;//use DHCP IP address 00113 00114 /*Initialize the tickers*/ 00115 wifi_isr.attach_us(Wifi_ticker, 1000); //decreasing the time period to 1ms may be causing overrun issue with UART?\ 00116 //UART error not evident but characters are sometimes missing in pipeline(ring_buffer)\ 00117 //specifically in the +WIND:25:WiFi Association with 'STM' successful WIND (why specifically this?) 00118 00119 wifi_callback.attach_us(Wifi_scheduler, 5000);//How low can we go? 00120 00121 sync_wait_signal = false; 00122 status = wifi_init(&config); 00123 if(status!=WiFi_MODULE_SUCCESS) 00124 { 00125 return -1; 00126 } 00127 00128 while(!sync_wait_signal) 00129 { 00130 if (timer.read_ms() > _timeout) { 00131 return -1; 00132 } 00133 __NOP(); 00134 } 00135 00136 return 0; 00137 } 00138 00139 /** 00140 * @brief network connect 00141 wrapper function for FW 00142 * @param ssid: Access Point (AP) Name String 00143 * sec_key: Password String for AP 00144 * priv_mode: type of security supported (FW mode) 00145 * @retval NSAPI Error Type 00146 */ 00147 int SpwfSADevice::connect(char * ssid, char * sec_key, WiFi_Priv_Mode priv_mode) 00148 { 00149 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00150 Timer timer; 00151 00152 timer.start(); 00153 sync_wait_signal = false; 00154 status = wifi_connect(ssid, sec_key, priv_mode); 00155 if(status!=WiFi_MODULE_SUCCESS) 00156 { 00157 return -1; 00158 } 00159 00160 while(!sync_wait_signal) 00161 { 00162 if (timer.read_ms() > _timeout) { 00163 return -1; 00164 } 00165 __NOP(); 00166 } 00167 00168 return 0; 00169 } 00170 00171 /** 00172 * @brief network disconnect 00173 wrapper function for FW 00174 * @param none 00175 * @retval error value 00176 */ 00177 int SpwfSADevice::disconnect() 00178 { 00179 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00180 00181 status = wifi_disconnect();//will set to Idle Mode 00182 if(status!=WiFi_MODULE_SUCCESS) 00183 { 00184 return -1; 00185 } 00186 00187 return 0; 00188 } 00189 00190 /** 00191 * @brief Get the local IP address 00192 * wrapper function for FW 00193 * @param none 00194 * @retval Null-terminated representation of the local IP address 00195 * or null if not yet connected 00196 */ 00197 const char *SpwfSADevice::getIPAddress() 00198 { 00199 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00200 00201 status = WiFi_Get_IP_Address((uint8_t *)_ip_buffer); 00202 00203 if(status!=WiFi_MODULE_SUCCESS) 00204 { 00205 return NULL; 00206 } else 00207 return _ip_buffer; 00208 } 00209 00210 /** 00211 * @brief Get the MAC address 00212 * wrapper function for FW 00213 * @param none 00214 * @retval Null-terminated representation of the MAC address 00215 * or null if not yet connected 00216 */ 00217 const char *SpwfSADevice::getMACAddress() 00218 { 00219 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00220 00221 status = WiFi_Get_MAC_Address((uint8_t *)_mac_buffer); 00222 00223 if(status!=WiFi_MODULE_SUCCESS) 00224 { 00225 return NULL; 00226 } else 00227 return _mac_buffer; 00228 } 00229 00230 /** 00231 * @brief connect to a remote socket 00232 * @param hostname: address of socket 00233 port_number: port number to connect 00234 protocol: TCP/UDP protocol 00235 * sock_id: pointer to socket ID returned by FW 00236 * @retval error value 00237 */ 00238 int SpwfSADevice::socket_client_open(uint8_t * hostname, uint32_t port_number, uint8_t * protocol, uint8_t * sock_id) 00239 { 00240 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00241 00242 //Timeout of synchronous functions? 00243 status = wifi_socket_client_open(hostname, port_number, protocol, sock_id); 00244 if(status!=WiFi_MODULE_SUCCESS) 00245 { 00246 *sock_id = 99;//make sure socket id is not set(set to out of bounds of SPWFSA_SOCKET_COUNT range) 00247 return -1; 00248 } 00249 00250 return 0; 00251 } 00252 00253 /** 00254 * @brief write to a remote socket 00255 * @param sock_id: FW ID of the socket 00256 DataLength: size of the data 00257 pData: pointer to data 00258 * @retval error value 00259 */ 00260 int SpwfSADevice::socket_client_write(uint8_t sock_id, uint16_t DataLength,char * pData) 00261 { 00262 int status=0;//number of bytes 00263 00264 status = wifi_socket_client_write(sock_id, DataLength, pData); 00265 //map error to enum ns_error_t 00266 00267 if(status > 0) 00268 { 00269 return status; 00270 } 00271 return 0; 00272 } 00273 00274 /** 00275 * @brief receive from a remote socket 00276 * @param sock_id: FW ID of the socket 00277 DataLength: size of the data 00278 pData: pointer to data 00279 * @retval error value 00280 */ 00281 int SpwfSADevice::socket_client_recv(uint8_t sock_id, uint16_t RecvLength,char * pData) 00282 { 00283 static Timer recv_timer; 00284 //char debug_str[10]; 00285 static bool recv_call = true; 00286 00287 if(recv_call) 00288 { 00289 //debug_print("\r\nrecv_call\r\n"); 00290 //__disable_irq(); 00291 wait_for_socket_data = false; 00292 recv_buff = (uint8_t*)pData; 00293 //__enable_irq(); 00294 if(_timeout>0) 00295 recv_timer.start(); 00296 recv_call = false; 00297 bytes_to_read = RecvLength; 00298 bytes_read=0; 00299 } 00300 00301 00302 if(wait_for_socket_data || recv_timer.read_ms() >= _timeout) 00303 { 00304 recv_call = true; 00305 _timeout = 0; 00306 wait_for_socket_data = true; 00307 recv_timer.stop(); 00308 recv_timer.reset(); 00309 wait_ms(1); 00310 if(bytes_read == 0) //<bytes_to_read?? 00311 return -1;//return error if no bytes are read! 00312 else 00313 return bytes_read;//return amount of data arrived so far 00314 } 00315 wait_ms(1); //CHECK:TODO: Need to wait to allow other IRQ's to run in case of non-blocking call? 00316 return -1; 00317 } 00318 00319 /** 00320 * @brief scan the network 00321 * @param scan_result: scan result data pointer 00322 max_scan_number: size of the scan result 00323 * @retval error value 00324 */ 00325 void SpwfSADevice::network_scan(wifi_scan *scan_result, uint16_t max_scan_number) 00326 { 00327 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00328 00329 status = wifi_network_scan(scan_result, max_scan_number); 00330 if(status!=WiFi_MODULE_SUCCESS) 00331 { 00332 return; 00333 } 00334 } 00335 00336 /** 00337 * @brief HTTP GET from remote host 00338 * @param hostname: address of remote host 00339 path: path to resource 00340 port_number: port number 00341 * @retval none 00342 */ 00343 void SpwfSADevice::http_get(uint8_t * hostname, uint8_t * path, uint32_t port_number) 00344 { 00345 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00346 00347 status = wifi_http_get((uint8_t *)hostname, (uint8_t *)path, port_number); 00348 if(status!=WiFi_MODULE_SUCCESS) 00349 { 00350 return; 00351 } 00352 } 00353 00354 /** 00355 * @brief HTTP GET from remote host 00356 * @param url_path: complete url of remote resource 00357 * @retval none 00358 */ 00359 void SpwfSADevice::http_post(uint8_t * url_path) 00360 { 00361 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00362 00363 status = wifi_http_post(url_path); 00364 if(status!=WiFi_MODULE_SUCCESS) 00365 { 00366 return; 00367 } 00368 } 00369 00370 /** 00371 * @brief FW callback with data in socket 00372 * @param sock_id: FW ID of the socket 00373 data_ptr: pointer to data from FW 00374 message_size: total data to arrive 00375 chunk_size: size of the data in this callback (<= message_size) 00376 * @retval none 00377 */ 00378 void SpwfSADevice::signal_data_receive(uint8_t socket_id, uint8_t * data_ptr, uint32_t message_size, uint32_t chunk_size) 00379 { 00380 char debug_str[50]; 00381 //Data will be copied or returned to user only if there is a pending request 00382 //Copy data to pData 00383 //sprintf((char*)debug_str,"sock_id: %d, size: %d, chunk: %d\r\n",socket_id, message_size, chunk_size); 00384 //debug_print(debug_str); 00385 00386 if(recv_buff && !wait_for_socket_data) 00387 { 00388 if((bytes_read + chunk_size)<= bytes_to_read) 00389 { 00390 memcpy(recv_buff + bytes_read, data_ptr, chunk_size);//only copy bytes_to_read asked by user//rest of the data is lost!! 00391 bytes_read += chunk_size; 00392 } 00393 else 00394 { 00395 uint32_t x_size = (bytes_read + chunk_size) - bytes_to_read; 00396 memcpy(recv_buff + bytes_read, data_ptr, chunk_size-x_size); 00397 bytes_read += (chunk_size-x_size); 00398 } 00399 00400 if(bytes_read >= bytes_to_read) 00401 { 00402 __disable_irq(); 00403 wait_for_socket_data = true; 00404 __enable_irq(); 00405 } 00406 } 00407 else 00408 { 00409 debug_print("\r\n Socket:: Data Dropped: "); 00410 sprintf((char*)debug_str,"%d\r\n",chunk_size); 00411 debug_print(debug_str); 00412 __disable_irq(); 00413 wait_for_socket_data = true; 00414 __enable_irq(); 00415 } 00416 } 00417 00418 /** 00419 * @brief synchronization function called from FW (used for connect,disconnect, ready, etc.) 00420 * @param code: Status code value returned 00421 * @retval none 00422 */ 00423 void SpwfSADevice::signal_synch_wait(WiFi_Status_t code) 00424 { 00425 if(code == WiFi_DISASSOCIATION) 00426 { 00427 //do nothing 00428 } 00429 else 00430 { 00431 __disable_irq(); 00432 sync_wait_signal = true; 00433 __enable_irq(); 00434 } 00435 } 00436 00437 /** 00438 * @brief close a client socket 00439 * @param sock_close_id: FW ID of the socket to close 00440 * @retval error value 00441 */ 00442 int SpwfSADevice::socket_client_close(uint8_t sock_close_id) 00443 { 00444 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00445 00446 status = wifi_socket_client_close(sock_close_id); 00447 //map error to enum ns_error_t 00448 if(status!=WiFi_MODULE_SUCCESS) 00449 { 00450 return -1; 00451 } 00452 00453 return 0; 00454 } 00455 00456 /** 00457 * @brief open a server socket 00458 * @param port_number: port number to listen on 00459 * protocol: TCP/UDP protocol 00460 * @retval error value 00461 */ 00462 int SpwfSADevice::socket_server_open(uint32_t port_number, uint8_t * protocol) 00463 { 00464 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00465 00466 status = wifi_socket_server_open(port_number, protocol); 00467 //map error to enum ns_error_t 00468 if(status!=WiFi_MODULE_SUCCESS) 00469 { 00470 return -1; 00471 } 00472 00473 return 0; 00474 } 00475 00476 /** 00477 * @brief write to a server socket 00478 * @param data_length: size of the data 00479 * pdata: pointer to data 00480 * @retval error value 00481 */ 00482 int SpwfSADevice::socket_server_write(uint16_t data_length,char * pdata) 00483 { 00484 int status = 0;//number of bytes 00485 00486 status = wifi_socket_server_write(data_length, pdata); 00487 //map error to enum ns_error_t 00488 if(status > 0) 00489 { 00490 return status; 00491 } 00492 return 0; 00493 } 00494 00495 /** 00496 * @brief close a server socket 00497 * @param none (only one server socket supported) 00498 * @retval error value 00499 */ 00500 int SpwfSADevice::socket_server_close(void) 00501 { 00502 WiFi_Status_t status = WiFi_MODULE_SUCCESS; 00503 00504 status = wifi_socket_server_close(); 00505 //map error to enum ns_error_t 00506 if(status!=WiFi_MODULE_SUCCESS) 00507 { 00508 return -1; 00509 } 00510 00511 return 0; 00512 } 00513 00514 /** 00515 * @brief attach/remove IRQ handler to UART 00516 * @param attach: attach/remove boolean 00517 * @retval none 00518 */ 00519 void SpwfSADevice::spwf_attach_irq(wifi_bool attach) 00520 { 00521 if(attach) 00522 { 00523 uart_.attach(Rx_irq_handler, SerialBase::RxIrq); 00524 } 00525 else 00526 { 00527 uart_.attach(NULL, SerialBase::RxIrq); 00528 } 00529 } 00530 00531 /** 00532 * @brief write byte(s) to the UART 00533 * @param cmd: pointer to data 00534 * size: size of data 00535 * @retval error value 00536 */ 00537 int SpwfSADevice::spwf_send(const char * cmd, uint16_t size) 00538 { 00539 Timer timer; 00540 int i, bytes; 00541 //timer.start(); 00542 00543 //uart_.puts(cmd);//string may contain '\0' character in between hence not used 00544 00545 for(i=0;i<size;i++) 00546 { 00547 uart_.putc(cmd[i]); 00548 //if (timer.read_ms() > _timeout) { 00549 //return -1; 00550 //} 00551 } 00552 00553 bytes = (int) size - 2;//we send 2 bytes extra for module 00554 return bytes; 00555 } 00556 00557 /** 00558 * @brief read a byte from the UART 00559 * @param none 00560 * @retval byte character 00561 */ 00562 char SpwfSADevice::spwf_get(void) 00563 { 00564 return(uart_.getc()); 00565 } 00566 00567 /** 00568 * @brief (re)set the SPWF wakeup GPIO pin 00569 * @param wake (re)set value 00570 * @retval none 00571 */ 00572 void SpwfSADevice::spwf_wakeup(int wake) 00573 { 00574 wakeup_.write(wake); 00575 } 00576 00577 /** 00578 * @brief (re)set the SPWF reset GPIO pin 00579 * @param reset (re)set value 00580 * @retval none 00581 */ 00582 void SpwfSADevice::spwf_reset(int reset) 00583 { 00584 rst_.write(reset); 00585 } 00586 00587 /** 00588 * @brief (re)set the SPWF RTS GPIO line 00589 * @param rts (re)set value 00590 * @retval none 00591 */ 00592 void SpwfSADevice::spwf_rts(int rts) 00593 { 00594 rts_.write(rts); 00595 } 00596 00597 /** 00598 * @brief read the SPWF RTS GPIO pin 00599 * @param none 00600 * @retval none 00601 */ 00602 int SpwfSADevice::spwf_read_rts() 00603 { 00604 return(rts_.read()); 00605 } 00606 00607 /** 00608 * @brief send debug print to serial terminal 00609 * @param string: data for debug print 00610 * @retval none 00611 */ 00612 void SpwfSADevice::debug_print(const char * string) 00613 { 00614 term_.puts(string); 00615 } 00616 00617 /** 00618 * @brief (re)set the switch for incoming client (server socket) 00619 * @param set: boolean to (re)set 00620 * @retval none 00621 */ 00622 void SpwfSADevice::set_wait_for_incoming_client(bool set) 00623 { 00624 wait_for_incoming_client = set; 00625 } 00626 00627 /** 00628 * @brief get the switch for incoming client (server socket) 00629 * @param none 00630 * @retval boolean 00631 */ 00632 bool SpwfSADevice::get_wait_for_incoming_client() 00633 { 00634 return wait_for_incoming_client; 00635 } 00636
Generated on Tue Jul 12 2022 16:20:36 by
1.7.2

X-NUCLEO-IDW01M1 Wi-Fi expansion board