Date: March 20, 2011 This library is created from "LPC17xx CMSIS-Compliant Standard Peripheral Firmware Driver Library (GNU, Keil, IAR) (Jan 28, 2011)", available from NXP's website, under "All microcontrollers support documents" [[http://ics.nxp.com/support/documents/microcontrollers/?type=software]] You will need to follow [[/projects/libraries/svn/mbed/trunk/LPC1768/LPC17xx.h]] while using this library Examples provided here [[/users/frank26080115/programs/LPC1700CMSIS_Examples/]] The beautiful thing is that NXP does not place copyright protection on any of the files in here Only a few modifications are made to make it compile with the mbed online compiler, I fixed some warnings as well. This is untested as of March 20, 2011 Forum post about this library: [[/forum/mbed/topic/2030/]]

Committer:
frank26080115
Date:
Sun Mar 20 18:45:15 2011 +0000
Revision:
0:84d7747641aa

        

Who changed what in which revision?

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