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 12 11:23:03 2011 +0000
Revision:
0:19f5f51584de
Initial release (alpha quality)

Who changed what in which revision?

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