LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
enet_002.c
Go to the documentation of this file.
1 /*
2  * @brief Ethernet control functions
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2012
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include "enet_002.h"
33 
34 /*****************************************************************************
35  * Private types/enumerations/variables
36  ****************************************************************************/
37 
38 /* Saved address for PHY and clock divider */
40 
41 /*****************************************************************************
42  * Public types/enumerations/variables
43  ****************************************************************************/
44 
45 /*****************************************************************************
46  * Private functions
47  ****************************************************************************/
48 
49 /*****************************************************************************
50  * Public functions
51  ****************************************************************************/
52 
53 /* Resets ethernet interface */
55 {
56  /* This should be called prior to IP_ENET_Init. The MAC controller may
57  not be ready for a call to init right away so a small delay should
58  occur after this call. */
63 }
64 
65 /* Sets the address of the interface */
66 void IP_ENET_SetADDR(IP_ENET_002_T *pENET, const uint8_t *macAddr)
67 {
68  /* Save MAC address */
69  pENET->MAC.SA[0] = ((uint32_t) macAddr[5] << 8) | ((uint32_t) macAddr[4]);
70  pENET->MAC.SA[1] = ((uint32_t) macAddr[3] << 8) | ((uint32_t) macAddr[2]);
71  pENET->MAC.SA[2] = ((uint32_t) macAddr[1] << 8) | ((uint32_t) macAddr[0]);
72 }
73 
74 /* Initialize ethernet interface */
76 {
77  /* Initial MAC configuration for full duplex,
78  100Mbps, inter-frame gap use default values */
79  pENET->MAC.MAC1 = ENET_MAC1_PARF;
81 #if defined(USE_RMII)
83 #else
85 #endif
86  pENET->MAC.IPGT = ENET_IPGT_FULLDUPLEX;
87  pENET->MAC.IPGR = ENET_IPGR_P2_DEF;
89  pENET->MAC.MAXF = ENET_ETH_MAX_FLEN;
90  pENET->MAC.CLRT = ENET_CLRT_DEF;
91 
92  /* Setup default filter */
94 
95  /* Clear all MAC interrupts */
96  pENET->MODULE_CONTROL.INTCLEAR = 0xFFFF;
97 
98  /* Disable MAC interrupts */
99  pENET->MODULE_CONTROL.INTENABLE = 0;
100 }
101 
102 /* Sets up the PHY link clock divider and PHY address */
103 void IP_ENET_SetupMII(IP_ENET_002_T *pENET, uint8_t div, uint8_t addr)
104 {
105  /* Save clock divider and PHY address in MII address register */
106  phyAddr = ENET_MADR_PHYADDR(addr);
107 
108  /* Write to MII configuration register and reset */
110 
111  /* release reset */
112  pENET->MAC.MCFG &= ~(ENET_MCFG_RES_MII);
113 }
114 
115 /*De-initialize the ethernet interface */
117 {
118  /* Disable packet reception */
119  pENET->MAC.MAC1 &= ~ENET_MAC1_RXENABLE;
120  pENET->CONTROL.COMMAND = 0;
121 
122  /* Clear all MAC interrupts */
123  pENET->MODULE_CONTROL.INTCLEAR = 0xFFFF;
124 
125  /* Disable MAC interrupts */
126  pENET->MODULE_CONTROL.INTENABLE = 0;
127 }
128 
129 /* Starts a PHY write via the MII */
130 void IP_ENET_StartMIIWrite(IP_ENET_002_T *pENET, uint8_t reg, uint16_t data)
131 {
132  /* Write value at PHY address and register */
133  pENET->MAC.MCMD = 0;
134  pENET->MAC.MADR = phyAddr | ENET_MADR_REGADDR(reg);
135  pENET->MAC.MWTD = data;
136 }
137 
138 /*Starts a PHY read via the MII */
139 void IP_ENET_StartMIIRead(IP_ENET_002_T *pENET, uint8_t reg)
140 {
141  /* Read value at PHY address and register */
142  pENET->MAC.MADR = phyAddr | ENET_MADR_REGADDR(reg);
143  pENET->MAC.MCMD = ENET_MCMD_READ;
144 }
145 
146 /* Returns MII link (PHY) busy status */
148 {
149  if (pENET->MAC.MIND & ENET_MIND_BUSY) {
150  return true;
151  }
152 
153  return false;
154 }
155 
156 /* Read MII data */
158 {
159  pENET->MAC.MCMD = 0;
160  return pENET->MAC.MRDD;
161 }
162 
163 /* Configures the initial ethernet transmit descriptors */
165  IP_ENET_002_TXDESC_T *pDescs,
166  IP_ENET_002_TXSTAT_T *pStatus,
167  uint32_t descNum)
168 {
169  /* Setup descriptor list base addresses */
170  pENET->CONTROL.TX.DESCRIPTOR = (uint32_t) pDescs;
171  pENET->CONTROL.TX.DESCRIPTORNUMBER = descNum - 1;
172  pENET->CONTROL.TX.STATUS = (uint32_t) pStatus;
173  pENET->CONTROL.TX.PRODUCEINDEX = 0;
174 }
175 
176 /* Configures the initial ethernet receive descriptors */
178  IP_ENET_002_RXDESC_T *pDescs,
179  IP_ENET_002_RXSTAT_T *pStatus,
180  uint32_t descNum)
181 {
182  /* Setup descriptor list base addresses */
183  pENET->CONTROL.RX.DESCRIPTOR = (uint32_t) pDescs;
184  pENET->CONTROL.RX.DESCRIPTORNUMBER = descNum - 1;
185  pENET->CONTROL.RX.STATUS = (uint32_t) pStatus;
186  pENET->CONTROL.RX.CONSUMEINDEX = 0;
187 }
188 
189 /* Get status for the descriptor list */
190 IP_ENET_002_BUFF_STATUS_T IP_ENET_GetBufferStatus(uint16_t produceIndex, uint16_t consumeIndex, uint16_t buffSize)
191 {
192  /* Empty descriptor list */
193  if (consumeIndex == produceIndex) {
194  return ENET_BUFF_EMPTY;
195  }
196 
197  /* Full descriptor list */
198  if ((consumeIndex == 0) &&
199  (produceIndex == (buffSize - 1))) {
200  return ENET_BUFF_FULL;
201  }
202 
203  /* Wrap-around, full descriptor list */
204  if (consumeIndex == (produceIndex + 1)) {
205  return ENET_BUFF_FULL;
206  }
207 
208  return ENET_BUFF_PARTIAL_FULL;
209 }
210 
211 /* Get the number of descriptor filled */
212 uint32_t IP_ENET_GetFillDescNum(uint16_t produceIndex, uint16_t consumeIndex, uint16_t buffSize)
213 {
214  /* Empty descriptor list */
215  if (consumeIndex == produceIndex) {
216  return 0;
217  }
218 
219  if (consumeIndex > produceIndex) {
220  return (buffSize - consumeIndex) + produceIndex;
221  }
222 
223  return produceIndex - consumeIndex;
224 }
225 
226 /* Increase the current Tx Produce Descriptor Index */
228 {
229  /* Get current TX produce index */
230  uint32_t idx = pENET->CONTROL.TX.PRODUCEINDEX;
231 
232  /* Start frame transmission by incrementing descriptor */
233  idx++;
234  if (idx > pENET->CONTROL.TX.DESCRIPTORNUMBER) {
235  idx = 0;
236  }
237  pENET->CONTROL.TX.PRODUCEINDEX = idx;
238 
239  return idx;
240 }
241 
242 /* Increase the current Rx Consume Descriptor Index */
244 {
245  /* Get current RX consume index */
246  uint32_t idx = pENET->CONTROL.RX.CONSUMEINDEX;
247 
248  /* Consume descriptor */
249  idx++;
250  if (idx > pENET->CONTROL.RX.DESCRIPTORNUMBER) {
251  idx = 0;
252  }
253  pENET->CONTROL.RX.CONSUMEINDEX = idx;
254 
255  return idx;
256 }