msp432e4_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file msp432e4_eth_driver.c
3  * @brief MSP432E4 Ethernet 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 <stdint.h>
34 #include "msp432.h"
35 #include "inc/hw_emac.h"
36 #include "driverlib/gpio.h"
37 #include "driverlib/interrupt.h"
38 #include "driverlib/pin_map.h"
39 #include "driverlib/sysctl.h"
40 #include "core/net.h"
42 #include "debug.h"
43 
44 //Underlying network interface
45 static NetInterface *nicDriverInterface;
46 
47 //IAR EWARM compiler?
48 #if defined(__ICCARM__)
49 
50 //Transmit buffer
51 #pragma data_alignment = 4
53 //Receive buffer
54 #pragma data_alignment = 4
56 //Transmit DMA descriptors
57 #pragma data_alignment = 4
59 //Receive DMA descriptors
60 #pragma data_alignment = 4
62 
63 //Keil MDK-ARM or GCC compiler?
64 #else
65 
66 //Transmit buffer
68  __attribute__((aligned(4)));
69 //Receive buffer
71  __attribute__((aligned(4)));
72 //Transmit DMA descriptors
74  __attribute__((aligned(4)));
75 //Receive DMA descriptors
77  __attribute__((aligned(4)));
78 
79 #endif
80 
81 //Pointer to the current TX DMA descriptor
82 static Tm4c129TxDmaDesc *txCurDmaDesc;
83 //Pointer to the current RX DMA descriptor
84 static Tm4c129RxDmaDesc *rxCurDmaDesc;
85 
86 
87 /**
88  * @brief MSP432E4 Ethernet MAC driver
89  **/
90 
92 {
94  ETH_MTU,
102  NULL,
103  NULL,
104  NULL,
105  TRUE,
106  TRUE,
107  TRUE,
108  FALSE
109 };
110 
111 
112 /**
113  * @brief MSP432E4 Ethernet MAC initialization
114  * @param[in] interface Underlying network interface
115  * @return Error code
116  **/
117 
119 {
120  //Debug message
121  TRACE_INFO("Initializing MSP432E4 Ethernet controller...\r\n");
122 
123  //Save underlying network interface
124  nicDriverInterface = interface;
125 
126  //Enable Ethernet controller clock
127  SysCtlPeripheralEnable(SYSCTL_PERIPH_EMAC0);
128  //Reset Ethernet controller
129  SysCtlPeripheralReset(SYSCTL_PERIPH_EMAC0);
130  //Wait for the reset to complete
131  while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EMAC0));
132 
133  //Enable internal PHY clock
134  SysCtlPeripheralEnable(SYSCTL_PERIPH_EPHY0);
135  //Reset internal PHY
136  SysCtlPeripheralReset(SYSCTL_PERIPH_EPHY0);
137  //Wait for the reset to complete
138  while(!SysCtlPeripheralReady(SYSCTL_PERIPH_EPHY0));
139 
140  //GPIO configuration
141  msp432e4EthInitGpio(interface);
142 
143  //Perform a software reset
144  EMAC0->DMABUSMOD |= EMAC_DMABUSMOD_SWR;
145  //Wait for the reset to complete
146  while(EMAC0->DMABUSMOD & EMAC_DMABUSMOD_SWR);
147 
148  //Adjust MDC clock range depending on SYSCLK frequency
149  EMAC0->MIIADDR = EMAC_MIIADDR_CR_100_150;
150 
151  //Reset PHY transceiver
152  msp432e4EthWritePhyReg(EPHY_BMCR, EPHY_BMCR_MIIRESET);
153  //Wait for the reset to complete
154  while(msp432e4EthReadPhyReg(EPHY_BMCR) & EPHY_BMCR_MIIRESET);
155 
156  //Dump PHY registers for debugging purpose
158 
159  //Configure LED0, LED1 and LED2
160  msp432e4EthWritePhyReg(EPHY_LEDCFG, EPHY_LEDCFG_LED0_TX |
161  EPHY_LEDCFG_LED1_RX | EPHY_LEDCFG_LED2_LINK);
162 
163  //Configure PHY interrupts as desired
164  msp432e4EthWritePhyReg(EPHY_MISR1, EPHY_MISR1_LINKSTATEN);
165  //Enable PHY interrupts
166  msp432e4EthWritePhyReg(EPHY_SCR, EPHY_SCR_INTEN);
167 
168  //Use default MAC configuration
169  EMAC0->CFG = EMAC_CFG_DRO;
170 
171  //Set the MAC address
172  EMAC0->ADDR0L = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
173  EMAC0->ADDR0H = interface->macAddr.w[2];
174 
175  //Initialize hash table
176  EMAC0->HASHTBLL = 0;
177  EMAC0->HASHTBLH = 0;
178 
179  //Configure the receive filter
180  EMAC0->FRAMEFLTR = EMAC_FRAMEFLTR_HPF | EMAC_FRAMEFLTR_HMC;
181  //Disable flow control
182  EMAC0->FLOWCTL = 0;
183  //Enable store and forward mode
184  EMAC0->DMAOPMODE = EMAC_DMAOPMODE_RSF | EMAC_DMAOPMODE_TSF;
185 
186  //Configure DMA bus mode
187  EMAC0->DMABUSMOD = EMAC_DMABUSMOD_AAL | EMAC_DMABUSMOD_USP | EMAC_DMABUSMOD_RPBL_1 |
188  EMAC_DMABUSMOD_PR_1_1 | EMAC_DMABUSMOD_PBL_1 | EMAC_DMABUSMOD_ATDS;
189 
190  //Initialize DMA descriptor lists
191  msp432e4EthInitDmaDesc(interface);
192 
193  //Prevent interrupts from being generated when the transmit statistic
194  //counters reach half their maximum value
195  EMAC0->MMCTXIM = EMAC_MMCTXIM_OCTCNT | EMAC_MMCTXIM_MCOLLGF |
196  EMAC_MMCTXIM_SCOLLGF | EMAC_MMCTXIM_GBF;
197 
198  //Prevent interrupts from being generated when the receive statistic
199  //counters reach half their maximum value
200  EMAC0->MMCRXIM = EMAC_MMCRXIM_UCGF | EMAC_MMCRXIM_ALGNERR |
201  EMAC_MMCRXIM_CRCERR | EMAC_MMCRXIM_GBF;
202 
203  //Disable MAC interrupts
204  EMAC0->IM = EMAC_IM_TSI | EMAC_IM_PMT;
205  //Enable the desired DMA interrupts
206  EMAC0->DMAIM = EMAC_DMAIM_NIE | EMAC_DMAIM_RIE | EMAC_DMAIM_TIE;
207  //Enable PHY interrupts
208  EMAC0->EPHYIM = EMAC_EPHYIM_INT;
209 
210  //Set priority grouping (3 bits for pre-emption priority, no bits for subpriority)
211  IntPriorityGroupingSet(MSP432E4_ETH_IRQ_PRIORITY_GROUPING);
212  //Configure Ethernet interrupt priority
213  IntPrioritySet(INT_EMAC0, MSP432E4_ETH_IRQ_PRIORITY);
214 
215  //Enable MAC transmission and reception
216  EMAC0->CFG |= EMAC_CFG_TE | EMAC_CFG_RE;
217  //Enable DMA transmission and reception
218  EMAC0->DMAOPMODE |= EMAC_DMAOPMODE_ST | EMAC_DMAOPMODE_SR;
219 
220  //Accept any packets from the upper layer
221  osSetEvent(&interface->nicTxEvent);
222 
223  //Successful initialization
224  return NO_ERROR;
225 }
226 
227 
228 //MSP-EXP432E401Y evaluation board?
229 #if defined(USE_MSP_EXP432E401Y)
230 
231 /**
232  * @brief GPIO configuration
233  * @param[in] interface Underlying network interface
234  **/
235 
236 void msp432e4EthInitGpio(NetInterface *interface)
237 {
238  //Enable GPIO clock
239  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
240 
241  //Select the relevant alternate function for PF0 and PF4
242  GPIOPinConfigure(GPIO_PF0_EN0LED0);
243  GPIOPinConfigure(GPIO_PF4_EN0LED1);
244 
245  //Configure Ethernet LED pins for proper operation
246  GPIOPinTypeEthernetLED(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4);
247 }
248 
249 #endif
250 
251 
252 /**
253  * @brief Initialize DMA descriptor lists
254  * @param[in] interface Underlying network interface
255  **/
256 
258 {
259  uint_t i;
260 
261  //Initialize TX DMA descriptor list
262  for(i = 0; i < MSP432E4_ETH_TX_BUFFER_COUNT; i++)
263  {
264  //Use chain structure rather than ring structure
266  //Initialize transmit buffer size
267  txDmaDesc[i].tdes1 = 0;
268  //Transmit buffer address
269  txDmaDesc[i].tdes2 = (uint32_t) txBuffer[i];
270  //Next descriptor address
271  txDmaDesc[i].tdes3 = (uint32_t) &txDmaDesc[i + 1];
272  //Reserved fields
273  txDmaDesc[i].tdes4 = 0;
274  txDmaDesc[i].tdes5 = 0;
275  //Transmit frame time stamp
276  txDmaDesc[i].tdes6 = 0;
277  txDmaDesc[i].tdes7 = 0;
278  }
279 
280  //The last descriptor is chained to the first entry
281  txDmaDesc[i - 1].tdes3 = (uint32_t) &txDmaDesc[0];
282  //Point to the very first descriptor
283  txCurDmaDesc = &txDmaDesc[0];
284 
285  //Initialize RX DMA descriptor list
286  for(i = 0; i < MSP432E4_ETH_RX_BUFFER_COUNT; i++)
287  {
288  //The descriptor is initially owned by the DMA
289  rxDmaDesc[i].rdes0 = EMAC_RDES0_OWN;
290  //Use chain structure rather than ring structure
292  //Receive buffer address
293  rxDmaDesc[i].rdes2 = (uint32_t) rxBuffer[i];
294  //Next descriptor address
295  rxDmaDesc[i].rdes3 = (uint32_t) &rxDmaDesc[i + 1];
296  //Extended status
297  rxDmaDesc[i].rdes4 = 0;
298  //Reserved field
299  rxDmaDesc[i].rdes5 = 0;
300  //Receive frame time stamp
301  rxDmaDesc[i].rdes6 = 0;
302  rxDmaDesc[i].rdes7 = 0;
303  }
304 
305  //The last descriptor is chained to the first entry
306  rxDmaDesc[i - 1].rdes3 = (uint32_t) &rxDmaDesc[0];
307  //Point to the very first descriptor
308  rxCurDmaDesc = &rxDmaDesc[0];
309 
310  //Start location of the TX descriptor list
311  EMAC0->TXDLADDR = (uint32_t) txDmaDesc;
312  //Start location of the RX descriptor list
313  EMAC0->RXDLADDR = (uint32_t) rxDmaDesc;
314 }
315 
316 
317 /**
318  * @brief MSP432E4 Ethernet MAC timer handler
319  *
320  * This routine is periodically called by the TCP/IP stack to
321  * handle periodic operations such as polling the link state
322  *
323  * @param[in] interface Underlying network interface
324  **/
325 
327 {
328 }
329 
330 
331 /**
332  * @brief Enable interrupts
333  * @param[in] interface Underlying network interface
334  **/
335 
337 {
338  //Enable Ethernet MAC interrupts
339  IntEnable(INT_EMAC0);
340 }
341 
342 
343 /**
344  * @brief Disable interrupts
345  * @param[in] interface Underlying network interface
346  **/
347 
349 {
350  //Disable Ethernet MAC interrupts
351  IntDisable(INT_EMAC0);
352 }
353 
354 
355 /**
356  * @brief MSP432E4 Ethernet MAC interrupt service routine
357  **/
358 
360 {
361  bool_t flag;
362  uint32_t status;
363 
364  //Enter interrupt service routine
365  osEnterIsr();
366 
367  //This flag will be set if a higher priority task must be woken
368  flag = FALSE;
369 
370  //Read PHY status register
371  status = EMAC0->EPHYRIS;
372 
373  //PHY interrupt?
374  if(status & EMAC_EPHYRIS_INT)
375  {
376  //Disable PHY interrupt
377  EMAC0->EPHYIM &= ~EMAC_EPHYIM_INT;
378 
379  //Set event flag
380  nicDriverInterface->nicEvent = TRUE;
381  //Notify the TCP/IP stack of the event
382  flag |= osSetEventFromIsr(&netEvent);
383  }
384 
385  //Read DMA status register
386  status = EMAC0->DMARIS;
387 
388  //A packet has been transmitted?
389  if(status & EMAC_DMARIS_TI)
390  {
391  //Clear TI interrupt flag
392  EMAC0->DMARIS = EMAC_DMARIS_TI;
393 
394  //Check whether the TX buffer is available for writing
395  if(!(txCurDmaDesc->tdes0 & EMAC_TDES0_OWN))
396  {
397  //Notify the TCP/IP stack that the transmitter is ready to send
398  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
399  }
400  }
401 
402  //A packet has been received?
403  if(status & EMAC_DMARIS_RI)
404  {
405  //Disable RIE interrupt
406  EMAC0->DMAIM &= ~EMAC_DMAIM_RIE;
407 
408  //Set event flag
409  nicDriverInterface->nicEvent = TRUE;
410  //Notify the TCP/IP stack of the event
411  flag |= osSetEventFromIsr(&netEvent);
412  }
413 
414  //Clear NIS interrupt flag
415  EMAC0->DMARIS = EMAC_DMARIS_NIS;
416 
417  //Leave interrupt service routine
418  osExitIsr(flag);
419 }
420 
421 
422 /**
423  * @brief MSP432E4 Ethernet MAC event handler
424  * @param[in] interface Underlying network interface
425  **/
426 
428 {
429  error_t error;
430  uint32_t status;
431 
432  //PHY interrupt?
433  if(EMAC0->EPHYRIS & EMAC_EPHYRIS_INT)
434  {
435  //Clear PHY interrupt flag
436  EMAC0->EPHYMISC = EMAC_EPHYMISC_INT;
437  //Read PHY interrupt status register
438  status = msp432e4EthReadPhyReg(EPHY_MISR1);
439 
440  //Check whether the link state has changed?
441  if(status & EPHY_MISR1_LINKSTAT)
442  {
443  //Read BMSR register
444  status = msp432e4EthReadPhyReg(EPHY_BMSR);
445 
446  //Check whether the link is up
447  if(status & EPHY_BMSR_LINKSTAT)
448  {
449  //Read PHY status register
450  status = msp432e4EthReadPhyReg(EPHY_STS);
451 
452  //Check current speed
453  if(status & EPHY_STS_SPEED)
454  {
455  //10BASE-T operation
456  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
457  //Update MAC configuration
458  EMAC0->CFG &= ~EMAC_CFG_FES;
459  }
460  else
461  {
462  //100BASE-TX operation
463  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
464  //Update MAC configuration
465  EMAC0->CFG |= EMAC_CFG_FES;
466  }
467 
468  //Check current duplex mode
469  if(status & EPHY_STS_DUPLEX)
470  {
471  //Full-Duplex mode
472  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
473  //Update MAC configuration
474  EMAC0->CFG |= EMAC_CFG_DUPM;
475  }
476  else
477  {
478  //Half-Duplex mode
479  interface->duplexMode = NIC_HALF_DUPLEX_MODE;
480  //Update MAC configuration
481  EMAC0->CFG &= ~EMAC_CFG_DUPM;
482  }
483 
484  //Update link state
485  interface->linkState = TRUE;
486  }
487  else
488  {
489  //Update link state
490  interface->linkState = FALSE;
491  }
492 
493  //Process link state change event
494  nicNotifyLinkChange(interface);
495  }
496  }
497 
498  //Packet received?
499  if(EMAC0->DMARIS & EMAC_DMARIS_RI)
500  {
501  //Clear interrupt flag
502  EMAC0->DMARIS = EMAC_DMARIS_RI;
503 
504  //Process all pending packets
505  do
506  {
507  //Read incoming packet
508  error = msp432e4EthReceivePacket(interface);
509 
510  //No more data in the receive buffer?
511  } while(error != ERROR_BUFFER_EMPTY);
512  }
513 
514  //Re-enable DMA interrupts
515  EMAC0->DMAIM |= EMAC_DMAIM_NIE | EMAC_DMAIM_RIE | EMAC_DMAIM_TIE;
516  //Re-enable PHY interrupts
517  EMAC0->EPHYIM |= EMAC_EPHYIM_INT;
518 }
519 
520 
521 /**
522  * @brief Send a packet
523  * @param[in] interface Underlying network interface
524  * @param[in] buffer Multi-part buffer containing the data to send
525  * @param[in] offset Offset to the first data byte
526  * @return Error code
527  **/
528 
530  const NetBuffer *buffer, size_t offset)
531 {
532  size_t length;
533 
534  //Retrieve the length of the packet
535  length = netBufferGetLength(buffer) - offset;
536 
537  //Check the frame length
539  {
540  //The transmitter can accept another packet
541  osSetEvent(&interface->nicTxEvent);
542  //Report an error
543  return ERROR_INVALID_LENGTH;
544  }
545 
546  //Make sure the current buffer is available for writing
547  if(txCurDmaDesc->tdes0 & EMAC_TDES0_OWN)
548  return ERROR_FAILURE;
549 
550  //Copy user data to the transmit buffer
551  netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length);
552 
553  //Write the number of bytes to send
554  txCurDmaDesc->tdes1 = length & EMAC_TDES1_TBS1;
555  //Set LS and FS flags as the data fits in a single buffer
556  txCurDmaDesc->tdes0 |= EMAC_TDES0_LS | EMAC_TDES0_FS;
557  //Give the ownership of the descriptor to the DMA
558  txCurDmaDesc->tdes0 |= EMAC_TDES0_OWN;
559 
560  //Clear TU flag to resume processing
561  EMAC0->DMARIS = EMAC_DMARIS_TU;
562  //Instruct the DMA to poll the transmit descriptor list
563  EMAC0->TXPOLLD = 0;
564 
565  //Point to the next descriptor in the list
566  txCurDmaDesc = (Tm4c129TxDmaDesc *) txCurDmaDesc->tdes3;
567 
568  //Check whether the next buffer is available for writing
569  if(!(txCurDmaDesc->tdes0 & EMAC_TDES0_OWN))
570  {
571  //The transmitter can accept another packet
572  osSetEvent(&interface->nicTxEvent);
573  }
574 
575  //Data successfully written
576  return NO_ERROR;
577 }
578 
579 
580 /**
581  * @brief Receive a packet
582  * @param[in] interface Underlying network interface
583  * @return Error code
584  **/
585 
587 {
588  error_t error;
589  size_t n;
590 
591  //The current buffer is available for reading?
592  if(!(rxCurDmaDesc->rdes0 & EMAC_RDES0_OWN))
593  {
594  //FS and LS flags should be set
595  if((rxCurDmaDesc->rdes0 & EMAC_RDES0_FS) && (rxCurDmaDesc->rdes0 & EMAC_RDES0_LS))
596  {
597  //Make sure no error occurred
598  if(!(rxCurDmaDesc->rdes0 & EMAC_RDES0_ES))
599  {
600  //Retrieve the length of the frame
601  n = (rxCurDmaDesc->rdes0 & EMAC_RDES0_FL) >> 16;
602  //Limit the number of data to read
604 
605  //Pass the packet to the upper layer
606  nicProcessPacket(interface, (uint8_t *) rxCurDmaDesc->rdes2, n);
607 
608  //Valid packet received
609  error = NO_ERROR;
610  }
611  else
612  {
613  //The received packet contains an error
614  error = ERROR_INVALID_PACKET;
615  }
616  }
617  else
618  {
619  //The packet is not valid
620  error = ERROR_INVALID_PACKET;
621  }
622 
623  //Give the ownership of the descriptor back to the DMA
624  rxCurDmaDesc->rdes0 = EMAC_RDES0_OWN;
625  //Point to the next descriptor in the list
626  rxCurDmaDesc = (Tm4c129RxDmaDesc *) rxCurDmaDesc->rdes3;
627  }
628  else
629  {
630  //No more data in the receive buffer
631  error = ERROR_BUFFER_EMPTY;
632  }
633 
634  //Clear RU flag to resume processing
635  EMAC0->DMARIS = EMAC_DMARIS_RU;
636  //Instruct the DMA to poll the receive descriptor list
637  EMAC0->RXPOLLD = 0;
638 
639  //Return status code
640  return error;
641 }
642 
643 
644 /**
645  * @brief Configure MAC address filtering
646  * @param[in] interface Underlying network interface
647  * @return Error code
648  **/
649 
651 {
652  uint_t i;
653  uint_t k;
654  uint32_t crc;
655  uint32_t hashTable[2];
656  MacFilterEntry *entry;
657 
658  //Debug message
659  TRACE_DEBUG("Updating MSP432E4 hash table...\r\n");
660 
661  //Clear hash table
662  hashTable[0] = 0;
663  hashTable[1] = 0;
664 
665  //The MAC address filter contains the list of MAC addresses to accept
666  //when receiving an Ethernet frame
667  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
668  {
669  //Point to the current entry
670  entry = &interface->macAddrFilter[i];
671 
672  //Valid entry?
673  if(entry->refCount > 0)
674  {
675  //Compute CRC over the current MAC address
676  crc = msp432e4EthCalcCrc(&entry->addr, sizeof(MacAddr));
677 
678  //The upper 6 bits in the CRC register are used to index the
679  //contents of the hash table
680  k = (crc >> 26) & 0x3F;
681 
682  //Update hash table contents
683  hashTable[k / 32] |= (1 << (k % 32));
684  }
685  }
686 
687  //Write the hash table
688  EMAC0->HASHTBLL = hashTable[0];
689  EMAC0->HASHTBLH = hashTable[1];
690 
691  //Debug message
692  TRACE_DEBUG(" HASHTBLL = %08" PRIX32 "\r\n", EMAC0->HASHTBLL);
693  TRACE_DEBUG(" HASHTBLH = %08" PRIX32 "\r\n", EMAC0->HASHTBLH);
694 
695  //Successful processing
696  return NO_ERROR;
697 }
698 
699 
700 /**
701  * @brief Write PHY register
702  * @param[in] regAddr Register address
703  * @param[in] data Register value
704  **/
705 
706 void msp432e4EthWritePhyReg(uint8_t regAddr, uint16_t data)
707 {
708  uint32_t value;
709 
710  //Take care not to alter MDC clock configuration
711  value = EMAC0->MIIADDR & EMAC_MIIADDR_CR_M;
712  //Set up a write operation
713  value |= EMAC_MIIADDR_MIIW | EMAC_MIIADDR_MIIB;
714  //The address of the integrated PHY is 0
715  value |= (0 << EMAC_MIIADDR_PLA_S) & EMAC_MIIADDR_PLA_M;
716  //Register address
717  value |= (regAddr << EMAC_MIIADDR_MII_S) & EMAC_MIIADDR_MII_M;
718 
719  //Data to be written in the PHY register
720  EMAC0->MIIDATA = data & EMAC_MIIDATA_DATA_M;
721 
722  //Start a write operation
723  EMAC0->MIIADDR = value;
724  //Wait for the write to complete
725  while(EMAC0->MIIADDR & EMAC_MIIADDR_MIIB);
726 }
727 
728 
729 /**
730  * @brief Read PHY register
731  * @param[in] regAddr Register address
732  * @return Register value
733  **/
734 
736 {
737  uint32_t value;
738 
739  //Take care not to alter MDC clock configuration
740  value = EMAC0->MIIADDR & EMAC_MIIADDR_CR_M;
741  //Set up a read operation
742  value |= EMAC_MIIADDR_MIIB;
743  //The address of the integrated PHY is 0
744  value |= (0 << EMAC_MIIADDR_PLA_S) & EMAC_MIIADDR_PLA_M;
745  //Register address
746  value |= (regAddr << EMAC_MIIADDR_MII_S) & EMAC_MIIADDR_MII_M;
747 
748  //Start a read operation
749  EMAC0->MIIADDR = value;
750  //Wait for the read to complete
751  while(EMAC0->MIIADDR & EMAC_MIIADDR_MIIB);
752 
753  //Return PHY register contents
754  return EMAC0->MIIDATA & EMAC_MIIDATA_DATA_M;
755 }
756 
757 
758 /**
759  * @brief Dump PHY registers for debugging purpose
760  **/
761 
763 {
764  uint8_t i;
765 
766  //Loop through PHY registers
767  for(i = 0; i < 32; i++)
768  {
769  //Display current PHY register
770  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i, msp432e4EthReadPhyReg(i));
771  }
772 
773  //Terminate with a line feed
774  TRACE_DEBUG("\r\n");
775 }
776 
777 
778 /**
779  * @brief CRC calculation
780  * @param[in] data Pointer to the data over which to calculate the CRC
781  * @param[in] length Number of bytes to process
782  * @return Resulting CRC value
783  **/
784 
785 uint32_t msp432e4EthCalcCrc(const void *data, size_t length)
786 {
787  uint_t i;
788  uint_t j;
789 
790  //Point to the data over which to calculate the CRC
791  const uint8_t *p = (uint8_t *) data;
792  //CRC preset value
793  uint32_t crc = 0xFFFFFFFF;
794 
795  //Loop through data
796  for(i = 0; i < length; i++)
797  {
798  //The message is processed bit by bit
799  for(j = 0; j < 8; j++)
800  {
801  //Update CRC value
802  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
803  crc = (crc << 1) ^ 0x04C11DB7;
804  else
805  crc = crc << 1;
806  }
807  }
808 
809  //Return CRC value
810  return ~crc;
811 }
#define txDmaDesc
MacAddr addr
MAC address.
Definition: ethernet.h:210
void nicNotifyLinkChange(NetInterface *interface)
Process link state change event.
Definition: nic.c:298
#define EMAC_RDES1_RCH
uint32_t msp432e4EthCalcCrc(const void *data, size_t length)
CRC calculation.
TCP/IP stack core.
void msp432e4EthDisableIrq(NetInterface *interface)
Disable interrupts.
MSP432E4 Ethernet controller.
Debugging facilities.
uint8_t p
Definition: ndp.h:295
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
#define rxDmaDesc
#define EMAC_RDES0_OWN
void msp432e4EthDumpPhyReg(void)
Dump PHY registers for debugging purpose.
#define txBuffer
#define EMAC_TDES1_TBS1
#define EMAC_DMABUSMOD_PBL_1
#define MSP432E4_ETH_TX_BUFFER_COUNT
error_t msp432e4EthInit(NetInterface *interface)
MSP432E4 Ethernet MAC initialization.
void msp432e4EthTick(NetInterface *interface)
MSP432E4 Ethernet MAC timer handler.
#define EMAC_DMABUSMOD_PR_1_1
void msp432e4EthEventHandler(NetInterface *interface)
MSP432E4 Ethernet MAC event handler.
#define MSP432E4_ETH_TX_BUFFER_SIZE
#define MSP432E4_ETH_IRQ_PRIORITY
#define EMAC_RDES0_LS
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
#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
error_t msp432e4EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
NIC driver.
Definition: nic.h:161
#define MSP432E4_ETH_RX_BUFFER_SIZE
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
error_t msp432e4EthReceivePacket(NetInterface *interface)
Receive a packet.
#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.
uint16_t msp432e4EthReadPhyReg(uint8_t regAddr)
Read PHY register.
void msp432e4EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
#define MSP432E4_ETH_IRQ_PRIORITY_GROUPING
error_t msp432e4EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define TRACE_INFO(...)
Definition: debug.h:86
void msp432e4EthWritePhyReg(uint8_t regAddr, uint16_t data)
Write PHY register.
uint16_t regAddr
void msp432e4EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
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
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:211
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
error_t
Error codes.
Definition: error.h:40
void msp432e4EthInitGpio(NetInterface *interface)
unsigned int uint_t
Definition: compiler_port.h:43
#define EMAC_RDES0_FS
void EMAC0_IRQHandler(void)
MSP432E4 Ethernet MAC interrupt service routine.
#define EMAC_TDES0_FS
__start_packed struct @112 MacAddr
MAC address.
#define EMAC_DMABUSMOD_RPBL_1
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
Enhanced RX DMA descriptor.
uint8_t value[]
Definition: dtls_misc.h:141
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
#define EMAC_TDES0_TCH
#define osExitIsr(flag)
#define EMAC_TDES0_LS
#define osEnterIsr()
#define MSP432E4_ETH_RX_BUFFER_COUNT
#define EMAC_TDES0_IC
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
Enhanced TX DMA descriptor.
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
const NicDriver msp432e4EthDriver
MSP432E4 Ethernet MAC driver.
MAC filter table entry.
Definition: ethernet.h:208
#define TRACE_DEBUG(...)
Definition: debug.h:98