fm4_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file fm4_eth_driver.c
3  * @brief Spansion FM4 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 "s6e2cc.h"
34 #include "core/net.h"
36 #include "debug.h"
37 
38 //Underlying network interface
39 static NetInterface *nicDriverInterface;
40 
41 //IAR EWARM compiler?
42 #if defined(__ICCARM__)
43 
44 //Transmit buffer
45 #pragma data_alignment = 4
47 //Receive buffer
48 #pragma data_alignment = 4
50 //Transmit DMA descriptors
51 #pragma data_alignment = 4
53 //Receive DMA descriptors
54 #pragma data_alignment = 4
56 
57 //Keil MDK-ARM or GCC compiler?
58 #else
59 
60 //Transmit buffer
62  __attribute__((aligned(4)));
63 //Receive buffer
65  __attribute__((aligned(4)));
66 //Transmit DMA descriptors
68  __attribute__((aligned(4)));
69 //Receive DMA descriptors
71  __attribute__((aligned(4)));
72 
73 #endif
74 
75 //Pointer to the current TX DMA descriptor
76 static Fm4TxDmaDesc *txCurDmaDesc;
77 //Pointer to the current RX DMA descriptor
78 static Fm4RxDmaDesc *rxCurDmaDesc;
79 
80 
81 /**
82  * @brief Spansion FM4 Ethernet MAC driver
83  **/
84 
86 {
88  ETH_MTU,
89  fm4EthInit,
90  fm4EthTick,
99  TRUE,
100  TRUE,
101  TRUE,
102  FALSE
103 };
104 
105 
106 /**
107  * @brief Spansion FM4 Ethernet MAC initialization
108  * @param[in] interface Underlying network interface
109  * @return Error code
110  **/
111 
113 {
114  error_t error;
115 
116  //Debug message
117  TRACE_INFO("Initializing Spansion FM4 Ethernet MAC...\r\n");
118 
119  //Save underlying network interface
120  nicDriverInterface = interface;
121 
122  //GPIO configuration
123  fm4EthInitGpio(interface);
124 
125  //Enable Ethernet MAC clock
126  FM4_ETHERNET_CONTROL->ETH_CLKG_f.MACEN = 1;
127 
128  //Reset Ethernet MAC peripheral
129  FM4_ETHERNET_CONTROL->ETH_MODE_f.RST0 = 1;
130  FM4_ETHERNET_CONTROL->ETH_MODE_f.RST0 = 0;
131 
132  //Perform a software reset
133  FM4_ETHERNET_MAC0->BMR_f.SWR = 1;
134  //Wait for the reset to complete
135  while(FM4_ETHERNET_MAC0->BMR_f.SWR);
136 
137  //Ensure that on-going AHB transactions are complete
138  while(FM4_ETHERNET_MAC0->AHBSR_f.AHBS);
139 
140  //Adjust MDC clock range depending on HCLK frequency
141  FM4_ETHERNET_MAC0->GAR_f.CR = 5;
142 
143  //PHY transceiver initialization
144  error = interface->phyDriver->init(interface);
145  //Failed to initialize PHY transceiver?
146  if(error)
147  return error;
148 
149  //Use default MAC configuration
150  FM4_ETHERNET_MAC0->MCR = 0;
151  FM4_ETHERNET_MAC0->MCR_f.PS = 1;
152  FM4_ETHERNET_MAC0->MCR_f.DO = 1;
153 
154  //Set the MAC address
155  FM4_ETHERNET_MAC0->MAR0L = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
156  FM4_ETHERNET_MAC0->MAR0H = interface->macAddr.w[2];
157 
158  //Initialize hash table
159  FM4_ETHERNET_MAC0->MHTRL = 0;
160  FM4_ETHERNET_MAC0->MHTRH = 0;
161 
162  //Configure the receive filter
163  FM4_ETHERNET_MAC0->MFFR = 0;
164  FM4_ETHERNET_MAC0->MFFR_f.HPF = 1;
165  FM4_ETHERNET_MAC0->MFFR_f.HMC = 1;
166 
167  //Disable flow control
168  FM4_ETHERNET_MAC0->FCR = 0;
169 
170  //Enable store and forward mode
171  FM4_ETHERNET_MAC0->OMR = 0;
172  FM4_ETHERNET_MAC0->OMR_f.RSF = 1;
173  FM4_ETHERNET_MAC0->OMR_f.TSF = 1;
174 
175  //Configure DMA bus mode
176  FM4_ETHERNET_MAC0->BMR = 0;
177  FM4_ETHERNET_MAC0->BMR_f.TXPR = 0;
178  FM4_ETHERNET_MAC0->BMR_f.MB = 1;
179  FM4_ETHERNET_MAC0->BMR_f.AAL = 0;
180  FM4_ETHERNET_MAC0->BMR_f._8XPBL = 0;
181  FM4_ETHERNET_MAC0->BMR_f.USP = 1;
182  FM4_ETHERNET_MAC0->BMR_f.RPBL = 1;
183  FM4_ETHERNET_MAC0->BMR_f.FB = 0;
184  FM4_ETHERNET_MAC0->BMR_f.PR = 0;
185  FM4_ETHERNET_MAC0->BMR_f.PBL = 1;
186  FM4_ETHERNET_MAC0->BMR_f.ATDS = 1;
187  FM4_ETHERNET_MAC0->BMR_f.DSL = 0;
188  FM4_ETHERNET_MAC0->BMR_f.DA = 0;
189 
190  //Initialize DMA descriptor lists
191  fm4EthInitDmaDesc(interface);
192 
193  //Prevent interrupts from being generated when statistic counters reach
194  //half their maximum value
195  FM4_ETHERNET_MAC0->mmc_intr_mask_tx = 0xFFFFFFFF;
196  FM4_ETHERNET_MAC0->mmc_intr_mask_rx = 0xFFFFFFFF;
197  FM4_ETHERNET_MAC0->mmc_ipc_intr_mask_rx = 0xFFFFFFFF;
198 
199  //Disable MAC interrupts
200  bFM4_ETHERNET_MAC0_IMR_LPIIM = 1;
201  bFM4_ETHERNET_MAC0_IMR_TSIM = 1;
202  bFM4_ETHERNET_MAC0_IMR_PIM = 1;
203  bFM4_ETHERNET_MAC0_IMR_RGIM = 1;
204 
205  //Enable the desired DMA interrupts
206  bFM4_ETHERNET_MAC0_IER_NIE = 1;
207  bFM4_ETHERNET_MAC0_IER_RIE = 1;
208  bFM4_ETHERNET_MAC0_IER_TIE = 1;
209 
210  //Set priority grouping (4 bits for pre-emption priority, no bits for subpriority)
211  NVIC_SetPriorityGrouping(FM4_ETH_IRQ_PRIORITY_GROUPING);
212 
213  //Configure Ethernet interrupt priority
214  NVIC_SetPriority(ETHER0_IRQn, NVIC_EncodePriority(FM4_ETH_IRQ_PRIORITY_GROUPING,
216 
217  //Enable MAC transmission and reception
218  bFM4_ETHERNET_MAC0_MCR_TE = 1;
219  bFM4_ETHERNET_MAC0_MCR_RE = 1;
220 
221  //Enable DMA transmission and reception
222  bFM4_ETHERNET_MAC0_OMR_ST = 1;
223  bFM4_ETHERNET_MAC0_OMR_SR = 1;
224 
225  //Accept any packets from the upper layer
226  osSetEvent(&interface->nicTxEvent);
227 
228  //Successful initialization
229  return NO_ERROR;
230 }
231 
232 
233 //SK-FM4-176L-S6E2CC-ETH evaluation board?
234 #if defined(USE_SK_FM4_176L_S6E2CC_ETH)
235 
236 /**
237  * @brief GPIO configuration
238  * @param[in] interface Underlying network interface
239  **/
240 
241 void fm4EthInitGpio(NetInterface *interface)
242 {
243  //Select MII interface mode
244  FM4_ETHERNET_CONTROL->ETH_MODE_f.IFMODE = 0;
245 
246  //Configure E_RXER (PC0)
247  FM4_GPIO->PFRC_f.P0 = 1;
248  //Configure E_RX03 (PC1)
249  FM4_GPIO->PFRC_f.P1 = 1;
250  //Configure E_RX02 (PC2)
251  FM4_GPIO->PFRC_f.P2 = 1;
252  //Configure E_RX01 (PC3)
253  FM4_GPIO->PFRC_f.P3 = 1;
254  //Configure E_RX00 (PC4)
255  FM4_GPIO->PFRC_f.P4 = 1;
256  //Configure E_RXDV (PC5)
257  FM4_GPIO->PFRC_f.P5 = 1;
258  //Configure E_MDIO (PC6)
259  FM4_GPIO->PFRC_f.P6 = 1;
260  //Configure E_MDC (PC7)
261  FM4_GPIO->PFRC_f.P7 = 1;
262  //Configure E_RXCK_REFCK (PC8)
263  FM4_GPIO->PFRC_f.P8 = 1;
264  //Configure E_COL (PC9)
265  FM4_GPIO->PFRC_f.P9 = 1;
266  //Configure E_CRS (PCA)
267  FM4_GPIO->PFRC_f.PA = 1;
268  //Configure E_TCK (PCC)
269  FM4_GPIO->PFRC_f.PC = 1;
270  //Configure E_TXER (PCD)
271  FM4_GPIO->PFRC_f.PD = 1;
272  //Configure E_TX03 (PCE)
273  FM4_GPIO->PFRC_f.PE = 1;
274  //Configure E_TX02 (PCF)
275  FM4_GPIO->PFRC_f.PF = 1;
276  //Configure E_TX01 (PD0)
277  FM4_GPIO->PFRD_f.P0 = 1;
278  //Configure E_TX00 (PD1)
279  FM4_GPIO->PFRD_f.P1 = 1;
280  //Configure E_TXEN (PD2)
281  FM4_GPIO->PFRD_f.P2 = 1;
282 
283  //Peripheral assignment
284  FM4_GPIO->EPFR14_f.E_TD0E = 1;
285  FM4_GPIO->EPFR14_f.E_TD1E = 1;
286  FM4_GPIO->EPFR14_f.E_TE0E = 1;
287  FM4_GPIO->EPFR14_f.E_TE1E = 1;
288  FM4_GPIO->EPFR14_f.E_MC0E = 1;
289  FM4_GPIO->EPFR14_f.E_MC1B = 1;
290  FM4_GPIO->EPFR14_f.E_MD0B = 1;
291  FM4_GPIO->EPFR14_f.E_MD1B = 1;
292  FM4_GPIO->EPFR14_f.E_SPLC = 1;
293 
294  //Configure PHY_RST as an output
295  FM4_GPIO->PFR6_f.PA = 0;
296  FM4_GPIO->DDR6_f.PA = 1;
297 
298  //Reset PHY transceiver
299  FM4_GPIO->PDOR6_f.PA = 0;
300  sleep(10);
301 
302  //Take the PHY transceiver out of reset
303  FM4_GPIO->PDOR6_f.PA = 1;
304  sleep(10);
305 }
306 
307 #endif
308 
309 
310 /**
311  * @brief Initialize DMA descriptor lists
312  * @param[in] interface Underlying network interface
313  **/
314 
316 {
317  uint_t i;
318 
319  //Initialize TX DMA descriptor list
320  for(i = 0; i < FM4_ETH_TX_BUFFER_COUNT; i++)
321  {
322  //Use chain structure rather than ring structure
323  txDmaDesc[i].tdes0 = ETH_TDES0_IC | ETH_TDES0_TCH;
324  //Initialize transmit buffer size
325  txDmaDesc[i].tdes1 = 0;
326  //Transmit buffer address
327  txDmaDesc[i].tdes2 = (uint32_t) txBuffer[i];
328  //Next descriptor address
329  txDmaDesc[i].tdes3 = (uint32_t) &txDmaDesc[i + 1];
330  //Reserved fields
331  txDmaDesc[i].tdes4 = 0;
332  txDmaDesc[i].tdes5 = 0;
333  //Transmit frame time stamp
334  txDmaDesc[i].tdes6 = 0;
335  txDmaDesc[i].tdes7 = 0;
336  }
337 
338  //The last descriptor is chained to the first entry
339  txDmaDesc[i - 1].tdes3 = (uint32_t) &txDmaDesc[0];
340  //Point to the very first descriptor
341  txCurDmaDesc = &txDmaDesc[0];
342 
343  //Initialize RX DMA descriptor list
344  for(i = 0; i < FM4_ETH_RX_BUFFER_COUNT; i++)
345  {
346  //The descriptor is initially owned by the DMA
347  rxDmaDesc[i].rdes0 = ETH_RDES0_OWN;
348  //Use chain structure rather than ring structure
350  //Receive buffer address
351  rxDmaDesc[i].rdes2 = (uint32_t) rxBuffer[i];
352  //Next descriptor address
353  rxDmaDesc[i].rdes3 = (uint32_t) &rxDmaDesc[i + 1];
354  //Extended status
355  rxDmaDesc[i].rdes4 = 0;
356  //Reserved field
357  rxDmaDesc[i].rdes5 = 0;
358  //Receive frame time stamp
359  rxDmaDesc[i].rdes6 = 0;
360  rxDmaDesc[i].rdes7 = 0;
361  }
362 
363  //The last descriptor is chained to the first entry
364  rxDmaDesc[i - 1].rdes3 = (uint32_t) &rxDmaDesc[0];
365  //Point to the very first descriptor
366  rxCurDmaDesc = &rxDmaDesc[0];
367 
368  //Start location of the TX descriptor list
369  FM4_ETHERNET_MAC0->TDLAR = (uint32_t) txDmaDesc;
370  //Start location of the RX descriptor list
371  FM4_ETHERNET_MAC0->RDLAR = (uint32_t) rxDmaDesc;
372 }
373 
374 
375 /**
376  * @brief Spansion FM4 Ethernet MAC timer handler
377  *
378  * This routine is periodically called by the TCP/IP stack to
379  * handle periodic operations such as polling the link state
380  *
381  * @param[in] interface Underlying network interface
382  **/
383 
384 void fm4EthTick(NetInterface *interface)
385 {
386  //Handle periodic operations
387  interface->phyDriver->tick(interface);
388 }
389 
390 
391 /**
392  * @brief Enable interrupts
393  * @param[in] interface Underlying network interface
394  **/
395 
397 {
398  //Enable Ethernet MAC interrupts
399  NVIC_EnableIRQ(ETHER0_IRQn);
400  //Enable Ethernet PHY interrupts
401  interface->phyDriver->enableIrq(interface);
402 }
403 
404 
405 /**
406  * @brief Disable interrupts
407  * @param[in] interface Underlying network interface
408  **/
409 
411 {
412  //Disable Ethernet MAC interrupts
413  NVIC_DisableIRQ(ETHER0_IRQn);
414  //Disable Ethernet PHY interrupts
415  interface->phyDriver->disableIrq(interface);
416 }
417 
418 
419 /**
420  * @brief Spansion FM4 Ethernet MAC interrupt service routine
421  **/
422 
424 {
425  bool_t flag;
426 
427  //Enter interrupt service routine
428  osEnterIsr();
429 
430  //This flag will be set if a higher priority task must be woken
431  flag = FALSE;
432 
433  //A packet has been transmitted?
434  if(bFM4_ETHERNET_MAC0_SR_TI)
435  {
436  //Clear TI interrupt flag
437  bFM4_ETHERNET_MAC0_SR_TI = 1;
438 
439  //Check whether the TX buffer is available for writing
440  if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN))
441  {
442  //Notify the TCP/IP stack that the transmitter is ready to send
443  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
444  }
445  }
446 
447  //A packet has been received?
448  if(bFM4_ETHERNET_MAC0_SR_RI)
449  {
450  //Disable RIE interrupt
451  bFM4_ETHERNET_MAC0_IER_RIE = 0;
452 
453  //Set event flag
454  nicDriverInterface->nicEvent = TRUE;
455  //Notify the TCP/IP stack of the event
456  flag |= osSetEventFromIsr(&netEvent);
457  }
458 
459  //Clear NIS interrupt flag
460  bFM4_ETHERNET_MAC0_SR_NIS = 1;
461 
462  //Leave interrupt service routine
463  osExitIsr(flag);
464 }
465 
466 
467 /**
468  * @brief Spansion FM4 Ethernet MAC event handler
469  * @param[in] interface Underlying network interface
470  **/
471 
473 {
474  error_t error;
475 
476  //Packet received?
477  if(bFM4_ETHERNET_MAC0_SR_RI)
478  {
479  //Clear interrupt flag
480  bFM4_ETHERNET_MAC0_SR_RI = 1;
481 
482  //Process all pending packets
483  do
484  {
485  //Read incoming packet
486  error = fm4EthReceivePacket(interface);
487 
488  //No more data in the receive buffer?
489  } while(error != ERROR_BUFFER_EMPTY);
490  }
491 
492  //Re-enable DMA interrupts
493  bFM4_ETHERNET_MAC0_IER_NIE = 1;
494  bFM4_ETHERNET_MAC0_IER_RIE = 1;
495  bFM4_ETHERNET_MAC0_IER_TIE = 1;
496 }
497 
498 
499 /**
500  * @brief Send a packet
501  * @param[in] interface Underlying network interface
502  * @param[in] buffer Multi-part buffer containing the data to send
503  * @param[in] offset Offset to the first data byte
504  * @return Error code
505  **/
506 
508  const NetBuffer *buffer, size_t offset)
509 {
510  size_t length;
511 
512  //Retrieve the length of the packet
513  length = netBufferGetLength(buffer) - offset;
514 
515  //Check the frame length
517  {
518  //The transmitter can accept another packet
519  osSetEvent(&interface->nicTxEvent);
520  //Report an error
521  return ERROR_INVALID_LENGTH;
522  }
523 
524  //Make sure the current buffer is available for writing
525  if(txCurDmaDesc->tdes0 & ETH_TDES0_OWN)
526  return ERROR_FAILURE;
527 
528  //Copy user data to the transmit buffer
529  netBufferRead((uint8_t *) txCurDmaDesc->tdes2, buffer, offset, length);
530 
531  //Write the number of bytes to send
532  txCurDmaDesc->tdes1 = length & ETH_TDES1_TBS1;
533  //Set LS and FS flags as the data fits in a single buffer
534  txCurDmaDesc->tdes0 |= ETH_TDES0_LS | ETH_TDES0_FS;
535  //Give the ownership of the descriptor to the DMA
536  txCurDmaDesc->tdes0 |= ETH_TDES0_OWN;
537 
538  //Clear TU flag to resume processing
539  bFM4_ETHERNET_MAC0_SR_TU = 1;
540  //Instruct the DMA to poll the transmit descriptor list
541  FM4_ETHERNET_MAC0->TPDR = 0;
542 
543  //Point to the next descriptor in the list
544  txCurDmaDesc = (Fm4TxDmaDesc *) txCurDmaDesc->tdes3;
545 
546  //Check whether the next buffer is available for writing
547  if(!(txCurDmaDesc->tdes0 & ETH_TDES0_OWN))
548  {
549  //The transmitter can accept another packet
550  osSetEvent(&interface->nicTxEvent);
551  }
552 
553  //Data successfully written
554  return NO_ERROR;
555 }
556 
557 
558 /**
559  * @brief Receive a packet
560  * @param[in] interface Underlying network interface
561  * @return Error code
562  **/
563 
565 {
566  error_t error;
567  size_t n;
568 
569  //The current buffer is available for reading?
570  if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_OWN))
571  {
572  //FS and LS flags should be set
573  if((rxCurDmaDesc->rdes0 & ETH_RDES0_FS) && (rxCurDmaDesc->rdes0 & ETH_RDES0_LS))
574  {
575  //Make sure no error occurred
576  if(!(rxCurDmaDesc->rdes0 & ETH_RDES0_ES))
577  {
578  //Retrieve the length of the frame
579  n = (rxCurDmaDesc->rdes0 & ETH_RDES0_FL) >> 16;
580  //Limit the number of data to read
582 
583  //Pass the packet to the upper layer
584  nicProcessPacket(interface, (uint8_t *) rxCurDmaDesc->rdes2, n);
585 
586  //Valid packet received
587  error = NO_ERROR;
588  }
589  else
590  {
591  //The received packet contains an error
592  error = ERROR_INVALID_PACKET;
593  }
594  }
595  else
596  {
597  //The packet is not valid
598  error = ERROR_INVALID_PACKET;
599  }
600 
601  //Give the ownership of the descriptor back to the DMA
602  rxCurDmaDesc->rdes0 = ETH_RDES0_OWN;
603  //Point to the next descriptor in the list
604  rxCurDmaDesc = (Fm4RxDmaDesc *) rxCurDmaDesc->rdes3;
605  }
606  else
607  {
608  //No more data in the receive buffer
609  error = ERROR_BUFFER_EMPTY;
610  }
611 
612  //Clear RU flag to resume processing
613  bFM4_ETHERNET_MAC0_SR_RU = 1;
614  //Instruct the DMA to poll the receive descriptor list
615  FM4_ETHERNET_MAC0->RPDR = 0;
616 
617  //Return status code
618  return error;
619 }
620 
621 
622 /**
623  * @brief Configure MAC address filtering
624  * @param[in] interface Underlying network interface
625  * @return Error code
626  **/
627 
629 {
630  uint_t i;
631  uint_t k;
632  uint32_t crc;
633  uint32_t hashTable[2];
634  MacFilterEntry *entry;
635 
636  //Debug message
637  TRACE_DEBUG("Updating Spansion FM4 hash table...\r\n");
638 
639  //Clear hash table
640  hashTable[0] = 0;
641  hashTable[1] = 0;
642 
643  //The MAC address filter contains the list of MAC addresses to accept
644  //when receiving an Ethernet frame
645  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
646  {
647  //Point to the current entry
648  entry = &interface->macAddrFilter[i];
649 
650  //Valid entry?
651  if(entry->refCount > 0)
652  {
653  //Compute CRC over the current MAC address
654  crc = fm4EthCalcCrc(&entry->addr, sizeof(MacAddr));
655 
656  //The upper 6 bits in the CRC register are used to index the
657  //contents of the hash table
658  k = (crc >> 26) & 0x3F;
659 
660  //Update hash table contents
661  hashTable[k / 32] |= (1 << (k % 32));
662  }
663  }
664 
665  //Write the hash table
666  FM4_ETHERNET_MAC0->MHTRL = hashTable[0];
667  FM4_ETHERNET_MAC0->MHTRH = hashTable[1];
668 
669  //Debug message
670  TRACE_DEBUG(" MACHTLR = %08" PRIX32 "\r\n", FM4_ETHERNET_MAC0->MHTRL);
671  TRACE_DEBUG(" MACHTHR = %08" PRIX32 "\r\n", FM4_ETHERNET_MAC0->MHTRH);
672 
673  //Successful processing
674  return NO_ERROR;
675 }
676 
677 
678 /**
679  * @brief Adjust MAC configuration parameters for proper operation
680  * @param[in] interface Underlying network interface
681  * @return Error code
682  **/
683 
685 {
686  //10BASE-T or 100BASE-TX operation mode?
687  if(interface->linkSpeed == NIC_LINK_SPEED_100MBPS)
688  bFM4_ETHERNET_MAC0_MCR_FES = 1;
689  else
690  bFM4_ETHERNET_MAC0_MCR_FES = 0;
691 
692  //Half-duplex or full-duplex mode?
693  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
694  bFM4_ETHERNET_MAC0_MCR_DM = 1;
695  else
696  bFM4_ETHERNET_MAC0_MCR_DM = 0;
697 
698  //Successful processing
699  return NO_ERROR;
700 }
701 
702 
703 /**
704  * @brief Write PHY register
705  * @param[in] phyAddr PHY address
706  * @param[in] regAddr Register address
707  * @param[in] data Register value
708  **/
709 
710 void fm4EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
711 {
712  //Set up a write operation
713  FM4_ETHERNET_MAC0->GAR_f.GW = 1;
714  //PHY address
715  FM4_ETHERNET_MAC0->GAR_f.PA = phyAddr;
716  //Register address
717  FM4_ETHERNET_MAC0->GAR_f.GR = regAddr;
718 
719  //Data to be written in the PHY register
720  FM4_ETHERNET_MAC0->GDR_f.GD = data;
721 
722  //Start a write operation
723  FM4_ETHERNET_MAC0->GAR_f.GB = 1;
724  //Wait for the write to complete
725  while(FM4_ETHERNET_MAC0->GAR_f.GB);
726 }
727 
728 
729 /**
730  * @brief Read PHY register
731  * @param[in] phyAddr PHY address
732  * @param[in] regAddr Register address
733  * @return Register value
734  **/
735 
736 uint16_t fm4EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
737 {
738  //Set up a read operation
739  FM4_ETHERNET_MAC0->GAR_f.GW = 0;
740  //PHY address
741  FM4_ETHERNET_MAC0->GAR_f.PA = phyAddr;
742  //Register address
743  FM4_ETHERNET_MAC0->GAR_f.GR = regAddr;
744 
745  //Start a read operation
746  FM4_ETHERNET_MAC0->GAR_f.GB = 1;
747  //Wait for the read to complete
748  while(FM4_ETHERNET_MAC0->GAR_f.GB);
749 
750  //Return PHY register contents
751  return FM4_ETHERNET_MAC0->GDR_f.GD;
752 }
753 
754 
755 /**
756  * @brief CRC calculation
757  * @param[in] data Pointer to the data over which to calculate the CRC
758  * @param[in] length Number of bytes to process
759  * @return Resulting CRC value
760  **/
761 
762 uint32_t fm4EthCalcCrc(const void *data, size_t length)
763 {
764  uint_t i;
765  uint_t j;
766 
767  //Point to the data over which to calculate the CRC
768  const uint8_t *p = (uint8_t *) data;
769  //CRC preset value
770  uint32_t crc = 0xFFFFFFFF;
771 
772  //Loop through data
773  for(i = 0; i < length; i++)
774  {
775  //The message is processed bit by bit
776  for(j = 0; j < 8; j++)
777  {
778  //Update CRC value
779  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
780  crc = (crc << 1) ^ 0x04C11DB7;
781  else
782  crc = crc << 1;
783  }
784  }
785 
786  //Return CRC value
787  return ~crc;
788 }
#define txDmaDesc
MacAddr addr
MAC address.
Definition: ethernet.h:210
error_t fm4EthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
void fm4EthInitDmaDesc(NetInterface *interface)
Initialize DMA descriptor lists.
TCP/IP stack core.
uint16_t fm4EthReadPhyReg(uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
Debugging facilities.
void ETHER0_IRQHandler(void)
Spansion FM4 Ethernet MAC interrupt service routine.
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
#define FM4_ETH_TX_BUFFER_COUNT
Generic error code.
Definition: error.h:43
#define rxDmaDesc
#define txBuffer
uint32_t fm4EthCalcCrc(const void *data, size_t length)
CRC calculation.
#define sleep(delay)
Definition: os_port.h:126
void fm4EthDisableIrq(NetInterface *interface)
Disable interrupts.
uint32_t rdes0
#define ETH_RDES0_OWN
void fm4EthWritePhyReg(uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define ETH_RDES0_FL
uint32_t tdes3
#define TRUE
Definition: os_port.h:48
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:65
uint32_t rdes2
uint32_t tdes1
void fm4EthInitGpio(NetInterface *interface)
#define FM4_ETH_TX_BUFFER_SIZE
#define FM4_ETH_RX_BUFFER_SIZE
#define ETH_TDES0_IC
#define ETH_TDES0_OWN
#define FM4_ETH_RX_BUFFER_COUNT
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
void fm4EthEnableIrq(NetInterface *interface)
Enable interrupts.
#define ETH_TDES0_FS
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:86
#define MIN(a, b)
Definition: os_port.h:60
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void fm4EthEventHandler(NetInterface *interface)
Spansion FM4 Ethernet MAC event handler.
#define ETH_TDES0_LS
const NicDriver fm4EthDriver
Spansion FM4 Ethernet MAC driver.
Spansion FM4 Ethernet MAC controller.
uint32_t tdes0
#define TRACE_INFO(...)
Definition: debug.h:86
uint16_t regAddr
uint32_t tdes2
#define ETH_MTU
Definition: ethernet.h:82
Ethernet interface.
Definition: nic.h:69
Success.
Definition: error.h:42
#define rxBuffer
#define ETH_RDES0_LS
OsEvent netEvent
Definition: net.c:72
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
Enhanced TX DMA descriptor.
unsigned int uint_t
Definition: compiler_port.h:43
error_t fm4EthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
__start_packed struct @112 MacAddr
MAC address.
uint8_t data[]
Definition: dtls_misc.h:167
#define NetInterface
Definition: net.h:34
#define FM4_ETH_IRQ_PRIORITY_GROUPING
error_t fm4EthReceivePacket(NetInterface *interface)
Receive a packet.
#define ETH_RDES1_RCH
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
uint32_t rdes3
#define osExitIsr(flag)
#define ETH_TDES0_TCH
#define FM4_ETH_IRQ_GROUP_PRIORITY
void fm4EthTick(NetInterface *interface)
Spansion FM4 Ethernet MAC timer handler.
#define ETH_TDES1_TBS1
#define osEnterIsr()
Enhanced RX DMA descriptor.
#define ETH_RDES1_RBS1
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
#define FM4_ETH_IRQ_SUB_PRIORITY
#define FALSE
Definition: os_port.h:44
int bool_t
Definition: compiler_port.h:47
error_t fm4EthInit(NetInterface *interface)
Spansion FM4 Ethernet MAC initialization.
error_t fm4EthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define ETH_RDES0_FS
MAC filter table entry.
Definition: ethernet.h:208
#define ETH_RDES0_ES
#define TRACE_DEBUG(...)
Definition: debug.h:98