| LPCOpen Platform v1.03 LPCOpen Platform for NXP LPC Microcontrollers

- Main Page
- Modules
- Data Structures
- Files
- Related Pages

- File List
- Globals

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 */
39 STATIC uint32_t phyAddr;
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 */
54 void IP_ENET_Reset(IP_ENET_002_T *pENET)
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. */
59 pENET->MAC.MAC1 = ENET_MAC1_RESETTX | ENET_MAC1_RESETMCSTX | ENET_MAC1_RESETRX |
60 ENET_MAC1_RESETMCSRX | ENET_MAC1_SIMRESET | ENET_MAC1_SOFTRESET;
61 pENET->CONTROL.COMMAND = ENET_COMMAND_REGRESET | ENET_COMMAND_TXRESET | ENET_COMMAND_RXRESET |
62 ENET_COMMAND_PASSRUNTFRAME;
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 */
75 void IP_ENET_Init(IP_ENET_002_T *pENET)
76 {
77 /* Initial MAC configuration for full duplex,
78 100Mbps, inter-frame gap use default values */
79 pENET->MAC.MAC1 = ENET_MAC1_PARF;
80 pENET->MAC.MAC2 = ENET_MAC2_FULLDUPLEX | ENET_MAC2_CRCEN | ENET_MAC2_PADCRCEN;
81 #if defined(USE_RMII)
82 pENET->CONTROL.COMMAND = ENET_COMMAND_FULLDUPLEX | ENET_COMMAND_PASSRUNTFRAME | ENET_COMMAND_RMII;
83 #else
84 pENET->CONTROL.COMMAND = ENET_COMMAND_FULLDUPLEX | ENET_COMMAND_PASSRUNTFRAME;
85 #endif
86 pENET->MAC.IPGT = ENET_IPGT_FULLDUPLEX;
87 pENET->MAC.IPGR = ENET_IPGR_P2_DEF;
88 pENET->MAC.SUPP = ENET_SUPP_100Mbps_SPEED;
89 pENET->MAC.MAXF = ENET_ETH_MAX_FLEN;
90 pENET->MAC.CLRT = ENET_CLRT_DEF;
91
92 /* Setup default filter */
93 pENET->CONTROL.COMMAND |= ENET_COMMAND_PASSRXFILTER;
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 */
109 pENET->MAC.MCFG = ENET_MCFG_CLOCKSEL(div) | ENET_MCFG_RES_MII;
110
111 /* release reset */
112 pENET->MAC.MCFG &= ~(ENET_MCFG_RES_MII);
113 }
114
115 /*De-initialize the ethernet interface */
116 void IP_ENET_DeInit(IP_ENET_002_T *pENET)
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 */
147 bool IP_ENET_IsMIIBusy(IP_ENET_002_T *pENET)
148 {
149 if (pENET->MAC.MIND & ENET_MIND_BUSY) {
150 return true;
151 }
152
153 return false;
154 }
155
156 /* Read MII data */
157 uint16_t IP_ENET_ReadMIIData(IP_ENET_002_T *pENET)
158 {
159 pENET->MAC.MCMD = 0;
160 return pENET->MAC.MRDD;
161 }
162
163 /* Configures the initial ethernet transmit descriptors */
164 void IP_ENET_InitTxDescriptors(IP_ENET_002_T *pENET,
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 */
177 void IP_ENET_InitRxDescriptors(IP_ENET_002_T *pENET,
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 */
227 uint16_t IP_ENET_IncTXProduceIndex(IP_ENET_002_T *pENET)
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 */
243 uint16_t IP_ENET_IncRXConsumeIndex(IP_ENET_002_T *pENET)
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 }