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 19:17:11 2011 +0000
Revision:
1:f4040665bc61
Child:
4:cb3dc3361be5
Frames are now received using an interrupt handler

Who changed what in which revision?

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