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.
Diff: mbedNetIF.cpp
- Revision:
- 1:f4040665bc61
- Child:
- 5:3cd83fcb1467
diff -r 19f5f51584de -r f4040665bc61 mbedNetIF.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbedNetIF.cpp Sun Jun 12 19:17:11 2011 +0000 @@ -0,0 +1,244 @@ +/* + * $Id: mbedNetIF.c 28 2011-06-10 10:16:30Z benoit $ + * $Author: benoit $ + * $Date: 2011-06-10 12:16:30 +0200 (ven., 10 juin 2011) $ + * $Rev: 28 $ + * + * + * + * + * + */ + +#include "mbedNetIF.h" +#include "Ethernet.h" +#include "mbedNet.h" +#include "NetIF.h" +#include "Debug.h" +#include "lpc17xx_pinsel.h" +#include "lpc17xx_emac.h" +#include <string.h> + + +#define DEBUG_CURRENT_MODULE_NAME "mbedNetIF" +#define DEBUG_CURRENT_MODULE_ID DEBUG_MODULE_MBEDNETIF + + +static int32_t Init(NetIF_t *netif); +static int32_t Read(uint8_t **packet, int32_t *length); +static int32_t Write(uint8_t *packet, int32_t length); +static void Enable(void); +static void Disable(void); +static uint8_t *GetTxBuffer(void); + + +#define MBEDNETIF_DRIVER_NAME "mbedEMAC" + + +static EMAC_CFG_Type Emac_Config; +static PINSEL_CFG_Type PinCfg; +static uint8_t rxPacket[EMAC_ETH_MAX_FLEN], + txPacket[EMAC_ETH_MAX_FLEN]; +static EMAC_PACKETBUF_Type rxBuffer, + txBuffer; +static NetIF_t *mbedNetIF = NULL; + +static Bool_t EMAC_TxBufferNotFull(void); + + +NetIF_Driver_t mbedNetIF_Driver = +{ + MBEDNETIF_DRIVER_NAME, + Init, + Read, + Write, + Enable, + Disable, + GetTxBuffer, + ðernet, + EMAC_ETH_MAX_FLEN +}; + + +static int32_t Init(NetIF_t *netIF) +{ + int32_t result = 0; + uint8_t initMac[6]; + Ethernet_Addr_t *hwAddress = (Ethernet_Addr_t *)netIF->driverParameter; + + initMac[0] = hwAddress->MA0; + initMac[1] = hwAddress->MA1; + initMac[2] = hwAddress->MA2; + initMac[3] = hwAddress->MA3; + initMac[4] = hwAddress->MA4; + initMac[5] = hwAddress->MA5; + + DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing device driver '%s' with hardware address %02x:%02x:%02x:%02x:%02x:%02x", + netIF->driver->name, + initMac[0], + initMac[1], + initMac[2], + initMac[3], + initMac[4], + initMac[5] + )); + + rxBuffer.pbDataBuf = (uint32_t *)&rxPacket; + + mbedNetIF = netIF; + + PinCfg.Funcnum = 1; + PinCfg.OpenDrain = 0; + PinCfg.Pinmode = 0; + PinCfg.Portnum = 1; + + PinCfg.Pinnum = 0; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 1; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 4; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 8; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 9; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 10; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 14; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 15; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 16; + PINSEL_ConfigPin(&PinCfg); + PinCfg.Pinnum = 17; + PINSEL_ConfigPin(&PinCfg); + + Emac_Config.Mode = EMAC_MODE_AUTO; + Emac_Config.pbEMAC_Addr = initMac; + + memset(txPacket, 0, sizeof(txPacket)); + + if (EMAC_Init(&Emac_Config) == ERROR) + { + DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Error during initializing EMAC, restart after a while")); + } + + 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 */ + + //NVIC_SetPriority(ENET_IRQn, 10); + + Disable(); + + DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result)); + return result; +} + + +static int32_t Read(uint8_t **packet, int32_t *length) +{ + int32_t result = 0; + + if (EMAC_CheckReceiveIndex() == FALSE) + { + mbedNet_LastError = mbedNetResult_QueueEmpty; + result = -1; + } + else + { + rxBuffer.ulDataLen = EMAC_GetReceiveDataSize(); + *length = rxBuffer.ulDataLen; + EMAC_ReadPacketBuffer(&rxBuffer); + EMAC_UpdateRxConsumeIndex(); + + *packet = (uint8_t *)rxBuffer.pbDataBuf; + DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("received %d byte frame", *length)); + } + + DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result)); + return result; +} + + +static int32_t Write(uint8_t *packet, int32_t length) +{ + int32_t result = 0; + + DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("request to send %d bytes", length)); + + if (EMAC_TxBufferNotFull()) + { + DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0) + { + Debug_DumpBufferHex(packet, length); + } + txBuffer.ulDataLen = length; + txBuffer.pbDataBuf = (uint32_t *)packet; + EMAC_WritePacketBuffer(&txBuffer); + EMAC_UpdateTxProduceIndex(); + DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("transmitted %d byte frame", length)); + } + else + { + DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("transmission queue is full")); + mbedNet_LastError = mbedNetResult_QueueEmpty; + result = -1; + } + DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result)); + return result; +} + + +static void Enable(void) +{ + /* Enable receive and transmit mode of MAC Ethernet core */ + LPC_EMAC->Command |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN); + LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN; + NVIC_EnableIRQ(ENET_IRQn); +} + + +static void Disable(void) +{ + /* Disable receive and transmit mode of MAC Ethernet core */ + NVIC_DisableIRQ(ENET_IRQn); + LPC_EMAC->Command &= ~(EMAC_CR_RX_EN | EMAC_CR_TX_EN); + LPC_EMAC->MAC1 &= ~EMAC_MAC1_REC_EN; + while(EMAC_CheckReceiveIndex()) EMAC_UpdateRxConsumeIndex(); +} + + +static uint8_t *GetTxBuffer(void) +{ + return txPacket; +} + + +static Bool_t EMAC_TxBufferNotFull(void) +{ + uint32_t tmp = LPC_EMAC->TxProduceIndex + 1; + + if (tmp == EMAC_NUM_TX_FRAG) tmp = 0; + return (LPC_EMAC->TxConsumeIndex != tmp) ? True : False; +} + + +extern "C" void ENET_IRQHandler(void) +{ + uint32_t status; + Packet_t rxP; + + status = LPC_EMAC->IntStatus; + LPC_EMAC->IntClear = status; + + if(status & EMAC_INT_RX_DONE) + { + while(EMAC_CheckReceiveIndex() == TRUE) + { + if (Read(&rxP.data, &rxP.length) == 0) + { + rxP.depth = -1; + ethernet.HandlePacket(mbedNetIF, &rxP); + } + } + } +}