Webserver+3d print

Dependents:   Nucleo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers bcm43362_driver.c Source File

bcm43362_driver.c

Go to the documentation of this file.
00001 /**
00002  * @file bcm43362_driver.c
00003  * @brief BCM43362 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 "core/net.h"
00034 #include "bcm43362_driver.h"
00035 #include "debug.h"
00036 
00037 //WICED dependencies
00038 #include "platform_init.h"
00039 #include "platform_mcu_peripheral.h"
00040 #include "wwd_constants.h"
00041 #include "wwd_structures.h"
00042 #include "wwd_buffer.h"
00043 #include "wwd_events.h"
00044 #include "wwd_management.h"
00045 #include "wwd_poll.h"
00046 #include "wwd_wifi.h"
00047 #include "wwd_buffer_interface.h"
00048 #include "wwd_bus_protocol_interface.h"
00049 #include "wwd_network_constants.h"
00050 #include "wwd_network_interface.h"
00051 
00052 //Underlying network interface
00053 static NetInterface *bcm43362StaInterface = NULL;
00054 static NetInterface *bcm43362ApInterface = NULL;
00055 
00056 //RX queue
00057 QueueHandle_t wwdRxQueue;
00058 
00059 //Regitered Wi-Fi events
00060 static const wwd_event_num_t app_wifi_events[] =
00061 {
00062    WLC_E_IF,
00063    WLC_E_LINK,
00064    WLC_E_ASSOC_IND,
00065    WLC_E_DISASSOC_IND,
00066    WLC_E_NONE
00067 };
00068 
00069 //Forward declaration of functions
00070 void *app_wifi_event_handler(const wwd_event_header_t *event_header,
00071    const uint8_t *event_data, void *handler_user_data);
00072 
00073 
00074 /**
00075  * @brief BCM43362 driver (STA mode)
00076  **/
00077 
00078 const NicDriver bcm43362StaDriver =
00079 {
00080    NIC_TYPE_ETHERNET,
00081    ETH_MTU,
00082    bcm43362Init,
00083    bcm43362Tick,
00084    bcm43362EnableIrq,
00085    bcm43362DisableIrq,
00086    bcm43362EventHandler,
00087    bcm43362SendPacket,
00088    bcm43362SetMulticastFilter,
00089    NULL,
00090    NULL,
00091    NULL,
00092    TRUE,
00093    TRUE,
00094    TRUE,
00095    TRUE
00096 };
00097 
00098 
00099 /**
00100  * @brief BCM43362 driver (AP mode)
00101  **/
00102 
00103 const NicDriver bcm43362ApDriver =
00104 {
00105    NIC_TYPE_ETHERNET,
00106    ETH_MTU,
00107    bcm43362Init,
00108    bcm43362Tick,
00109    bcm43362EnableIrq,
00110    bcm43362DisableIrq,
00111    bcm43362EventHandler,
00112    bcm43362SendPacket,
00113    bcm43362SetMulticastFilter,
00114    NULL,
00115    NULL,
00116    NULL,
00117    TRUE,
00118    TRUE,
00119    TRUE,
00120    TRUE
00121 };
00122 
00123 
00124 /**
00125  * @brief BCM43362 initialization
00126  * @param[in] interface Underlying network interface
00127  * @return Error code
00128  **/
00129 
00130 error_t bcm43362Init(NetInterface *interface)
00131 {
00132    wwd_result_t ret;
00133    //MacAddr macAddr;
00134 
00135    //STA or AP mode?
00136    if(interface->nicDriver == &bcm43362StaDriver)
00137    {
00138       //Debug message
00139       TRACE_INFO("Initializing BCM43362 (STA mode)...\r\n");
00140    }
00141    else
00142    {
00143       //Debug message
00144       TRACE_INFO("Initializing BCM43362 (AP mode)...\r\n");
00145    }
00146 
00147    //Start of exception handling block
00148    do
00149    {
00150       //Initialization sequence is performed once at startup
00151       if(bcm43362StaInterface == NULL && bcm43362ApInterface == NULL)
00152       {
00153          platform_init_mcu_infrastructure();
00154          wwd_buffer_init(NULL);
00155 
00156          //Create TX queue
00157          wwdRxQueue = xQueueCreate(16, sizeof(wiced_buffer_t));
00158 
00159          //Initialize Wi-Fi controller
00160          ret = wwd_management_wifi_on(WICED_COUNTRY_FRANCE);
00161          TRACE_INFO("wwd_management_wifi_on=%d (0x%04X)\r\n", ret, ret);
00162 
00163          ret = wwd_management_set_event_handler(app_wifi_events, app_wifi_event_handler, NULL, WWD_AP_INTERFACE);
00164          TRACE_INFO("wwd_management_set_event_handler=%d (0x%04X)\r\n", ret, ret);
00165       }
00166       else
00167       {
00168          //Initialization was already done
00169          ret = WWD_SUCCESS;
00170       }
00171 
00172       //STA or AP mode?
00173       if(interface->nicDriver == &bcm43362StaDriver)
00174       {
00175          //Save underlying network interface (STA mode)
00176          bcm43362StaInterface = interface;
00177 
00178          //Optionally set the station MAC address
00179          //if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
00180          {
00181             //Use the factory preprogrammed station address
00182             ret = wwd_wifi_get_mac_address((wiced_mac_t *) &interface->macAddr, WWD_STA_INTERFACE);
00183             TRACE_INFO("wwd_wifi_get_mac_address=%d (0x%04X)\r\n", ret, ret);
00184             TRACE_INFO("MAC=%s\r\n", macAddrToString(&interface->macAddr, NULL));
00185 
00186             //Generate the 64-bit interface identifier
00187             macAddrToEui64(&interface->macAddr, &interface->eui64);
00188          }
00189       }
00190       else
00191       {
00192          //Save underlying network interface (AP mode)
00193          bcm43362ApInterface = interface;
00194 
00195          //Optionally set the station MAC address
00196          //if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
00197          {
00198             //Use the factory preprogrammed station address
00199             ret = wwd_wifi_get_mac_address((wiced_mac_t *) &interface->macAddr, WWD_STA_INTERFACE);
00200             TRACE_INFO("wwd_wifi_get_mac_address=%d (0x%04X)\r\n", ret, ret);
00201             TRACE_INFO("MAC=%s\r\n", macAddrToString(&interface->macAddr, NULL));
00202 
00203             //Generate the 64-bit interface identifier
00204             macAddrToEui64(&interface->macAddr, &interface->eui64);
00205          }
00206       }
00207 
00208       //End of exception handling block
00209    } while(0);
00210 
00211    //BCM43362 is now ready to send
00212    osSetEvent(&interface->nicTxEvent);
00213 
00214    //Successful initialization
00215    return NO_ERROR;
00216 }
00217 
00218 
00219 /**
00220  * @brief BCM43362 timer handler
00221  *
00222  * This routine is periodically called by the TCP/IP stack to
00223  * handle periodic operations such as polling the link state
00224  *
00225  * @param[in] interface Underlying network interface
00226  **/
00227 
00228 void bcm43362Tick(NetInterface *interface)
00229 {
00230 }
00231 
00232 
00233 /**
00234  * @brief Enable interrupts
00235  * @param[in] interface Underlying network interface
00236  **/
00237 
00238 void bcm43362EnableIrq(NetInterface *interface)
00239 {
00240 }
00241 
00242 
00243 /**
00244  * @brief Disable interrupts
00245  * @param[in] interface Underlying network interface
00246  **/
00247 
00248 void bcm43362DisableIrq(NetInterface *interface)
00249 {
00250 }
00251 
00252 
00253 /**
00254  * @brief BCM43362 interrupt service routine
00255  * @return TRUE if a higher priority task must be woken. Else FALSE is returned
00256  **/
00257 
00258 bool_t bcm43362IrqHandler(void)
00259 {
00260    bool_t flag;
00261 
00262    //This flag will be set if a higher priority task must be woken
00263    flag = FALSE;
00264 
00265    //STA and/or AP mode?
00266    if(bcm43362StaInterface != NULL)
00267       bcm43362StaInterface->nicEvent = TRUE;
00268    else if(bcm43362ApInterface != NULL)
00269       bcm43362ApInterface->nicEvent = TRUE;
00270 
00271    //Notify the TCP/IP stack of the event
00272    flag = osSetEventFromIsr(&netEvent);
00273 
00274    //A higher priority task must be woken?
00275    return flag;
00276 }
00277 
00278 
00279 /**
00280  * @brief BCM43362 event handler
00281  * @param[in] interface Underlying network interface
00282  **/
00283 
00284 void bcm43362EventHandler(NetInterface *interface)
00285 {
00286 }
00287 
00288 
00289 /**
00290  * @brief Send a packet
00291  * @param[in] interface Underlying network interface
00292  * @param[in] buffer Multi-part buffer containing the data to send
00293  * @param[in] offset Offset to the first data byte
00294  * @return Error code
00295  **/
00296 
00297 error_t bcm43362SendPacket(NetInterface *interface,
00298    const NetBuffer *buffer, size_t offset)
00299 {
00300    wwd_result_t ret;
00301    wiced_buffer_t packet;
00302    size_t length;
00303    uint8_t *p;
00304 
00305    //Retrieve the length of the packet
00306    length = netBufferGetLength(buffer) - offset;
00307 
00308    //Allocate a network buffer
00309    ret = host_buffer_get(&packet, WWD_NETWORK_TX, length + WICED_LINK_OVERHEAD_BELOW_ETHERNET_FRAME_MAX, FALSE);
00310 
00311    //Check status code
00312    if(ret == WWD_SUCCESS)
00313    {
00314       //Make room for additional headers
00315       host_buffer_add_remove_at_front(&packet, WICED_LINK_OVERHEAD_BELOW_ETHERNET_FRAME_MAX);
00316 
00317       //Point to the data payload
00318       p = host_buffer_get_current_piece_data_pointer(packet);
00319 
00320       //Copy user data
00321       netBufferRead(p, buffer, offset, length);
00322 
00323       //Adjust the length of the buffer
00324       host_buffer_set_size(packet, length);
00325 
00326       //STA or AP mode?
00327       if(interface == bcm43362StaInterface)
00328       {
00329          //Send packet
00330          wwd_network_send_ethernet_data(packet, WWD_STA_INTERFACE);
00331       }
00332       else
00333       {
00334          //Send packet
00335          wwd_network_send_ethernet_data(packet, WWD_AP_INTERFACE);
00336       }
00337    }
00338    else
00339    {
00340       TRACE_ERROR("##### bcm43362SendPacket ALLOC FAILED ####\r\n");
00341    }
00342 
00343    //The transmitter can accept another packet
00344    osSetEvent(&interface->nicTxEvent);
00345 
00346    //Return status code
00347    if(ret == WWD_SUCCESS)
00348       return NO_ERROR;
00349    else
00350       return ERROR_FAILURE;
00351 }
00352 
00353 
00354 /**
00355  * @brief Configure multicast MAC address filtering
00356  * @param[in] interface Underlying network interface
00357  * @return Error code
00358  **/
00359 
00360 error_t bcm43362SetMulticastFilter(NetInterface *interface)
00361 {
00362    uint_t i;
00363    wwd_result_t ret;
00364    MacFilterEntry *entry;
00365 
00366    //Debug message
00367    TRACE_INFO("Updating BCM43362 multicast filter...\r\n");
00368 
00369    //STA interface?
00370    if(interface == bcm43362StaInterface)
00371    {
00372       //The MAC filter table contains the multicast MAC addresses
00373       //to accept when receiving an Ethernet frame
00374       for(i = 0; i < MAC_MULTICAST_FILTER_SIZE; i++)
00375       {
00376          //Point to the current entry
00377          entry = &interface->macMulticastFilter[i];
00378 
00379          //Check whether the MAC filter table should be updated for the
00380          //current multicast address
00381          if(!macCompAddr(&entry->addr, &MAC_UNSPECIFIED_ADDR))
00382          {
00383             if(entry->addFlag)
00384             {
00385                //Add a new entry to the MAC filter table
00386                //ret = wwd_wifi_register_multicast_address((wiced_mac_t *) entry->addr.b);
00387                //TRACE_ERROR("wwd_wifi_register_multicast_address=%d (0x%04X)\r\n", ret, ret);
00388             }
00389             else if(entry->deleteFlag)
00390             {
00391                //Remove the current entry from the MAC filter table
00392                //ret = wwd_wifi_unregister_multicast_address((wiced_mac_t *) entry->addr.b);
00393                //TRACE_ERROR("wwd_wifi_unregister_multicast_address=%d (0x%04X)\r\n", ret, ret);
00394             }
00395          }
00396       }
00397    }
00398 
00399    //Successful processing
00400    return NO_ERROR;
00401 }
00402 
00403 
00404 /**
00405  * @brief Callback function that handles Wi-Fi events
00406  **/
00407 
00408 void *app_wifi_event_handler(const wwd_event_header_t *event_header, const uint8_t *event_data, void *handler_user_data)
00409 {
00410    //Check event type
00411    switch(event_header->event_type)
00412    {
00413    //I/F change?
00414    case WLC_E_IF:
00415       TRACE_INFO("### app_wifi_event_handler: WLC_E_IF\r\n");
00416       break;
00417 
00418    //802.11 ASSOC indication?
00419    case WLC_E_ASSOC_IND:
00420       TRACE_INFO("### app_wifi_event_handler: WLC_E_ASSOC_IND\r\n");
00421       break;
00422 
00423    //802.11 DISASSOC indication?
00424    case WLC_E_DISASSOC_IND:
00425       TRACE_INFO("### app_wifi_event_handler: WLC_E_DISASSOC_IND\r\n");
00426       break;
00427 
00428    //Generic link indication?
00429    case WLC_E_LINK:
00430       //Debug message
00431       TRACE_INFO("### app_wifi_event_handler: WLC_E_LINK\r\n");
00432 
00433       //STA interface?
00434       if(event_header->interface == WWD_STA_INTERFACE)
00435       {
00436          if(bcm43362StaInterface != NULL)
00437          {
00438             //Check link state
00439             if(event_header->flags & 0x01)
00440                bcm43362StaInterface->linkState = TRUE;
00441             else
00442                bcm43362StaInterface->linkState = FALSE;
00443 
00444             //Get exclusive access
00445             osAcquireMutex(&netMutex);
00446             //Process link state change event
00447             nicNotifyLinkChange(bcm43362StaInterface);
00448             //Release exclusive access
00449             osReleaseMutex(&netMutex);
00450          }
00451       }
00452       //AP interface?
00453       else if(event_header->interface == WWD_AP_INTERFACE)
00454       {
00455          if(bcm43362ApInterface != NULL)
00456          {
00457             //Check link state
00458             if(event_header->flags & 0x01)
00459                bcm43362ApInterface->linkState = TRUE;
00460             else
00461                bcm43362ApInterface->linkState = FALSE;
00462 
00463             //Get exclusive access
00464             osAcquireMutex(&netMutex);
00465             //Process link state change event
00466             nicNotifyLinkChange(bcm43362ApInterface);
00467             //Release exclusive access
00468             osReleaseMutex(&netMutex);
00469          }
00470       }
00471 
00472       break;
00473 
00474    //Unknown event?
00475    default:
00476       TRACE_INFO("### app_wifi_event_handler: Unknown event\r\n");
00477       break;
00478    }
00479 
00480    return handler_user_data;
00481 }
00482 
00483 
00484 /**
00485  * @brief Callback function that handles incoming packets
00486  **/
00487 
00488 void host_network_process_ethernet_data(wiced_buffer_t buffer, wwd_interface_t interface)
00489 {
00490    size_t n;
00491    uint8_t *p;
00492 
00493    //Point to the incoming packet
00494    p = host_buffer_get_current_piece_data_pointer(buffer);
00495    //Retrieve the length of the packet
00496    n = host_buffer_get_current_piece_size(buffer);
00497 
00498    //Valid packet received?
00499    if(p != NULL && n > 0)
00500    {
00501       if(interface == WWD_STA_INTERFACE)
00502       {
00503          if(bcm43362StaInterface != NULL)
00504          {
00505             //Get exclusive access
00506             osAcquireMutex(&netMutex);
00507             //Process link state change event
00508             nicProcessPacket(bcm43362StaInterface, p, n);
00509             //Release exclusive access
00510             osReleaseMutex(&netMutex);
00511          }
00512       }
00513       else if(interface == WWD_AP_INTERFACE)
00514       {
00515          if(bcm43362ApInterface != NULL)
00516          {
00517             //Get exclusive access
00518             osAcquireMutex(&netMutex);
00519             //Process link state change event
00520             nicProcessPacket(bcm43362ApInterface, p, n);
00521             //Release exclusive access
00522             osReleaseMutex(&netMutex);
00523          }
00524       }
00525    }
00526 
00527    //Release network buffer
00528    host_buffer_release(buffer, WWD_NETWORK_RX);
00529 }
00530 
00531 
00532 //Miscellaneous WICED dependencies
00533 signed int xTaskIsTaskFinished(void *xTask)
00534 {
00535    TRACE_INFO("### xTaskIsTaskFinished\r\n");
00536    return pdTRUE;
00537 }
00538 
00539 portBASE_TYPE vTaskFreeTerminated(TaskHandle_t xTask)
00540 {
00541    TRACE_INFO("### vTaskFreeTerminated\r\n");
00542    return pdTRUE;
00543 }
00544