f28m35x_eth_driver.c
Go to the documentation of this file.
1 /**
2  * @file f28m35x_eth_driver.c
3  * @brief F28M35x Ethernet MAC driver
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2020 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.8
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include "inc/hw_ethernet.h"
36 #include "inc/hw_ints.h"
37 #include "inc/hw_memmap.h"
38 #include "inc/hw_types.h"
39 #include "driverlib/gpio.h"
40 #include "driverlib/interrupt.h"
41 #include "driverlib/sysctl.h"
42 #include "core/net.h"
44 #include "debug.h"
45 
46 //Underlying network interface
47 static NetInterface *nicDriverInterface;
48 
49 //IAR EWARM compiler?
50 #if defined(__ICCARM__)
51 
52 //Transmit buffer
53 #pragma data_alignment = 4
54 static uint8_t txBuffer[ETH_MAX_FRAME_SIZE + 2];
55 //Receive buffer
56 #pragma data_alignment = 4
57 static uint8_t rxBuffer[ETH_MAX_FRAME_SIZE];
58 
59 //Keil MDK-ARM or GCC compiler?
60 #else
61 
62 //Transmit buffer
63 static uint8_t txBuffer[ETH_MAX_FRAME_SIZE + 2] __attribute__((aligned(4)));
64 //Receive buffer
65 static uint8_t rxBuffer[ETH_MAX_FRAME_SIZE] __attribute__((aligned(4)));
66 
67 #endif
68 
69 
70 /**
71  * @brief F28M35x Ethernet MAC driver
72  **/
73 
75 {
77  ETH_MTU,
88  TRUE,
89  TRUE,
90  TRUE,
91  FALSE
92 };
93 
94 
95 /**
96  * @brief F28M35x Ethernet MAC driver initialization
97  * @param[in] interface Underlying network interface
98  * @return Error code
99  **/
100 
102 {
103  error_t error;
104  uint_t div;
105 #ifdef ti_sysbios_BIOS___VERS
106  Hwi_Params hwiParams;
107 #endif
108 
109  //Debug message
110  TRACE_INFO("Initializing F28M35x Ethernet MAC driver...\r\n");
111 
112  //Save underlying network interface
113  nicDriverInterface = interface;
114 
115  //Enable Ethernet controller clock
116  SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH);
117  //Reset Ethernet controller
118  SysCtlPeripheralReset(SYSCTL_PERIPH_ETH);
119 
120  //GPIO configuration
121  f28m35xEthInitGpio(interface);
122 
123  //The MDC clock frequency cannot exceed 2.5MHz
124  div = SysCtlClockGet(20000000) / (2 * 2500000) - 1;
125  //Adjust MDC clock frequency
126  MAC_MDV_R = div & MAC_MDV_DIV_M;
127 
128  //Valid Ethernet PHY or switch driver?
129  if(interface->phyDriver != NULL)
130  {
131  //Ethernet PHY initialization
132  error = interface->phyDriver->init(interface);
133  }
134  else if(interface->switchDriver != NULL)
135  {
136  //Ethernet switch initialization
137  error = interface->switchDriver->init(interface);
138  }
139  else
140  {
141  //The interface is not properly configured
142  error = ERROR_FAILURE;
143  }
144 
145  //Any error to report?
146  if(error)
147  {
148  return error;
149  }
150 
151  //Set the MAC address of the station
152  MAC_IA0_R = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
153  MAC_IA1_R = interface->macAddr.w[2];
154 
155  //Enable automatic CRC generation and packet padding
156  MAC_TCTL_R = MAC_TCTL_DUPLEX | MAC_TCTL_CRC | MAC_TCTL_PADEN;
157  //Flush the receive FIFO and enable CRC verification
158  MAC_RCTL_R = MAC_RCTL_RSTFIFO | MAC_RCTL_BADCRC;
159 
160  //Configure Ethernet interrupts
161  MAC_IM_R = MAC_IM_TXEMPM | MAC_IM_RXINTM;
162 
163 #ifdef ti_sysbios_BIOS___VERS
164  //Configure Ethernet interrupt
165  Hwi_Params_init(&hwiParams);
166  hwiParams.enableInt = FALSE;
167  hwiParams.priority = F28M35X_ETH_IRQ_PRIORITY;
168 
169  //Register interrupt handler
170  Hwi_create(INT_ETH, (Hwi_FuncPtr) f28m35xEthIrqHandler, &hwiParams, NULL);
171 #else
172  //Register interrupt handler
173  IntRegister(INT_ETH, f28m35xEthIrqHandler);
174 
175  //Set priority grouping (3 bits for pre-emption priority, no bits for subpriority)
176  IntPriorityGroupingSet(F28M35X_ETH_IRQ_PRIORITY_GROUPING);
177  //Configure Ethernet interrupt priority
178  IntPrioritySet(INT_ETH, F28M35X_ETH_IRQ_PRIORITY);
179 #endif
180 
181  //Enable transmitter
182  MAC_TCTL_R |= MAC_TCTL_TXEN;
183  //Enable receiver
184  MAC_RCTL_R |= MAC_RCTL_RXEN;
185 
186  //Accept any packets from the upper layer
187  osSetEvent(&interface->nicTxEvent);
188 
189  //Successful initialization
190  return NO_ERROR;
191 }
192 
193 
194 //TMDXCNCDH52C1 evaluation board?
195 #if defined(USE_TMDXCNCDH52C1)
196 
197 /**
198  * @brief GPIO configuration
199  * @param[in] interface Underlying network interface
200  **/
201 
202 void f28m35xEthInitGpio(NetInterface *interface)
203 {
204  //Enable GPIO clocks
205  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
206  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
207  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
208  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
209  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
210  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
211 
212  //Configure MII_TXD3 (PC4)
213  GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
214  GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
215  GPIOPinConfigure(GPIO_PC4_MIITXD3);
216 
217  //Configure MII_MDIO (PE6)
218  GPIODirModeSet(GPIO_PORTE_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
219  GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
220  GPIOPinConfigure(GPIO_PE6_MIIMDIO);
221 
222  //Configure MII_RXD3 (PF5)
223  GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
224  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
225  GPIOPinConfigure(GPIO_PF5_MIIRXD3);
226 
227  //Configure MII_RXD2 (PG0)
228  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_DIR_MODE_HW);
229  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_PIN_TYPE_STD);
230  GPIOPinConfigure(GPIO_PG0_MIIRXD2);
231 
232  //Configure MII_RXD1 (PG1)
233  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_1, GPIO_DIR_MODE_HW);
234  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_1, GPIO_PIN_TYPE_STD);
235  GPIOPinConfigure(GPIO_PG1_MIIRXD1);
236 
237  //Configure MII_RXDV (PG3)
238  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
239  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
240  GPIOPinConfigure(GPIO_PG3_MIIRXDV);
241 
242  //Configure MII_TXER (PG7)
243  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
244  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
245  GPIOPinConfigure(GPIO_PG7_MIITXER);
246 
247  //Configure MII_RXD0 (PH1)
248  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_1, GPIO_DIR_MODE_HW);
249  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_1, GPIO_PIN_TYPE_STD);
250  GPIOPinConfigure(GPIO_PH1_MIIRXD0);
251 
252  //Configure MII_TXD2 (PH3)
253  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
254  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
255  GPIOPinConfigure(GPIO_PH3_MIITXD2);
256 
257  //Configure MII_TXD1 (PH4)
258  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
259  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
260  GPIOPinConfigure(GPIO_PH4_MIITXD1);
261 
262  //Configure MII_TXD0 (PH5)
263  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
264  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
265  GPIOPinConfigure(GPIO_PH5_MIITXD0);
266 
267  //Configure MII_TXEN (PH6)
268  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
269  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
270  GPIOPinConfigure(GPIO_PH6_MIITXEN);
271 
272  //Configure MII_TXCK (PH7)
273  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
274  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
275  GPIOPinConfigure(GPIO_PH7_MIITXCK);
276 
277  //Configure MII_RXER (PJ0)
278  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_DIR_MODE_HW);
279  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_PIN_TYPE_STD);
280  GPIOPinConfigure(GPIO_PJ0_MIIRXER);
281 
282  //Configure MII_RXCK (PJ2)
283  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_2, GPIO_DIR_MODE_HW);
284  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_2, GPIO_PIN_TYPE_STD);
285  GPIOPinConfigure(GPIO_PJ2_MIIRXCK);
286 
287  //Configure MII_MDC (PJ3)
288  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
289  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
290  GPIOPinConfigure(GPIO_PJ3_MIIMDC);
291 
292  //Configure MII_COL (PJ4)
293  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
294  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
295  GPIOPinConfigure(GPIO_PJ4_MIICOL);
296 
297  //Configure MII_CRS (PJ5)
298  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
299  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
300  GPIOPinConfigure(GPIO_PJ5_MIICRS);
301 
302  //Configure MII_PHYINTR (PJ6)
303  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
304  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
305  GPIOPinConfigure(GPIO_PJ6_MIIPHYINTRn);
306 
307  //Configure MII_PHYRSTn (PJ7)
308  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
309  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
310  GPIOPinConfigure(GPIO_PJ7_MIIPHYRSTn);
311 }
312 
313 #endif
314 
315 
316 /**
317  * @brief F28M35x Ethernet MAC timer handler
318  *
319  * This routine is periodically called by the TCP/IP stack to handle periodic
320  * operations such as polling the link state
321  *
322  * @param[in] interface Underlying network interface
323  **/
324 
325 void f28m35xEthTick(NetInterface *interface)
326 {
327  //Valid Ethernet PHY or switch driver?
328  if(interface->phyDriver != NULL)
329  {
330  //Handle periodic operations
331  interface->phyDriver->tick(interface);
332  }
333  else if(interface->switchDriver != NULL)
334  {
335  //Handle periodic operations
336  interface->switchDriver->tick(interface);
337  }
338  else
339  {
340  //Just for sanity
341  }
342 }
343 
344 
345 /**
346  * @brief Enable interrupts
347  * @param[in] interface Underlying network interface
348  **/
349 
351 {
352 #ifdef ti_sysbios_BIOS___VERS
353  //Enable Ethernet MAC interrupts
354  Hwi_enableInterrupt(INT_ETH);
355 #else
356  //Enable Ethernet MAC interrupts
357  IntEnable(INT_ETH);
358 #endif
359 
360 
361  //Valid Ethernet PHY or switch driver?
362  if(interface->phyDriver != NULL)
363  {
364  //Enable Ethernet PHY interrupts
365  interface->phyDriver->enableIrq(interface);
366  }
367  else if(interface->switchDriver != NULL)
368  {
369  //Enable Ethernet switch interrupts
370  interface->switchDriver->enableIrq(interface);
371  }
372  else
373  {
374  //Just for sanity
375  }
376 }
377 
378 
379 /**
380  * @brief Disable interrupts
381  * @param[in] interface Underlying network interface
382  **/
383 
385 {
386 #ifdef ti_sysbios_BIOS___VERS
387  //Disable Ethernet MAC interrupts
388  Hwi_disableInterrupt(INT_ETH);
389 #else
390  //Disable Ethernet MAC interrupts
391  IntDisable(INT_ETH);
392 #endif
393 
394 
395  //Valid Ethernet PHY or switch driver?
396  if(interface->phyDriver != NULL)
397  {
398  //Disable Ethernet PHY interrupts
399  interface->phyDriver->disableIrq(interface);
400  }
401  else if(interface->switchDriver != NULL)
402  {
403  //Disable Ethernet switch interrupts
404  interface->switchDriver->disableIrq(interface);
405  }
406  else
407  {
408  //Just for sanity
409  }
410 }
411 
412 
413 /**
414  * @brief F28M35x Ethernet MAC interrupt service routine
415  **/
416 
418 {
419  bool_t flag;
420  uint32_t status;
421 
422  //Interrupt service routine prologue
423  osEnterIsr();
424 
425  //This flag will be set if a higher priority task must be woken
426  flag = FALSE;
427 
428  //Read interrupt status register
429  status = MAC_RIS_R;
430 
431  //Transmit FIFO empty?
432  if((status & MAC_RIS_TXEMP) != 0)
433  {
434  //Acknowledge TXEMP interrupt
435  MAC_IACK_R = MAC_IACK_TXEMP;
436 
437  //Check whether the transmit FIFO is available for writing
438  if((MAC_TR_R & MAC_TR_NEWTX) == 0)
439  {
440  //Notify the TCP/IP stack that the transmitter is ready to send
441  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
442  }
443  }
444 
445  //Packet received?
446  if((status & MAC_RIS_RXINT) != 0)
447  {
448  //Disable RXINT interrupt
449  MAC_IM_R &= ~MAC_IM_RXINTM;
450 
451  //Set event flag
452  nicDriverInterface->nicEvent = TRUE;
453  //Notify the TCP/IP stack of the event
454  flag |= osSetEventFromIsr(&netEvent);
455  }
456 
457  //Interrupt service routine epilogue
458  osExitIsr(flag);
459 }
460 
461 
462 /**
463  * @brief F28M35x Ethernet MAC event handler
464  * @param[in] interface Underlying network interface
465  **/
466 
468 {
469  //Packet received?
470  if((MAC_RIS_R & MAC_RIS_RXINT) != 0)
471  {
472  //Acknowledge RXINT interrupt
473  MAC_IACK_R = MAC_IACK_RXINT;
474 
475  //Process all the pending packets
476  while((MAC_NP_R & MAC_NP_NPR_M) != 0)
477  {
478  //Read incoming packet
479  f28m35xEthReceivePacket(interface);
480  }
481  }
482 
483  //Re-enable Ethernet interrupts
484  MAC_IM_R = MAC_IM_TXEMPM | MAC_IM_RXINTM;
485 }
486 
487 
488 /**
489  * @brief Send a packet
490  * @param[in] interface Underlying network interface
491  * @param[in] buffer Multi-part buffer containing the data to send
492  * @param[in] offset Offset to the first data byte
493  * @param[in] ancillary Additional options passed to the stack along with
494  * the packet
495  * @return Error code
496  **/
497 
499  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
500 {
501  size_t i;
502  size_t length;
503  uint32_t *p;
504 
505  //Retrieve the length of the packet
506  length = netBufferGetLength(buffer) - offset;
507 
508  //Check the frame length
509  if(length < sizeof(EthHeader) || length > ETH_MAX_FRAME_SIZE)
510  {
511  //The transmitter can accept another packet
512  osSetEvent(&interface->nicTxEvent);
513  //Report an error
514  return ERROR_INVALID_LENGTH;
515  }
516 
517  //Make sure the transmit FIFO is available for writing
518  if((MAC_TR_R & MAC_TR_NEWTX) != 0)
519  {
520  return ERROR_FAILURE;
521  }
522 
523  //Copy user data
524  netBufferRead(txBuffer + 2, buffer, offset, length);
525 
526  //The packet is preceded by a 16-bit length field
527  txBuffer[0] = LSB(length - sizeof(EthHeader));
528  txBuffer[1] = MSB(length - sizeof(EthHeader));
529 
530  //Point to the beginning of the packet
531  p = (uint32_t *) txBuffer;
532  //Compute the length of the packet in 32-bit words
533  length = (length + 5) / 4;
534 
535  //Copy packet to transmit FIFO
536  for(i = 0; i < length; i++)
537  {
538  MAC_DATA_R = p[i];
539  }
540 
541  //Start transmitting
542  MAC_TR_R = MAC_TR_NEWTX;
543 
544  //Data successfully written
545  return NO_ERROR;
546 }
547 
548 
549 /**
550  * @brief Receive a packet
551  * @param[in] interface Underlying network interface
552  * @return Error code
553  **/
554 
556 {
557  error_t error;
558  size_t i;
559  size_t n;
560  size_t length;
561  uint32_t data;
562  uint16_t *p;
563 
564  //Make sure the FIFO is not empty
565  if((MAC_NP_R & MAC_NP_NPR_M) != 0)
566  {
567  //Read the first word
568  data = MAC_DATA_R;
569  //Retrieve the total length of the packet
570  length = data & 0xFFFF;
571 
572  //Make sure the length field is valid
573  if(length > 2)
574  {
575  //Point to the beginning of the buffer
576  p = (uint16_t *) rxBuffer;
577 
578  //Retrieve the length of the frame
579  length -= 2;
580  //Limit the number of data to be read
582 
583  //Copy the first half word
584  if(n > 0)
585  {
586  *(p++) = (uint16_t) (data >> 16);
587  }
588 
589  //Copy data from receive FIFO
590  for(i = 2; i < n; i += 4)
591  {
592  //Read a 32-bit word from the FIFO
593  data = MAC_DATA_R;
594  //Write the 32-bit to the receive buffer
595  *(p++) = (uint16_t) data;
596  *(p++) = (uint16_t) (data >> 16);
597  }
598 
599  //Skip the remaining bytes
600  while(i < length)
601  {
602  //Read a 32-bit word from the FIFO
603  data = MAC_DATA_R;
604  //Increment byte counter
605  i += 4;
606  }
607 
608  //Valid packet received
609  error = NO_ERROR;
610  }
611  else
612  {
613  //Disable receiver
614  MAC_RCTL_R &= ~MAC_RCTL_RXEN;
615  //Flush the receive FIFO
616  MAC_RCTL_R |= MAC_RCTL_RSTFIFO;
617  //Re-enable receiver
618  MAC_RCTL_R |= MAC_RCTL_RXEN;
619 
620  //The packet is not valid
621  error = ERROR_INVALID_PACKET;
622  }
623  }
624  else
625  {
626  //No more data in the receive buffer
627  error = ERROR_BUFFER_EMPTY;
628  }
629 
630  //Check whether a valid packet has been received
631  if(!error)
632  {
633  NetRxAncillary ancillary;
634 
635  //Additional options can be passed to the stack along with the packet
636  ancillary = NET_DEFAULT_RX_ANCILLARY;
637 
638  //Pass the packet to the upper layer
639  nicProcessPacket(interface, rxBuffer, n, &ancillary);
640  }
641 
642  //Return status code
643  return error;
644 }
645 
646 
647 /**
648  * @brief Configure MAC address filtering
649  * @param[in] interface Underlying network interface
650  * @return Error code
651  **/
652 
654 {
655  uint_t i;
656  bool_t acceptMulticast;
657 
658  //Debug message
659  TRACE_DEBUG("Updating MAC filter...\r\n");
660 
661  //Set the MAC address of the station
662  MAC_IA0_R = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
663  MAC_IA1_R = interface->macAddr.w[2];
664 
665  //This flag will be set if multicast addresses should be accepted
666  acceptMulticast = FALSE;
667 
668  //The MAC address filter contains the list of MAC addresses to accept
669  //when receiving an Ethernet frame
670  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
671  {
672  //Valid entry?
673  if(interface->macAddrFilter[i].refCount > 0)
674  {
675  //Accept multicast addresses
676  acceptMulticast = TRUE;
677  //We are done
678  break;
679  }
680  }
681 
682  //Enable the reception of multicast frames if necessary
683  if(acceptMulticast)
684  {
685  MAC_RCTL_R |= MAC_RCTL_AMUL;
686  }
687  else
688  {
689  MAC_RCTL_R &= ~MAC_RCTL_AMUL;
690  }
691 
692  //Successful processing
693  return NO_ERROR;
694 }
695 
696 
697 /**
698  * @brief Adjust MAC configuration parameters for proper operation
699  * @param[in] interface Underlying network interface
700  * @return Error code
701  **/
702 
704 {
705  //Half-duplex or full-duplex mode?
706  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
707  {
708  MAC_TCTL_R |= MAC_TCTL_DUPLEX;
709  }
710  else
711  {
712  MAC_TCTL_R &= ~MAC_TCTL_DUPLEX;
713  }
714 
715  //Successful processing
716  return NO_ERROR;
717 }
718 
719 
720 /**
721  * @brief Write PHY register
722  * @param[in] opcode Access type (2 bits)
723  * @param[in] phyAddr PHY address (5 bits)
724  * @param[in] regAddr Register address (5 bits)
725  * @param[in] data Register value
726  **/
727 
728 void f28m35xEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
729  uint8_t regAddr, uint16_t data)
730 {
731  //Valid opcode?
732  if(opcode == SMI_OPCODE_WRITE)
733  {
734  //Set PHY address
735  MAC_MAR_R = phyAddr;
736  //Data to be written in the PHY register
737  MAC_MTXD_R = data & MAC_MTXD_MDTX_M;
738  //Start a write operation
739  MAC_MCTL_R = (regAddr << 3) | MAC_MCTL_WRITE | MAC_MCTL_START;
740 
741  //Wait for the write to complete
742  while((MAC_MCTL_R & MAC_MCTL_START) != 0)
743  {
744  }
745  }
746  else
747  {
748  //The MAC peripheral only supports standard Clause 22 opcodes
749  }
750 }
751 
752 
753 /**
754  * @brief Read PHY register
755  * @param[in] opcode Access type (2 bits)
756  * @param[in] phyAddr PHY address (5 bits)
757  * @param[in] regAddr Register address (5 bits)
758  * @return Register value
759  **/
760 
761 uint16_t f28m35xEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
762  uint8_t regAddr)
763 {
764  uint16_t data;
765 
766  //Valid opcode?
767  if(opcode == SMI_OPCODE_READ)
768  {
769  //Set PHY address
770  MAC_MAR_R = phyAddr;
771  //Start a read operation
772  MAC_MCTL_R = (regAddr << 3) | MAC_MCTL_START;
773 
774  //Wait for the read to complete
775  while((MAC_MCTL_R & MAC_MCTL_START) != 0)
776  {
777  }
778 
779  //Get register value
780  data = MAC_MRXD_R & MAC_MRXD_MDRX_M;
781  }
782  else
783  {
784  //The MAC peripheral only supports standard Clause 22 opcodes
785  data = 0;
786  }
787 
788  //Return the value of the PHY register
789  return data;
790 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
uint8_t length
Definition: coap_common.h:190
error_t f28m35xEthReceivePacket(NetInterface *interface)
Receive a packet.
uint8_t opcode
Definition: dns_common.h:172
int bool_t
Definition: compiler_port.h:49
#define F28M35X_ETH_IRQ_PRIORITY_GROUPING
#define netEvent
Definition: net_legacy.h:267
uint8_t data[]
Definition: ethernet.h:209
#define MAC_TR_R
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:672
#define MAC_RCTL_R
uint8_t p
Definition: ndp.h:298
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
error_t f28m35xEthInit(NetInterface *interface)
F28M35x Ethernet MAC driver initialization.
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:88
#define TRUE
Definition: os_port.h:50
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:103
void f28m35xEthEventHandler(NetInterface *interface)
F28M35x Ethernet MAC event handler.
const NicDriver f28m35xEthDriver
F28M35x Ethernet MAC driver.
uint16_t f28m35xEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
#define MAC_IM_R
void f28m35xEthIrqHandler(void)
F28M35x Ethernet MAC interrupt service routine.
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:388
void f28m35xEthDisableIrq(NetInterface *interface)
Disable interrupts.
#define osExitIsr(flag)
#define SMI_OPCODE_WRITE
Definition: nic.h:65
void f28m35xEthInitGpio(NetInterface *interface)
error_t f28m35xEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define MAC_NP_R
#define FALSE
Definition: os_port.h:46
#define MAC_MTXD_R
error_t
Error codes.
Definition: error.h:42
#define MAC_RIS_R
error_t f28m35xEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:96
Generic error code.
Definition: error.h:45
#define txBuffer
#define NetRxAncillary
Definition: net_misc.h:40
#define NetInterface
Definition: net.h:36
error_t f28m35xEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define NetTxAncillary
Definition: net_misc.h:36
#define MAC_MAR_R
#define MSB(x)
Definition: os_port.h:58
#define SMI_OPCODE_READ
Definition: nic.h:66
#define TRACE_INFO(...)
Definition: debug.h:95
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
#define LSB(x)
Definition: os_port.h:54
#define MIN(a, b)
Definition: os_port.h:62
#define rxBuffer
void f28m35xEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
#define MAC_DATA_R
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define MAC_IACK_R
__start_packed struct @7 EthHeader
Ethernet frame header.
uint16_t regAddr
#define ETH_MTU
Definition: ethernet.h:105
uint8_t n
#define MAC_IA1_R
F28M35x Ethernet MAC driver.
#define osEnterIsr()
#define MAC_MDV_R
void f28m35xEthEnableIrq(NetInterface *interface)
Enable interrupts.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define MAC_MCTL_R
unsigned int uint_t
Definition: compiler_port.h:45
TCP/IP stack core.
#define MAC_MRXD_R
#define F28M35X_ETH_IRQ_PRIORITY
NIC driver.
Definition: nic.h:257
#define MAC_TCTL_R
#define MAC_IA0_R
Success.
Definition: error.h:44
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
Debugging facilities.
Ethernet interface.
Definition: nic.h:82
void f28m35xEthTick(NetInterface *interface)
F28M35x Ethernet MAC timer handler.