adin1110_driver.c
Go to the documentation of this file.
1 /**
2  * @file adin1110_driver.c
3  * @brief ADIN1110 10Base-T1L Ethernet controller
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 "core/net.h"
37 #include "debug.h"
38 
39 
40 /**
41  * @brief ADIN1110 driver
42  **/
43 
45 {
47  ETH_MTU,
55  NULL,
56  NULL,
57  NULL,
58  FALSE,
59  TRUE,
60  TRUE,
61  FALSE
62 };
63 
64 
65 /**
66  * @brief ADIN1110 controller initialization
67  * @param[in] interface Underlying network interface
68  * @return Error code
69  **/
70 
72 {
73  uint32_t value;
74 
75  //Debug message
76  TRACE_INFO("Initializing ADIN1110 Ethernet controller...\r\n");
77 
78  //Initialize SPI interface
79  interface->spiDriver->init();
80 
81  //Initialize external interrupt line driver
82  if(interface->extIntDriver != NULL)
83  {
84  interface->extIntDriver->init();
85  }
86 
87  //A full chip software reset can be initiated by writing 1 to the SWRESET
88  //field of the RESET register
90 
91  //Wait for the MAC to exit reset
92  do
93  {
94  //To confirm that the MAC has exited reset, read the PHY identification
95  //register
96  value = adin1110ReadReg(interface, ADIN1110_PHYID);
97 
98  //If the reset value of the register can be read, the device has exited
99  //reset and is ready for configuration
102 
103  //Next, the host must read the STATUS0 register and confirm that the RESETC
104  //field is 1
105  do
106  {
107  //Read the status register 0
108  value = adin1110ReadReg(interface, ADIN1110_STATUS0);
109 
110  //Check the value of the RESETC bit
111  } while((value & ADIN1110_STATUS0_RESETC) == 0);
112 
113  //Write 1 to the RESETC field in the STATUS0 register to clear this field
115 
116  //The system ready bit can also be read to verify that the start-up sequence
117  //is complete and the system is ready for normal operation
118  do
119  {
120  //Read the CRSM status register
122 
123  //Check the value of the CRSM_SYS_RDY bit
124  } while((value & ADIN1110_CRSM_STAT_CRSM_SYS_RDY) == 0);
125 
126  //Dump SPI registers for debugging purpose
127  adin1110DumpReg(interface);
128  //Dump PHY registers for debugging purpose
129  adin1110DumpPhyReg(interface);
130 
131  //Configure MAC address filtering
132  adin1110UpdateMacAddrFilter(interface);
133 
134  //Enable store and forward mode
135  value = adin1110ReadReg(interface, ADIN1110_CONFIG0);
138 
139  //Enable CRC append in the MAC TX path
140  value = adin1110ReadReg(interface, ADIN1110_CONFIG2);
143 
144  //Clear IMASK0 register
145  adin1110WriteReg(interface, ADIN1110_IMASK0, 0xFFFFFFFF);
146 
147  //Write the IMASK1 register to enable interrupts as required
150 
151  //When the MAC is configured, write 1 to the SYNC field in the CONFIG0
152  //register to indicate that the MAC configuration is complete
153  value = adin1110ReadReg(interface, ADIN1110_CONFIG0);
156 
157  //Enable LED1 output
162 
163  //Configure LED0 and LED1 function
169 
170  //Set LED0 and LED1 polarity
174 
175  //Perform custom configuration
176  adin1110InitHook(interface);
177 
178  //Clear the CRSM_SFT_PD bit to exit software power-down mode. At this point,
179  //the MAC-PHY starts autonegotiation and attempts to bring up a link after
180  //autonegotiation completes
184 
185  //Accept any packets from the upper layer
186  osSetEvent(&interface->nicTxEvent);
187 
188  //Force the TCP/IP stack to poll the link state at startup
189  interface->nicEvent = TRUE;
190  //Notify the TCP/IP stack of the event
192 
193  //Successful initialization
194  return NO_ERROR;
195 }
196 
197 
198 /**
199  * @brief ADIN1110 custom configuration
200  * @param[in] interface Underlying network interface
201  **/
202 
203 __weak_func void adin1110InitHook(NetInterface *interface)
204 {
205 }
206 
207 
208 /**
209  * @brief ADIN1110 timer handler
210  * @param[in] interface Underlying network interface
211  **/
212 
213 void adin1110Tick(NetInterface *interface)
214 {
215 }
216 
217 
218 /**
219  * @brief Enable interrupts
220  * @param[in] interface Underlying network interface
221  **/
222 
224 {
225  //Enable interrupts
226  if(interface->extIntDriver != NULL)
227  {
228  interface->extIntDriver->enableIrq();
229  }
230 }
231 
232 
233 /**
234  * @brief Disable interrupts
235  * @param[in] interface Underlying network interface
236  **/
237 
239 {
240  //Disable interrupts
241  if(interface->extIntDriver != NULL)
242  {
243  interface->extIntDriver->disableIrq();
244  }
245 }
246 
247 
248 /**
249  * @brief ADIN1110 interrupt service routine
250  * @param[in] interface Underlying network interface
251  * @return TRUE if a higher priority task must be woken. Else FALSE is returned
252  **/
253 
255 {
256  bool_t flag;
257  size_t n;
258  uint32_t mask;
259  uint32_t status;
260 
261  //This flag will be set if a higher priority task must be woken
262  flag = FALSE;
263 
264  //Save interrupt mask register value
265  mask = adin1110ReadReg(interface, ADIN1110_IMASK1);
266  //Disable interrupts to release the interrupt line
267  adin1110WriteReg(interface, ADIN1110_IMASK1, 0xFFFFFFFF);
268 
269  //Read interrupt status register
270  status = adin1110ReadReg(interface, ADIN1110_STATUS1);
271 
272  //Link status changed interrupt?
273  if((status & ADIN1110_STATUS1_LINK_CHANGE) != 0)
274  {
275  //Disable link status changed interrupt
277 
278  //Set event flag
279  interface->nicEvent = TRUE;
280  //Notify the TCP/IP stack of the event
281  flag |= osSetEventFromIsr(&netEvent);
282  }
283 
284  //Packet transmission complete?
285  if((status & ADIN1110_STATUS1_TX_RDY) != 0)
286  {
287  //Clear interrupt flag
289 
290  //The TX_SPACE register indicates the remaining space in the TX FIFO
291  n = adin1110ReadReg(interface, ADIN1110_TX_SPACE) &
293 
294  //Verify that there is space for a new frame
296  {
297  //Notify the TCP/IP stack that the transmitter is ready to send
298  flag |= osSetEventFromIsr(&interface->nicTxEvent);
299  }
300  }
301 
302  //Packet received?
303  if((status & ADIN1110_STATUS1_P1_RX_RDY) != 0)
304  {
305  //Disable P1_RX_RDY interrupt
307 
308  //Set event flag
309  interface->nicEvent = TRUE;
310  //Notify the TCP/IP stack of the event
311  flag |= osSetEventFromIsr(&netEvent);
312  }
313 
314  //Re-enable interrupts once the interrupt has been serviced
316 
317  //A higher priority task must be woken?
318  return flag;
319 }
320 
321 
322 /**
323  * @brief ADIN1110 event handler
324  * @param[in] interface Underlying network interface
325  **/
326 
328 {
329  uint32_t status;
330 
331  //When an interrupt occurs, the system can poll the MAC status registers
332  //(STATUS0 and STATUS1) to determine the origin of the interrupt
333  status = adin1110ReadReg(interface, ADIN1110_STATUS1);
334 
335  //Link status changed interrupt?
336  if((status & ADIN1110_STATUS1_LINK_CHANGE) != 0)
337  {
338  //Clear interrupt flag
341 
342  //Check link state
343  if((status & ADIN1110_STATUS1_P1_LINK_STATUS) != 0)
344  {
345  //The PHY is only able to operate in 10 Mbps mode
346  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
347  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
348 
349  //Link is up
350  interface->linkState = TRUE;
351  }
352  else
353  {
354  //Link is down
355  interface->linkState = FALSE;
356  }
357 
358  //Process link state change event
359  nicNotifyLinkChange(interface);
360  }
361 
362  //Packet received?
363  if((status & ADIN1110_STATUS1_P1_RX_RDY) != 0)
364  {
365  //Process all pending packets
366  do
367  {
368  //Read incoming packet
369  adin1110ReceivePacket(interface);
370 
371  //Read STATUS1 again
372  status = adin1110ReadReg(interface, ADIN1110_STATUS1);
373 
374  //If the P1_RX_RDY bit is set, another frame is available to read
375  } while((status & ADIN1110_STATUS1_P1_RX_RDY) != 0);
376  }
377 
378  //Re-enable interrupts
381 }
382 
383 
384 /**
385  * @brief Send a packet
386  * @param[in] interface Underlying network interface
387  * @param[in] buffer Multi-part buffer containing the data to send
388  * @param[in] offset Offset to the first data byte
389  * @param[in] ancillary Additional options passed to the stack along with
390  * the packet
391  * @return Error code
392  **/
393 
395  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
396 {
397  static uint8_t temp[ADIN1110_ETH_TX_BUFFER_SIZE];
398  size_t n;
399  size_t length;
400 
401  //Retrieve the length of the packet
402  length = netBufferGetLength(buffer) - offset;
403 
404  //Check the frame length
406  {
407  //The transmitter can accept another packet
408  osSetEvent(&interface->nicTxEvent);
409  //Report an error
410  return ERROR_INVALID_LENGTH;
411  }
412 
413  //The TX_SPACE register indicates the remaining space in the TX FIFO
414  n = adin1110ReadReg(interface, ADIN1110_TX_SPACE) &
416 
417  //Ensure that there is sufficient space for the Ethernet frame plus 2-byte
418  //header plus 2-byte size field
419  if((n * 2) < (length + ADIN1110_TX_FRAME_OVERHEAD))
420  {
421  return ERROR_FAILURE;
422  }
423 
424  //Copy user data
425  netBufferRead(temp, buffer, offset, length);
426 
427  //TX_FSIZE is still written with the original frame size + 2 bytes for the
428  //frame header
431 
432  //Write frame data
433  adin1110WriteFifo(interface, 0, temp, length);
434 
435  //The TX_SPACE register indicates the remaining space in the TX FIFO
436  n = adin1110ReadReg(interface, ADIN1110_TX_SPACE) &
438 
439  //Verify that there is space for a new frame
441  {
442  //The transmitter can accept another packet
443  osSetEvent(&interface->nicTxEvent);
444  }
445 
446  //Successful processing
447  return NO_ERROR;
448 }
449 
450 
451 /**
452  * @brief Receive a packet
453  * @param[in] interface Underlying network interface
454  **/
455 
457 {
458  static uint8_t temp[ADIN1110_ETH_RX_BUFFER_SIZE];
459  size_t length;
460  uint16_t header;
461 
462  //Get the size of the frame at the head of the RX FIFO in bytes
465 
466  //Any packet pending in the receive buffer?
468  {
469  NetRxAncillary ancillary;
470 
471  //The size of the frame includes the appended header
473  //Read frame data
474  adin1110ReadFifo(interface, &header, temp, length);
475 
476  //Limit the length of the payload
478  //Additional options can be passed to the stack along with the packet
479  ancillary = NET_DEFAULT_RX_ANCILLARY;
480 
481  //Pass the packet to the upper layer
482  nicProcessPacket(interface, temp, length, &ancillary);
483  }
484 }
485 
486 
487 /**
488  * @brief Configure MAC address filtering
489  * @param[in] interface Underlying network interface
490  * @return Error code
491  **/
492 
494 {
495  uint_t i;
496  uint_t j;
497  MacFilterEntry *entry;
498 
499  //Debug message
500  TRACE_DEBUG("Updating MAC filter...\r\n");
501 
502  //Set the upper 16 bits of the broadcast MAC address
506 
507  //Set the lower 32 bits of the broadcast MAC address
510 
511  //Set the upper 16 bits of the station MAC address
514  (interface->macAddr.b[0] << 8) | interface->macAddr.b[1]);
515 
516  //Set the lower 32 bits of the station MAC address
518  (interface->macAddr.b[2] << 24) | (interface->macAddr.b[3] << 16) |
519  (interface->macAddr.b[4] << 8) | interface->macAddr.b[5]);
520 
521  //The MAC address filter contains the list of MAC addresses to accept
522  //when receiving an Ethernet frame
523  for(i = 0, j = 2; i < MAC_ADDR_FILTER_SIZE &&
524  j < ADIN1110_ADDR_TABLE_SIZE; i++)
525  {
526  //Point to the current entry
527  entry = &interface->macAddrFilter[i];
528 
529  //Valid entry?
530  if(entry->refCount > 0)
531  {
532  //Set the upper 16 bits of the current MAC address
535  (entry->addr.b[0] << 8) | entry->addr.b[1]);
536 
537  //Set the lower 32 bits of the current MAC address
539  (entry->addr.b[2] << 24) | (entry->addr.b[3] << 16) |
540  (entry->addr.b[4] << 8) | entry->addr.b[5]);
541 
542  //Increment index
543  j++;
544  }
545  }
546 
547  //Clear unused table entries
548  for(; j < ADIN1110_ADDR_TABLE_SIZE; j++)
549  {
550  //Clear current MAC address
551  adin1110WriteReg(interface, ADIN1110_ADDR_FILT_UPRn(j), 0);
552  adin1110WriteReg(interface, ADIN1110_ADDR_FILT_LWRn(j), 0);
553  }
554 
555  //Successful processing
556  return NO_ERROR;
557 }
558 
559 
560 /**
561  * @brief Write SPI register
562  * @param[in] interface Underlying network interface
563  * @param[in] address Register address
564  * @param[in] data System register value
565  **/
566 
567 void adin1110WriteReg(NetInterface *interface, uint16_t address,
568  uint32_t data)
569 {
570  //Pull the CS pin low
571  interface->spiDriver->assertCs();
572 
573  //Write command
574  interface->spiDriver->transfer(ADIN1110_SPI_CMD_WRITE | (address >> 8));
575  interface->spiDriver->transfer(address & 0xFF);
576 
577  //Write data
578  interface->spiDriver->transfer((data >> 24) & 0xFF);
579  interface->spiDriver->transfer((data >> 16) & 0xFF);
580  interface->spiDriver->transfer((data >> 8) & 0xFF);
581  interface->spiDriver->transfer(data & 0xFF);
582 
583  //Terminate the operation by raising the CS pin
584  interface->spiDriver->deassertCs();
585 }
586 
587 
588 /**
589  * @brief Read SPI register
590  * @param[in] interface Underlying network interface
591  * @param[in] address System register address
592  * @return Register value
593  **/
594 
595 uint32_t adin1110ReadReg(NetInterface *interface, uint16_t address)
596 {
597  uint32_t data;
598 
599  //Pull the CS pin low
600  interface->spiDriver->assertCs();
601 
602  //Write command
603  interface->spiDriver->transfer(ADIN1110_SPI_CMD_READ | (address >> 8));
604  interface->spiDriver->transfer(address & 0xFF);
605 
606  //Turn around
607  interface->spiDriver->transfer(0x00);
608 
609  //Read data
610  data = interface->spiDriver->transfer(0x00) << 24;
611  data |= interface->spiDriver->transfer(0x00) << 16;
612  data |= interface->spiDriver->transfer(0x00) << 8;
613  data |= interface->spiDriver->transfer(0x00);
614 
615  //Terminate the operation by raising the CS pin
616  interface->spiDriver->deassertCs();
617 
618  //Return register value
619  return data;
620 }
621 
622 
623 /**
624  * @brief Dump SPI registers for debugging purpose
625  * @param[in] interface Underlying network interface
626  **/
627 
629 {
630  uint16_t i;
631 
632  //Loop through system registers
633  for(i = 0; i < 256; i++)
634  {
635  //Display current SPI register
636  TRACE_DEBUG("0x%02" PRIX16 ": 0x%08" PRIX32 "\r\n", i,
637  adin1110ReadReg(interface, i));
638  }
639 
640  //Terminate with a line feed
641  TRACE_DEBUG("\r\n");
642 }
643 
644 
645 /**
646  * @brief Write PHY register
647  * @param[in] interface Underlying network interface
648  * @param[in] address PHY register address
649  * @param[in] data Register value
650  **/
651 
652 void adin1110WritePhyReg(NetInterface *interface, uint8_t address,
653  uint16_t data)
654 {
655  uint32_t value;
656 
657  //Perform a Clause 22 write operation
659  //Set PHY address
661  //Set register address
663  //Set register value
665 
666  //Write MDIOACC0 register
668 
669  //Poll MDIOACC0.TRDONE to determine that the write operation has completed
670  do
671  {
672  //Read MDIOACC0 register
674 
675  //When the MDIO transaction completes, the TRDONE bit is set to 1
676  } while((value & ADIN1110_MDIOACC_MDIO_TRDONE) == 0);
677 }
678 
679 
680 /**
681  * @brief Read PHY register
682  * @param[in] interface Underlying network interface
683  * @param[in] address PHY register address
684  * @return Register value
685  **/
686 
687 uint16_t adin1110ReadPhyReg(NetInterface *interface, uint8_t address)
688 {
689  uint32_t value;
690 
691  //Perform a Clause 22 read operation
693  //Set PHY address
695  //Set register address
697 
698  //Write MDIOACC0 register
700 
701  //Poll MDIOACC0.TRDONE to determine that the read operation has completed
702  do
703  {
704  //Read MDIOACC0 register
706 
707  //When the MDIO transaction completes, the TRDONE bit is set to 1
708  } while((value & ADIN1110_MDIOACC_MDIO_TRDONE) == 0);
709 
710  //MDIOACC0.MDIO_DATA reflects the content of register
712 }
713 
714 
715 /**
716  * @brief Dump PHY registers for debugging purpose
717  * @param[in] interface Underlying network interface
718  **/
719 
721 {
722  uint8_t i;
723 
724  //Loop through PHY registers
725  for(i = 0; i < 32; i++)
726  {
727  //Display current PHY register
728  TRACE_DEBUG("%02" PRIu8 ": 0x%04" PRIX16 "\r\n", i,
729  adin1110ReadPhyReg(interface, i));
730  }
731 
732  //Terminate with a line feed
733  TRACE_DEBUG("\r\n");
734 }
735 
736 
737 /**
738  * @brief Write MMD register
739  * @param[in] interface Underlying network interface
740  * @param[in] devAddr Device address
741  * @param[in] regAddr Register address
742  * @param[in] data MMD register value
743  **/
744 
745 void adin1110WriteMmdReg(NetInterface *interface, uint8_t devAddr,
746  uint16_t regAddr, uint16_t data)
747 {
748  uint32_t value;
749 
750  //Perform a Clause 45 address write operation
752  //MDIO_PRTAD is always written to 1
754  //Set device address
755  value |= (devAddr << 16) & ADIN1110_MDIOACC_MDIO_DEVAD;
756  //Set register address
758 
759  //Write MDIOACC0 register
761 
762  //Perform a Clause 45 write operation
764  //MDIO_PRTAD is always written to 1
766  //Set device address
767  value |= (devAddr << 16) & ADIN1110_MDIOACC_MDIO_DEVAD;
768  //Set register value
770 
771  //Write MDIOACC1 register
773 
774  //Poll MDIOACC1.TRDONE to determine that the write operation has completed
775  do
776  {
777  //Read MDIOACC1 register
779 
780  //When the MDIO transaction completes, the TRDONE bit is set to 1
781  } while((value & ADIN1110_MDIOACC_MDIO_TRDONE) == 0);
782 }
783 
784 
785 /**
786  * @brief Read MMD register
787  * @param[in] interface Underlying network interface
788  * @param[in] devAddr Device address
789  * @param[in] regAddr Register address
790  * @return MMD register value
791  **/
792 
793 uint16_t adin1110ReadMmdReg(NetInterface *interface, uint8_t devAddr,
794  uint16_t regAddr)
795 {
796  uint32_t value;
797 
798  //Perform a Clause 45 address write operation
800  //MDIO_PRTAD is always written to 1
802  //Set device address
803  value |= (devAddr << 16) & ADIN1110_MDIOACC_MDIO_DEVAD;
804  //Set register address
806 
807  //Write MDIOACC0 register
809 
810  //Perform a Clause 45 read operation
812  //MDIO_PRTAD is always written to 1
814  //Set device address
815  value |= (devAddr << 16) & ADIN1110_MDIOACC_MDIO_DEVAD;
816 
817  //Write MDIOACC1 register
819 
820  //Poll MDIOACC1.TRDONE to determine that the read operation has completed
821  do
822  {
823  //Read MDIOACC1 register
825 
826  //When the MDIO transaction completes, the TRDONE bit is set to 1
827  } while((value & ADIN1110_MDIOACC_MDIO_TRDONE) == 0);
828 
829  //MDIOACC1.MDIO_DATA reflects the content of register
831 }
832 
833 
834 /**
835  * @brief Write TX FIFO
836  * @param[in] interface Underlying network interface
837  * @param[in] header Frame header
838  * @param[in] data Pointer to the data being written
839  * @param[in] length Number of data to write
840  **/
841 
842 void adin1110WriteFifo(NetInterface *interface, uint16_t header,
843  const uint8_t *data, size_t length)
844 {
845  size_t i;
846 
847  //Pull the CS pin low
848  interface->spiDriver->assertCs();
849 
850  //Write command
851  interface->spiDriver->transfer(ADIN1110_SPI_CMD_WRITE | (ADIN1110_TX >> 8));
852  interface->spiDriver->transfer(ADIN1110_TX & 0xFF);
853 
854  //The 2-byte frame header is appended to all transmitted frames. This always
855  //precedes the frame data
856  interface->spiDriver->transfer((header >> 8) & 0xFF);
857  interface->spiDriver->transfer(header & 0xFF);
858 
859  //Write frame data
860  for(i = 0; i < length; i++)
861  {
862  interface->spiDriver->transfer(data[i]);
863  }
864 
865  //The burst write data must always be in multiples of 4 bytes
866  for(; ((i + ADIN1110_FRAME_HEADER_SIZE) % 4) != 0; i++)
867  {
868  interface->spiDriver->transfer(0x00);
869  }
870 
871  //Terminate the operation by raising the CS pin
872  interface->spiDriver->deassertCs();
873 }
874 
875 
876 /**
877  * @brief Read RX FIFO
878  * @param[in] interface Underlying network interface
879  * @param[out] header Frame header
880  * @param[out] data Buffer where to store the incoming data
881  * @param[in] length Number of data to read
882  **/
883 
884 void adin1110ReadFifo(NetInterface *interface, uint16_t *header,
885  uint8_t *data, size_t length)
886 {
887  size_t i;
888 
889  //Pull the CS pin low
890  interface->spiDriver->assertCs();
891 
892  //Write command
893  interface->spiDriver->transfer(ADIN1110_SPI_CMD_READ | (ADIN1110_P1_RX >> 8));
894  interface->spiDriver->transfer(ADIN1110_P1_RX & 0xFF);
895 
896  //Turn around
897  interface->spiDriver->transfer(0x00);
898 
899  //The 2-byte frame header is appended to all received frames. This always
900  //precedes the frame data
901  *header = interface->spiDriver->transfer(0x00) << 16;
902  *header |= interface->spiDriver->transfer(0x00);
903 
904  //Read frame data
905  for(i = 0; i < length && i < ADIN1110_ETH_RX_BUFFER_SIZE; i++)
906  {
907  data[i] = interface->spiDriver->transfer(0x00);
908  }
909 
910  //Discard extra bytes
911  for(; i < length; i++)
912  {
913  interface->spiDriver->transfer(0x00);
914  }
915 
916  //The burst read data must always be in multiples of 4 bytes
917  for(; ((i + ADIN1110_FRAME_HEADER_SIZE) % 4) != 0; i++)
918  {
919  interface->spiDriver->transfer(0x00);
920  }
921 
922  //Terminate the operation by raising the CS pin
923  interface->spiDriver->deassertCs();
924 }
error_t adin1110SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
__weak_func void adin1110InitHook(NetInterface *interface)
ADIN1110 custom configuration.
void adin1110ReadFifo(NetInterface *interface, uint16_t *header, uint8_t *data, size_t length)
Read RX FIFO.
void adin1110EnableIrq(NetInterface *interface)
Enable interrupts.
bool_t adin1110IrqHandler(NetInterface *interface)
ADIN1110 interrupt service routine.
uint32_t adin1110ReadReg(NetInterface *interface, uint16_t address)
Read SPI register.
error_t adin1110Init(NetInterface *interface)
ADIN1110 controller initialization.
uint16_t adin1110ReadPhyReg(NetInterface *interface, uint8_t address)
Read PHY register.
void adin1110WriteMmdReg(NetInterface *interface, uint8_t devAddr, uint16_t regAddr, uint16_t data)
Write MMD register.
void adin1110Tick(NetInterface *interface)
ADIN1110 timer handler.
uint16_t adin1110ReadMmdReg(NetInterface *interface, uint8_t devAddr, uint16_t regAddr)
Read MMD register.
error_t adin1110UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void adin1110WriteReg(NetInterface *interface, uint16_t address, uint32_t data)
Write SPI register.
void adin1110WritePhyReg(NetInterface *interface, uint8_t address, uint16_t data)
Write PHY register.
void adin1110DisableIrq(NetInterface *interface)
Disable interrupts.
const NicDriver adin1110Driver
ADIN1110 driver.
void adin1110WriteFifo(NetInterface *interface, uint16_t header, const uint8_t *data, size_t length)
Write TX FIFO.
void adin1110DumpPhyReg(NetInterface *interface)
Dump PHY registers for debugging purpose.
void adin1110DumpReg(NetInterface *interface)
Dump SPI registers for debugging purpose.
void adin1110EventHandler(NetInterface *interface)
ADIN1110 event handler.
void adin1110ReceivePacket(NetInterface *interface)
Receive a packet.
ADIN1110 10Base-T1L Ethernet controller.
#define ADIN1110_FRAME_HEADER_SIZE
#define ADIN1110_MDIOACC_MDIO_OP_WRITE
#define ADIN1110_SPI_CMD_WRITE
#define ADIN1110_TX_SPACE_TX_SPACE
#define ADIN1110_IMASK1_TX_RDY_MASK
#define ADIN1110_MDIOACC_MDIO_ST_CLAUSE_22
#define ADIN1110_LED_CNTRL_LED1_EN
#define ADIN1110_IMASK1
#define ADIN1110_MDIOACC_MDIO_DATA
#define ADIN1110_P1_RX_FSIZE_P1_RX_FRM_SIZE
#define ADIN1110_STATUS1_TX_RDY
#define ADIN1110_CRSM_STAT
#define ADIN1110_LED_POLARITY_LED0_POLARITY_AUTOSENSE
#define ADIN1110_MDIOACC1
#define ADIN1110_LED_CNTRL_LED1_FUNCTION_MASTER
#define ADIN1110_CONFIG0_TXCTE
#define ADIN1110_STATUS1
#define ADIN1110_STATUS1_P1_RX_RDY
#define ADIN1110_MDIOACC_MDIO_TRDONE
#define ADIN1110_CRSM_SFT_PD_CNTRL_CRSM_SFT_PD
#define ADIN1110_STATUS1_P1_LINK_STATUS
#define ADIN1110_TX_SPACE
#define ADIN1110_STATUS0_RESETC
#define ADIN1110_CONFIG2
#define ADIN1110_STATUS1_LINK_CHANGE
#define ADIN1110_ETH_RX_BUFFER_SIZE
#define ADIN1110_ADDR_FILT_LWR_MAC_ADDR_31_0
#define ADIN1110_MDIOACC0
#define ADIN1110_IMASK1_LINK_CHANGE_MASK
#define ADIN1110_IMASK1_P1_RX_RDY_MASK
#define ADIN1110_ADDR_FILT_UPRn(index)
#define ADIN1110_LED_CNTRL_LED0_EN
#define ADIN1110_ETH_TX_BUFFER_SIZE
#define ADIN1110_P1_RX_FSIZE
#define ADIN1110_TX
#define ADIN1110_TX_FSIZE
#define ADIN1110_ADDR_FILT_UPR_TO_HOST
#define ADIN1110_STATUS0
#define ADIN1110_CONFIG0_RXCTE
#define ADIN1110_ADDR_FILT_UPR_APPLY2PORT1
#define ADIN1110_CONFIG2_CRC_APPEND
#define ADIN1110_DIGIO_PINMUX_DIGIO_LED1_PINMUX_LED_1
#define ADIN1110_PHYID_MODEL_DEFAULT
#define ADIN1110_P1_RX
#define ADIN1110_CRSM_SFT_PD_CNTRL
#define ADIN1110_RESET
#define ADIN1110_LED_CNTRL_LED0_FUNCTION_LINKUP_TXRX_ACTIVITY
#define ADIN1110_CRSM_STAT_CRSM_SYS_RDY
#define ADIN1110_LED_POLARITY
#define ADIN1110_LED_POLARITY_LED1_POLARITY_AUTOSENSE
#define ADIN1110_DIGIO_PINMUX_DIGIO_LED1_PINMUX
#define ADIN1110_ADDR_TABLE_SIZE
#define ADIN1110_CONFIG0_SYNC
#define ADIN1110_CONFIG0
#define ADIN1110_IMASK0
#define ADIN1110_MDIOACC_MDIO_OP_READ
#define ADIN1110_MDIOACC_MDIO_PRTAD_DEFAULT
#define ADIN1110_PHYID_OUI_DEFAULT
#define ADIN1110_TX_FRAME_OVERHEAD
#define ADIN1110_MDIOACC_MDIO_OP_ADDR
#define ADIN1110_LED_CNTRL
#define ADIN1110_ADDR_FILT_UPR_MAC_ADDR_47_32
#define ADIN1110_PHYID
#define ADIN1110_RESET_SWRESET
#define ADIN1110_MDIOACC_MDIO_ST_CLAUSE_45
#define ADIN1110_PHYID_REVISION_DEFAULT
#define ADIN1110_SPI_CMD_READ
#define ADIN1110_DIGIO_PINMUX
#define ADIN1110_MDIOACC_MDIO_DEVAD
#define ADIN1110_ADDR_FILT_LWRn(index)
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
error_t
Error codes.
Definition: error.h:43
@ NO_ERROR
Success.
Definition: error.h:44
@ 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 MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:95
Ipv6Addr address[]
Definition: ipv6.h:316
uint16_t regAddr
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
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:548
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
@ NIC_FULL_DUPLEX_MODE
Definition: nic.h:125
@ NIC_LINK_SPEED_10MBPS
Definition: nic.h:111
#define MIN(a, b)
Definition: os_port.h:63
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
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.
MAC filter table entry.
Definition: ethernet.h:262
MacAddr addr
MAC address.
Definition: ethernet.h:263
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:264
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
uint8_t value[]
Definition: tcp.h:369
uint8_t mask
Definition: web_socket.h:319