LPCOpen Platform  v1.03
LPCOpen Platform for NXP LPC Microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
enet.c
Go to the documentation of this file.
1 /*
2  * @brief Simple ethernet example
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 "board.h"
33 #include <stdio.h>
34 #include <string.h>
35 
73 /*****************************************************************************
74  * Private types/enumerations/variables
75  ****************************************************************************/
76 
77 #define ENET_NUM_TX_DESC 4
78 #define ENET_NUM_RX_DESC 4
79 
80 #if defined(CHIP_LPC175X_6X)
81 #define ENET_RX_DESC_BASE (0x2007C000)
82 #else
83 /* The Ethernet Block can only access Peripheral SRAM and External Memory. In this example,
84  Peripheral SRAM is selected for storing descriptors, status arrays and send/receive buffers.*/
85 #define ENET_RX_DESC_BASE (0x20000000UL)
86 #endif
87 #define ENET_RX_STAT_BASE (ENET_RX_DESC_BASE + ENET_NUM_RX_DESC * sizeof(ENET_RXDESC_T))
88 #define ENET_TX_DESC_BASE (ENET_RX_STAT_BASE + ENET_NUM_RX_DESC * sizeof(ENET_RXSTAT_T))
89 #define ENET_TX_STAT_BASE (ENET_TX_DESC_BASE + ENET_NUM_TX_DESC * sizeof(ENET_TXDESC_T))
90 #define ENET_RX_BUF_BASE (ENET_TX_STAT_BASE + ENET_NUM_TX_DESC * sizeof(ENET_TXSTAT_T))
91 #define ENET_TX_BUF_BASE (ENET_RX_BUF_BASE + ENET_NUM_RX_DESC * ENET_ETH_MAX_FLEN)
92 #define ENET_RX_BUF(i) (ENET_RX_BUF_BASE + ENET_ETH_MAX_FLEN * i)
93 #define ENET_TX_BUF(i) (ENET_TX_BUF_BASE + ENET_ETH_MAX_FLEN * i)
94 
99 
100 /* Transmit/receive buffers and indices */
103 
104 /*****************************************************************************
105  * Public types/enumerations/variables
106  ****************************************************************************/
107 
108 /*****************************************************************************
109  * Private functions
110  ****************************************************************************/
111 
112 /* Local delay function used by the ENET or PHY drivers . This can be
113  replaced with something more accurate if needed. */
115 {
116  ms = ms * 40000;
117  while (ms > 0) {
118  ms--;
119  }
120 }
121 
122 /* Initialize MAC descriptors for simple packet receive/transmit */
124 {
125  int i;
126 
127  /* Setup the descriptor list to a default state */
128  memset(pTXDescs, 0, ENET_NUM_TX_DESC * sizeof(ENET_TXDESC_T));
129  memset(pTXStats, 0, ENET_NUM_TX_DESC * sizeof(ENET_TXSTAT_T));
130  memset(pRXDescs, 0, ENET_NUM_RX_DESC * sizeof(ENET_RXDESC_T));
131  memset(pRXStats, 0, ENET_NUM_RX_DESC * sizeof(ENET_RXSTAT_T));
132 
133  rxConsumeIdx = 0;
134  rxConsumeIdx = 0;
135 
136  /* Build linked list, CPU is owner of descriptors */
137  for (i = 0; i < ENET_NUM_RX_DESC; i++) {
140  pRXStats[i].StatusInfo = 0;
141  pRXStats[i].StatusHashCRC = 0;
142  }
143  for (i = 0; i < ENET_NUM_TX_DESC; i++) {
145  pTXDescs[i].Control = 0;
146  pTXStats[i].StatusInfo = 0;
147  }
148 
149  /* Setup list pointers in Ethernet controller */
152 }
153 
154 /* Get the pointer to the Rx buffer storing new received frame */
155 STATIC void *ENET_RXGet(int32_t *bytes)
156 {
157  uint16_t produceIdx;
158  void *buffer;
159 
161  /* This doesn't check status of the received packet */
163  /* CPU owns descriptor, so a packet was received */
164  buffer = (void *) pRXDescs[rxConsumeIdx].Packet;
165  *bytes = (int32_t) (ENET_RINFO_SIZE(pRXStats[rxConsumeIdx].StatusInfo) - 4);/* Remove CRC */
166  }
167  else {
168  /* Nothing received */
169  *bytes = 0;
170  buffer = NULL;
171  }
172 
173  return buffer;
174 }
175 
176 /* Release Rx Buffer */
178 {
180 }
181 
182 /* Get Tx Buffer for the next transmission */
184 {
185  uint16_t consumeIdx = Chip_ENET_GetTXConsumeIndex(LPC_ETHERNET);
186 
188  return (void *) pTXDescs[txProduceIdx].Packet;
189  }
190  return NULL;
191 }
192 
193 /* Queue a new frame for transmission */
194 STATIC void ENET_TXQueue(int32_t bytes)
195 {
196  if (bytes > 0) {
199  }
200 }
201 
202 /* Check if tranmission finished */
204 {
205  uint16_t consumeIdx = Chip_ENET_GetTXConsumeIndex(LPC_ETHERNET);
206 
208  return true;
209  }
210  return false;
211 }
212 
213 /*****************************************************************************
214  * Public functions
215  ****************************************************************************/
216 
221 void ETH_IRQHandler(void)
222 {
223  /* This demo is entirely polled, so the IRQ isn't really needed */
224 }
225 
230 int main(void)
231 {
232  uint8_t macaddr[6], *workbuff;
233  uint32_t physts = 0;
234  int32_t rxBytes, i;
235  bool ethpkttgl = true;
236  volatile int k = 1;
237 
238  /* LED0 is used for the link status, on = PHY cable detected */
239  Board_Init();
240 
241  /* Initial LED state is off to show an unconnected cable state */
242  Board_LED_Set(0, false);
243 
244  /* Setup ethernet and PHY */
246 
247  /* Setup MII clock rate and PHY address */
249 
250  lpc_phy_init(true, localMsDelay);
251 
252  /* Setup MAC address for device */
253  Board_ENET_GetMacADDR(macaddr);
255 
256  /* Setup descriptors */
257  InitDescriptors();
258 
259  /* Enable RX/TX after descriptors are setup */
262 
263  while (k) {
264  /* Check for receive packets */
265  workbuff = ENET_RXGet(&rxBytes);
266  if (workbuff) {
267  /* Packet was received. Dump some info from the packet */
268  DEBUGOUT("Packet received: ");
269  ethpkttgl = (bool) !ethpkttgl;
270 
271  /* Toggle LED2 on each packet received */
272  Board_LED_Set(1, ethpkttgl);
273 
274  /* Destination and source MAC addresses */
275  DEBUGOUT("-Dest MAC: %02x:%02x:%02x:%02x:%02x:%02x-",
276  workbuff[0], workbuff[1], workbuff[2], workbuff[3], workbuff[4], workbuff[5]);
277  DEBUGOUT("-Source MAC: %02x:%02x:%02x:%02x:%02x:%02x-",
278  workbuff[6], workbuff[7], workbuff[8], workbuff[9], workbuff[10], workbuff[11]);
279 
280  /* Length of received packet and embedded len/type */
281  DEBUGOUT("-Packet len: %d", rxBytes);
282  DEBUGOUT("-Type: %04x\r\n", ((((uint32_t) workbuff[12]) << 8) | (((uint32_t) workbuff[13]))));
284  }
285 
286  /* Send a 'dummy' broadcast packet on a keypress. You'll only see this
287  if your using a tool such as WireShark and the packet will not have
288  a checksum */
289  if (DEBUGIN() != EOF) {
290  /* Only if link detected */
291  if (physts & PHY_LINK_CONNECTED) {
292  workbuff = ENET_TXBuffGet();
293  if (workbuff) {
294  /* Destination is broadcast */
295  for (i = 0; i < 6; i++) {
296  workbuff[i] = 0xFF;
297  }
298 
299  /* Source is this MAC address */
300  memcpy(&workbuff[6], macaddr, 6);
301 
302  /* Size will be 128 bytes (total) */
303  workbuff[12] = 0;
304  workbuff[13] = 128;
305 
306  /* Some dummy data, fill beyond end of packet */
307  for (i = 0; i < 128; i++) {
308  workbuff[i + 14] = (uint8_t) (i & 0xFF);
309  }
310 
311  ENET_TXQueue(128);
312  DEBUGOUT("Packet sent! \r\n");
313  Board_LED_Set(1, true);
314  }
315  }
316  }
317  if (ENET_IsTXFinish()) {
318  Board_LED_Set(1, false);
319  }
320  /* PHY status state machine, LED on when connected. This function will
321  not block. */
322  physts = lpcPHYStsPoll();
323 
324  /* Only check for connection state when the PHY status has changed */
325  if (physts & PHY_LINK_CHANGED) {
326  if (physts & PHY_LINK_CONNECTED) {
327  Board_LED_Set(0, true);
328 
329  /* Set interface speed and duplex */
330  if(physts & PHY_LINK_FULLDUPLX)
332  else
334  if(physts & PHY_LINK_SPEED100)
336  else
338  }
339  else {
340  Board_LED_Set(0, false);
341  }
342 
343  DEBUGOUT("Link connect status: %d\r\n", ((physts & PHY_LINK_CONNECTED) != 0));
344  }
345  }
346 
347  /* Never returns, for warning only */
348  return 0;
349 }
350