Benoît Locher / mbedNet
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 ------------------------------ */