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.

Committer:
Benoit
Date:
Sun Jun 26 09:56:31 2011 +0000
Revision:
7:8e12f7357b9f
Parent:
5:3cd83fcb1467
Added IPv4 global broadcast address to processed frames inside IPv4 layer.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Benoit 1:f4040665bc61 1 /*
Benoit 1:f4040665bc61 2 * $Id: mbedNetIF.c 28 2011-06-10 10:16:30Z benoit $
Benoit 1:f4040665bc61 3 * $Author: benoit $
Benoit 1:f4040665bc61 4 * $Date: 2011-06-10 12:16:30 +0200 (ven., 10 juin 2011) $
Benoit 1:f4040665bc61 5 * $Rev: 28 $
Benoit 1:f4040665bc61 6 *
Benoit 1:f4040665bc61 7 *
Benoit 1:f4040665bc61 8 *
Benoit 1:f4040665bc61 9 *
Benoit 1:f4040665bc61 10 *
Benoit 1:f4040665bc61 11 */
Benoit 1:f4040665bc61 12
Benoit 1:f4040665bc61 13 #include "mbedNetIF.h"
Benoit 1:f4040665bc61 14 #include "Ethernet.h"
Benoit 1:f4040665bc61 15 #include "mbedNet.h"
Benoit 1:f4040665bc61 16 #include "NetIF.h"
Benoit 1:f4040665bc61 17 #include "Debug.h"
Benoit 1:f4040665bc61 18 #include "lpc17xx_pinsel.h"
Benoit 1:f4040665bc61 19 #include "lpc17xx_emac.h"
Benoit 1:f4040665bc61 20 #include <string.h>
Benoit 1:f4040665bc61 21
Benoit 1:f4040665bc61 22
Benoit 1:f4040665bc61 23 #define DEBUG_CURRENT_MODULE_NAME "mbedNetIF"
Benoit 1:f4040665bc61 24 #define DEBUG_CURRENT_MODULE_ID DEBUG_MODULE_MBEDNETIF
Benoit 1:f4040665bc61 25
Benoit 1:f4040665bc61 26
Benoit 1:f4040665bc61 27 static int32_t Init(NetIF_t *netif);
Benoit 1:f4040665bc61 28 static int32_t Read(uint8_t **packet, int32_t *length);
Benoit 1:f4040665bc61 29 static int32_t Write(uint8_t *packet, int32_t length);
Benoit 1:f4040665bc61 30 static void Enable(void);
Benoit 1:f4040665bc61 31 static void Disable(void);
Benoit 1:f4040665bc61 32 static uint8_t *GetTxBuffer(void);
Benoit 1:f4040665bc61 33
Benoit 1:f4040665bc61 34
Benoit 1:f4040665bc61 35 #define MBEDNETIF_DRIVER_NAME "mbedEMAC"
Benoit 1:f4040665bc61 36
Benoit 1:f4040665bc61 37
Benoit 1:f4040665bc61 38 static EMAC_CFG_Type Emac_Config;
Benoit 1:f4040665bc61 39 static PINSEL_CFG_Type PinCfg;
Benoit 1:f4040665bc61 40 static uint8_t rxPacket[EMAC_ETH_MAX_FLEN],
Benoit 1:f4040665bc61 41 txPacket[EMAC_ETH_MAX_FLEN];
Benoit 1:f4040665bc61 42 static EMAC_PACKETBUF_Type rxBuffer,
Benoit 1:f4040665bc61 43 txBuffer;
Benoit 1:f4040665bc61 44 static NetIF_t *mbedNetIF = NULL;
Benoit 1:f4040665bc61 45
Benoit 1:f4040665bc61 46 static Bool_t EMAC_TxBufferNotFull(void);
Benoit 1:f4040665bc61 47
Benoit 1:f4040665bc61 48
Benoit 1:f4040665bc61 49 NetIF_Driver_t mbedNetIF_Driver =
Benoit 1:f4040665bc61 50 {
Benoit 1:f4040665bc61 51 MBEDNETIF_DRIVER_NAME,
Benoit 1:f4040665bc61 52 Init,
Benoit 1:f4040665bc61 53 Read,
Benoit 1:f4040665bc61 54 Write,
Benoit 1:f4040665bc61 55 Enable,
Benoit 1:f4040665bc61 56 Disable,
Benoit 1:f4040665bc61 57 GetTxBuffer,
Benoit 1:f4040665bc61 58 &ethernet,
Benoit 1:f4040665bc61 59 EMAC_ETH_MAX_FLEN
Benoit 1:f4040665bc61 60 };
Benoit 1:f4040665bc61 61
Benoit 1:f4040665bc61 62
Benoit 1:f4040665bc61 63 static int32_t Init(NetIF_t *netIF)
Benoit 1:f4040665bc61 64 {
Benoit 1:f4040665bc61 65 int32_t result = 0;
Benoit 1:f4040665bc61 66 uint8_t initMac[6];
Benoit 1:f4040665bc61 67 Ethernet_Addr_t *hwAddress = (Ethernet_Addr_t *)netIF->driverParameter;
Benoit 1:f4040665bc61 68
Benoit 1:f4040665bc61 69 initMac[0] = hwAddress->MA0;
Benoit 1:f4040665bc61 70 initMac[1] = hwAddress->MA1;
Benoit 1:f4040665bc61 71 initMac[2] = hwAddress->MA2;
Benoit 1:f4040665bc61 72 initMac[3] = hwAddress->MA3;
Benoit 1:f4040665bc61 73 initMac[4] = hwAddress->MA4;
Benoit 1:f4040665bc61 74 initMac[5] = hwAddress->MA5;
Benoit 1:f4040665bc61 75
Benoit 1:f4040665bc61 76 DEBUG_MODULE(DEBUG_LEVEL_INFO, ("Initializing device driver '%s' with hardware address %02x:%02x:%02x:%02x:%02x:%02x",
Benoit 1:f4040665bc61 77 netIF->driver->name,
Benoit 1:f4040665bc61 78 initMac[0],
Benoit 1:f4040665bc61 79 initMac[1],
Benoit 1:f4040665bc61 80 initMac[2],
Benoit 1:f4040665bc61 81 initMac[3],
Benoit 1:f4040665bc61 82 initMac[4],
Benoit 1:f4040665bc61 83 initMac[5]
Benoit 1:f4040665bc61 84 ));
Benoit 1:f4040665bc61 85
Benoit 1:f4040665bc61 86 rxBuffer.pbDataBuf = (uint32_t *)&rxPacket;
Benoit 1:f4040665bc61 87
Benoit 1:f4040665bc61 88 mbedNetIF = netIF;
Benoit 1:f4040665bc61 89
Benoit 1:f4040665bc61 90 PinCfg.Funcnum = 1;
Benoit 1:f4040665bc61 91 PinCfg.OpenDrain = 0;
Benoit 1:f4040665bc61 92 PinCfg.Pinmode = 0;
Benoit 1:f4040665bc61 93 PinCfg.Portnum = 1;
Benoit 1:f4040665bc61 94
Benoit 1:f4040665bc61 95 PinCfg.Pinnum = 0;
Benoit 1:f4040665bc61 96 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 97 PinCfg.Pinnum = 1;
Benoit 1:f4040665bc61 98 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 99 PinCfg.Pinnum = 4;
Benoit 1:f4040665bc61 100 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 101 PinCfg.Pinnum = 8;
Benoit 1:f4040665bc61 102 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 103 PinCfg.Pinnum = 9;
Benoit 1:f4040665bc61 104 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 105 PinCfg.Pinnum = 10;
Benoit 1:f4040665bc61 106 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 107 PinCfg.Pinnum = 14;
Benoit 1:f4040665bc61 108 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 109 PinCfg.Pinnum = 15;
Benoit 1:f4040665bc61 110 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 111 PinCfg.Pinnum = 16;
Benoit 1:f4040665bc61 112 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 113 PinCfg.Pinnum = 17;
Benoit 1:f4040665bc61 114 PINSEL_ConfigPin(&PinCfg);
Benoit 1:f4040665bc61 115
Benoit 1:f4040665bc61 116 Emac_Config.Mode = EMAC_MODE_AUTO;
Benoit 1:f4040665bc61 117 Emac_Config.pbEMAC_Addr = initMac;
Benoit 1:f4040665bc61 118
Benoit 1:f4040665bc61 119 memset(txPacket, 0, sizeof(txPacket));
Benoit 1:f4040665bc61 120
Benoit 1:f4040665bc61 121 if (EMAC_Init(&Emac_Config) == ERROR)
Benoit 1:f4040665bc61 122 {
Benoit 1:f4040665bc61 123 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("Error during initializing EMAC, restart after a while"));
Benoit 1:f4040665bc61 124 }
Benoit 1:f4040665bc61 125
Benoit 1:f4040665bc61 126 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 */
Benoit 1:f4040665bc61 127
Benoit 1:f4040665bc61 128 //NVIC_SetPriority(ENET_IRQn, 10);
Benoit 1:f4040665bc61 129
Benoit 1:f4040665bc61 130 Disable();
Benoit 1:f4040665bc61 131
Benoit 1:f4040665bc61 132 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
Benoit 1:f4040665bc61 133 return result;
Benoit 1:f4040665bc61 134 }
Benoit 1:f4040665bc61 135
Benoit 1:f4040665bc61 136
Benoit 1:f4040665bc61 137 static int32_t Read(uint8_t **packet, int32_t *length)
Benoit 1:f4040665bc61 138 {
Benoit 1:f4040665bc61 139 int32_t result = 0;
Benoit 1:f4040665bc61 140
Benoit 1:f4040665bc61 141 if (EMAC_CheckReceiveIndex() == FALSE)
Benoit 1:f4040665bc61 142 {
Benoit 1:f4040665bc61 143 mbedNet_LastError = mbedNetResult_QueueEmpty;
Benoit 1:f4040665bc61 144 result = -1;
Benoit 1:f4040665bc61 145 }
Benoit 1:f4040665bc61 146 else
Benoit 1:f4040665bc61 147 {
Benoit 1:f4040665bc61 148 rxBuffer.ulDataLen = EMAC_GetReceiveDataSize();
Benoit 1:f4040665bc61 149 *length = rxBuffer.ulDataLen;
Benoit 1:f4040665bc61 150 EMAC_ReadPacketBuffer(&rxBuffer);
Benoit 1:f4040665bc61 151 EMAC_UpdateRxConsumeIndex();
Benoit 1:f4040665bc61 152
Benoit 1:f4040665bc61 153 *packet = (uint8_t *)rxBuffer.pbDataBuf;
Benoit 1:f4040665bc61 154 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("received %d byte frame", *length));
Benoit 1:f4040665bc61 155 }
Benoit 1:f4040665bc61 156
Benoit 1:f4040665bc61 157 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
Benoit 1:f4040665bc61 158 return result;
Benoit 1:f4040665bc61 159 }
Benoit 1:f4040665bc61 160
Benoit 1:f4040665bc61 161
Benoit 1:f4040665bc61 162 static int32_t Write(uint8_t *packet, int32_t length)
Benoit 1:f4040665bc61 163 {
Benoit 1:f4040665bc61 164 int32_t result = 0;
Benoit 1:f4040665bc61 165
Benoit 1:f4040665bc61 166 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("request to send %d bytes", length));
Benoit 1:f4040665bc61 167
Benoit 1:f4040665bc61 168 if (EMAC_TxBufferNotFull())
Benoit 1:f4040665bc61 169 {
Benoit 1:f4040665bc61 170 DEBUG_BLOCK(DEBUG_LEVEL_VERBOSE0)
Benoit 1:f4040665bc61 171 {
Benoit 1:f4040665bc61 172 Debug_DumpBufferHex(packet, length);
Benoit 1:f4040665bc61 173 }
Benoit 1:f4040665bc61 174 txBuffer.ulDataLen = length;
Benoit 1:f4040665bc61 175 txBuffer.pbDataBuf = (uint32_t *)packet;
Benoit 1:f4040665bc61 176 EMAC_WritePacketBuffer(&txBuffer);
Benoit 1:f4040665bc61 177 EMAC_UpdateTxProduceIndex();
Benoit 1:f4040665bc61 178 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE1, ("transmitted %d byte frame", length));
Benoit 1:f4040665bc61 179 }
Benoit 1:f4040665bc61 180 else
Benoit 1:f4040665bc61 181 {
Benoit 1:f4040665bc61 182 DEBUG_SOURCE(DEBUG_LEVEL_ERROR, ("transmission queue is full"));
Benoit 1:f4040665bc61 183 mbedNet_LastError = mbedNetResult_QueueEmpty;
Benoit 1:f4040665bc61 184 result = -1;
Benoit 1:f4040665bc61 185 }
Benoit 1:f4040665bc61 186 DEBUG_MODULE(DEBUG_LEVEL_VERBOSE2, ("leaving with code %d", result));
Benoit 1:f4040665bc61 187 return result;
Benoit 1:f4040665bc61 188 }
Benoit 1:f4040665bc61 189
Benoit 1:f4040665bc61 190
Benoit 1:f4040665bc61 191 static void Enable(void)
Benoit 1:f4040665bc61 192 {
Benoit 1:f4040665bc61 193 /* Enable receive and transmit mode of MAC Ethernet core */
Benoit 1:f4040665bc61 194 LPC_EMAC->Command |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
Benoit 1:f4040665bc61 195 LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;
Benoit 1:f4040665bc61 196 NVIC_EnableIRQ(ENET_IRQn);
Benoit 1:f4040665bc61 197 }
Benoit 1:f4040665bc61 198
Benoit 1:f4040665bc61 199
Benoit 1:f4040665bc61 200 static void Disable(void)
Benoit 1:f4040665bc61 201 {
Benoit 1:f4040665bc61 202 /* Disable receive and transmit mode of MAC Ethernet core */
Benoit 1:f4040665bc61 203 NVIC_DisableIRQ(ENET_IRQn);
Benoit 1:f4040665bc61 204 LPC_EMAC->Command &= ~(EMAC_CR_RX_EN | EMAC_CR_TX_EN);
Benoit 1:f4040665bc61 205 LPC_EMAC->MAC1 &= ~EMAC_MAC1_REC_EN;
Benoit 1:f4040665bc61 206 while(EMAC_CheckReceiveIndex()) EMAC_UpdateRxConsumeIndex();
Benoit 1:f4040665bc61 207 }
Benoit 1:f4040665bc61 208
Benoit 1:f4040665bc61 209
Benoit 1:f4040665bc61 210 static uint8_t *GetTxBuffer(void)
Benoit 1:f4040665bc61 211 {
Benoit 1:f4040665bc61 212 return txPacket;
Benoit 1:f4040665bc61 213 }
Benoit 1:f4040665bc61 214
Benoit 1:f4040665bc61 215
Benoit 1:f4040665bc61 216 static Bool_t EMAC_TxBufferNotFull(void)
Benoit 1:f4040665bc61 217 {
Benoit 1:f4040665bc61 218 uint32_t tmp = LPC_EMAC->TxProduceIndex + 1;
Benoit 1:f4040665bc61 219
Benoit 1:f4040665bc61 220 if (tmp == EMAC_NUM_TX_FRAG) tmp = 0;
Benoit 1:f4040665bc61 221 return (LPC_EMAC->TxConsumeIndex != tmp) ? True : False;
Benoit 1:f4040665bc61 222 }
Benoit 1:f4040665bc61 223
Benoit 1:f4040665bc61 224
Benoit 1:f4040665bc61 225 extern "C" void ENET_IRQHandler(void)
Benoit 1:f4040665bc61 226 {
Benoit 1:f4040665bc61 227 uint32_t status;
Benoit 5:3cd83fcb1467 228 NetPacket_t rxP;
Benoit 1:f4040665bc61 229
Benoit 1:f4040665bc61 230 status = LPC_EMAC->IntStatus;
Benoit 1:f4040665bc61 231 LPC_EMAC->IntClear = status;
Benoit 1:f4040665bc61 232
Benoit 1:f4040665bc61 233 if(status & EMAC_INT_RX_DONE)
Benoit 1:f4040665bc61 234 {
Benoit 1:f4040665bc61 235 while(EMAC_CheckReceiveIndex() == TRUE)
Benoit 1:f4040665bc61 236 {
Benoit 1:f4040665bc61 237 if (Read(&rxP.data, &rxP.length) == 0)
Benoit 1:f4040665bc61 238 {
Benoit 1:f4040665bc61 239 rxP.depth = -1;
Benoit 1:f4040665bc61 240 ethernet.HandlePacket(mbedNetIF, &rxP);
Benoit 1:f4040665bc61 241 }
Benoit 1:f4040665bc61 242 }
Benoit 1:f4040665bc61 243 }
Benoit 1:f4040665bc61 244 }