Rewrite from scratch a TCP/IP stack for mbed. So far the following parts are usable: Drivers: - EMAC driver (from CMSIS 2.0) Protocols: - Ethernet protocol - ARP over ethernet for IPv4 - IPv4 over Ethernet - ICMPv4 over IPv4 - UDPv4 over IPv4 APIs: - Sockets for UDPv4 The structure of this stack is designed to be very modular. Each protocol can register one or more protocol to handle its payload, and in each protocol, an API can be hooked (like Sockets for example). This is an early release.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mbedNetIF.cpp Source File

mbedNetIF.cpp

00001 /*
00002  * $Id: mbedNetIF.c 28 2011-06-10 10:16:30Z benoit $
00003  * $Author: benoit $
00004  * $Date: 2011-06-10 12:16:30 +0200 (ven., 10 juin 2011) $
00005  * $Rev: 28 $
00006  * 
00007  * 
00008  * 
00009  * 
00010  * 
00011  */
00012  
00013 #include "mbedNetIF.h"
00014 #include "Ethernet.h"
00015 #include "mbedNet.h"
00016 #include "NetIF.h"
00017 #include "Debug.h"
00018 #include "lpc17xx_pinsel.h"
00019 #include "lpc17xx_emac.h"
00020 #include <string.h>
00021 
00022 
00023 #define    DEBUG_CURRENT_MODULE_NAME    "mbedNetIF"
00024 #define    DEBUG_CURRENT_MODULE_ID        DEBUG_MODULE_MBEDNETIF
00025 
00026 
00027 static int32_t Init(NetIF_t *netif);
00028 static int32_t Read(uint8_t **packet, int32_t *length);
00029 static int32_t Write(uint8_t *packet, int32_t length);
00030 static void Enable(void);
00031 static void Disable(void);
00032 static uint8_t *GetTxBuffer(void);
00033 
00034 
00035 #define    MBEDNETIF_DRIVER_NAME    "mbedEMAC"
00036 
00037 
00038 static EMAC_CFG_Type            Emac_Config;
00039 static PINSEL_CFG_Type          PinCfg;
00040 static uint8_t                  rxPacket[EMAC_ETH_MAX_FLEN],
00041                                 txPacket[EMAC_ETH_MAX_FLEN];
00042 static EMAC_PACKETBUF_Type      rxBuffer,
00043                                 txBuffer;
00044 static NetIF_t                  *mbedNetIF = NULL;
00045 
00046 static Bool_t EMAC_TxBufferNotFull(void);
00047 
00048 
00049 NetIF_Driver_t mbedNetIF_Driver = 
00050 { 
00051     MBEDNETIF_DRIVER_NAME,  
00052     Init, 
00053     Read, 
00054     Write, 
00055     Enable,
00056     Disable,
00057     GetTxBuffer,
00058     &ethernet,
00059     EMAC_ETH_MAX_FLEN
00060 };
00061 
00062 
00063 static int32_t Init(NetIF_t *netIF)
00064 {
00065     int32_t                result = 0;
00066     uint8_t                initMac[6];
00067     Ethernet_Addr_t        *hwAddress = (Ethernet_Addr_t *)netIF->driverParameter;
00068 
00069     initMac[0] = hwAddress->MA0;
00070     initMac[1] = hwAddress->MA1;
00071     initMac[2] = hwAddress->MA2;
00072     initMac[3] = hwAddress->MA3;
00073     initMac[4] = hwAddress->MA4;
00074     initMac[5] = hwAddress->MA5;
00075     
00076     DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing device driver '%s' with hardware address %02x:%02x:%02x:%02x:%02x:%02x",
00077         netIF->driver->name,
00078         initMac[0],
00079         initMac[1],
00080         initMac[2],
00081         initMac[3],
00082         initMac[4],
00083         initMac[5]
00084     ));
00085 
00086     rxBuffer.pbDataBuf = (uint32_t *)&rxPacket;
00087     
00088     mbedNetIF = netIF;
00089     
00090     PinCfg.Funcnum = 1;
00091     PinCfg.OpenDrain = 0;
00092     PinCfg.Pinmode = 0;
00093     PinCfg.Portnum = 1;
00094 
00095     PinCfg.Pinnum = 0;
00096     PINSEL_ConfigPin(&PinCfg);
00097     PinCfg.Pinnum = 1;
00098     PINSEL_ConfigPin(&PinCfg);
00099     PinCfg.Pinnum = 4;
00100     PINSEL_ConfigPin(&PinCfg);
00101     PinCfg.Pinnum = 8;
00102     PINSEL_ConfigPin(&PinCfg);
00103     PinCfg.Pinnum = 9;
00104     PINSEL_ConfigPin(&PinCfg);
00105     PinCfg.Pinnum = 10;
00106     PINSEL_ConfigPin(&PinCfg);
00107     PinCfg.Pinnum = 14;
00108     PINSEL_ConfigPin(&PinCfg);
00109     PinCfg.Pinnum = 15;
00110     PINSEL_ConfigPin(&PinCfg);
00111     PinCfg.Pinnum = 16;
00112     PINSEL_ConfigPin(&PinCfg);
00113     PinCfg.Pinnum = 17;
00114     PINSEL_ConfigPin(&PinCfg);
00115     
00116     Emac_Config.Mode = EMAC_MODE_AUTO;
00117     Emac_Config.pbEMAC_Addr = initMac;
00118     
00119     memset(txPacket, 0, sizeof(txPacket));
00120     
00121     if (EMAC_Init(&Emac_Config) == ERROR)
00122     {
00123         DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Error during initializing EMAC, restart after a while"));
00124     }
00125 
00126     Write(txPacket, 14);    /* Send dummy frame at init as workaround described in chapter 3.3 of errata sheet document 'ES_LPC176x' rev 9 from June 2011 page 6 */
00127     
00128     //NVIC_SetPriority(ENET_IRQn, 10);
00129     
00130     Disable();
00131         
00132     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
00133     return result;
00134 }
00135 
00136 
00137 static int32_t Read(uint8_t **packet, int32_t *length)
00138 {
00139     int32_t        result = 0;
00140 
00141     if (EMAC_CheckReceiveIndex() == FALSE)
00142     {
00143         mbedNet_LastError = mbedNetResult_QueueEmpty;
00144         result = -1;
00145     }
00146     else
00147     {
00148         rxBuffer.ulDataLen = EMAC_GetReceiveDataSize();
00149         *length = rxBuffer.ulDataLen;
00150         EMAC_ReadPacketBuffer(&rxBuffer);
00151         EMAC_UpdateRxConsumeIndex();
00152         
00153         *packet = (uint8_t *)rxBuffer.pbDataBuf;
00154         DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("received %d byte frame", *length));
00155     }
00156     
00157     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
00158     return result;
00159 }
00160 
00161 
00162 static int32_t Write(uint8_t *packet, int32_t length)
00163 {
00164     int32_t        result = 0;
00165     
00166     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("request to send %d bytes", length));
00167     
00168     if (EMAC_TxBufferNotFull())
00169     {
00170         DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
00171         {
00172             Debug_DumpBufferHex(packet, length);
00173         }
00174         txBuffer.ulDataLen = length;
00175         txBuffer.pbDataBuf = (uint32_t *)packet;
00176         EMAC_WritePacketBuffer(&txBuffer);
00177         EMAC_UpdateTxProduceIndex();
00178         DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("transmitted %d byte frame", length));
00179     }
00180     else
00181     {
00182         DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("transmission queue is full"));
00183         mbedNet_LastError = mbedNetResult_QueueEmpty;
00184         result = -1;
00185     }
00186     DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
00187     return result;
00188 }
00189 
00190 
00191 static void Enable(void)
00192 {
00193     /* Enable receive and transmit mode of MAC Ethernet core */
00194     LPC_EMAC->Command  |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
00195     LPC_EMAC->MAC1     |= EMAC_MAC1_REC_EN; 
00196     NVIC_EnableIRQ(ENET_IRQn);
00197 }
00198 
00199 
00200 static void Disable(void)
00201 {
00202     /* Disable receive and transmit mode of MAC Ethernet core */
00203     NVIC_DisableIRQ(ENET_IRQn);
00204     LPC_EMAC->Command  &= ~(EMAC_CR_RX_EN | EMAC_CR_TX_EN);
00205     LPC_EMAC->MAC1     &= ~EMAC_MAC1_REC_EN;    
00206     while(EMAC_CheckReceiveIndex()) EMAC_UpdateRxConsumeIndex();
00207 }
00208 
00209 
00210 static uint8_t *GetTxBuffer(void)
00211 {
00212     return txPacket;
00213 }
00214 
00215 
00216 static Bool_t EMAC_TxBufferNotFull(void)
00217 {
00218     uint32_t    tmp = LPC_EMAC->TxProduceIndex + 1;
00219     
00220     if (tmp == EMAC_NUM_TX_FRAG) tmp = 0;
00221     return (LPC_EMAC->TxConsumeIndex != tmp) ? True : False;
00222 }
00223 
00224 
00225 extern "C" void ENET_IRQHandler(void)
00226 {
00227     uint32_t        status;
00228     NetPacket_t     rxP;
00229     
00230     status = LPC_EMAC->IntStatus;
00231     LPC_EMAC->IntClear = status;
00232     
00233     if(status & EMAC_INT_RX_DONE) 
00234     {
00235         while(EMAC_CheckReceiveIndex() == TRUE)
00236         {
00237             if (Read(&rxP.data, &rxP.length) == 0)
00238             {
00239                 rxP.depth = -1;
00240                 ethernet.HandlePacket(mbedNetIF, &rxP);
00241             }
00242         }
00243     }
00244 }