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 4:cb3dc3361be5 1 /* @cond */
Benoit 1:f4040665bc61 2 /**
Benoit 1:f4040665bc61 3 * @file lpc17xx_emac.c
Benoit 1:f4040665bc61 4 * @brief Contains all functions support for Ethernet MAC firmware library on LPC17xx
Benoit 1:f4040665bc61 5 * @version 2.0
Benoit 1:f4040665bc61 6 * @date 21. May. 2010
Benoit 1:f4040665bc61 7 * @author NXP MCU SW Application Team
Benoit 1:f4040665bc61 8 **************************************************************************
Benoit 1:f4040665bc61 9 * Software that is described herein is for illustrative purposes only
Benoit 1:f4040665bc61 10 * which provides customers with programming information regarding the
Benoit 1:f4040665bc61 11 * products. This software is supplied "AS IS" without any warranties.
Benoit 1:f4040665bc61 12 * NXP Semiconductors assumes no responsibility or liability for the
Benoit 1:f4040665bc61 13 * use of the software, conveys no license or title under any patent,
Benoit 1:f4040665bc61 14 * copyright, or mask work right to the product. NXP Semiconductors
Benoit 1:f4040665bc61 15 * reserves the right to make changes in the software without
Benoit 1:f4040665bc61 16 * notification. NXP Semiconductors also make no representation or
Benoit 1:f4040665bc61 17 * warranty that such application will be suitable for the specified
Benoit 1:f4040665bc61 18 * use without further testing or modification.
Benoit 1:f4040665bc61 19 **********************************************************************/
Benoit 1:f4040665bc61 20
Benoit 1:f4040665bc61 21 /* Peripheral group ----------------------------------------------------------- */
Benoit 1:f4040665bc61 22 /** @addtogroup EMAC
Benoit 1:f4040665bc61 23 * @{
Benoit 1:f4040665bc61 24 */
Benoit 1:f4040665bc61 25
Benoit 1:f4040665bc61 26 /* Includes ------------------------------------------------------------------- */
Benoit 1:f4040665bc61 27 #include "lpc17xx_emac.h"
Benoit 1:f4040665bc61 28 #include "lpc17xx_clkpwr.h"
Benoit 1:f4040665bc61 29
Benoit 1:f4040665bc61 30 /* If this source file built with example, the LPC17xx FW library configuration
Benoit 1:f4040665bc61 31 * file in each example directory ("lpc17xx_libcfg.h") must be included,
Benoit 1:f4040665bc61 32 * otherwise the default FW library configuration file must be included instead
Benoit 1:f4040665bc61 33 */
Benoit 1:f4040665bc61 34 #ifdef __BUILD_WITH_EXAMPLE__
Benoit 1:f4040665bc61 35 #include "lpc17xx_libcfg.h"
Benoit 1:f4040665bc61 36 #else
Benoit 1:f4040665bc61 37 #include "lpc17xx_libcfg_default.h"
Benoit 1:f4040665bc61 38 #endif /* __BUILD_WITH_EXAMPLE__ */
Benoit 1:f4040665bc61 39
Benoit 1:f4040665bc61 40
Benoit 1:f4040665bc61 41 #ifdef _EMAC
Benoit 1:f4040665bc61 42
Benoit 1:f4040665bc61 43 /* Private Variables ---------------------------------------------------------- */
Benoit 1:f4040665bc61 44 /** @defgroup EMAC_Private_Variables EMAC Private Variables
Benoit 1:f4040665bc61 45 * @{
Benoit 1:f4040665bc61 46 */
Benoit 1:f4040665bc61 47
Benoit 1:f4040665bc61 48 /* MII Mgmt Configuration register - Clock divider setting */
Benoit 1:f4040665bc61 49 const uint8_t EMAC_clkdiv[] = { 4, 6, 8, 10, 14, 20, 28 };
Benoit 1:f4040665bc61 50
Benoit 1:f4040665bc61 51 /* EMAC local DMA Descriptors */
Benoit 1:f4040665bc61 52
Benoit 1:f4040665bc61 53 /** Rx Descriptor data array */
Benoit 1:f4040665bc61 54 static RX_Desc Rx_Desc[EMAC_NUM_RX_FRAG];
Benoit 1:f4040665bc61 55
Benoit 1:f4040665bc61 56 /** Rx Status data array - Must be 8-Byte aligned */
Benoit 1:f4040665bc61 57 #if defined ( __CC_ARM )
Benoit 1:f4040665bc61 58 static __align(8) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
Benoit 1:f4040665bc61 59 #elif defined ( __ICCARM__ )
Benoit 1:f4040665bc61 60 #pragma data_alignment=8
Benoit 1:f4040665bc61 61 static RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
Benoit 1:f4040665bc61 62 #elif defined ( __GNUC__ )
Benoit 1:f4040665bc61 63 static __attribute__ ((aligned (8))) RX_Stat Rx_Stat[EMAC_NUM_RX_FRAG];
Benoit 1:f4040665bc61 64 #endif
Benoit 1:f4040665bc61 65
Benoit 1:f4040665bc61 66 /** Tx Descriptor data array */
Benoit 1:f4040665bc61 67 static TX_Desc Tx_Desc[EMAC_NUM_TX_FRAG];
Benoit 1:f4040665bc61 68 /** Tx Status data array */
Benoit 1:f4040665bc61 69 static TX_Stat Tx_Stat[EMAC_NUM_TX_FRAG];
Benoit 1:f4040665bc61 70
Benoit 1:f4040665bc61 71 /* EMAC local DMA buffers */
Benoit 1:f4040665bc61 72 /** Rx buffer data */
Benoit 1:f4040665bc61 73 static __align(8) uint32_t rx_buf[EMAC_NUM_RX_FRAG][EMAC_ETH_MAX_FLEN>>2] __attribute((section("AHBSRAM1"),aligned)) ;
Benoit 1:f4040665bc61 74 /** Tx buffer data */
Benoit 1:f4040665bc61 75 static __align(8) uint32_t tx_buf[EMAC_NUM_TX_FRAG][EMAC_ETH_MAX_FLEN>>2] __attribute((section("AHBSRAM1"),aligned)) ;
Benoit 1:f4040665bc61 76
Benoit 1:f4040665bc61 77 /**
Benoit 1:f4040665bc61 78 * @}
Benoit 1:f4040665bc61 79 */
Benoit 1:f4040665bc61 80
Benoit 1:f4040665bc61 81 /* Private Functions ---------------------------------------------------------- */
Benoit 1:f4040665bc61 82 static void rx_descr_init (void);
Benoit 1:f4040665bc61 83 static void tx_descr_init (void);
Benoit 1:f4040665bc61 84 static int32_t write_PHY (uint32_t PhyReg, uint16_t Value);
Benoit 1:f4040665bc61 85 static int32_t read_PHY (uint32_t PhyReg);
Benoit 1:f4040665bc61 86
Benoit 1:f4040665bc61 87 static void setEmacAddr(uint8_t abStationAddr[]);
Benoit 1:f4040665bc61 88 static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len);
Benoit 1:f4040665bc61 89
Benoit 1:f4040665bc61 90
Benoit 1:f4040665bc61 91 /*--------------------------- rx_descr_init ---------------------------------*/
Benoit 1:f4040665bc61 92 /*********************************************************************//**
Benoit 1:f4040665bc61 93 * @brief Initializes RX Descriptor
Benoit 1:f4040665bc61 94 * @param[in] None
Benoit 1:f4040665bc61 95 * @return None
Benoit 1:f4040665bc61 96 ***********************************************************************/
Benoit 1:f4040665bc61 97 static void rx_descr_init (void)
Benoit 1:f4040665bc61 98 {
Benoit 1:f4040665bc61 99 /* Initialize Receive Descriptor and Status array. */
Benoit 1:f4040665bc61 100 uint32_t i;
Benoit 1:f4040665bc61 101
Benoit 1:f4040665bc61 102 for (i = 0; i < EMAC_NUM_RX_FRAG; i++) {
Benoit 1:f4040665bc61 103 Rx_Desc[i].Packet = (uint32_t)&rx_buf[i];
Benoit 1:f4040665bc61 104 Rx_Desc[i].Ctrl = EMAC_RCTRL_INT | (EMAC_ETH_MAX_FLEN - 1);
Benoit 1:f4040665bc61 105 Rx_Stat[i].Info = 0;
Benoit 1:f4040665bc61 106 Rx_Stat[i].HashCRC = 0;
Benoit 1:f4040665bc61 107 }
Benoit 1:f4040665bc61 108
Benoit 1:f4040665bc61 109 /* Set EMAC Receive Descriptor Registers. */
Benoit 1:f4040665bc61 110 LPC_EMAC->RxDescriptor = (uint32_t)&Rx_Desc[0];
Benoit 1:f4040665bc61 111 LPC_EMAC->RxStatus = (uint32_t)&Rx_Stat[0];
Benoit 1:f4040665bc61 112 LPC_EMAC->RxDescriptorNumber = EMAC_NUM_RX_FRAG - 1;
Benoit 1:f4040665bc61 113
Benoit 1:f4040665bc61 114 /* Rx Descriptors Point to 0 */
Benoit 1:f4040665bc61 115 LPC_EMAC->RxConsumeIndex = 0;
Benoit 1:f4040665bc61 116 }
Benoit 1:f4040665bc61 117
Benoit 1:f4040665bc61 118
Benoit 1:f4040665bc61 119 /*--------------------------- tx_descr_init ---- ----------------------------*/
Benoit 1:f4040665bc61 120 /*********************************************************************//**
Benoit 1:f4040665bc61 121 * @brief Initializes TX Descriptor
Benoit 1:f4040665bc61 122 * @param[in] None
Benoit 1:f4040665bc61 123 * @return None
Benoit 1:f4040665bc61 124 ***********************************************************************/
Benoit 1:f4040665bc61 125 static void tx_descr_init (void) {
Benoit 1:f4040665bc61 126 /* Initialize Transmit Descriptor and Status array. */
Benoit 1:f4040665bc61 127 uint32_t i;
Benoit 1:f4040665bc61 128
Benoit 1:f4040665bc61 129 for (i = 0; i < EMAC_NUM_TX_FRAG; i++) {
Benoit 1:f4040665bc61 130 Tx_Desc[i].Packet = (uint32_t)&tx_buf[i];
Benoit 1:f4040665bc61 131 Tx_Desc[i].Ctrl = 0;
Benoit 1:f4040665bc61 132 Tx_Stat[i].Info = 0;
Benoit 1:f4040665bc61 133 }
Benoit 1:f4040665bc61 134
Benoit 1:f4040665bc61 135 /* Set EMAC Transmit Descriptor Registers. */
Benoit 1:f4040665bc61 136 LPC_EMAC->TxDescriptor = (uint32_t)&Tx_Desc[0];
Benoit 1:f4040665bc61 137 LPC_EMAC->TxStatus = (uint32_t)&Tx_Stat[0];
Benoit 1:f4040665bc61 138 LPC_EMAC->TxDescriptorNumber = EMAC_NUM_TX_FRAG - 1;
Benoit 1:f4040665bc61 139
Benoit 1:f4040665bc61 140 /* Tx Descriptors Point to 0 */
Benoit 1:f4040665bc61 141 LPC_EMAC->TxProduceIndex = 0;
Benoit 1:f4040665bc61 142 }
Benoit 1:f4040665bc61 143
Benoit 1:f4040665bc61 144
Benoit 1:f4040665bc61 145 /*--------------------------- write_PHY -------------------------------------*/
Benoit 1:f4040665bc61 146 /*********************************************************************//**
Benoit 1:f4040665bc61 147 * @brief Write value to PHY device
Benoit 1:f4040665bc61 148 * @param[in] PhyReg: PHY Register address
Benoit 1:f4040665bc61 149 * @param[in] Value: Value to write
Benoit 1:f4040665bc61 150 * @return 0 - if success
Benoit 1:f4040665bc61 151 * 1 - if fail
Benoit 1:f4040665bc61 152 ***********************************************************************/
Benoit 1:f4040665bc61 153 static int32_t write_PHY (uint32_t PhyReg, uint16_t Value)
Benoit 1:f4040665bc61 154 {
Benoit 1:f4040665bc61 155 /* Write a data 'Value' to PHY register 'PhyReg'. */
Benoit 1:f4040665bc61 156 uint32_t tout;
Benoit 1:f4040665bc61 157
Benoit 1:f4040665bc61 158 LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
Benoit 1:f4040665bc61 159 LPC_EMAC->MWTD = Value;
Benoit 1:f4040665bc61 160
Benoit 1:f4040665bc61 161 /* Wait until operation completed */
Benoit 1:f4040665bc61 162 tout = 0;
Benoit 1:f4040665bc61 163 for (tout = 0; tout < EMAC_MII_WR_TOUT; tout++) {
Benoit 1:f4040665bc61 164 if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
Benoit 1:f4040665bc61 165 return (0);
Benoit 1:f4040665bc61 166 }
Benoit 1:f4040665bc61 167 }
Benoit 1:f4040665bc61 168 // Time out!
Benoit 1:f4040665bc61 169 return (-1);
Benoit 1:f4040665bc61 170 }
Benoit 1:f4040665bc61 171
Benoit 1:f4040665bc61 172
Benoit 1:f4040665bc61 173 /*--------------------------- read_PHY --------------------------------------*/
Benoit 1:f4040665bc61 174 /*********************************************************************//**
Benoit 1:f4040665bc61 175 * @brief Read value from PHY device
Benoit 1:f4040665bc61 176 * @param[in] PhyReg: PHY Register address
Benoit 1:f4040665bc61 177 * @return 0 - if success
Benoit 1:f4040665bc61 178 * 1 - if fail
Benoit 1:f4040665bc61 179 ***********************************************************************/
Benoit 1:f4040665bc61 180 static int32_t read_PHY (uint32_t PhyReg)
Benoit 1:f4040665bc61 181 {
Benoit 1:f4040665bc61 182 /* Read a PHY register 'PhyReg'. */
Benoit 1:f4040665bc61 183 uint32_t tout;
Benoit 1:f4040665bc61 184
Benoit 1:f4040665bc61 185 LPC_EMAC->MADR = EMAC_DEF_ADR | PhyReg;
Benoit 1:f4040665bc61 186 LPC_EMAC->MCMD = EMAC_MCMD_READ;
Benoit 1:f4040665bc61 187
Benoit 1:f4040665bc61 188 /* Wait until operation completed */
Benoit 1:f4040665bc61 189 tout = 0;
Benoit 1:f4040665bc61 190 for (tout = 0; tout < EMAC_MII_RD_TOUT; tout++) {
Benoit 1:f4040665bc61 191 if ((LPC_EMAC->MIND & EMAC_MIND_BUSY) == 0) {
Benoit 1:f4040665bc61 192 LPC_EMAC->MCMD = 0;
Benoit 1:f4040665bc61 193 return (LPC_EMAC->MRDD);
Benoit 1:f4040665bc61 194 }
Benoit 1:f4040665bc61 195 }
Benoit 1:f4040665bc61 196 // Time out!
Benoit 1:f4040665bc61 197 return (-1);
Benoit 1:f4040665bc61 198 }
Benoit 1:f4040665bc61 199
Benoit 1:f4040665bc61 200 /*********************************************************************//**
Benoit 1:f4040665bc61 201 * @brief Set Station MAC address for EMAC module
Benoit 1:f4040665bc61 202 * @param[in] abStationAddr Pointer to Station address that contains 6-bytes
Benoit 1:f4040665bc61 203 * of MAC address (should be in order from MAC Address 1 to MAC Address 6)
Benoit 1:f4040665bc61 204 * @return None
Benoit 1:f4040665bc61 205 **********************************************************************/
Benoit 1:f4040665bc61 206 static void setEmacAddr(uint8_t abStationAddr[])
Benoit 1:f4040665bc61 207 {
Benoit 1:f4040665bc61 208 /* Set the Ethernet MAC Address registers */
Benoit 1:f4040665bc61 209 LPC_EMAC->SA0 = ((uint32_t)abStationAddr[5] << 8) | (uint32_t)abStationAddr[4];
Benoit 1:f4040665bc61 210 LPC_EMAC->SA1 = ((uint32_t)abStationAddr[3] << 8) | (uint32_t)abStationAddr[2];
Benoit 1:f4040665bc61 211 LPC_EMAC->SA2 = ((uint32_t)abStationAddr[1] << 8) | (uint32_t)abStationAddr[0];
Benoit 1:f4040665bc61 212 }
Benoit 1:f4040665bc61 213
Benoit 1:f4040665bc61 214
Benoit 1:f4040665bc61 215 /*********************************************************************//**
Benoit 1:f4040665bc61 216 * @brief Calculates CRC code for number of bytes in the frame
Benoit 1:f4040665bc61 217 * @param[in] frame_no_fcs Pointer to the first byte of the frame
Benoit 1:f4040665bc61 218 * @param[in] frame_len length of the frame without the FCS
Benoit 1:f4040665bc61 219 * @return the CRC as a 32 bit integer
Benoit 1:f4040665bc61 220 **********************************************************************/
Benoit 1:f4040665bc61 221 static int32_t emac_CRCCalc(uint8_t frame_no_fcs[], int32_t frame_len)
Benoit 1:f4040665bc61 222 {
Benoit 1:f4040665bc61 223 int i; // iterator
Benoit 1:f4040665bc61 224 int j; // another iterator
Benoit 1:f4040665bc61 225 char byte; // current byte
Benoit 1:f4040665bc61 226 int crc; // CRC result
Benoit 1:f4040665bc61 227 int q0, q1, q2, q3; // temporary variables
Benoit 1:f4040665bc61 228 crc = 0xFFFFFFFF;
Benoit 1:f4040665bc61 229 for (i = 0; i < frame_len; i++) {
Benoit 1:f4040665bc61 230 byte = *frame_no_fcs++;
Benoit 1:f4040665bc61 231 for (j = 0; j < 2; j++) {
Benoit 1:f4040665bc61 232 if (((crc >> 28) ^ (byte >> 3)) & 0x00000001) {
Benoit 1:f4040665bc61 233 q3 = 0x04C11DB7;
Benoit 1:f4040665bc61 234 } else {
Benoit 1:f4040665bc61 235 q3 = 0x00000000;
Benoit 1:f4040665bc61 236 }
Benoit 1:f4040665bc61 237 if (((crc >> 29) ^ (byte >> 2)) & 0x00000001) {
Benoit 1:f4040665bc61 238 q2 = 0x09823B6E;
Benoit 1:f4040665bc61 239 } else {
Benoit 1:f4040665bc61 240 q2 = 0x00000000;
Benoit 1:f4040665bc61 241 }
Benoit 1:f4040665bc61 242 if (((crc >> 30) ^ (byte >> 1)) & 0x00000001) {
Benoit 1:f4040665bc61 243 q1 = 0x130476DC;
Benoit 1:f4040665bc61 244 } else {
Benoit 1:f4040665bc61 245 q1 = 0x00000000;
Benoit 1:f4040665bc61 246 }
Benoit 1:f4040665bc61 247 if (((crc >> 31) ^ (byte >> 0)) & 0x00000001) {
Benoit 1:f4040665bc61 248 q0 = 0x2608EDB8;
Benoit 1:f4040665bc61 249 } else {
Benoit 1:f4040665bc61 250 q0 = 0x00000000;
Benoit 1:f4040665bc61 251 }
Benoit 1:f4040665bc61 252 crc = (crc << 4) ^ q3 ^ q2 ^ q1 ^ q0;
Benoit 1:f4040665bc61 253 byte >>= 4;
Benoit 1:f4040665bc61 254 }
Benoit 1:f4040665bc61 255 }
Benoit 1:f4040665bc61 256 return crc;
Benoit 1:f4040665bc61 257 }
Benoit 1:f4040665bc61 258 /* End of Private Functions --------------------------------------------------- */
Benoit 1:f4040665bc61 259
Benoit 1:f4040665bc61 260
Benoit 1:f4040665bc61 261 /* Public Functions ----------------------------------------------------------- */
Benoit 1:f4040665bc61 262 /** @addtogroup EMAC_Public_Functions
Benoit 1:f4040665bc61 263 * @{
Benoit 1:f4040665bc61 264 */
Benoit 1:f4040665bc61 265
Benoit 1:f4040665bc61 266
Benoit 1:f4040665bc61 267 /*********************************************************************//**
Benoit 1:f4040665bc61 268 * @brief Initializes the EMAC peripheral according to the specified
Benoit 1:f4040665bc61 269 * parameters in the EMAC_ConfigStruct.
Benoit 1:f4040665bc61 270 * @param[in] EMAC_ConfigStruct Pointer to a EMAC_CFG_Type structure
Benoit 1:f4040665bc61 271 * that contains the configuration information for the
Benoit 1:f4040665bc61 272 * specified EMAC peripheral.
Benoit 1:f4040665bc61 273 * @return None
Benoit 1:f4040665bc61 274 *
Benoit 1:f4040665bc61 275 * Note: This function will initialize EMAC module according to procedure below:
Benoit 1:f4040665bc61 276 * - Remove the soft reset condition from the MAC
Benoit 1:f4040665bc61 277 * - Configure the PHY via the MIIM interface of the MAC
Benoit 1:f4040665bc61 278 * - Select RMII mode
Benoit 1:f4040665bc61 279 * - Configure the transmit and receive DMA engines, including the descriptor arrays
Benoit 1:f4040665bc61 280 * - Configure the host registers (MAC1,MAC2 etc.) in the MAC
Benoit 1:f4040665bc61 281 * - Enable the receive and transmit data paths
Benoit 1:f4040665bc61 282 * In default state after initializing, only Rx Done and Tx Done interrupt are enabled,
Benoit 1:f4040665bc61 283 * all remain interrupts are disabled
Benoit 1:f4040665bc61 284 * (Ref. from LPC17xx UM)
Benoit 1:f4040665bc61 285 **********************************************************************/
Benoit 1:f4040665bc61 286 Status EMAC_Init(EMAC_CFG_Type *EMAC_ConfigStruct)
Benoit 1:f4040665bc61 287 {
Benoit 1:f4040665bc61 288 /* Initialize the EMAC Ethernet controller. */
Benoit 1:f4040665bc61 289 int32_t regv,tout, tmp;
Benoit 1:f4040665bc61 290
Benoit 1:f4040665bc61 291 /* Set up clock and power for Ethernet module */
Benoit 1:f4040665bc61 292 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, ENABLE);
Benoit 1:f4040665bc61 293
Benoit 1:f4040665bc61 294 /* Reset all EMAC internal modules */
Benoit 1:f4040665bc61 295 LPC_EMAC->MAC1 = EMAC_MAC1_RES_TX | EMAC_MAC1_RES_MCS_TX | EMAC_MAC1_RES_RX |
Benoit 1:f4040665bc61 296 EMAC_MAC1_RES_MCS_RX | EMAC_MAC1_SIM_RES | EMAC_MAC1_SOFT_RES;
Benoit 1:f4040665bc61 297
Benoit 1:f4040665bc61 298 LPC_EMAC->Command = EMAC_CR_REG_RES | EMAC_CR_TX_RES | EMAC_CR_RX_RES | EMAC_CR_PASS_RUNT_FRM;
Benoit 1:f4040665bc61 299
Benoit 1:f4040665bc61 300 /* A short delay after reset. */
Benoit 1:f4040665bc61 301 for (tout = 100; tout; tout--);
Benoit 1:f4040665bc61 302
Benoit 1:f4040665bc61 303 /* Initialize MAC control registers. */
Benoit 1:f4040665bc61 304 LPC_EMAC->MAC1 = EMAC_MAC1_PASS_ALL;
Benoit 1:f4040665bc61 305 LPC_EMAC->MAC2 = EMAC_MAC2_CRC_EN | EMAC_MAC2_PAD_EN;
Benoit 1:f4040665bc61 306 LPC_EMAC->MAXF = EMAC_ETH_MAX_FLEN;
Benoit 1:f4040665bc61 307 /*
Benoit 1:f4040665bc61 308 * Find the clock that close to desired target clock
Benoit 1:f4040665bc61 309 */
Benoit 1:f4040665bc61 310 tmp = SystemCoreClock / EMAC_MCFG_MII_MAXCLK;
Benoit 1:f4040665bc61 311 for (tout = 0; tout < sizeof (EMAC_clkdiv); tout++){
Benoit 1:f4040665bc61 312 if (EMAC_clkdiv[tout] >= tmp) break;
Benoit 1:f4040665bc61 313 }
Benoit 1:f4040665bc61 314 tout++;
Benoit 1:f4040665bc61 315 // Write to MAC configuration register and reset
Benoit 1:f4040665bc61 316 LPC_EMAC->MCFG = EMAC_MCFG_CLK_SEL(tout) | EMAC_MCFG_RES_MII;
Benoit 1:f4040665bc61 317 // release reset
Benoit 1:f4040665bc61 318 LPC_EMAC->MCFG &= ~(EMAC_MCFG_RES_MII);
Benoit 1:f4040665bc61 319 LPC_EMAC->CLRT = EMAC_CLRT_DEF;
Benoit 1:f4040665bc61 320 LPC_EMAC->IPGR = EMAC_IPGR_P2_DEF;
Benoit 1:f4040665bc61 321
Benoit 1:f4040665bc61 322 /* Enable Reduced MII interface. */
Benoit 1:f4040665bc61 323 LPC_EMAC->Command = EMAC_CR_RMII | EMAC_CR_PASS_RUNT_FRM;
Benoit 1:f4040665bc61 324
Benoit 1:f4040665bc61 325 /* Reset Reduced MII Logic. */
Benoit 1:f4040665bc61 326 LPC_EMAC->SUPP = EMAC_SUPP_RES_RMII;
Benoit 1:f4040665bc61 327
Benoit 1:f4040665bc61 328 for (tout = 100; tout; tout--);
Benoit 1:f4040665bc61 329 LPC_EMAC->SUPP = 0;
Benoit 1:f4040665bc61 330
Benoit 1:f4040665bc61 331 /* Put the DP83848C in reset mode */
Benoit 1:f4040665bc61 332 write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_RESET);
Benoit 1:f4040665bc61 333
Benoit 1:f4040665bc61 334 /* Wait for hardware reset to end. */
Benoit 1:f4040665bc61 335 for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
Benoit 1:f4040665bc61 336 regv = read_PHY (EMAC_PHY_REG_BMCR);
Benoit 1:f4040665bc61 337 if (!(regv & (EMAC_PHY_BMCR_RESET | EMAC_PHY_BMCR_POWERDOWN))) {
Benoit 1:f4040665bc61 338 /* Reset complete, device not Power Down. */
Benoit 1:f4040665bc61 339 break;
Benoit 1:f4040665bc61 340 }
Benoit 1:f4040665bc61 341 if (tout == 0){
Benoit 1:f4040665bc61 342 // Time out, return ERROR
Benoit 1:f4040665bc61 343 return (ERROR);
Benoit 1:f4040665bc61 344 }
Benoit 1:f4040665bc61 345 }
Benoit 1:f4040665bc61 346
Benoit 1:f4040665bc61 347 // Set PHY mode
Benoit 1:f4040665bc61 348 if (EMAC_SetPHYMode(EMAC_ConfigStruct->Mode) < 0){
Benoit 1:f4040665bc61 349 return (ERROR);
Benoit 1:f4040665bc61 350 }
Benoit 1:f4040665bc61 351
Benoit 1:f4040665bc61 352 // Set EMAC address
Benoit 1:f4040665bc61 353 setEmacAddr(EMAC_ConfigStruct->pbEMAC_Addr);
Benoit 1:f4040665bc61 354
Benoit 1:f4040665bc61 355 /* Initialize Tx and Rx DMA Descriptors */
Benoit 1:f4040665bc61 356 rx_descr_init ();
Benoit 1:f4040665bc61 357 tx_descr_init ();
Benoit 1:f4040665bc61 358
Benoit 1:f4040665bc61 359 // Set Receive Filter register: enable broadcast and multicast
Benoit 1:f4040665bc61 360 LPC_EMAC->RxFilterCtrl = EMAC_RFC_MCAST_EN | EMAC_RFC_BCAST_EN | EMAC_RFC_PERFECT_EN;
Benoit 1:f4040665bc61 361
Benoit 1:f4040665bc61 362 /* Enable Rx Done and Tx Done interrupt for EMAC */
Benoit 1:f4040665bc61 363 LPC_EMAC->IntEnable = EMAC_INT_RX_DONE/* | EMAC_INT_TX_DONE*/;
Benoit 1:f4040665bc61 364
Benoit 1:f4040665bc61 365 /* Reset all interrupts */
Benoit 1:f4040665bc61 366 LPC_EMAC->IntClear = 0xFFFF;
Benoit 1:f4040665bc61 367
Benoit 1:f4040665bc61 368 /* Enable receive and transmit mode of MAC Ethernet core */
Benoit 1:f4040665bc61 369 LPC_EMAC->Command |= (EMAC_CR_RX_EN | EMAC_CR_TX_EN);
Benoit 1:f4040665bc61 370 LPC_EMAC->MAC1 |= EMAC_MAC1_REC_EN;
Benoit 1:f4040665bc61 371
Benoit 1:f4040665bc61 372 return SUCCESS;
Benoit 1:f4040665bc61 373 }
Benoit 1:f4040665bc61 374
Benoit 1:f4040665bc61 375
Benoit 1:f4040665bc61 376 /*********************************************************************//**
Benoit 1:f4040665bc61 377 * @brief De-initializes the EMAC peripheral registers to their
Benoit 1:f4040665bc61 378 * default reset values.
Benoit 1:f4040665bc61 379 * @param[in] None
Benoit 1:f4040665bc61 380 * @return None
Benoit 1:f4040665bc61 381 **********************************************************************/
Benoit 1:f4040665bc61 382 void EMAC_DeInit(void)
Benoit 1:f4040665bc61 383 {
Benoit 1:f4040665bc61 384 // Disable all interrupt
Benoit 1:f4040665bc61 385 LPC_EMAC->IntEnable = 0x00;
Benoit 1:f4040665bc61 386 // Clear all pending interrupt
Benoit 1:f4040665bc61 387 LPC_EMAC->IntClear = (0xFF) | (EMAC_INT_SOFT_INT | EMAC_INT_WAKEUP);
Benoit 1:f4040665bc61 388
Benoit 1:f4040665bc61 389 /* TurnOff clock and power for Ethernet module */
Benoit 1:f4040665bc61 390 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCENET, DISABLE);
Benoit 1:f4040665bc61 391 }
Benoit 1:f4040665bc61 392
Benoit 1:f4040665bc61 393
Benoit 1:f4040665bc61 394 /*********************************************************************//**
Benoit 1:f4040665bc61 395 * @brief Check specified PHY status in EMAC peripheral
Benoit 1:f4040665bc61 396 * @param[in] ulPHYState Specified PHY Status Type, should be:
Benoit 1:f4040665bc61 397 * - EMAC_PHY_STAT_LINK: Link Status
Benoit 1:f4040665bc61 398 * - EMAC_PHY_STAT_SPEED: Speed Status
Benoit 1:f4040665bc61 399 * - EMAC_PHY_STAT_DUP: Duplex Status
Benoit 1:f4040665bc61 400 * @return Status of specified PHY status (0 or 1).
Benoit 1:f4040665bc61 401 * (-1) if error.
Benoit 1:f4040665bc61 402 *
Benoit 1:f4040665bc61 403 * Note:
Benoit 1:f4040665bc61 404 * For EMAC_PHY_STAT_LINK, return value:
Benoit 1:f4040665bc61 405 * - 0: Link Down
Benoit 1:f4040665bc61 406 * - 1: Link Up
Benoit 1:f4040665bc61 407 * For EMAC_PHY_STAT_SPEED, return value:
Benoit 1:f4040665bc61 408 * - 0: 10Mbps
Benoit 1:f4040665bc61 409 * - 1: 100Mbps
Benoit 1:f4040665bc61 410 * For EMAC_PHY_STAT_DUP, return value:
Benoit 1:f4040665bc61 411 * - 0: Half-Duplex
Benoit 1:f4040665bc61 412 * - 1: Full-Duplex
Benoit 1:f4040665bc61 413 **********************************************************************/
Benoit 1:f4040665bc61 414 int32_t EMAC_CheckPHYStatus(uint32_t ulPHYState)
Benoit 1:f4040665bc61 415 {
Benoit 1:f4040665bc61 416 int32_t regv, tmp;
Benoit 1:f4040665bc61 417 #ifdef MCB_LPC_1768
Benoit 1:f4040665bc61 418 regv = read_PHY (EMAC_PHY_REG_STS);
Benoit 1:f4040665bc61 419 switch(ulPHYState){
Benoit 1:f4040665bc61 420 case EMAC_PHY_STAT_LINK:
Benoit 1:f4040665bc61 421 tmp = (regv & EMAC_PHY_SR_LINK) ? 1 : 0;
Benoit 1:f4040665bc61 422 break;
Benoit 1:f4040665bc61 423 case EMAC_PHY_STAT_SPEED:
Benoit 1:f4040665bc61 424 tmp = (regv & EMAC_PHY_SR_SPEED) ? 0 : 1;
Benoit 1:f4040665bc61 425 break;
Benoit 1:f4040665bc61 426 case EMAC_PHY_STAT_DUP:
Benoit 1:f4040665bc61 427 tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
Benoit 1:f4040665bc61 428 break;
Benoit 1:f4040665bc61 429 #elif defined(IAR_LPC_1768)
Benoit 1:f4040665bc61 430 /* Use IAR_LPC_1768 board:
Benoit 1:f4040665bc61 431 * FSZ8721BL doesn't have Status Register
Benoit 1:f4040665bc61 432 * so we read Basic Mode Status Register (0x01h) instead
Benoit 1:f4040665bc61 433 */
Benoit 1:f4040665bc61 434 regv = read_PHY (EMAC_PHY_REG_BMSR);
Benoit 1:f4040665bc61 435 switch(ulPHYState){
Benoit 1:f4040665bc61 436 case EMAC_PHY_STAT_LINK:
Benoit 1:f4040665bc61 437 tmp = (regv & EMAC_PHY_BMSR_LINK_STATUS) ? 1 : 0;
Benoit 1:f4040665bc61 438 break;
Benoit 1:f4040665bc61 439 case EMAC_PHY_STAT_SPEED:
Benoit 1:f4040665bc61 440 tmp = (regv & EMAC_PHY_SR_100_SPEED) ? 1 : 0;
Benoit 1:f4040665bc61 441 break;
Benoit 1:f4040665bc61 442 case EMAC_PHY_STAT_DUP:
Benoit 1:f4040665bc61 443 tmp = (regv & EMAC_PHY_SR_FULL_DUP) ? 1 : 0;
Benoit 1:f4040665bc61 444 break;
Benoit 1:f4040665bc61 445 #endif
Benoit 1:f4040665bc61 446 default:
Benoit 1:f4040665bc61 447 tmp = -1;
Benoit 1:f4040665bc61 448 break;
Benoit 1:f4040665bc61 449 }
Benoit 1:f4040665bc61 450 return (tmp);
Benoit 1:f4040665bc61 451 }
Benoit 1:f4040665bc61 452
Benoit 1:f4040665bc61 453
Benoit 1:f4040665bc61 454 /*********************************************************************//**
Benoit 1:f4040665bc61 455 * @brief Set specified PHY mode in EMAC peripheral
Benoit 1:f4040665bc61 456 * @param[in] ulPHYMode Specified PHY mode, should be:
Benoit 1:f4040665bc61 457 * - EMAC_MODE_AUTO
Benoit 1:f4040665bc61 458 * - EMAC_MODE_10M_FULL
Benoit 1:f4040665bc61 459 * - EMAC_MODE_10M_HALF
Benoit 1:f4040665bc61 460 * - EMAC_MODE_100M_FULL
Benoit 1:f4040665bc61 461 * - EMAC_MODE_100M_HALF
Benoit 1:f4040665bc61 462 * @return Return (0) if no error, otherwise return (-1)
Benoit 1:f4040665bc61 463 **********************************************************************/
Benoit 1:f4040665bc61 464 int32_t EMAC_SetPHYMode(uint32_t ulPHYMode)
Benoit 1:f4040665bc61 465 {
Benoit 1:f4040665bc61 466 int32_t id1, id2, tout, regv;
Benoit 1:f4040665bc61 467
Benoit 1:f4040665bc61 468 /* Check if this is a DP83848C PHY. */
Benoit 1:f4040665bc61 469 id1 = read_PHY (EMAC_PHY_REG_IDR1);
Benoit 1:f4040665bc61 470 id2 = read_PHY (EMAC_PHY_REG_IDR2);
Benoit 1:f4040665bc61 471
Benoit 1:f4040665bc61 472 #ifdef MCB_LPC_1768
Benoit 1:f4040665bc61 473 if (((id1 << 16) | (id2 & 0xFFF0)) == EMAC_DP83848C_ID) {
Benoit 1:f4040665bc61 474 switch(ulPHYMode){
Benoit 1:f4040665bc61 475 case EMAC_MODE_AUTO:
Benoit 1:f4040665bc61 476 write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
Benoit 1:f4040665bc61 477 #elif defined(IAR_LPC_1768) /* Use IAR LPC1768 KickStart board */
Benoit 1:f4040665bc61 478 if (((id1 << 16) | id2) == EMAC_KSZ8721BL_ID) {
Benoit 1:f4040665bc61 479 /* Configure the PHY device */
Benoit 1:f4040665bc61 480 switch(ulPHYMode){
Benoit 1:f4040665bc61 481 case EMAC_MODE_AUTO:
Benoit 1:f4040665bc61 482 /* Use auto-negotiation about the link speed. */
Benoit 1:f4040665bc61 483 write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_AUTO_NEG);
Benoit 1:f4040665bc61 484 // write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_BMCR_AN);
Benoit 1:f4040665bc61 485 #endif
Benoit 1:f4040665bc61 486 /* Wait to complete Auto_Negotiation */
Benoit 1:f4040665bc61 487 for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
Benoit 1:f4040665bc61 488 regv = read_PHY (EMAC_PHY_REG_BMSR);
Benoit 1:f4040665bc61 489 if (regv & EMAC_PHY_BMSR_AUTO_DONE) {
Benoit 1:f4040665bc61 490 /* Auto-negotiation Complete. */
Benoit 1:f4040665bc61 491 break;
Benoit 1:f4040665bc61 492 }
Benoit 1:f4040665bc61 493 if (tout == 0){
Benoit 1:f4040665bc61 494 // Time out, return error
Benoit 1:f4040665bc61 495 return (-1);
Benoit 1:f4040665bc61 496 }
Benoit 1:f4040665bc61 497 }
Benoit 1:f4040665bc61 498 break;
Benoit 1:f4040665bc61 499 case EMAC_MODE_10M_FULL:
Benoit 1:f4040665bc61 500 /* Connect at 10MBit full-duplex */
Benoit 1:f4040665bc61 501 write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_10M);
Benoit 1:f4040665bc61 502 break;
Benoit 1:f4040665bc61 503 case EMAC_MODE_10M_HALF:
Benoit 1:f4040665bc61 504 /* Connect at 10MBit half-duplex */
Benoit 1:f4040665bc61 505 write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_10M);
Benoit 1:f4040665bc61 506 break;
Benoit 1:f4040665bc61 507 case EMAC_MODE_100M_FULL:
Benoit 1:f4040665bc61 508 /* Connect at 100MBit full-duplex */
Benoit 1:f4040665bc61 509 write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_FULLD_100M);
Benoit 1:f4040665bc61 510 break;
Benoit 1:f4040665bc61 511 case EMAC_MODE_100M_HALF:
Benoit 1:f4040665bc61 512 /* Connect at 100MBit half-duplex */
Benoit 1:f4040665bc61 513 write_PHY (EMAC_PHY_REG_BMCR, EMAC_PHY_HALFD_100M);
Benoit 1:f4040665bc61 514 break;
Benoit 1:f4040665bc61 515 default:
Benoit 1:f4040665bc61 516 // un-supported
Benoit 1:f4040665bc61 517 return (-1);
Benoit 1:f4040665bc61 518 }
Benoit 1:f4040665bc61 519 }
Benoit 1:f4040665bc61 520 // It's not correct module ID
Benoit 1:f4040665bc61 521 else {
Benoit 1:f4040665bc61 522 return (-1);
Benoit 1:f4040665bc61 523 }
Benoit 1:f4040665bc61 524
Benoit 1:f4040665bc61 525 // Update EMAC configuration with current PHY status
Benoit 1:f4040665bc61 526 if (EMAC_UpdatePHYStatus() < 0){
Benoit 1:f4040665bc61 527 return (-1);
Benoit 1:f4040665bc61 528 }
Benoit 1:f4040665bc61 529
Benoit 1:f4040665bc61 530 // Complete
Benoit 1:f4040665bc61 531 return (0);
Benoit 1:f4040665bc61 532 }
Benoit 1:f4040665bc61 533
Benoit 1:f4040665bc61 534
Benoit 1:f4040665bc61 535 /*********************************************************************//**
Benoit 1:f4040665bc61 536 * @brief Auto-Configures value for the EMAC configuration register to
Benoit 1:f4040665bc61 537 * match with current PHY mode
Benoit 1:f4040665bc61 538 * @param[in] None
Benoit 1:f4040665bc61 539 * @return Return (0) if no error, otherwise return (-1)
Benoit 1:f4040665bc61 540 *
Benoit 1:f4040665bc61 541 * Note: The EMAC configuration will be auto-configured:
Benoit 1:f4040665bc61 542 * - Speed mode.
Benoit 1:f4040665bc61 543 * - Half/Full duplex mode
Benoit 1:f4040665bc61 544 **********************************************************************/
Benoit 1:f4040665bc61 545 int32_t EMAC_UpdatePHYStatus(void)
Benoit 1:f4040665bc61 546 {
Benoit 1:f4040665bc61 547 int32_t regv, tout;
Benoit 1:f4040665bc61 548
Benoit 1:f4040665bc61 549 /* Check the link status. */
Benoit 1:f4040665bc61 550 #ifdef MCB_LPC_1768
Benoit 1:f4040665bc61 551 for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
Benoit 1:f4040665bc61 552 regv = read_PHY (EMAC_PHY_REG_STS);
Benoit 1:f4040665bc61 553 if (regv & EMAC_PHY_SR_LINK) {
Benoit 1:f4040665bc61 554 /* Link is on. */
Benoit 1:f4040665bc61 555 break;
Benoit 1:f4040665bc61 556 }
Benoit 1:f4040665bc61 557 if (tout == 0){
Benoit 1:f4040665bc61 558 // time out
Benoit 1:f4040665bc61 559 return (-1);
Benoit 1:f4040665bc61 560 }
Benoit 1:f4040665bc61 561 }
Benoit 1:f4040665bc61 562 /* Configure Full/Half Duplex mode. */
Benoit 1:f4040665bc61 563 if (regv & EMAC_PHY_SR_DUP) {
Benoit 1:f4040665bc61 564 /* Full duplex is enabled. */
Benoit 1:f4040665bc61 565 LPC_EMAC->MAC2 |= EMAC_MAC2_FULL_DUP;
Benoit 1:f4040665bc61 566 LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
Benoit 1:f4040665bc61 567 LPC_EMAC->IPGT = EMAC_IPGT_FULL_DUP;
Benoit 1:f4040665bc61 568 } else {
Benoit 1:f4040665bc61 569 /* Half duplex mode. */
Benoit 1:f4040665bc61 570 LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
Benoit 1:f4040665bc61 571 }
Benoit 1:f4040665bc61 572 if (regv & EMAC_PHY_SR_SPEED) {
Benoit 1:f4040665bc61 573 /* 10MBit mode. */
Benoit 1:f4040665bc61 574 LPC_EMAC->SUPP = 0;
Benoit 1:f4040665bc61 575 } else {
Benoit 1:f4040665bc61 576 /* 100MBit mode. */
Benoit 1:f4040665bc61 577 LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
Benoit 1:f4040665bc61 578 }
Benoit 1:f4040665bc61 579 #elif defined(IAR_LPC_1768)
Benoit 1:f4040665bc61 580 for (tout = EMAC_PHY_RESP_TOUT; tout; tout--) {
Benoit 1:f4040665bc61 581 regv = read_PHY (EMAC_PHY_REG_BMSR);
Benoit 1:f4040665bc61 582 if (regv & EMAC_PHY_BMSR_LINK_STATUS) {
Benoit 1:f4040665bc61 583 /* Link is on. */
Benoit 1:f4040665bc61 584 break;
Benoit 1:f4040665bc61 585 }
Benoit 1:f4040665bc61 586 if (tout == 0){
Benoit 1:f4040665bc61 587 // time out
Benoit 1:f4040665bc61 588 return (-1);
Benoit 1:f4040665bc61 589 }
Benoit 1:f4040665bc61 590 }
Benoit 1:f4040665bc61 591
Benoit 1:f4040665bc61 592 /* Configure Full/Half Duplex mode. */
Benoit 1:f4040665bc61 593 if (regv & EMAC_PHY_SR_FULL_DUP) {
Benoit 1:f4040665bc61 594 /* Full duplex is enabled. */
Benoit 1:f4040665bc61 595 LPC_EMAC->MAC2 |= EMAC_MAC2_FULL_DUP;
Benoit 1:f4040665bc61 596 LPC_EMAC->Command |= EMAC_CR_FULL_DUP;
Benoit 1:f4040665bc61 597 LPC_EMAC->IPGT = EMAC_IPGT_FULL_DUP;
Benoit 1:f4040665bc61 598 } else {
Benoit 1:f4040665bc61 599 /* Half duplex mode. */
Benoit 1:f4040665bc61 600 LPC_EMAC->IPGT = EMAC_IPGT_HALF_DUP;
Benoit 1:f4040665bc61 601 }
Benoit 1:f4040665bc61 602
Benoit 1:f4040665bc61 603 /* Configure 100MBit/10MBit mode. */
Benoit 1:f4040665bc61 604 if (!(regv & EMAC_PHY_SR_100_SPEED)) {
Benoit 1:f4040665bc61 605 /* 10MBit mode. */
Benoit 1:f4040665bc61 606 LPC_EMAC->SUPP = 0;
Benoit 1:f4040665bc61 607 } else {
Benoit 1:f4040665bc61 608 /* 100MBit mode. */
Benoit 1:f4040665bc61 609 LPC_EMAC->SUPP = EMAC_SUPP_SPEED;
Benoit 1:f4040665bc61 610 }
Benoit 1:f4040665bc61 611 #endif
Benoit 1:f4040665bc61 612 // Complete
Benoit 1:f4040665bc61 613 return (0);
Benoit 1:f4040665bc61 614 }
Benoit 1:f4040665bc61 615
Benoit 1:f4040665bc61 616
Benoit 1:f4040665bc61 617 /*********************************************************************//**
Benoit 1:f4040665bc61 618 * @brief Enable/Disable hash filter functionality for specified destination
Benoit 1:f4040665bc61 619 * MAC address in EMAC module
Benoit 1:f4040665bc61 620 * @param[in] dstMAC_addr Pointer to the first MAC destination address, should
Benoit 1:f4040665bc61 621 * be 6-bytes length, in order LSB to the MSB
Benoit 1:f4040665bc61 622 * @param[in] NewState New State of this command, should be:
Benoit 1:f4040665bc61 623 * - ENABLE.
Benoit 1:f4040665bc61 624 * - DISABLE.
Benoit 1:f4040665bc61 625 * @return None
Benoit 1:f4040665bc61 626 *
Benoit 1:f4040665bc61 627 * Note:
Benoit 1:f4040665bc61 628 * The standard Ethernet cyclic redundancy check (CRC) function is calculated from
Benoit 1:f4040665bc61 629 * the 6 byte destination address in the Ethernet frame (this CRC is calculated
Benoit 1:f4040665bc61 630 * anyway as part of calculating the CRC of the whole frame), then bits [28:23] out of
Benoit 1:f4040665bc61 631 * the 32 bits CRC result are taken to form the hash. The 6 bit hash is used to access
Benoit 1:f4040665bc61 632 * the hash table: it is used as an index in the 64 bit HashFilter register that has been
Benoit 1:f4040665bc61 633 * programmed with accept values. If the selected accept value is 1, the frame is
Benoit 1:f4040665bc61 634 * accepted.
Benoit 1:f4040665bc61 635 **********************************************************************/
Benoit 1:f4040665bc61 636 void EMAC_SetHashFilter(uint8_t dstMAC_addr[], FunctionalState NewState)
Benoit 1:f4040665bc61 637 {
Benoit 1:f4040665bc61 638 uint32_t *pReg;
Benoit 1:f4040665bc61 639 uint32_t tmp;
Benoit 1:f4040665bc61 640 int32_t crc;
Benoit 1:f4040665bc61 641
Benoit 1:f4040665bc61 642 // Calculate the CRC from the destination MAC address
Benoit 1:f4040665bc61 643 crc = emac_CRCCalc(dstMAC_addr, 6);
Benoit 1:f4040665bc61 644 // Extract the value from CRC to get index value for hash filter table
Benoit 1:f4040665bc61 645 crc = (crc >> 23) & 0x3F;
Benoit 1:f4040665bc61 646
Benoit 1:f4040665bc61 647 pReg = (crc > 31) ? ((uint32_t *)&LPC_EMAC->HashFilterH) \
Benoit 1:f4040665bc61 648 : ((uint32_t *)&LPC_EMAC->HashFilterL);
Benoit 1:f4040665bc61 649 tmp = (crc > 31) ? (crc - 32) : crc;
Benoit 1:f4040665bc61 650 if (NewState == ENABLE) {
Benoit 1:f4040665bc61 651 (*pReg) |= (1UL << tmp);
Benoit 1:f4040665bc61 652 } else {
Benoit 1:f4040665bc61 653 (*pReg) &= ~(1UL << tmp);
Benoit 1:f4040665bc61 654 }
Benoit 1:f4040665bc61 655 // Enable Rx Filter
Benoit 1:f4040665bc61 656 LPC_EMAC->Command &= ~EMAC_CR_PASS_RX_FILT;
Benoit 1:f4040665bc61 657 }
Benoit 1:f4040665bc61 658
Benoit 1:f4040665bc61 659 /*********************************************************************//**
Benoit 1:f4040665bc61 660 * @brief Enable/Disable Filter mode for each specified type EMAC peripheral
Benoit 1:f4040665bc61 661 * @param[in] ulFilterMode Filter mode, should be:
Benoit 1:f4040665bc61 662 * - EMAC_RFC_UCAST_EN: all frames of unicast types
Benoit 1:f4040665bc61 663 * will be accepted
Benoit 1:f4040665bc61 664 * - EMAC_RFC_BCAST_EN: broadcast frame will be
Benoit 1:f4040665bc61 665 * accepted
Benoit 1:f4040665bc61 666 * - EMAC_RFC_MCAST_EN: all frames of multicast
Benoit 1:f4040665bc61 667 * types will be accepted
Benoit 1:f4040665bc61 668 * - EMAC_RFC_UCAST_HASH_EN: The imperfect hash
Benoit 1:f4040665bc61 669 * filter will be applied to unicast addresses
Benoit 1:f4040665bc61 670 * - EMAC_RFC_MCAST_HASH_EN: The imperfect hash
Benoit 1:f4040665bc61 671 * filter will be applied to multicast addresses
Benoit 1:f4040665bc61 672 * - EMAC_RFC_PERFECT_EN: the destination address
Benoit 1:f4040665bc61 673 * will be compared with the 6 byte station address
Benoit 1:f4040665bc61 674 * programmed in the station address by the filter
Benoit 1:f4040665bc61 675 * - EMAC_RFC_MAGP_WOL_EN: the result of the magic
Benoit 1:f4040665bc61 676 * packet filter will generate a WoL interrupt when
Benoit 1:f4040665bc61 677 * there is a match
Benoit 1:f4040665bc61 678 * - EMAC_RFC_PFILT_WOL_EN: the result of the perfect address
Benoit 1:f4040665bc61 679 * matching filter and the imperfect hash filter will
Benoit 1:f4040665bc61 680 * generate a WoL interrupt when there is a match
Benoit 1:f4040665bc61 681 * @param[in] NewState New State of this command, should be:
Benoit 1:f4040665bc61 682 * - ENABLE
Benoit 1:f4040665bc61 683 * - DISABLE
Benoit 1:f4040665bc61 684 * @return None
Benoit 1:f4040665bc61 685 **********************************************************************/
Benoit 1:f4040665bc61 686 void EMAC_SetFilterMode(uint32_t ulFilterMode, FunctionalState NewState)
Benoit 1:f4040665bc61 687 {
Benoit 1:f4040665bc61 688 if (NewState == ENABLE){
Benoit 1:f4040665bc61 689 LPC_EMAC->RxFilterCtrl |= ulFilterMode;
Benoit 1:f4040665bc61 690 } else {
Benoit 1:f4040665bc61 691 LPC_EMAC->RxFilterCtrl &= ~ulFilterMode;
Benoit 1:f4040665bc61 692 }
Benoit 1:f4040665bc61 693 }
Benoit 1:f4040665bc61 694
Benoit 1:f4040665bc61 695 /*********************************************************************//**
Benoit 1:f4040665bc61 696 * @brief Get status of Wake On LAN Filter for each specified
Benoit 1:f4040665bc61 697 * type in EMAC peripheral, clear this status if it is set
Benoit 1:f4040665bc61 698 * @param[in] ulWoLMode WoL Filter mode, should be:
Benoit 1:f4040665bc61 699 * - EMAC_WOL_UCAST: unicast frames caused WoL
Benoit 1:f4040665bc61 700 * - EMAC_WOL_UCAST: broadcast frame caused WoL
Benoit 1:f4040665bc61 701 * - EMAC_WOL_MCAST: multicast frame caused WoL
Benoit 1:f4040665bc61 702 * - EMAC_WOL_UCAST_HASH: unicast frame that passes the
Benoit 1:f4040665bc61 703 * imperfect hash filter caused WoL
Benoit 1:f4040665bc61 704 * - EMAC_WOL_MCAST_HASH: multicast frame that passes the
Benoit 1:f4040665bc61 705 * imperfect hash filter caused WoL
Benoit 1:f4040665bc61 706 * - EMAC_WOL_PERFECT:perfect address matching filter
Benoit 1:f4040665bc61 707 * caused WoL
Benoit 1:f4040665bc61 708 * - EMAC_WOL_RX_FILTER: the receive filter caused WoL
Benoit 1:f4040665bc61 709 * - EMAC_WOL_MAG_PACKET: the magic packet filter caused WoL
Benoit 1:f4040665bc61 710 * @return SET/RESET
Benoit 1:f4040665bc61 711 **********************************************************************/
Benoit 1:f4040665bc61 712 FlagStatus EMAC_GetWoLStatus(uint32_t ulWoLMode)
Benoit 1:f4040665bc61 713 {
Benoit 1:f4040665bc61 714 if (LPC_EMAC->RxFilterWoLStatus & ulWoLMode) {
Benoit 1:f4040665bc61 715 LPC_EMAC->RxFilterWoLClear = ulWoLMode;
Benoit 1:f4040665bc61 716 return SET;
Benoit 1:f4040665bc61 717 } else {
Benoit 1:f4040665bc61 718 return RESET;
Benoit 1:f4040665bc61 719 }
Benoit 1:f4040665bc61 720 }
Benoit 1:f4040665bc61 721
Benoit 1:f4040665bc61 722
Benoit 1:f4040665bc61 723 /*********************************************************************//**
Benoit 1:f4040665bc61 724 * @brief Write data to Tx packet data buffer at current index due to
Benoit 1:f4040665bc61 725 * TxProduceIndex
Benoit 1:f4040665bc61 726 * @param[in] pDataStruct Pointer to a EMAC_PACKETBUF_Type structure
Benoit 1:f4040665bc61 727 * data that contain specified information about
Benoit 1:f4040665bc61 728 * Packet data buffer.
Benoit 1:f4040665bc61 729 * @return None
Benoit 1:f4040665bc61 730 **********************************************************************/
Benoit 1:f4040665bc61 731 void EMAC_WritePacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
Benoit 1:f4040665bc61 732 {
Benoit 1:f4040665bc61 733 uint32_t idx,len;
Benoit 1:f4040665bc61 734 uint32_t *sp,*dp;
Benoit 1:f4040665bc61 735
Benoit 1:f4040665bc61 736 idx = LPC_EMAC->TxProduceIndex;
Benoit 1:f4040665bc61 737 sp = (uint32_t *)pDataStruct->pbDataBuf;
Benoit 1:f4040665bc61 738 dp = (uint32_t *)Tx_Desc[idx].Packet;
Benoit 1:f4040665bc61 739 /* Copy frame data to EMAC packet buffers. */
Benoit 1:f4040665bc61 740 for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
Benoit 1:f4040665bc61 741 *dp++ = *sp++;
Benoit 1:f4040665bc61 742 }
Benoit 1:f4040665bc61 743 Tx_Desc[idx].Ctrl = (pDataStruct->ulDataLen - 1) | (EMAC_TCTRL_INT | EMAC_TCTRL_LAST);
Benoit 1:f4040665bc61 744 }
Benoit 1:f4040665bc61 745
Benoit 1:f4040665bc61 746 /*********************************************************************//**
Benoit 1:f4040665bc61 747 * @brief Read data from Rx packet data buffer at current index due
Benoit 1:f4040665bc61 748 * to RxConsumeIndex
Benoit 1:f4040665bc61 749 * @param[in] pDataStruct Pointer to a EMAC_PACKETBUF_Type structure
Benoit 1:f4040665bc61 750 * data that contain specified information about
Benoit 1:f4040665bc61 751 * Packet data buffer.
Benoit 1:f4040665bc61 752 * @return None
Benoit 1:f4040665bc61 753 **********************************************************************/
Benoit 1:f4040665bc61 754 void EMAC_ReadPacketBuffer(EMAC_PACKETBUF_Type *pDataStruct)
Benoit 1:f4040665bc61 755 {
Benoit 1:f4040665bc61 756 uint32_t idx, len;
Benoit 1:f4040665bc61 757 uint32_t *dp, *sp;
Benoit 1:f4040665bc61 758
Benoit 1:f4040665bc61 759 idx = LPC_EMAC->RxConsumeIndex;
Benoit 1:f4040665bc61 760 dp = (uint32_t *)pDataStruct->pbDataBuf;
Benoit 1:f4040665bc61 761 sp = (uint32_t *)Rx_Desc[idx].Packet;
Benoit 1:f4040665bc61 762
Benoit 1:f4040665bc61 763 if (pDataStruct->pbDataBuf != NULL) {
Benoit 1:f4040665bc61 764 for (len = (pDataStruct->ulDataLen + 3) >> 2; len; len--) {
Benoit 1:f4040665bc61 765 *dp++ = *sp++;
Benoit 1:f4040665bc61 766 }
Benoit 1:f4040665bc61 767 }
Benoit 1:f4040665bc61 768 }
Benoit 1:f4040665bc61 769
Benoit 1:f4040665bc61 770 /*********************************************************************//**
Benoit 1:f4040665bc61 771 * @brief Enable/Disable interrupt for each type in EMAC
Benoit 1:f4040665bc61 772 * @param[in] ulIntType Interrupt Type, should be:
Benoit 1:f4040665bc61 773 * - EMAC_INT_RX_OVERRUN: Receive Overrun
Benoit 1:f4040665bc61 774 * - EMAC_INT_RX_ERR: Receive Error
Benoit 1:f4040665bc61 775 * - EMAC_INT_RX_FIN: Receive Descriptor Finish
Benoit 1:f4040665bc61 776 * - EMAC_INT_RX_DONE: Receive Done
Benoit 1:f4040665bc61 777 * - EMAC_INT_TX_UNDERRUN: Transmit Under-run
Benoit 1:f4040665bc61 778 * - EMAC_INT_TX_ERR: Transmit Error
Benoit 1:f4040665bc61 779 * - EMAC_INT_TX_FIN: Transmit descriptor finish
Benoit 1:f4040665bc61 780 * - EMAC_INT_TX_DONE: Transmit Done
Benoit 1:f4040665bc61 781 * - EMAC_INT_SOFT_INT: Software interrupt
Benoit 1:f4040665bc61 782 * - EMAC_INT_WAKEUP: Wakeup interrupt
Benoit 1:f4040665bc61 783 * @param[in] NewState New State of this function, should be:
Benoit 1:f4040665bc61 784 * - ENABLE.
Benoit 1:f4040665bc61 785 * - DISABLE.
Benoit 1:f4040665bc61 786 * @return None
Benoit 1:f4040665bc61 787 **********************************************************************/
Benoit 1:f4040665bc61 788 void EMAC_IntCmd(uint32_t ulIntType, FunctionalState NewState)
Benoit 1:f4040665bc61 789 {
Benoit 1:f4040665bc61 790 if (NewState == ENABLE) {
Benoit 1:f4040665bc61 791 LPC_EMAC->IntEnable |= ulIntType;
Benoit 1:f4040665bc61 792 } else {
Benoit 1:f4040665bc61 793 LPC_EMAC->IntEnable &= ~(ulIntType);
Benoit 1:f4040665bc61 794 }
Benoit 1:f4040665bc61 795 }
Benoit 1:f4040665bc61 796
Benoit 1:f4040665bc61 797 /*********************************************************************//**
Benoit 1:f4040665bc61 798 * @brief Check whether if specified interrupt flag is set or not
Benoit 1:f4040665bc61 799 * for each interrupt type in EMAC and clear interrupt pending
Benoit 1:f4040665bc61 800 * if it is set.
Benoit 1:f4040665bc61 801 * @param[in] ulIntType Interrupt Type, should be:
Benoit 1:f4040665bc61 802 * - EMAC_INT_RX_OVERRUN: Receive Overrun
Benoit 1:f4040665bc61 803 * - EMAC_INT_RX_ERR: Receive Error
Benoit 1:f4040665bc61 804 * - EMAC_INT_RX_FIN: Receive Descriptor Finish
Benoit 1:f4040665bc61 805 * - EMAC_INT_RX_DONE: Receive Done
Benoit 1:f4040665bc61 806 * - EMAC_INT_TX_UNDERRUN: Transmit Under-run
Benoit 1:f4040665bc61 807 * - EMAC_INT_TX_ERR: Transmit Error
Benoit 1:f4040665bc61 808 * - EMAC_INT_TX_FIN: Transmit descriptor finish
Benoit 1:f4040665bc61 809 * - EMAC_INT_TX_DONE: Transmit Done
Benoit 1:f4040665bc61 810 * - EMAC_INT_SOFT_INT: Software interrupt
Benoit 1:f4040665bc61 811 * - EMAC_INT_WAKEUP: Wakeup interrupt
Benoit 1:f4040665bc61 812 * @return New state of specified interrupt (SET or RESET)
Benoit 1:f4040665bc61 813 **********************************************************************/
Benoit 1:f4040665bc61 814 IntStatus EMAC_IntGetStatus(uint32_t ulIntType)
Benoit 1:f4040665bc61 815 {
Benoit 1:f4040665bc61 816 if (LPC_EMAC->IntStatus & ulIntType) {
Benoit 1:f4040665bc61 817 LPC_EMAC->IntClear = ulIntType;
Benoit 1:f4040665bc61 818 return SET;
Benoit 1:f4040665bc61 819 } else {
Benoit 1:f4040665bc61 820 return RESET;
Benoit 1:f4040665bc61 821 }
Benoit 1:f4040665bc61 822 }
Benoit 1:f4040665bc61 823
Benoit 1:f4040665bc61 824
Benoit 1:f4040665bc61 825 /*********************************************************************//**
Benoit 1:f4040665bc61 826 * @brief Check whether if the current RxConsumeIndex is not equal to the
Benoit 1:f4040665bc61 827 * current RxProduceIndex.
Benoit 1:f4040665bc61 828 * @param[in] None
Benoit 1:f4040665bc61 829 * @return TRUE if they're not equal, otherwise return FALSE
Benoit 1:f4040665bc61 830 *
Benoit 1:f4040665bc61 831 * Note: In case the RxConsumeIndex is not equal to the RxProduceIndex,
Benoit 1:f4040665bc61 832 * it means there're available data has been received. They should be read
Benoit 1:f4040665bc61 833 * out and released the Receive Data Buffer by updating the RxConsumeIndex value.
Benoit 1:f4040665bc61 834 **********************************************************************/
Benoit 1:f4040665bc61 835 Bool EMAC_CheckReceiveIndex(void)
Benoit 1:f4040665bc61 836 {
Benoit 1:f4040665bc61 837 if (LPC_EMAC->RxConsumeIndex != LPC_EMAC->RxProduceIndex) {
Benoit 1:f4040665bc61 838 return TRUE;
Benoit 1:f4040665bc61 839 } else {
Benoit 1:f4040665bc61 840 return FALSE;
Benoit 1:f4040665bc61 841 }
Benoit 1:f4040665bc61 842 }
Benoit 1:f4040665bc61 843
Benoit 1:f4040665bc61 844
Benoit 1:f4040665bc61 845 /*********************************************************************//**
Benoit 1:f4040665bc61 846 * @brief Check whether if the current TxProduceIndex is not equal to the
Benoit 1:f4040665bc61 847 * current RxProduceIndex - 1.
Benoit 1:f4040665bc61 848 * @param[in] None
Benoit 1:f4040665bc61 849 * @return TRUE if they're not equal, otherwise return FALSE
Benoit 1:f4040665bc61 850 *
Benoit 1:f4040665bc61 851 * Note: In case the RxConsumeIndex is equal to the RxProduceIndex - 1,
Benoit 1:f4040665bc61 852 * it means the transmit buffer is available and data can be written to transmit
Benoit 1:f4040665bc61 853 * buffer to be sent.
Benoit 1:f4040665bc61 854 **********************************************************************/
Benoit 1:f4040665bc61 855 Bool EMAC_CheckTransmitIndex(void)
Benoit 1:f4040665bc61 856 {
Benoit 1:f4040665bc61 857 uint32_t tmp = LPC_EMAC->TxConsumeIndex -1;
Benoit 1:f4040665bc61 858 if (LPC_EMAC->TxProduceIndex == tmp) {
Benoit 1:f4040665bc61 859 return FALSE;
Benoit 1:f4040665bc61 860 } else {
Benoit 1:f4040665bc61 861 return TRUE;
Benoit 1:f4040665bc61 862 }
Benoit 1:f4040665bc61 863 }
Benoit 1:f4040665bc61 864
Benoit 1:f4040665bc61 865
Benoit 1:f4040665bc61 866 /*********************************************************************//**
Benoit 1:f4040665bc61 867 * @brief Get current status value of receive data (due to RxConsumeIndex)
Benoit 1:f4040665bc61 868 * @param[in] ulRxStatType Received Status type, should be one of following:
Benoit 1:f4040665bc61 869 * - EMAC_RINFO_CTRL_FRAME: Control Frame
Benoit 1:f4040665bc61 870 * - EMAC_RINFO_VLAN: VLAN Frame
Benoit 1:f4040665bc61 871 * - EMAC_RINFO_FAIL_FILT: RX Filter Failed
Benoit 1:f4040665bc61 872 * - EMAC_RINFO_MCAST: Multicast Frame
Benoit 1:f4040665bc61 873 * - EMAC_RINFO_BCAST: Broadcast Frame
Benoit 1:f4040665bc61 874 * - EMAC_RINFO_CRC_ERR: CRC Error in Frame
Benoit 1:f4040665bc61 875 * - EMAC_RINFO_SYM_ERR: Symbol Error from PHY
Benoit 1:f4040665bc61 876 * - EMAC_RINFO_LEN_ERR: Length Error
Benoit 1:f4040665bc61 877 * - EMAC_RINFO_RANGE_ERR: Range error(exceeded max size)
Benoit 1:f4040665bc61 878 * - EMAC_RINFO_ALIGN_ERR: Alignment error
Benoit 1:f4040665bc61 879 * - EMAC_RINFO_OVERRUN: Receive overrun
Benoit 1:f4040665bc61 880 * - EMAC_RINFO_NO_DESCR: No new Descriptor available
Benoit 1:f4040665bc61 881 * - EMAC_RINFO_LAST_FLAG: last Fragment in Frame
Benoit 1:f4040665bc61 882 * - EMAC_RINFO_ERR: Error Occurred (OR of all error)
Benoit 1:f4040665bc61 883 * @return Current value of receive data (due to RxConsumeIndex)
Benoit 1:f4040665bc61 884 **********************************************************************/
Benoit 1:f4040665bc61 885 FlagStatus EMAC_CheckReceiveDataStatus(uint32_t ulRxStatType)
Benoit 1:f4040665bc61 886 {
Benoit 1:f4040665bc61 887 uint32_t idx;
Benoit 1:f4040665bc61 888 idx = LPC_EMAC->RxConsumeIndex;
Benoit 1:f4040665bc61 889 return (((Rx_Stat[idx].Info) & ulRxStatType) ? SET : RESET);
Benoit 1:f4040665bc61 890 }
Benoit 1:f4040665bc61 891
Benoit 1:f4040665bc61 892
Benoit 1:f4040665bc61 893 /*********************************************************************//**
Benoit 1:f4040665bc61 894 * @brief Get size of current Received data in received buffer (due to
Benoit 1:f4040665bc61 895 * RxConsumeIndex)
Benoit 1:f4040665bc61 896 * @param[in] None
Benoit 1:f4040665bc61 897 * @return Size of received data
Benoit 1:f4040665bc61 898 **********************************************************************/
Benoit 1:f4040665bc61 899 uint32_t EMAC_GetReceiveDataSize(void)
Benoit 1:f4040665bc61 900 {
Benoit 1:f4040665bc61 901 uint32_t idx;
Benoit 1:f4040665bc61 902 idx =LPC_EMAC->RxConsumeIndex;
Benoit 1:f4040665bc61 903 return ((Rx_Stat[idx].Info) & EMAC_RINFO_SIZE);
Benoit 1:f4040665bc61 904 }
Benoit 1:f4040665bc61 905
Benoit 1:f4040665bc61 906 /*********************************************************************//**
Benoit 1:f4040665bc61 907 * @brief Increase the RxConsumeIndex (after reading the Receive buffer
Benoit 1:f4040665bc61 908 * to release the Receive buffer) and wrap-around the index if
Benoit 1:f4040665bc61 909 * it reaches the maximum Receive Number
Benoit 1:f4040665bc61 910 * @param[in] None
Benoit 1:f4040665bc61 911 * @return None
Benoit 1:f4040665bc61 912 **********************************************************************/
Benoit 1:f4040665bc61 913 void EMAC_UpdateRxConsumeIndex(void)
Benoit 1:f4040665bc61 914 {
Benoit 1:f4040665bc61 915 // Get current Rx consume index
Benoit 1:f4040665bc61 916 uint32_t idx = LPC_EMAC->RxConsumeIndex;
Benoit 1:f4040665bc61 917
Benoit 1:f4040665bc61 918 /* Release frame from EMAC buffer */
Benoit 1:f4040665bc61 919 if (++idx == EMAC_NUM_RX_FRAG) idx = 0;
Benoit 1:f4040665bc61 920 LPC_EMAC->RxConsumeIndex = idx;
Benoit 1:f4040665bc61 921 }
Benoit 1:f4040665bc61 922
Benoit 1:f4040665bc61 923 /*********************************************************************//**
Benoit 1:f4040665bc61 924 * @brief Increase the TxProduceIndex (after writting to the Transmit buffer
Benoit 1:f4040665bc61 925 * to enable the Transmit buffer) and wrap-around the index if
Benoit 1:f4040665bc61 926 * it reaches the maximum Transmit Number
Benoit 1:f4040665bc61 927 * @param[in] None
Benoit 1:f4040665bc61 928 * @return None
Benoit 1:f4040665bc61 929 **********************************************************************/
Benoit 1:f4040665bc61 930 void EMAC_UpdateTxProduceIndex(void)
Benoit 1:f4040665bc61 931 {
Benoit 1:f4040665bc61 932 // Get current Tx produce index
Benoit 1:f4040665bc61 933 uint32_t idx = LPC_EMAC->TxProduceIndex;
Benoit 1:f4040665bc61 934
Benoit 1:f4040665bc61 935 /* Start frame transmission */
Benoit 1:f4040665bc61 936 if (++idx == EMAC_NUM_TX_FRAG) idx = 0;
Benoit 1:f4040665bc61 937 LPC_EMAC->TxProduceIndex = idx;
Benoit 1:f4040665bc61 938 }
Benoit 1:f4040665bc61 939
Benoit 1:f4040665bc61 940
Benoit 1:f4040665bc61 941 /**
Benoit 1:f4040665bc61 942 * @}
Benoit 1:f4040665bc61 943 */
Benoit 1:f4040665bc61 944
Benoit 1:f4040665bc61 945 #endif /* _EMAC */
Benoit 1:f4040665bc61 946
Benoit 1:f4040665bc61 947 /**
Benoit 1:f4040665bc61 948 * @}
Benoit 1:f4040665bc61 949 */
Benoit 1:f4040665bc61 950
Benoit 1:f4040665bc61 951 /* --------------------------------- End Of File ------------------------------ */
Benoit 5:3cd83fcb1467 952 /* @endcond */