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.
wilc1000_driver.c
00001 /** 00002 * @file wilc1000_driver.c 00003 * @brief WILC1000 Wi-Fi controller 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneTCP Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL NIC_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include "driver/include/m2m_wifi.h" 00034 #include "core/net.h" 00035 #include "wilc1000_driver.h" 00036 #include "wilc1000_config.h" 00037 #include "debug.h" 00038 00039 //Underlying network interface 00040 static NetInterface *wilc1000StaInterface = NULL; 00041 static NetInterface *wilc1000ApInterface = NULL; 00042 00043 //Transmit buffer 00044 static uint8_t txBuffer[WILC1000_TX_BUFFER_SIZE]; 00045 //Receive buffer 00046 static uint8_t rxBuffer[WILC1000_RX_BUFFER_SIZE]; 00047 00048 00049 /** 00050 * @brief WILC1000 driver (STA mode) 00051 **/ 00052 00053 const NicDriver wilc1000StaDriver = 00054 { 00055 NIC_TYPE_ETHERNET, 00056 ETH_MTU, 00057 wilc1000Init, 00058 wilc1000Tick, 00059 wilc1000EnableIrq, 00060 wilc1000DisableIrq, 00061 wilc1000EventHandler, 00062 wilc1000SendPacket, 00063 wilc1000SetMulticastFilter, 00064 NULL, 00065 NULL, 00066 NULL, 00067 TRUE, 00068 TRUE, 00069 TRUE, 00070 TRUE 00071 }; 00072 00073 00074 /** 00075 * @brief WILC1000 driver (AP mode) 00076 **/ 00077 00078 const NicDriver wilc1000ApDriver = 00079 { 00080 NIC_TYPE_ETHERNET, 00081 ETH_MTU, 00082 wilc1000Init, 00083 wilc1000Tick, 00084 wilc1000EnableIrq, 00085 wilc1000DisableIrq, 00086 wilc1000EventHandler, 00087 wilc1000SendPacket, 00088 wilc1000SetMulticastFilter, 00089 NULL, 00090 NULL, 00091 NULL, 00092 TRUE, 00093 TRUE, 00094 TRUE, 00095 TRUE 00096 }; 00097 00098 00099 /** 00100 * @brief WILC1000 initialization 00101 * @param[in] interface Underlying network interface 00102 * @return Error code 00103 **/ 00104 00105 error_t wilc1000Init(NetInterface *interface) 00106 { 00107 int8_t status; 00108 tstrWifiInitParam param; 00109 MacAddr staMacAddr; 00110 MacAddr apMacAddr; 00111 00112 //STA or AP mode? 00113 if(interface->nicDriver == &wilc1000StaDriver) 00114 { 00115 //Debug message 00116 TRACE_INFO("Initializing WILC1000 (STA mode)...\r\n"); 00117 //Save underlying network interface 00118 wilc1000StaInterface = interface; 00119 } 00120 else 00121 { 00122 //Debug message 00123 TRACE_INFO("Initializing WILC1000 (AP mode)...\r\n"); 00124 //Save underlying network interface 00125 wilc1000ApInterface = interface; 00126 } 00127 00128 //Start of exception handling block 00129 do 00130 { 00131 //Initialization sequence is performed once 00132 if(wilc1000StaInterface == NULL || wilc1000ApInterface == NULL) 00133 { 00134 //Low-level initialization 00135 status = nm_bsp_init(); 00136 00137 //Check status code 00138 if(status != M2M_SUCCESS) 00139 break; 00140 00141 //Set default parameters 00142 memset(¶m, 0, sizeof(param)); 00143 00144 //Register callback functions 00145 param.pfAppWifiCb = wilc1000AppWifiEvent; 00146 param.pfAppMonCb = NULL; 00147 param.strEthInitParam.pfAppWifiCb = NULL; 00148 param.strEthInitParam.pfAppEthCb = wilc1000AppEthEvent; 00149 00150 //Set receive buffer 00151 param.strEthInitParam.au8ethRcvBuf = rxBuffer; 00152 param.strEthInitParam.u16ethRcvBufSize = WILC1000_RX_BUFFER_SIZE; 00153 00154 //Initialize WILC1000 controller 00155 status = m2m_wifi_init(¶m); 00156 00157 //Check status code 00158 if(status != M2M_SUCCESS) 00159 break; 00160 } 00161 00162 //Retrieve current MAC addresses 00163 status = m2m_wifi_get_mac_address(staMacAddr.b, apMacAddr.b); 00164 00165 //Check status code 00166 if(status != M2M_SUCCESS) 00167 break; 00168 00169 //Optionally set the MAC address 00170 if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR)) 00171 { 00172 //Use the factory preprogrammed MAC address 00173 if(interface == wilc1000StaInterface) 00174 interface->macAddr = staMacAddr; 00175 else 00176 interface->macAddr = apMacAddr; 00177 00178 //Generate the 64-bit interface identifier 00179 macAddrToEui64(&interface->macAddr, &interface->eui64); 00180 } 00181 else 00182 { 00183 //Override the factory preprogrammed address 00184 if(interface == wilc1000StaInterface) 00185 staMacAddr = interface->macAddr; 00186 else 00187 apMacAddr = interface->macAddr; 00188 00189 //Assign MAC addresses 00190 status = m2m_wifi_set_mac_address(apMacAddr.b, staMacAddr.b); 00191 00192 //Check status code 00193 if(status != M2M_SUCCESS) 00194 break; 00195 } 00196 00197 //End of exception handling block 00198 } while(0); 00199 00200 //WILC1000 is now ready to send 00201 osSetEvent(&interface->nicTxEvent); 00202 00203 //Return status code 00204 if(status == M2M_SUCCESS) 00205 return NO_ERROR; 00206 else 00207 return ERROR_FAILURE; 00208 } 00209 00210 00211 /** 00212 * @brief WILC1000 timer handler 00213 * 00214 * This routine is periodically called by the TCP/IP stack to 00215 * handle periodic operations such as polling the link state 00216 * 00217 * @param[in] interface Underlying network interface 00218 **/ 00219 00220 void wilc1000Tick(NetInterface *interface) 00221 { 00222 } 00223 00224 00225 /** 00226 * @brief Enable interrupts 00227 * @param[in] interface Underlying network interface 00228 **/ 00229 00230 void wilc1000EnableIrq(NetInterface *interface) 00231 { 00232 } 00233 00234 00235 /** 00236 * @brief Disable interrupts 00237 * @param[in] interface Underlying network interface 00238 **/ 00239 00240 void wilc1000DisableIrq(NetInterface *interface) 00241 { 00242 } 00243 00244 00245 /** 00246 * @brief WILC1000 interrupt service routine 00247 * @return TRUE if a higher priority task must be woken. Else FALSE is returned 00248 **/ 00249 00250 bool_t wilc1000IrqHandler(void) 00251 { 00252 bool_t flag; 00253 00254 //This flag will be set if a higher priority task must be woken 00255 flag = FALSE; 00256 00257 //STA and/or AP mode? 00258 if(wilc1000StaInterface != NULL) 00259 wilc1000StaInterface->nicEvent = TRUE; 00260 else if(wilc1000ApInterface != NULL) 00261 wilc1000ApInterface->nicEvent = TRUE; 00262 00263 //Notify the TCP/IP stack of the event 00264 flag = osSetEventFromIsr(&netEvent); 00265 00266 //A higher priority task must be woken? 00267 return flag; 00268 } 00269 00270 00271 /** 00272 * @brief WILC1000 event handler 00273 * @param[in] interface Underlying network interface 00274 **/ 00275 00276 void wilc1000EventHandler(NetInterface *interface) 00277 { 00278 //Process Wi-Fi events 00279 m2m_wifi_handle_events(NULL); 00280 } 00281 00282 00283 /** 00284 * @brief Send a packet 00285 * @param[in] interface Underlying network interface 00286 * @param[in] buffer Multi-part buffer containing the data to send 00287 * @param[in] offset Offset to the first data byte 00288 * @return Error code 00289 **/ 00290 00291 error_t wilc1000SendPacket(NetInterface *interface, 00292 const NetBuffer *buffer, size_t offset) 00293 { 00294 int8_t status; 00295 size_t length; 00296 00297 //Retrieve the length of the packet 00298 length = netBufferGetLength(buffer) - offset; 00299 00300 //Check the frame length 00301 if(length > WILC1000_TX_BUFFER_SIZE) 00302 { 00303 //The transmitter can accept another packet 00304 osSetEvent(&interface->nicTxEvent); 00305 //Report an error 00306 return ERROR_INVALID_LENGTH; 00307 } 00308 00309 //Make sure the link is up before transmitting the frame 00310 if(!interface->linkState) 00311 { 00312 //The transmitter can accept another packet 00313 osSetEventFromIsr(&interface->nicTxEvent); 00314 //Drop current packet 00315 return NO_ERROR; 00316 } 00317 00318 //Copy user data to the transmit buffer 00319 netBufferRead(txBuffer + M2M_ETHERNET_HDR_OFFSET + M2M_ETH_PAD_SIZE, 00320 buffer, offset, length); 00321 00322 //STA or AP mode? 00323 if(interface == wilc1000StaInterface) 00324 { 00325 //Send packet 00326 status = m2m_wifi_send_ethernet_pkt(txBuffer, length); 00327 } 00328 else 00329 { 00330 //Send packet 00331 status = m2m_wifi_send_ethernet_pkt_ifc1(txBuffer, length); 00332 } 00333 00334 //The transmitter can accept another packet 00335 osSetEvent(&interface->nicTxEvent); 00336 00337 //Return status code 00338 if(status == M2M_SUCCESS) 00339 return NO_ERROR; 00340 else 00341 return ERROR_FAILURE; 00342 } 00343 00344 00345 /** 00346 * @brief Configure multicast MAC address filtering 00347 * @param[in] interface Underlying network interface 00348 * @return Error code 00349 **/ 00350 00351 error_t wilc1000SetMulticastFilter(NetInterface *interface) 00352 { 00353 uint_t i; 00354 uint_t refCount; 00355 MacFilterEntry *entry; 00356 00357 //Debug message 00358 TRACE_INFO("Updating WILC1000 multicast filter...\r\n"); 00359 00360 //The MAC filter table contains the multicast MAC addresses 00361 //to accept when receiving an Ethernet frame 00362 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++) 00363 { 00364 //Point to the current entry 00365 entry = &interface->macMulticastFilter[i]; 00366 00367 //Valid entry? 00368 if(!macCompAddr(&entry->addr, &MAC_UNSPECIFIED_ADDR)) 00369 { 00370 //Check whether the multicast MAC address has already been registered 00371 //on the alternate interface 00372 if(interface == wilc1000StaInterface) 00373 refCount = wilc1000GetAddrRefCount(wilc1000ApInterface, &entry->addr); 00374 else 00375 refCount = wilc1000GetAddrRefCount(wilc1000StaInterface, &entry->addr); 00376 00377 //Ensure that there are not duplicate address entries in the table 00378 if(refCount == 0) 00379 { 00380 //Update MAC filter table only if necessary 00381 if(entry->addFlag) 00382 { 00383 //Add a new entry to the MAC filter table 00384 m2m_wifi_enable_mac_mcast(entry->addr.b, TRUE); 00385 } 00386 else if(entry->deleteFlag) 00387 { 00388 //Remove the current entry from the MAC filter table 00389 m2m_wifi_enable_mac_mcast(entry->addr.b, FALSE); 00390 } 00391 } 00392 } 00393 } 00394 00395 //Successful processing 00396 return NO_ERROR; 00397 } 00398 00399 00400 /** 00401 * @brief Get reference count for the specified multicast MAC address 00402 * @param[in] interface Underlying network interface 00403 * @param[in] macAddr MAC address 00404 * @return Reference count 00405 **/ 00406 00407 bool_t wilc1000GetAddrRefCount(NetInterface *interface, const MacAddr *macAddr) 00408 { 00409 uint_t i; 00410 uint_t refCount; 00411 MacFilterEntry *entry; 00412 00413 //Clear reference count 00414 refCount = 0; 00415 00416 //Valid network interface? 00417 if(interface != NULL) 00418 { 00419 //Go through the multicast filter table 00420 for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++) 00421 { 00422 //Point to the current entry 00423 entry = &interface->macMulticastFilter[i]; 00424 00425 //Valid entry? 00426 if(entry->refCount > 0) 00427 { 00428 //Check whether the specified MAC address matches 00429 //a multicast address in the table 00430 if(macCompAddr(&entry->addr, macAddr)) 00431 { 00432 //Get reference count 00433 refCount = entry->refCount; 00434 //We are done 00435 break; 00436 } 00437 } 00438 } 00439 } 00440 00441 //Return reference count 00442 return refCount; 00443 } 00444 00445 00446 /** 00447 * @brief Callback function that handles Wi-Fi events 00448 * @param[in] msgType Type of notification 00449 * @param[in] msg Pointer to the buffer containing the notification parameters 00450 **/ 00451 00452 void wilc1000AppWifiEvent(uint8_t msgType, void *msg) 00453 { 00454 tstrM2mWifiStateChanged *stateChangedMsg; 00455 00456 //Debug message 00457 TRACE_INFO("WILC1000 Wi-Fi event callback\r\n"); 00458 00459 //Check message type 00460 if(msgType == M2M_WIFI_RESP_FIRMWARE_STRTED) 00461 { 00462 //Debug message 00463 TRACE_INFO(" M2M_WIFI_RESP_FIRMWARE_STRTED\r\n"); 00464 } 00465 else if(msgType == M2M_WIFI_RESP_CON_STATE_CHANGED) 00466 { 00467 //Debug message 00468 TRACE_INFO(" M2M_WIFI_RESP_CON_STATE_CHANGED\r\n"); 00469 00470 //Connection state 00471 stateChangedMsg = (tstrM2mWifiStateChanged*) msg; 00472 00473 //Check interface identifier 00474 if(stateChangedMsg->u8IfcId == INTERFACE_1) 00475 { 00476 //Check whether STA mode is enabled 00477 if(wilc1000StaInterface != NULL) 00478 { 00479 //Check link state 00480 if(stateChangedMsg->u8CurrState == M2M_WIFI_CONNECTED) 00481 { 00482 //Link is up 00483 wilc1000StaInterface->linkState = TRUE; 00484 } 00485 else 00486 { 00487 //Link is down 00488 wilc1000StaInterface->linkState = FALSE; 00489 } 00490 00491 //Process link state change event 00492 nicNotifyLinkChange(wilc1000StaInterface); 00493 } 00494 } 00495 else if(stateChangedMsg->u8IfcId == INTERFACE_2) 00496 { 00497 //Check whether AP mode is enabled 00498 if(wilc1000ApInterface != NULL) 00499 { 00500 //Check link state 00501 if(stateChangedMsg->u8CurrState == M2M_WIFI_CONNECTED) 00502 { 00503 //Link is up 00504 wilc1000ApInterface->linkState = TRUE; 00505 } 00506 else 00507 { 00508 //Link is down 00509 wilc1000ApInterface->linkState = FALSE; 00510 } 00511 00512 //Process link state change event 00513 nicNotifyLinkChange(wilc1000ApInterface); 00514 } 00515 } 00516 } 00517 00518 #if defined(CONF_WILC_EVENT_HOOK) 00519 //Release exclusive access 00520 osReleaseMutex(&netMutex); 00521 //Invoke user callback function 00522 CONF_WILC_EVENT_HOOK(msgType, msg); 00523 //Get exclusive access 00524 osAcquireMutex(&netMutex); 00525 #endif 00526 } 00527 00528 00529 /** 00530 * @brief Callback function that handles events in bypass mode 00531 * @param[in] msgType Type of notification 00532 * @param[in] msg Pointer to the buffer containing the notification parameters 00533 * @param[in] ctrlBuf Pointer to the control buffer 00534 **/ 00535 00536 void wilc1000AppEthEvent(uint8_t msgType, void *msg, void *ctrlBuf) 00537 { 00538 size_t length; 00539 uint8_t *packet; 00540 tstrM2mIpCtrlBuf *ctrl; 00541 00542 //Debug message 00543 TRACE_DEBUG("WILC1000 RX event callback\r\n"); 00544 00545 //Point to the control buffer 00546 ctrl = (tstrM2mIpCtrlBuf *) ctrlBuf; 00547 00548 //Check message type 00549 if(msgType == M2M_WIFI_RESP_ETHERNET_RX_PACKET) 00550 { 00551 //Debug message 00552 TRACE_DEBUG(" M2M_WIFI_RESP_ETHERNET_RX_PACKET\r\n"); 00553 00554 //Point to the beginning of the packet 00555 packet = rxBuffer + ctrl->u8DataOffset; 00556 //Retrieve the length of the packet 00557 length = ctrl->u16DataSize; 00558 00559 //Check interface identifier 00560 if(ctrl->u8IfcId == INTERFACE_1) 00561 { 00562 //Valid interface? 00563 if(wilc1000StaInterface != NULL) 00564 { 00565 //Check destination MAC address 00566 if(wilc1000ApInterface != NULL) 00567 { 00568 if(macCompAddr(packet, wilc1000ApInterface->macAddr.b)) 00569 macCopyAddr(packet, wilc1000StaInterface->macAddr.b); 00570 } 00571 00572 //Pass the packet to the upper layer (STA mode) 00573 nicProcessPacket(wilc1000StaInterface, packet, length); 00574 } 00575 } 00576 else if(ctrl->u8IfcId == INTERFACE_2) 00577 { 00578 //Valid interface? 00579 if(wilc1000ApInterface != NULL) 00580 { 00581 //Check destination MAC address 00582 if(wilc1000StaInterface != NULL) 00583 { 00584 if(macCompAddr(packet, wilc1000StaInterface->macAddr.b)) 00585 macCopyAddr(packet, wilc1000ApInterface->macAddr.b); 00586 } 00587 00588 //Pass the packet to the upper layer (STA mode) 00589 nicProcessPacket(wilc1000ApInterface, packet, length); 00590 } 00591 } 00592 } 00593 } 00594
Generated on Tue Jul 12 2022 17:10:17 by
1.7.2