esp32_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file esp32_eth_driver.c
3  * @brief ESP32 Ethernet MAC controller
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL NIC_TRACE_LEVEL
31 
32 //Dependencies
33 #include "soc/soc.h"
34 #include "soc/dport_reg.h"
35 #include "soc/emac_ex_reg.h"
36 #include "soc/emac_reg_v2.h"
37 #include "driver/periph_ctrl.h"
38 #include "core/net.h"
40 #include "debug.h"
41 
42 //Underlying network interface
43 static NetInterface *nicDriverInterface;
44 
45 //Transmit buffer
47  __attribute__((aligned(1024)));
48 //Receive buffer
50  __attribute__((aligned(1024)));
51 //Transmit DMA descriptors
53  __attribute__((aligned(1024)));
54 //Receive DMA descriptors
56  __attribute__((aligned(1024)));
57 
58 //Pointer to the current TX DMA descriptor
59 static Esp32EthTxDmaDesc *txCurDmaDesc;
60 //Pointer to the current RX DMA descriptor
61 static Esp32EthRxDmaDesc *rxCurDmaDesc;
62 
63 
64 /**
65  * @brief ESP32 Ethernet MAC driver
66  **/
67 
69 {
71  ETH_MTU,
82  TRUE,
83  TRUE,
84  TRUE,
85  FALSE
86 };
87 
88 
89 /**
90  * @brief ESP32 Ethernet MAC initialization
91  * @param[in] interface Underlying network interface
92  * @return Error code
93  **/
94 
96 {
97  error_t error;
98 
99  //Debug message
100  TRACE_INFO("Initializing ESP32 Ethernet MAC...\r\n");
101 
102  //Save underlying network interface
103  nicDriverInterface = interface;
104 
105  //Enable EMAC module
106  periph_module_enable(PERIPH_EMAC_MODULE);
107  //Enable Ethernet MAC clock
108  DPORT_REG_SET_BIT(EMAC_CLK_EN_REG, EMAC_CLK_EN);
109 
110  //GPIO configuration
111  esp32EthInitGpio(interface);
112 
113  //Perform a software reset
114  REG_SET_BIT(EMAC_DMABUSMODE_REG, EMAC_SW_RST);
115  //Wait for the reset to complete
116  while(REG_GET_BIT(EMAC_DMABUSMODE_REG, EMAC_SW_RST));
117 
118  //Adjust MDC clock range
119  REG_SET_FIELD(EMAC_GMACGMIIDATA_REG, EMAC_GMIICSRCLK, 1);
120 
121  //PHY transceiver initialization
122  error = interface->phyDriver->init(interface);
123  //Failed to initialize PHY transceiver?
124  if(error)
125  return error;
126 
127  //Use default MAC configuration
128  REG_WRITE(EMAC_GMACCONFIG_REG, 0);
129  REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACMIIGMII);
130  REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACRXOWN);
131 
132  //Set the MAC address
133  REG_WRITE(EMAC_GMACADDR0HIGH_REG, interface->macAddr.w[2] | EMAC_ADDRESS_ENABLE0_M);
134  REG_WRITE(EMAC_GMACADDR0LOW_REG, interface->macAddr.w[0] | (interface->macAddr.w[1] << 16));
135 
136  //Configure the receive filter
137  REG_WRITE(EMAC_GMACFRAMEFILTER_REG, 0);
138  //Disable flow control
139  REG_WRITE(EMAC_GMACFLOWCONTROL_REG, 0);
140 
141  //Enable store and forward mode
142  REG_WRITE(EMAC_DMAOPERATION_MODE_REG, 0);
143  REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_RECV_STORE_FORWARD);
144  REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_TRANSMIT_STORE_FORWARD);
145 
146  //Configure DMA bus mode
147  REG_SET_FIELD(EMAC_DMABUSMODE_REG, EMAC_RX_DMA_PBL, 1);
148  REG_SET_FIELD(EMAC_DMABUSMODE_REG, EMAC_PROG_BURST_LEN, 1);
149  REG_SET_BIT(EMAC_DMABUSMODE_REG, EMAC_ALT_DESC_SIZE);
150 
151  //Initialize DMA descriptor lists
152  esp32EthInitDmaDesc(interface);
153 
154  //Disable MAC interrupts
155  REG_SET_BIT(EMAC_GMACINTERRUPTMASK_REG, EMAC_LPI_INTERRUPT_MASK);
156  REG_SET_BIT(EMAC_GMACINTERRUPTMASK_REG, EMAC_PMT_INTERRUPT_MASK);
157  REG_SET_BIT(EMAC_GMACINTERRUPTMASK_REG, EMAC_INTERRUPT_MASK);
158 
159  //Enable the desired DMA interrupts
160  REG_WRITE(EMAC_DMAINTERRUPT_EN_REG, 0);
161  REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG, EMAC_NORMAL_INTERRUPT_SUMMARY_ENABLE);
162  REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG, EMAC_RECEIVE_INTERRUPT_ENABLE);
163  REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG, EMAC_TRANSMIT_INTERRUPT_ENABLE);
164 
165  //Register interrupt handler
166  esp_intr_alloc(ETS_ETH_MAC_INTR_SOURCE, 0, esp32EthIrqHandler, NULL, NULL);
167 
168  //Enable MAC transmission and reception
169  REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACTX);
170  REG_SET_BIT(EMAC_GMACCONFIG_REG, EMAC_GMACRX);
171 
172  //Enable DMA transmission and reception
173  REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_START_STOP_TRANSMISSION_COMMAND);
174  REG_SET_BIT(EMAC_DMAOPERATION_MODE_REG, EMAC_START_STOP_RECEIVE);
175 
176  //Accept any packets from the upper layer
177  osSetEvent(&interface->nicTxEvent);
178 
179  //Successful initialization
180  return NO_ERROR;
181 }
182 
183 
184 //ESP32-EVB or ESP32-GATEWAY evaluation board?
185 #if defined(ESP32_EVB) || defined(ESP32_GATEWAY)
186 
187 /**
188  * @brief GPIO configuration
189  * @param[in] interface Underlying network interface
190  **/
191 
192 void esp32EthInitGpio(NetInterface *interface)
193 {
194  //Select RMII interface mode
195  REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL, EMAC_EX_PHY_INTF_RMII);
196 
197  //Select clock source
198  REG_SET_BIT(EMAC_EX_CLK_CTRL_REG, EMAC_EX_EXT_OSC_EN);
199  //Enable clock
200  REG_SET_BIT(EMAC_EX_OSCCLK_CONF_REG, EMAC_EX_OSC_CLK_SEL);
201 
202  //Configure RMII CLK (GPIO0)
203  gpio_set_direction(0, GPIO_MODE_INPUT);
204 
205  //Configure TXD0 (GPIO19)
206  PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO19_U, FUNC_GPIO19_EMAC_TXD0);
207  //Configure TX_EN (GPIO21)
208  PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO21_U, FUNC_GPIO21_EMAC_TX_EN);
209  //Configure TXD1 (GPIO22)
210  PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO22_U, FUNC_GPIO22_EMAC_TXD1);
211 
212  //Configure RXD0 (GPIO25)
213  gpio_set_direction(25, GPIO_MODE_INPUT);
214  //Configure RXD1 (GPIO26)
215  gpio_set_direction(26, GPIO_MODE_INPUT);
216  //Configure CRS_DRV (GPIO27)
217  PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO27_U, FUNC_GPIO27_EMAC_RX_DV);
218 
219  //Configure MDC (GPIO23)
220  gpio_matrix_out(23, EMAC_MDC_O_IDX, 0, 0);
221 
222  //Configure MDIO (GPIO18)
223  gpio_matrix_out(18, EMAC_MDO_O_IDX, 0, 0);
224  gpio_matrix_in(18, EMAC_MDI_I_IDX, 0);
225 }
226 
227 #endif
228 
229 
230 /**
231  * @brief Initialize DMA descriptor lists
232  * @param[in] interface Underlying network interface
233  **/
234 
236 {
237  uint_t i;
238 
239  //Initialize TX DMA descriptor list
240  for(i = 0; i < ESP32_ETH_TX_BUFFER_COUNT; i++)
241  {
242  //Use chain structure rather than ring structure
244  //Initialize transmit buffer size
245  txDmaDesc[i].tdes1 = 0;
246  //Transmit buffer address
247  txDmaDesc[i].tdes2 = (uint32_t) txBuffer[i];
248  //Next descriptor address
249  txDmaDesc[i].tdes3 = (uint32_t) &txDmaDesc[i + 1];
250  //Reserved fields
251  txDmaDesc[i].tdes4 = 0;
252  txDmaDesc[i].tdes5 = 0;
253  //Transmit frame time stamp
254  txDmaDesc[i].tdes6 = 0;
255  txDmaDesc[i].tdes7 = 0;
256  }
257 
258  //The last descriptor is chained to the first entry
259  txDmaDesc[i - 1].tdes3 = (uint32_t) &txDmaDesc[0];
260  //Point to the very first descriptor
261  txCurDmaDesc = &txDmaDesc[0];
262 
263  //Initialize RX DMA descriptor list
264  for(i = 0; i < ESP32_ETH_RX_BUFFER_COUNT; i++)
265  {
266  //The descriptor is initially owned by the DMA
267  rxDmaDesc[i].rdes0 = EMAC_RDES0_OWN;
268  //Use chain structure rather than ring structure
270  //Receive buffer address
271  rxDmaDesc[i].rdes2 = (uint32_t) rxBuffer[i];
272  //Next descriptor address
273  rxDmaDesc[i].rdes3 = (uint32_t) &rxDmaDesc[i + 1];
274  //Extended status
275  rxDmaDesc[i].rdes4 = 0;
276  //Reserved field
277  rxDmaDesc[i].rdes5 = 0;
278  //Receive frame time stamp
279  rxDmaDesc[i].rdes6 = 0;
280  rxDmaDesc[i].rdes7 = 0;
281  }
282 
283  //The last descriptor is chained to the first entry
284  rxDmaDesc[i - 1].rdes3 = (uint32_t) &rxDmaDesc[0];
285  //Point to the very first descriptor
286  rxCurDmaDesc = &rxDmaDesc[0];
287 
288  //Start location of the TX descriptor list
289  REG_WRITE(EMAC_DMATXBASEADDR_REG, (uint32_t) txDmaDesc);
290  //Start location of the RX descriptor list
291  REG_WRITE(EMAC_DMARXBASEADDR_REG, (uint32_t) rxDmaDesc);
292 }
293 
294 
295 /**
296  * @brief ESP32 Ethernet MAC timer handler
297  *
298  * This routine is periodically called by the TCP/IP stack to
299  * handle periodic operations such as polling the link state
300  *
301  * @param[in] interface Underlying network interface
302  **/
303 
304 void esp32EthTick(NetInterface *interface)
305 {
306  //Handle periodic operations
307  interface->phyDriver->tick(interface);
308 }
309 
310 
311 /**
312  * @brief Enable interrupts
313  * @param[in] interface Underlying network interface
314  **/
315 
317 {
318  //Enable Ethernet MAC interrupts
319 
320  //Enable Ethernet PHY interrupts
321  interface->phyDriver->enableIrq(interface);
322 }
323 
324 
325 /**
326  * @brief Disable interrupts
327  * @param[in] interface Underlying network interface
328  **/
329 
331 {
332  //Disable Ethernet MAC interrupts
333 
334  //Disable Ethernet PHY interrupts
335  interface->phyDriver->disableIrq(interface);
336 }
337 
338 
339 /**
340  * @brief ESP32 Ethernet MAC interrupt service routine
341  * @param[in] arg Unused parameter
342  **/
343 
344 void IRAM_ATTR esp32EthIrqHandler(void *arg)
345 {
346  bool_t flag;
347  uint32_t status;
348 
349  //Enter interrupt service routine
350  osEnterIsr();
351 
352  //This flag will be set if a higher priority task must be woken
353  flag = FALSE;
354 
355  //Read DMA status register
356  status = REG_READ(EMAC_DMASTATUS_REG);
357 
358  //A packet has been transmitted?
359  if(status & EMAC_TRANS_INT_M)
360  {
361  //Clear TI interrupt flag
362  REG_WRITE(EMAC_DMASTATUS_REG, EMAC_TRANS_INT_M);
363 
364  //Check whether the TX buffer is available for writing
365  if(!(txCurDmaDesc->tdes0 & EMAC_TDES0_OWN))
366  {
367  //Notify the TCP/IP stack that the transmitter is ready to send
368  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
369  }
370  }
371 
372  //A packet has been received?
373  if(status & EMAC_RECV_INT_M)
374  {
375  //Disable RIE interrupt
376  REG_CLR_BIT(EMAC_DMAINTERRUPT_EN_REG, EMAC_RECEIVE_INTERRUPT_ENABLE);
377 
378  //Set event flag
379  nicDriverInterface->nicEvent = TRUE;
380  //Notify the TCP/IP stack of the event
381  flag |= osSetEventFromIsr(&netEvent);
382  }
383 
384  //Clear NIS interrupt flag
385  REG_WRITE(EMAC_DMASTATUS_REG, EMAC_NORM_INT_SUMM_M);
386 
387  //Leave interrupt service routine
388  osExitIsr(flag);
389 }
390 
391 
392 /**
393  * @brief ESP32 Ethernet MAC event handler
394  * @param[in] interface Underlying network interface
395  **/
396 
398 {
399  error_t error;
400 
401  //Packet received?
402  if(REG_GET_BIT(EMAC_DMASTATUS_REG, EMAC_RECV_INT))
403  {
404  //Clear interrupt flag
405  REG_WRITE(EMAC_DMASTATUS_REG, EMAC_RECV_INT_M);
406 
407  //Process all pending packets
408  do
409  {
410  //Read incoming packet
411  error = esp32EthReceivePacket(interface);
412 
413  //No more data in the receive buffer?
414  } while(error != ERROR_BUFFER_EMPTY);
415  }
416 
417  //Re-enable DMA interrupts
418  REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG, EMAC_NORMAL_INTERRUPT_SUMMARY_ENABLE);
419  REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG, EMAC_RECEIVE_INTERRUPT_ENABLE);
420  REG_SET_BIT(EMAC_DMAINTERRUPT_EN_REG, EMAC_TRANSMIT_INTERRUPT_ENABLE);
421 }
422 
423 
424 /**
425  * @brief Send a packet
426  * @param[in] interface Underlying network interface
427  * @param[in] buffer Multi-part buffer containing the data to send
428  * @param[in] offset Offset to the first data byte
429  * @return Error code
430  **/
431 
433  const NetBuffer *buffer, size_t offset)
434 {
435  size_t length;
436 
437  //Retrieve the length of the packet
438  length = netBufferGetLength(buffer) - offset;
439 
440  //Check the frame length
442  {
443  //The transmitter can accept another packet
444  osSetEvent(&interface->nicTxEvent);
445  //Report an error
446  return ERROR_INVALID_LENGTH;
447  }
448 
449  //Make sure the current buffer is available for writing
450  if(txCurDmaDesc->tdes0 & EMAC_TDES0_OWN)
451  return ERROR_FAILURE;
452 
453  //Copy user data to the transmit buffer
454  netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length);
455 
456  //Write the number of bytes to send
457  txCurDmaDesc->tdes1 = length & EMAC_TDES1_TBS1;
458  //Set LS and FS flags as the data fits in a single buffer
459  txCurDmaDesc->tdes0 |= EMAC_TDES0_LS | EMAC_TDES0_FS;
460  //Give the ownership of the descriptor to the DMA
461  txCurDmaDesc->tdes0 |= EMAC_TDES0_OWN;
462 
463  //Clear TBUS flag to resume processing
464  REG_WRITE(EMAC_DMASTATUS_REG, EMAC_TRANS_BUF_UNAVAIL_M);
465  //Instruct the DMA to poll the transmit descriptor list
466  REG_WRITE(EMAC_DMATXPOLLDEMAND_REG, 0);
467 
468  //Point to the next descriptor in the list
469  txCurDmaDesc = (Esp32EthTxDmaDesc *) txCurDmaDesc->tdes3;
470 
471  //Check whether the next buffer is available for writing
472  if(!(txCurDmaDesc->tdes0 & EMAC_TDES0_OWN))
473  {
474  //The transmitter can accept another packet
475  osSetEvent(&interface->nicTxEvent);
476  }
477 
478  //Data successfully written
479  return NO_ERROR;
480 }
481 
482 
483 /**
484  * @brief Receive a packet
485  * @param[in] interface Underlying network interface
486  * @return Error code
487  **/
488 
490 {
491  error_t error;
492  size_t n;
493 
494  //The current buffer is available for reading?
495  if(!(rxCurDmaDesc->rdes0 & EMAC_RDES0_OWN))
496  {
497  //FS and LS flags should be set
498  if((rxCurDmaDesc->rdes0 & EMAC_RDES0_FS) && (rxCurDmaDesc->rdes0 & EMAC_RDES0_LS))
499  {
500  //Make sure no error occurred
501  if(!(rxCurDmaDesc->rdes0 & EMAC_RDES0_ES))
502  {
503  //Retrieve the length of the frame
504  n = (rxCurDmaDesc->rdes0 & EMAC_RDES0_FL) >> 16;
505  //Limit the number of data to read
507 
508  //Pass the packet to the upper layer
509  nicProcessPacket(interface, (uint8_t *) rxCurDmaDesc->rdes2, n);
510 
511  //Valid packet received
512  error = NO_ERROR;
513  }
514  else
515  {
516  //The received packet contains an error
517  error = ERROR_INVALID_PACKET;
518  }
519  }
520  else
521  {
522  //The packet is not valid
523  error = ERROR_INVALID_PACKET;
524  }
525 
526  //Give the ownership of the descriptor back to the DMA
527  rxCurDmaDesc->rdes0 = EMAC_RDES0_OWN;
528  //Point to the next descriptor in the list
529  rxCurDmaDesc = (Esp32EthRxDmaDesc *) rxCurDmaDesc->rdes3;
530  }
531  else
532  {
533  //No more data in the receive buffer
534  error = ERROR_BUFFER_EMPTY;
535  }
536 
537  //Clear RBUS flag to resume processing
538  REG_WRITE(EMAC_DMASTATUS_REG, EMAC_RECV_BUF_UNAVAIL_M);
539  //Instruct the DMA to poll the receive descriptor list
540  REG_WRITE(EMAC_DMARXPOLLDEMAND_REG, 0);
541 
542  //Return status code
543  return error;
544 }
545 
546 
547 /**
548  * @brief Configure MAC address filtering
549  * @param[in] interface Underlying network interface
550  * @return Error code
551  **/
552 
554 {
555  uint_t i;
556  bool_t acceptMulticast;
557 
558  //This flag will be set if multicast addresses should be accepted
559  acceptMulticast = FALSE;
560 
561  //The MAC address filter contains the list of MAC addresses to accept
562  //when receiving an Ethernet frame
563  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
564  {
565  //Valid entry?
566  if(interface->macAddrFilter[i].refCount > 0)
567  {
568  //Accept multicast addresses
569  acceptMulticast = TRUE;
570  //We are done
571  break;
572  }
573  }
574 
575  //Enable the reception of multicast frames if necessary
576  if(acceptMulticast)
577  REG_SET_BIT(EMAC_GMACFRAMEFILTER_REG, EMAC_PASS_ALL_MULTICAST);
578  else
579  REG_CLR_BIT(EMAC_GMACFRAMEFILTER_REG, EMAC_PASS_ALL_MULTICAST);
580 
581  //Successful processing
582  return NO_ERROR;
583 }
584 
585 
586 /**
587  * @brief Adjust MAC configuration parameters for proper operation
588  * @param[in] interface Underlying network interface
589  * @return Error code
590  **/
591 
593 {
594  uint32_t config;
595 
596  //Read current MAC configuration
597  config = REG_READ(EMAC_GMACCONFIG_REG);
598 
599  //10BASE-T or 100BASE-TX operation mode?
600  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
601  config |= EMAC_GMACFESPEED_M;
602  else
603  config &= ~EMAC_GMACFESPEED_M;
604 
605  //Half-duplex or full-duplex mode?
606  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
607  config |= EMAC_GMACDUPLEX_M;
608  else
609  config &= ~EMAC_GMACDUPLEX_M;
610 
611  //Update MAC configuration register
612  REG_WRITE(EMAC_GMACCONFIG_REG, config);
613 
614  //Successful processing
615  return NO_ERROR;
616 }
617 
618 
619 /**
620  * @brief Write PHY register
621  * @param[in] phyAddr PHY address
622  * @param[in] regAddr Register address
623  * @param[in] data Register value
624  **/
625 
626 void esp32EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
627 {
628  uint32_t value;
629 
630  //Take care not to alter MDC clock configuration
631  value = REG_READ(EMAC_GMACGMIIADDR_REG) & EMAC_GMIICSRCLK_M;
632  //Set up a write operation
633  value |= EMAC_GMIIWRITE_M | EMAC_GMIIBUSY_M;
634  //PHY address
635  value |= (phyAddr << EMAC_GMIIDEV_S) & EMAC_GMIIDEV_M;
636  //Register address
637  value |= (regAddr << EMAC_GMIIREG_S) & EMAC_GMIIREG_M;
638 
639  //Data to be written in the PHY register
640  REG_WRITE(EMAC_GMACGMIIDATA_REG, data);
641 
642  //Start a write operation
643  REG_WRITE(EMAC_GMACGMIIADDR_REG, value);
644  //Wait for the write to complete
645  while(REG_GET_BIT(EMAC_GMACGMIIADDR_REG, EMAC_GMIIBUSY));
646 }
647 
648 
649 /**
650  * @brief Read PHY register
651  * @param[in] phyAddr PHY address
652  * @param[in] regAddr Register address
653  * @return Register value
654  **/
655 
656 uint16_t esp32EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
657 {
658  uint32_t value;
659 
660  //Take care not to alter MDC clock configuration
661  value = REG_READ(EMAC_GMACGMIIADDR_REG) & EMAC_GMIICSRCLK_M;
662  //Set up a read operation
663  value |= EMAC_GMIIBUSY_M;
664  //PHY address
665  value |= (phyAddr << EMAC_GMIIDEV_S) & EMAC_GMIIDEV_M;
666  //Register address
667  value |= (regAddr << EMAC_GMIIREG_S) & EMAC_GMIIREG_M;
668 
669  //Start a read operation
670  REG_WRITE(EMAC_GMACGMIIADDR_REG, value);
671  //Wait for the read to complete
672  while(REG_GET_BIT(EMAC_GMACGMIIADDR_REG, EMAC_GMIIBUSY));
673 
674  //Return PHY register contents
675  return REG_READ(EMAC_GMACGMIIDATA_REG);
676 }
Enhanced TX DMA descriptor.
#define txDmaDesc
#define EMAC_RDES1_RCH
TCP/IP stack core.
const NicDriver esp32EthDriver
ESP32 Ethernet MAC driver.
Debugging facilities.
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:295
Generic error code.
Definition: error.h:43
void esp32EthInitGpio(NetInterface *interface)
#define rxDmaDesc
#define EMAC_RDES0_OWN
ESP32 Ethernet MAC controller.
void esp32EthDisableIrq(NetInterface *interface)
Disable interrupts.
#define txBuffer
#define EMAC_TDES1_TBS1
error_t esp32EthInit(NetInterface *interface)
ESP32 Ethernet MAC initialization.
void esp32EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
void IRAM_ATTR esp32EthIrqHandler(void *arg)
ESP32 Ethernet MAC interrupt service routine.
error_t esp32EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
error_t esp32EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define EMAC_RDES0_LS
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
#define ESP32_ETH_RX_BUFFER_SIZE
#define EMAC_RDES0_ES
#define EMAC_RDES1_RBS1
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:670
NIC driver.
Definition: nic.h:161
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
#define EMAC_TDES0_OWN
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
#define ESP32_ETH_RX_BUFFER_COUNT
Success.
Definition: error.h:42
#define rxBuffer
OsEvent netEvent
Definition: net.c:72
#define EMAC_RDES0_FL
void nicProcessPacket(NetInterface *interface, void *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:239
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
#define ESP32_ETH_TX_BUFFER_SIZE
void esp32EthEventHandler(NetInterface *interface)
ESP32 Ethernet MAC event handler.
unsigned int uint_t
Definition: compiler_port.h:43
#define EMAC_RDES0_FS
error_t esp32EthReceivePacket(NetInterface *interface)
Receive a packet.
#define EMAC_TDES0_FS
void esp32EthEnableIrq(NetInterface *interface)
Enable interrupts.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
uint8_t value[]
Definition: dtls_misc.h:141
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
void esp32EthTick(NetInterface *interface)
ESP32 Ethernet MAC timer handler.
#define EMAC_TDES0_TCH
Enhanced RX DMA descriptor.
uint16_t esp32EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define osExitIsr(flag)
#define EMAC_TDES0_LS
error_t esp32EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define osEnterIsr()
#define EMAC_TDES0_IC
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
void esp32EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
#define ESP32_ETH_TX_BUFFER_COUNT