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-2024 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 2.4.0
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 //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 /**
195  * @brief GPIO configuration
196  * @param[in] interface Underlying network interface
197  **/
198 
199 __weak_func void f28m35xEthInitGpio(NetInterface *interface)
200 {
201 //TMDXCNCDH52C1 evaluation board?
202 #if defined(USE_TMDXCNCDH52C1)
203  //Enable GPIO clocks
204  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
205  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
206  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
207  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
208  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOH);
209  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
210 
211  //Configure MII_TXD3 (PC4)
212  GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
213  GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
214  GPIOPinConfigure(GPIO_PC4_MIITXD3);
215 
216  //Configure MII_MDIO (PE6)
217  GPIODirModeSet(GPIO_PORTE_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
218  GPIOPadConfigSet(GPIO_PORTE_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
219  GPIOPinConfigure(GPIO_PE6_MIIMDIO);
220 
221  //Configure MII_RXD3 (PF5)
222  GPIODirModeSet(GPIO_PORTF_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
223  GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
224  GPIOPinConfigure(GPIO_PF5_MIIRXD3);
225 
226  //Configure MII_RXD2 (PG0)
227  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_DIR_MODE_HW);
228  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_0, GPIO_PIN_TYPE_STD);
229  GPIOPinConfigure(GPIO_PG0_MIIRXD2);
230 
231  //Configure MII_RXD1 (PG1)
232  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_1, GPIO_DIR_MODE_HW);
233  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_1, GPIO_PIN_TYPE_STD);
234  GPIOPinConfigure(GPIO_PG1_MIIRXD1);
235 
236  //Configure MII_RXDV (PG3)
237  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
238  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
239  GPIOPinConfigure(GPIO_PG3_MIIRXDV);
240 
241  //Configure MII_TXER (PG7)
242  GPIODirModeSet(GPIO_PORTG_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
243  GPIOPadConfigSet(GPIO_PORTG_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
244  GPIOPinConfigure(GPIO_PG7_MIITXER);
245 
246  //Configure MII_RXD0 (PH1)
247  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_1, GPIO_DIR_MODE_HW);
248  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_1, GPIO_PIN_TYPE_STD);
249  GPIOPinConfigure(GPIO_PH1_MIIRXD0);
250 
251  //Configure MII_TXD2 (PH3)
252  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
253  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
254  GPIOPinConfigure(GPIO_PH3_MIITXD2);
255 
256  //Configure MII_TXD1 (PH4)
257  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
258  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
259  GPIOPinConfigure(GPIO_PH4_MIITXD1);
260 
261  //Configure MII_TXD0 (PH5)
262  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
263  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
264  GPIOPinConfigure(GPIO_PH5_MIITXD0);
265 
266  //Configure MII_TXEN (PH6)
267  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
268  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
269  GPIOPinConfigure(GPIO_PH6_MIITXEN);
270 
271  //Configure MII_TXCK (PH7)
272  GPIODirModeSet(GPIO_PORTH_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
273  GPIOPadConfigSet(GPIO_PORTH_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
274  GPIOPinConfigure(GPIO_PH7_MIITXCK);
275 
276  //Configure MII_RXER (PJ0)
277  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_DIR_MODE_HW);
278  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_0, GPIO_PIN_TYPE_STD);
279  GPIOPinConfigure(GPIO_PJ0_MIIRXER);
280 
281  //Configure MII_RXCK (PJ2)
282  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_2, GPIO_DIR_MODE_HW);
283  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_2, GPIO_PIN_TYPE_STD);
284  GPIOPinConfigure(GPIO_PJ2_MIIRXCK);
285 
286  //Configure MII_MDC (PJ3)
287  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);
288  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_3, GPIO_PIN_TYPE_STD);
289  GPIOPinConfigure(GPIO_PJ3_MIIMDC);
290 
291  //Configure MII_COL (PJ4)
292  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);
293  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_4, GPIO_PIN_TYPE_STD);
294  GPIOPinConfigure(GPIO_PJ4_MIICOL);
295 
296  //Configure MII_CRS (PJ5)
297  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
298  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_5, GPIO_PIN_TYPE_STD);
299  GPIOPinConfigure(GPIO_PJ5_MIICRS);
300 
301  //Configure MII_PHYINTR (PJ6)
302  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
303  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_6, GPIO_PIN_TYPE_STD);
304  GPIOPinConfigure(GPIO_PJ6_MIIPHYINTRn);
305 
306  //Configure MII_PHYRSTn (PJ7)
307  GPIODirModeSet(GPIO_PORTJ_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
308  GPIOPadConfigSet(GPIO_PORTJ_BASE, GPIO_PIN_7, GPIO_PIN_TYPE_STD);
309  GPIOPinConfigure(GPIO_PJ7_MIIPHYRSTn);
310 #endif
311 }
312 
313 
314 /**
315  * @brief F28M35x Ethernet MAC timer handler
316  *
317  * This routine is periodically called by the TCP/IP stack to handle periodic
318  * operations such as polling the link state
319  *
320  * @param[in] interface Underlying network interface
321  **/
322 
323 void f28m35xEthTick(NetInterface *interface)
324 {
325  //Valid Ethernet PHY or switch driver?
326  if(interface->phyDriver != NULL)
327  {
328  //Handle periodic operations
329  interface->phyDriver->tick(interface);
330  }
331  else if(interface->switchDriver != NULL)
332  {
333  //Handle periodic operations
334  interface->switchDriver->tick(interface);
335  }
336  else
337  {
338  //Just for sanity
339  }
340 }
341 
342 
343 /**
344  * @brief Enable interrupts
345  * @param[in] interface Underlying network interface
346  **/
347 
349 {
350 #ifdef ti_sysbios_BIOS___VERS
351  //Enable Ethernet MAC interrupts
352  Hwi_enableInterrupt(INT_ETH);
353 #else
354  //Enable Ethernet MAC interrupts
355  IntEnable(INT_ETH);
356 #endif
357 
358 
359  //Valid Ethernet PHY or switch driver?
360  if(interface->phyDriver != NULL)
361  {
362  //Enable Ethernet PHY interrupts
363  interface->phyDriver->enableIrq(interface);
364  }
365  else if(interface->switchDriver != NULL)
366  {
367  //Enable Ethernet switch interrupts
368  interface->switchDriver->enableIrq(interface);
369  }
370  else
371  {
372  //Just for sanity
373  }
374 }
375 
376 
377 /**
378  * @brief Disable interrupts
379  * @param[in] interface Underlying network interface
380  **/
381 
383 {
384 #ifdef ti_sysbios_BIOS___VERS
385  //Disable Ethernet MAC interrupts
386  Hwi_disableInterrupt(INT_ETH);
387 #else
388  //Disable Ethernet MAC interrupts
389  IntDisable(INT_ETH);
390 #endif
391 
392 
393  //Valid Ethernet PHY or switch driver?
394  if(interface->phyDriver != NULL)
395  {
396  //Disable Ethernet PHY interrupts
397  interface->phyDriver->disableIrq(interface);
398  }
399  else if(interface->switchDriver != NULL)
400  {
401  //Disable Ethernet switch interrupts
402  interface->switchDriver->disableIrq(interface);
403  }
404  else
405  {
406  //Just for sanity
407  }
408 }
409 
410 
411 /**
412  * @brief F28M35x Ethernet MAC interrupt service routine
413  **/
414 
416 {
417  bool_t flag;
418  uint32_t status;
419 
420  //Interrupt service routine prologue
421  osEnterIsr();
422 
423  //This flag will be set if a higher priority task must be woken
424  flag = FALSE;
425 
426  //Read interrupt status register
427  status = MAC_RIS_R;
428 
429  //Transmit FIFO empty?
430  if((status & MAC_RIS_TXEMP) != 0)
431  {
432  //Acknowledge TXEMP interrupt
433  MAC_IACK_R = MAC_IACK_TXEMP;
434 
435  //Check whether the transmit FIFO is available for writing
436  if((MAC_TR_R & MAC_TR_NEWTX) == 0)
437  {
438  //Notify the TCP/IP stack that the transmitter is ready to send
439  flag |= osSetEventFromIsr(&nicDriverInterface->nicTxEvent);
440  }
441  }
442 
443  //Packet received?
444  if((status & MAC_RIS_RXINT) != 0)
445  {
446  //Disable RXINT interrupt
447  MAC_IM_R &= ~MAC_IM_RXINTM;
448 
449  //Set event flag
450  nicDriverInterface->nicEvent = TRUE;
451  //Notify the TCP/IP stack of the event
452  flag |= osSetEventFromIsr(&netEvent);
453  }
454 
455  //Interrupt service routine epilogue
456  osExitIsr(flag);
457 }
458 
459 
460 /**
461  * @brief F28M35x Ethernet MAC event handler
462  * @param[in] interface Underlying network interface
463  **/
464 
466 {
467  //Packet received?
468  if((MAC_RIS_R & MAC_RIS_RXINT) != 0)
469  {
470  //Acknowledge RXINT interrupt
471  MAC_IACK_R = MAC_IACK_RXINT;
472 
473  //Process all the pending packets
474  while((MAC_NP_R & MAC_NP_NPR_M) != 0)
475  {
476  //Read incoming packet
477  f28m35xEthReceivePacket(interface);
478  }
479  }
480 
481  //Re-enable Ethernet interrupts
482  MAC_IM_R = MAC_IM_TXEMPM | MAC_IM_RXINTM;
483 }
484 
485 
486 /**
487  * @brief Send a packet
488  * @param[in] interface Underlying network interface
489  * @param[in] buffer Multi-part buffer containing the data to send
490  * @param[in] offset Offset to the first data byte
491  * @param[in] ancillary Additional options passed to the stack along with
492  * the packet
493  * @return Error code
494  **/
495 
497  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
498 {
499  size_t i;
500  size_t length;
501  uint32_t *p;
502 
503  //Retrieve the length of the packet
504  length = netBufferGetLength(buffer) - offset;
505 
506  //Check the frame length
507  if(length < sizeof(EthHeader) || length > ETH_MAX_FRAME_SIZE)
508  {
509  //The transmitter can accept another packet
510  osSetEvent(&interface->nicTxEvent);
511  //Report an error
512  return ERROR_INVALID_LENGTH;
513  }
514 
515  //Make sure the transmit FIFO is available for writing
516  if((MAC_TR_R & MAC_TR_NEWTX) != 0)
517  {
518  return ERROR_FAILURE;
519  }
520 
521  //Copy user data
522  netBufferRead(txBuffer + 2, buffer, offset, length);
523 
524  //The packet is preceded by a 16-bit length field
525  txBuffer[0] = LSB(length - sizeof(EthHeader));
526  txBuffer[1] = MSB(length - sizeof(EthHeader));
527 
528  //Point to the beginning of the packet
529  p = (uint32_t *) txBuffer;
530  //Compute the length of the packet in 32-bit words
531  length = (length + 5) / 4;
532 
533  //Copy packet to transmit FIFO
534  for(i = 0; i < length; i++)
535  {
536  MAC_DATA_R = p[i];
537  }
538 
539  //Start transmitting
540  MAC_TR_R = MAC_TR_NEWTX;
541 
542  //Data successfully written
543  return NO_ERROR;
544 }
545 
546 
547 /**
548  * @brief Receive a packet
549  * @param[in] interface Underlying network interface
550  * @return Error code
551  **/
552 
554 {
555  error_t error;
556  size_t i;
557  size_t n;
558  size_t length;
559  uint32_t data;
560  uint16_t *p;
561 
562  //Make sure the FIFO is not empty
563  if((MAC_NP_R & MAC_NP_NPR_M) != 0)
564  {
565  //Read the first word
566  data = MAC_DATA_R;
567  //Retrieve the total length of the packet
568  length = data & 0xFFFF;
569 
570  //Make sure the length field is valid
571  if(length > 2)
572  {
573  //Point to the beginning of the buffer
574  p = (uint16_t *) rxBuffer;
575 
576  //Retrieve the length of the frame
577  length -= 2;
578  //Limit the number of data to be read
580 
581  //Copy the first half word
582  if(n > 0)
583  {
584  *(p++) = (uint16_t) (data >> 16);
585  }
586 
587  //Copy data from receive FIFO
588  for(i = 2; i < n; i += 4)
589  {
590  //Read a 32-bit word from the FIFO
591  data = MAC_DATA_R;
592  //Write the 32-bit to the receive buffer
593  *(p++) = (uint16_t) data;
594  *(p++) = (uint16_t) (data >> 16);
595  }
596 
597  //Skip the remaining bytes
598  while(i < length)
599  {
600  //Read a 32-bit word from the FIFO
601  data = MAC_DATA_R;
602  //Increment byte counter
603  i += 4;
604  }
605 
606  //Valid packet received
607  error = NO_ERROR;
608  }
609  else
610  {
611  //Disable receiver
612  MAC_RCTL_R &= ~MAC_RCTL_RXEN;
613  //Flush the receive FIFO
614  MAC_RCTL_R |= MAC_RCTL_RSTFIFO;
615  //Re-enable receiver
616  MAC_RCTL_R |= MAC_RCTL_RXEN;
617 
618  //The packet is not valid
619  error = ERROR_INVALID_PACKET;
620  }
621  }
622  else
623  {
624  //No more data in the receive buffer
625  error = ERROR_BUFFER_EMPTY;
626  }
627 
628  //Check whether a valid packet has been received
629  if(!error)
630  {
631  NetRxAncillary ancillary;
632 
633  //Additional options can be passed to the stack along with the packet
634  ancillary = NET_DEFAULT_RX_ANCILLARY;
635 
636  //Pass the packet to the upper layer
637  nicProcessPacket(interface, rxBuffer, n, &ancillary);
638  }
639 
640  //Return status code
641  return error;
642 }
643 
644 
645 /**
646  * @brief Configure MAC address filtering
647  * @param[in] interface Underlying network interface
648  * @return Error code
649  **/
650 
652 {
653  uint_t i;
654  bool_t acceptMulticast;
655 
656  //Debug message
657  TRACE_DEBUG("Updating MAC filter...\r\n");
658 
659  //Set the MAC address of the station
660  MAC_IA0_R = interface->macAddr.w[0] | (interface->macAddr.w[1] << 16);
661  MAC_IA1_R = interface->macAddr.w[2];
662 
663  //This flag will be set if multicast addresses should be accepted
664  acceptMulticast = FALSE;
665 
666  //The MAC address filter contains the list of MAC addresses to accept
667  //when receiving an Ethernet frame
668  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
669  {
670  //Valid entry?
671  if(interface->macAddrFilter[i].refCount > 0)
672  {
673  //Accept multicast addresses
674  acceptMulticast = TRUE;
675  //We are done
676  break;
677  }
678  }
679 
680  //Enable or disable the reception of multicast frames
681  if(acceptMulticast)
682  {
683  MAC_RCTL_R |= MAC_RCTL_AMUL;
684  }
685  else
686  {
687  MAC_RCTL_R &= ~MAC_RCTL_AMUL;
688  }
689 
690  //Successful processing
691  return NO_ERROR;
692 }
693 
694 
695 /**
696  * @brief Adjust MAC configuration parameters for proper operation
697  * @param[in] interface Underlying network interface
698  * @return Error code
699  **/
700 
702 {
703  //Half-duplex or full-duplex mode?
704  if(interface->duplexMode == NIC_FULL_DUPLEX_MODE)
705  {
706  MAC_TCTL_R |= MAC_TCTL_DUPLEX;
707  }
708  else
709  {
710  MAC_TCTL_R &= ~MAC_TCTL_DUPLEX;
711  }
712 
713  //Successful processing
714  return NO_ERROR;
715 }
716 
717 
718 /**
719  * @brief Write PHY register
720  * @param[in] opcode Access type (2 bits)
721  * @param[in] phyAddr PHY address (5 bits)
722  * @param[in] regAddr Register address (5 bits)
723  * @param[in] data Register value
724  **/
725 
726 void f28m35xEthWritePhyReg(uint8_t opcode, uint8_t phyAddr,
727  uint8_t regAddr, uint16_t data)
728 {
729  //Valid opcode?
730  if(opcode == SMI_OPCODE_WRITE)
731  {
732  //Set PHY address
733  MAC_MAR_R = phyAddr;
734  //Data to be written in the PHY register
735  MAC_MTXD_R = data & MAC_MTXD_MDTX_M;
736  //Start a write operation
737  MAC_MCTL_R = (regAddr << 3) | MAC_MCTL_WRITE | MAC_MCTL_START;
738 
739  //Wait for the write to complete
740  while((MAC_MCTL_R & MAC_MCTL_START) != 0)
741  {
742  }
743  }
744  else
745  {
746  //The MAC peripheral only supports standard Clause 22 opcodes
747  }
748 }
749 
750 
751 /**
752  * @brief Read PHY register
753  * @param[in] opcode Access type (2 bits)
754  * @param[in] phyAddr PHY address (5 bits)
755  * @param[in] regAddr Register address (5 bits)
756  * @return Register value
757  **/
758 
759 uint16_t f28m35xEthReadPhyReg(uint8_t opcode, uint8_t phyAddr,
760  uint8_t regAddr)
761 {
762  uint16_t data;
763 
764  //Valid opcode?
765  if(opcode == SMI_OPCODE_READ)
766  {
767  //Set PHY address
768  MAC_MAR_R = phyAddr;
769  //Start a read operation
770  MAC_MCTL_R = (regAddr << 3) | MAC_MCTL_START;
771 
772  //Wait for the read to complete
773  while((MAC_MCTL_R & MAC_MCTL_START) != 0)
774  {
775  }
776 
777  //Get register value
778  data = MAC_MRXD_R & MAC_MRXD_MDRX_M;
779  }
780  else
781  {
782  //The MAC peripheral only supports standard Clause 22 opcodes
783  data = 0;
784  }
785 
786  //Return the value of the PHY register
787  return data;
788 }
#define rxBuffer
#define txBuffer
__attribute__((naked))
AVR32 Ethernet MAC interrupt wrapper.
unsigned int uint_t
Definition: compiler_port.h:50
int bool_t
Definition: compiler_port.h:53
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
uint8_t opcode
Definition: dns_common.h:188
error_t
Error codes.
Definition: error.h:43
@ ERROR_BUFFER_EMPTY
Definition: error.h:141
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PACKET
Definition: error.h:140
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define ETH_MTU
Definition: ethernet.h:116
uint8_t data[]
Definition: ethernet.h:222
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:110
EthHeader
Definition: ethernet.h:223
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
void f28m35xEthDisableIrq(NetInterface *interface)
Disable interrupts.
uint16_t f28m35xEthReadPhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr)
Read PHY register.
const NicDriver f28m35xEthDriver
F28M35x Ethernet MAC driver.
void f28m35xEthEnableIrq(NetInterface *interface)
Enable interrupts.
error_t f28m35xEthUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void f28m35xEthIrqHandler(void)
F28M35x Ethernet MAC interrupt service routine.
error_t f28m35xEthSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
__weak_func void f28m35xEthInitGpio(NetInterface *interface)
GPIO configuration.
error_t f28m35xEthReceivePacket(NetInterface *interface)
Receive a packet.
void f28m35xEthTick(NetInterface *interface)
F28M35x Ethernet MAC timer handler.
error_t f28m35xEthInit(NetInterface *interface)
F28M35x Ethernet MAC driver initialization.
void f28m35xEthWritePhyReg(uint8_t opcode, uint8_t phyAddr, uint8_t regAddr, uint16_t data)
Write PHY register.
void f28m35xEthEventHandler(NetInterface *interface)
F28M35x Ethernet MAC event handler.
error_t f28m35xEthUpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
F28M35x Ethernet MAC driver.
#define MAC_TCTL_R
#define MAC_TR_R
#define MAC_IA1_R
#define MAC_RCTL_R
#define F28M35X_ETH_IRQ_PRIORITY_GROUPING
#define MAC_MTXD_R
#define MAC_RIS_R
#define MAC_IA0_R
#define MAC_DATA_R
#define MAC_NP_R
#define MAC_MRXD_R
#define MAC_IACK_R
#define MAC_MDV_R
#define F28M35X_ETH_IRQ_PRIORITY
#define MAC_IM_R
#define MAC_MAR_R
#define MAC_MCTL_R
uint16_t regAddr
uint8_t p
Definition: ndp.h:300
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netEvent
Definition: net_legacy.h:196
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
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:674
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:101
#define NetRxAncillary
Definition: net_misc.h:40
#define NetTxAncillary
Definition: net_misc.h:36
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:391
#define SMI_OPCODE_WRITE
Definition: nic.h:66
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define SMI_OPCODE_READ
Definition: nic.h:67
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
#define LSB(x)
Definition: os_port.h:55
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
#define MSB(x)
Definition: os_port.h:59
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define osEnterIsr()
#define osExitIsr(flag)
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:283
uint8_t length
Definition: tcp.h:368