enc624j600_driver.c
Go to the documentation of this file.
1 /**
2  * @file enc624j600_driver.c
3  * @brief ENC624J600/ENC424J600 Ethernet controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 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.6
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 ENC624J600 driver
42  **/
43 
45 {
47  ETH_MTU,
55  NULL,
56  NULL,
57  NULL,
58  TRUE,
59  TRUE,
60  TRUE,
61  FALSE
62 };
63 
64 
65 /**
66  * @brief ENC624J600 controller initialization
67  * @param[in] interface Underlying network interface
68  * @return Error code
69  **/
70 
72 {
73  Enc624j600Context *context;
74 
75  //Debug message
76  TRACE_INFO("Initializing ENC624J600 Ethernet controller...\r\n");
77 
78  //Initialize SPI
79  interface->spiDriver->init();
80  //Initialize external interrupt line
81  interface->extIntDriver->init();
82 
83  //Point to the driver context
84  context = (Enc624j600Context *) interface->nicContext;
85 
86  //Initialize driver specific variables
88 
89  //Allocate RX buffer
91  //Failed to allocate memory?
92  if(context->rxBuffer == NULL)
93  return ERROR_OUT_OF_MEMORY;
94 
95  //Issue a system reset
96  enc624j600SoftReset(interface);
97 
98  //Disable CLKOUT output
100 
101  //Optionally set the station MAC address
102  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
103  {
104  //Use the factory preprogrammed station address
105  interface->macAddr.w[0] = enc624j600ReadReg(interface, ENC624J600_REG_MAADR1);
106  interface->macAddr.w[1] = enc624j600ReadReg(interface, ENC624J600_REG_MAADR2);
107  interface->macAddr.w[2] = enc624j600ReadReg(interface, ENC624J600_REG_MAADR3);
108 
109  //Generate the 64-bit interface identifier
110  macAddrToEui64(&interface->macAddr, &interface->eui64);
111  }
112  else
113  {
114  //Override the factory preprogrammed address
115  enc624j600WriteReg(interface, ENC624J600_REG_MAADR1, interface->macAddr.w[0]);
116  enc624j600WriteReg(interface, ENC624J600_REG_MAADR2, interface->macAddr.w[1]);
117  enc624j600WriteReg(interface, ENC624J600_REG_MAADR3, interface->macAddr.w[2]);
118  }
119 
120  //Set receive buffer location
122  //Program the tail pointer ERXTAIL to the last even address of the buffer
124 
125  //Configure the receive filters
128 
129  //Initialize the hash table
130  enc624j600WriteReg(interface, ENC624J600_REG_EHT1, 0x0000);
131  enc624j600WriteReg(interface, ENC624J600_REG_EHT2, 0x0000);
132  enc624j600WriteReg(interface, ENC624J600_REG_EHT3, 0x0000);
133  enc624j600WriteReg(interface, ENC624J600_REG_EHT4, 0x0000);
134 
135  //All short frames will be zero-padded to 60 bytes and a valid CRC is then appended
138 
139  //Program the MAMXFL register with the maximum frame length to be accepted
141 
142  //PHY initialization
145 
146  //Clear interrupt flags
147  enc624j600WriteReg(interface, ENC624J600_REG_EIR, 0x0000);
148 
149  //Configure interrupts as desired
152 
153  //Set RXEN to enable reception
155 
156  //Dump registers for debugging purpose
157  enc624j600DumpReg(interface);
158  enc624j600DumpPhyReg(interface);
159 
160  //Accept any packets from the upper layer
161  osSetEvent(&interface->nicTxEvent);
162 
163  //Force the TCP/IP stack to poll the link state at startup
164  interface->nicEvent = TRUE;
165  //Notify the TCP/IP stack of the event
167 
168  //Successful initialization
169  return NO_ERROR;
170 }
171 
172 
173 /**
174  * @brief ENC624J600 timer handler
175  * @param[in] interface Underlying network interface
176  **/
177 
178 void enc624j600Tick(NetInterface *interface)
179 {
180 }
181 
182 
183 /**
184  * @brief Enable interrupts
185  * @param[in] interface Underlying network interface
186  **/
187 
189 {
190  //Enable interrupts
191  interface->extIntDriver->enableIrq();
192 }
193 
194 
195 /**
196  * @brief Disable interrupts
197  * @param[in] interface Underlying network interface
198  **/
199 
201 {
202  //Disable interrupts
203  interface->extIntDriver->disableIrq();
204 }
205 
206 
207 /**
208  * @brief ENC624J600 interrupt service routine
209  * @param[in] interface Underlying network interface
210  * @return TRUE if a higher priority task must be woken. Else FALSE is returned
211  **/
212 
214 {
215  bool_t flag;
216  uint16_t status;
217 
218  //This flag will be set if a higher priority task must be woken
219  flag = FALSE;
220 
221  //Clear the INTIE bit, immediately after an interrupt event
223 
224  //Read interrupt status register
225  status = enc624j600ReadReg(interface, ENC624J600_REG_EIR);
226 
227  //Link status change?
228  if(status & EIR_LINKIF)
229  {
230  //Disable LINKIE interrupt
232 
233  //Set event flag
234  interface->nicEvent = TRUE;
235  //Notify the TCP/IP stack of the event
236  flag |= osSetEventFromIsr(&netEvent);
237  }
238 
239  //Packet received?
240  if(status & EIR_PKTIF)
241  {
242  //Disable PKTIE interrupt
244 
245  //Set event flag
246  interface->nicEvent = TRUE;
247  //Notify the TCP/IP stack of the event
248  flag |= osSetEventFromIsr(&netEvent);
249  }
250 
251  //Packet transmission complete?
252  if(status & (EIR_TXIF | EIR_TXABTIF))
253  {
254  //Clear interrupt flags
256 
257  //Notify the TCP/IP stack that the transmitter is ready to send
258  flag |= osSetEventFromIsr(&interface->nicTxEvent);
259  }
260 
261  //Once the interrupt has been serviced, the INTIE bit
262  //is set again to re-enable interrupts
264 
265  //A higher priority task must be woken?
266  return flag;
267 }
268 
269 
270 /**
271  * @brief ENC624J600 event handler
272  * @param[in] interface Underlying network interface
273  **/
274 
276 {
277  error_t error;
278  uint16_t status;
279  uint16_t value;
280 
281  //Read interrupt status register
282  status = enc624j600ReadReg(interface, ENC624J600_REG_EIR);
283 
284  //Check whether the link state has changed
285  if(status & EIR_LINKIF)
286  {
287  //Clear interrupt flag
289  //Read Ethernet status register
291 
292  //Check link state
293  if(value & ESTAT_PHYLNK)
294  {
295  //Read PHY status register 3
297 
298  //Get current speed
299  if(value & PHSTAT3_SPDDPX1)
300  interface->linkSpeed = NIC_LINK_SPEED_100MBPS;
301  else
302  interface->linkSpeed = NIC_LINK_SPEED_10MBPS;
303 
304  //Determine the new duplex mode
305  if(value & PHSTAT3_SPDDPX2)
306  interface->duplexMode = NIC_FULL_DUPLEX_MODE;
307  else
308  interface->duplexMode = NIC_HALF_DUPLEX_MODE;
309 
310  //Link is up
311  interface->linkState = TRUE;
312 
313  //Update MAC configuration parameters for proper operation
314  enc624j600UpdateMacConfig(interface);
315  }
316  else
317  {
318  //Link is down
319  interface->linkState = FALSE;
320  }
321 
322  //Process link state change event
323  nicNotifyLinkChange(interface);
324  }
325 
326  //Check whether a packet has been received?
327  if(status & EIR_PKTIF)
328  {
329  //Clear interrupt flag
331 
332  //Process all pending packets
333  do
334  {
335  //Read incoming packet
336  error = enc624j600ReceivePacket(interface);
337 
338  //No more data in the receive buffer?
339  } while(error != ERROR_BUFFER_EMPTY);
340  }
341 
342  //Re-enable LINKIE and PKTIE interrupts
344 }
345 
346 
347 /**
348  * @brief Send a packet
349  * @param[in] interface Underlying network interface
350  * @param[in] buffer Multi-part buffer containing the data to send
351  * @param[in] offset Offset to the first data byte
352  * @return Error code
353  **/
354 
356  const NetBuffer *buffer, size_t offset)
357 {
358  size_t length;
359 
360  //Retrieve the length of the packet
361  length = netBufferGetLength(buffer) - offset;
362 
363  //Check the frame length
364  if(length > 1536)
365  {
366  //The transmitter can accept another packet
367  osSetEvent(&interface->nicTxEvent);
368  //Report an error
369  return ERROR_INVALID_LENGTH;
370  }
371 
372  //Make sure the link is up before transmitting the frame
373  if(!interface->linkState)
374  {
375  //The transmitter can accept another packet
376  osSetEvent(&interface->nicTxEvent);
377  //Drop current packet
378  return NO_ERROR;
379  }
380 
381  //Ensure that the transmitter is ready to send
383  return ERROR_FAILURE;
384 
385  //Point to the SRAM buffer
387  //Copy the packet to the SRAM buffer
388  enc624j600WriteBuffer(interface, ENC624J600_CMD_WGPDATA, buffer, offset);
389 
390  //Program ETXST to the start address of the packet
392  //Program ETXLEN with the length of data copied to the memory
394 
395  //Clear TXIF and TXABTIF interrupt flags
397  //Set the TXRTS bit to initiate transmission
399 
400  //Successful processing
401  return NO_ERROR;
402 }
403 
404 
405 /**
406  * @brief Receive a packet
407  * @param[in] interface Underlying network interface
408  * @return Error code
409  **/
410 
412 {
413  error_t error;
414  uint16_t n;
415  uint32_t status;
416  Enc624j600Context *context;
417 
418  //Point to the driver context
419  context = (Enc624j600Context *) interface->nicContext;
420 
421  //Verify that a packet is waiting by ensuring that PKTCNT is non-zero
423  {
424  //Point to the next packet
426 
427  //Read the first two bytes, which are the address of the next packet
429  (uint8_t *) &context->nextPacket, sizeof(uint16_t));
430 
431  //Get the length of the received frame in bytes
433  (uint8_t *) &n, sizeof(uint16_t));
434 
435  //Read the receive status vector (RSV)
437  (uint8_t *) &status, sizeof(uint32_t));
438 
439  //Make sure no error occurred
440  if(status & RSV_RECEIVED_OK)
441  {
442  //Limit the number of data to read
444  //Read the Ethernet frame
445  enc624j600ReadBuffer(interface, ENC624J600_CMD_RRXDATA, context->rxBuffer, n);
446  //Valid packet received
447  error = NO_ERROR;
448  }
449  else
450  {
451  //The received packet contains an error
452  error = ERROR_INVALID_PACKET;
453  }
454 
455  //Update the ERXTAIL pointer value to the point where the packet
456  //has been processed, taking care to wrap back at the end of the
457  //received memory buffer
458  if(context->nextPacket == ENC624J600_RX_BUFFER_START)
460  else
461  enc624j600WriteReg(interface, ENC624J600_REG_ERXTAIL, context->nextPacket - 2);
462 
463  //Set PKTDEC to decrement the PKTCNT bits
465  }
466  else
467  {
468  //No more data in the receive buffer
469  error = ERROR_BUFFER_EMPTY;
470  }
471 
472  //Check whether a valid packet has been received
473  if(!error)
474  {
475  //Pass the packet to the upper layer
476  nicProcessPacket(interface, context->rxBuffer, n);
477  }
478 
479  //Return status code
480  return error;
481 }
482 
483 
484 /**
485  * @brief Configure MAC address filtering
486  * @param[in] interface Underlying network interface
487  * @return Error code
488  **/
489 
491 {
492  uint_t i;
493  uint_t k;
494  uint32_t crc;
495  uint16_t hashTable[4];
496  MacFilterEntry *entry;
497 
498  //Debug message
499  TRACE_DEBUG("Updating MAC filter...\r\n");
500 
501  //Clear hash table
502  memset(hashTable, 0, sizeof(hashTable));
503 
504  //The MAC address filter contains the list of MAC addresses to accept
505  //when receiving an Ethernet frame
506  for(i = 0; i < MAC_ADDR_FILTER_SIZE; i++)
507  {
508  //Point to the current entry
509  entry = &interface->macAddrFilter[i];
510 
511  //Valid entry?
512  if(entry->refCount > 0)
513  {
514  //Compute CRC over the current MAC address
515  crc = enc624j600CalcCrc(&entry->addr, sizeof(MacAddr));
516  //Calculate the corresponding index in the table
517  k = (crc >> 23) & 0x3F;
518  //Update hash table contents
519  hashTable[k / 16] |= (1 << (k % 16));
520  }
521  }
522 
523  //Write the hash table to the ENC624J600 controller
524  enc624j600WriteReg(interface, ENC624J600_REG_EHT1, hashTable[0]);
525  enc624j600WriteReg(interface, ENC624J600_REG_EHT2, hashTable[1]);
526  enc624j600WriteReg(interface, ENC624J600_REG_EHT3, hashTable[2]);
527  enc624j600WriteReg(interface, ENC624J600_REG_EHT4, hashTable[3]);
528 
529  //Debug message
530  TRACE_DEBUG(" EHT1 = %04" PRIX16 "\r\n", enc624j600ReadReg(interface, ENC624J600_REG_EHT1));
531  TRACE_DEBUG(" EHT2 = %04" PRIX16 "\r\n", enc624j600ReadReg(interface, ENC624J600_REG_EHT2));
532  TRACE_DEBUG(" EHT3 = %04" PRIX16 "\r\n", enc624j600ReadReg(interface, ENC624J600_REG_EHT3));
533  TRACE_DEBUG(" EHT4 = %04" PRIX16 "\r\n", enc624j600ReadReg(interface, ENC624J600_REG_EHT4));
534 
535  //Successful processing
536  return NO_ERROR;
537 }
538 
539 
540 /**
541  * @brief Adjust MAC configuration parameters for proper operation
542  * @param[in] interface Underlying network interface
543  **/
544 
546 {
547  uint16_t duplexMode;
548 
549  //Determine the new duplex mode by reading the PHYDPX bit
550  duplexMode = enc624j600ReadReg(interface, ENC624J600_REG_ESTAT) & ESTAT_PHYDPX;
551 
552  //Full-duplex mode?
553  if(duplexMode)
554  {
555  //Configure the FULDPX bit to match the current duplex mode
558  //Configure the Back-to-Back Inter-Packet Gap register
559  enc624j600WriteReg(interface, ENC624J600_REG_MABBIPG, 0x15);
560  }
561  //Half-duplex mode?
562  else
563  {
564  //Configure the FULDPX bit to match the current duplex mode
567  //Configure the Back-to-Back Inter-Packet Gap register
568  enc624j600WriteReg(interface, ENC624J600_REG_MABBIPG, 0x12);
569  }
570 }
571 
572 
573 /**
574  * @brief Reset ENC624J600 controller
575  * @param[in] interface Underlying network interface
576  * @return Error code
577  **/
578 
580 {
581  //Wait for the SPI interface to be ready
582  do
583  {
584  //Write 0x1234 to EUDAST
585  enc624j600WriteReg(interface, ENC624J600_REG_EUDAST, 0x1234);
586  //Read back register and check contents
587  } while(enc624j600ReadReg(interface, ENC624J600_REG_EUDAST) != 0x1234);
588 
589  //Poll CLKRDY and wait for it to become set
590  while(!(enc624j600ReadReg(interface, ENC624J600_REG_ESTAT) & ESTAT_CLKRDY));
591 
592  //Issue a system reset command by setting ETHRST
594  //Wait at least 25us for the reset to take place
595  sleep(1);
596 
597  //Read EUDAST to confirm that the system reset took place.
598  //EUDAST should have reverted back to its reset default
599  if(enc624j600ReadReg(interface, ENC624J600_REG_EUDAST) != 0x0000)
600  return ERROR_FAILURE;
601 
602  //Wait at least 256us for the PHY registers and PHY
603  //status bits to become available
604  sleep(1);
605 
606  //The controller is now ready to accept further commands
607  return NO_ERROR;
608 }
609 
610 
611 /**
612  * @brief Write ENC624J600 register
613  * @param[in] interface Underlying network interface
614  * @param[in] address Register address
615  * @param[in] data Register value
616  **/
617 
618 void enc624j600WriteReg(NetInterface *interface, uint8_t address,
619  uint16_t data)
620 {
621  //Pull the CS pin low
622  interface->spiDriver->assertCs();
623 
624  //Write opcode
625  interface->spiDriver->transfer(ENC624J600_CMD_WCRU);
626  //Write register address
627  interface->spiDriver->transfer(address);
628  //Write register value
629  interface->spiDriver->transfer(LSB(data));
630  interface->spiDriver->transfer(MSB(data));
631 
632  //Terminate the operation by raising the CS pin
633  interface->spiDriver->deassertCs();
634 }
635 
636 
637 /**
638  * @brief Read ENC624J600 register
639  * @param[in] interface Underlying network interface
640  * @param[in] address Register address
641  * @return Register value
642  **/
643 
644 uint16_t enc624j600ReadReg(NetInterface *interface, uint8_t address)
645 {
646  uint16_t data;
647 
648  //Pull the CS pin low
649  interface->spiDriver->assertCs();
650 
651  //Write opcode
652  interface->spiDriver->transfer(ENC624J600_CMD_RCRU);
653  //Write register address
654  interface->spiDriver->transfer(address);
655  //Read the lower 8 bits of data
656  data = interface->spiDriver->transfer(0x00);
657  //Read the upper 8 bits of data
658  data |= interface->spiDriver->transfer(0x00) << 8;
659 
660  //Terminate the operation by raising the CS pin
661  interface->spiDriver->deassertCs();
662 
663  //Return register contents
664  return data;
665 }
666 
667 
668 /**
669  * @brief Write PHY register
670  * @param[in] interface Underlying network interface
671  * @param[in] address PHY register address
672  * @param[in] data Register value
673  **/
674 
675 void enc624j600WritePhyReg(NetInterface *interface, uint8_t address,
676  uint16_t data)
677 {
678  //Write the address of the PHY register to write to
680  //Write the 16 bits of data into the MIWR register
682 
683  //Wait until the PHY register has been written
685 }
686 
687 
688 /**
689  * @brief Read PHY register
690  * @param[in] interface Underlying network interface
691  * @param[in] address PHY register address
692  * @return Register value
693  **/
694 
695 uint16_t enc624j600ReadPhyReg(NetInterface *interface, uint8_t address)
696 {
697  //Write the address of the PHY register to read from
699  //Start read operation
701 
702  //Wait at least 25.6us before polling the BUSY bit
703  usleep(100);
704  //Wait for the read operation to complete
706 
707  //Clear command register
708  enc624j600WriteReg(interface, ENC624J600_REG_MICMD, 0x00);
709 
710  //Return register contents
711  return enc624j600ReadReg(interface, ENC624J600_REG_MIRD);
712 }
713 
714 
715 /**
716  * @brief Write SRAM buffer
717  * @param[in] interface Underlying network interface
718  * @param[in] opcode SRAM buffer operation
719  * @param[in] buffer Multi-part buffer containing the data to be written
720  * @param[in] offset Offset to the first data byte
721  **/
722 
724  uint8_t opcode, const NetBuffer *buffer, size_t offset)
725 {
726  uint_t i;
727  size_t j;
728  size_t n;
729  uint8_t *p;
730 
731  //Pull the CS pin low
732  interface->spiDriver->assertCs();
733 
734  //Write opcode
735  interface->spiDriver->transfer(opcode);
736 
737  //Loop through data chunks
738  for(i = 0; i < buffer->chunkCount; i++)
739  {
740  //Is there any data to copy from the current chunk?
741  if(offset < buffer->chunk[i].length)
742  {
743  //Point to the first byte to be read
744  p = (uint8_t *) buffer->chunk[i].address + offset;
745  //Compute the number of bytes to copy at a time
746  n = buffer->chunk[i].length - offset;
747 
748  //Copy data to SRAM buffer
749  for(j = 0; j < n; j++)
750  interface->spiDriver->transfer(p[j]);
751 
752  //Process the next block from the start
753  offset = 0;
754  }
755  else
756  {
757  //Skip the current chunk
758  offset -= buffer->chunk[i].length;
759  }
760  }
761 
762  //Terminate the operation by raising the CS pin
763  interface->spiDriver->deassertCs();
764 }
765 
766 
767 /**
768  * @brief Read SRAM buffer
769  * @param[in] interface Underlying network interface
770  * @param[in] opcode SRAM buffer operation
771  * @param[in] data Buffer where to store the incoming data
772  * @param[in] length Number of data to read
773  **/
774 
776  uint8_t opcode, uint8_t *data, size_t length)
777 {
778  size_t i;
779 
780  //Pull the CS pin low
781  interface->spiDriver->assertCs();
782 
783  //Write opcode
784  interface->spiDriver->transfer(opcode);
785 
786  //Copy data from SRAM buffer
787  for(i = 0; i < length; i++)
788  data[i] = interface->spiDriver->transfer(0x00);
789 
790  //Terminate the operation by raising the CS pin
791  interface->spiDriver->deassertCs();
792 }
793 
794 
795 /**
796  * @brief Set bit field
797  * @param[in] interface Underlying network interface
798  * @param[in] address Register address
799  * @param[in] mask Bits to set in the target register
800  **/
801 
802 void enc624j600SetBit(NetInterface *interface, uint8_t address,
803  uint16_t mask)
804 {
805  //Pull the CS pin low
806  interface->spiDriver->assertCs();
807 
808  //Write opcode
809  interface->spiDriver->transfer(ENC624J600_CMD_BFSU);
810  //Write register address
811  interface->spiDriver->transfer(address);
812  //Write bit mask
813  interface->spiDriver->transfer(LSB(mask));
814  interface->spiDriver->transfer(MSB(mask));
815 
816  //Terminate the operation by raising the CS pin
817  interface->spiDriver->deassertCs();
818 }
819 
820 
821 /**
822  * @brief Clear bit field
823  * @param[in] interface Underlying network interface
824  * @param[in] address Register address
825  * @param[in] mask Bits to clear in the target register
826  **/
827 
828 void enc624j600ClearBit(NetInterface *interface, uint8_t address,
829  uint16_t mask)
830 {
831  //Pull the CS pin low
832  interface->spiDriver->assertCs();
833 
834  //Write opcode
835  interface->spiDriver->transfer(ENC624J600_CMD_BFCU);
836  //Write register address
837  interface->spiDriver->transfer(address);
838  //Write bit mask
839  interface->spiDriver->transfer(LSB(mask));
840  interface->spiDriver->transfer(MSB(mask));
841 
842  //Terminate the operation by raising the CS pin
843  interface->spiDriver->deassertCs();
844 }
845 
846 
847 /**
848  * @brief CRC calculation using the polynomial 0x4C11DB7
849  * @param[in] data Pointer to the data over which to calculate the CRC
850  * @param[in] length Number of bytes to process
851  * @return Resulting CRC value
852  **/
853 
854 uint32_t enc624j600CalcCrc(const void *data, size_t length)
855 {
856  uint_t i;
857  uint_t j;
858 
859  //Point to the data over which to calculate the CRC
860  const uint8_t *p = (uint8_t *) data;
861  //CRC preset value
862  uint32_t crc = 0xFFFFFFFF;
863 
864  //Loop through data
865  for(i = 0; i < length; i++)
866  {
867  //The message is processed bit by bit
868  for(j = 0; j < 8; j++)
869  {
870  //Update CRC value
871  if(((crc >> 31) ^ (p[i] >> j)) & 0x01)
872  crc = (crc << 1) ^ 0x04C11DB7;
873  else
874  crc = crc << 1;
875  }
876  }
877 
878  //Return CRC value
879  return crc;
880 }
881 
882 
883 /**
884  * @brief Dump registers for debugging purpose
885  * @param[in] interface Underlying network interface
886  **/
887 
889 {
890 #if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
891  uint8_t i;
892  uint8_t bank;
893  uint16_t address;
894 
895  //Display header
896  TRACE_DEBUG(" Bank 0 Bank 1 Bank 2 Bank 3 Unbanked\r\n");
897 
898  //Loop through register addresses
899  for(i = 0; i < 32; i += 2)
900  {
901  //Display register address
902  TRACE_DEBUG("%02" PRIX8 ": ", i);
903 
904  //Loop through bank numbers
905  for(bank = 0; bank < 5; bank++)
906  {
907  //Format register address
908  address = 0x7E00 | (bank << 5) | i;
909  //Display register contents
910  TRACE_DEBUG("0x%04" PRIX16 " ", enc624j600ReadReg(interface, address));
911  }
912 
913  //Jump to the following line
914  TRACE_DEBUG("\r\n");
915  }
916 
917  //Terminate with a line feed
918  TRACE_DEBUG("\r\n");
919 #endif
920 }
921 
922 
923 /**
924  * @brief Dump PHY registers for debugging purpose
925  * @param[in] interface Underlying network interface
926  **/
927 
929 {
930 #if (TRACE_LEVEL >= TRACE_LEVEL_DEBUG)
931  uint8_t i;
932 
933  //Loop through PHY registers
934  for(i = 0; i < 32; i++)
935  {
936  //Display current PHY register
937  TRACE_DEBUG("%02" PRIX8 ": 0x%04" PRIX16 "\r\n", i, enc624j600ReadPhyReg(interface, i));
938  }
939 
940  //Terminate with a line feed
941  TRACE_DEBUG("\r\n");
942 #endif
943 }
bool_t osSetEventFromIsr(OsEvent *event)
Set an event object to the signaled state from an interrupt service routine.
void nicNotifyLinkChange(NetInterface *interface)
Process link state change notification.
Definition: nic.c:525
#define usleep(delay)
Definition: os_port.h:127
uint8_t length
Definition: dtls_misc.h:149
#define ENC624J600_REG_ETXST
ENC624J600/ENC424J600 Ethernet controller.
uint8_t opcode
Definition: dns_common.h:172
void enc624j600SetBit(NetInterface *interface, uint8_t address, uint16_t mask)
Set bit field.
#define EIR_PKTIF
int bool_t
Definition: compiler_port.h:49
#define ENC624J600_RX_BUFFER_STOP
#define ESTAT_PHYLNK
#define MACON2_PADCFG2
void macAddrToEui64(const MacAddr *macAddr, Eui64 *interfaceId)
Map a MAC address to the IPv6 modified EUI-64 identifier.
Definition: ethernet.c:800
#define MACON2_FULDPX
#define MICMD_MIIRD
error_t enc624j600ReceivePacket(NetInterface *interface)
Receive a packet.
void enc624j600EventHandler(NetInterface *interface)
ENC624J600 event handler.
uint8_t p
Definition: ndp.h:298
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length)
Handle a packet received by the network controller.
Definition: nic.c:383
#define ENC624J600_CMD_BFSU
void enc624j600DumpReg(NetInterface *interface)
Dump registers for debugging purpose.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:88
#define ENC624J600_REG_ERXRDPT
uint_t chunkCount
Definition: net_mem.h:90
#define MAC_ADDR_FILTER_SIZE
Definition: ethernet.h:74
#define TRUE
Definition: os_port.h:50
uint16_t nextPacket
Next packet in the receive buffer.
#define sleep(delay)
Definition: os_port.h:131
#define MACON2_PADCFG0
#define ETH_MAX_FRAME_SIZE
Definition: ethernet.h:89
#define ENC624J600_REG_ESTAT
void enc624j600ClearBit(NetInterface *interface, uint8_t address, uint16_t mask)
Clear bit field.
#define EIR_TXIF
#define ERXFCON_RUNTEN
uint_t refCount
Reference count for the current entry.
Definition: ethernet.h:223
void enc624j600DisableIrq(NetInterface *interface)
Disable interrupts.
#define ENC624J600_TX_BUFFER_START
#define ECON2_ETHEN
#define EIR_TXABTIF
#define ENC624J600_REG_EIE
#define MACON2_TXCRCEN
void enc624j600EnableIrq(NetInterface *interface)
Enable interrupts.
void * memPoolAlloc(size_t size)
Allocate a memory block.
Definition: net_mem.c:100
#define ENC624J600_REG_MABBIPG
#define ERXFCON_UCEN
#define EIR_LINKIF
#define ENC624J600_REG_EGPWRPT
#define EIE_TXIE
#define MISTAT_BUSY
#define ECON1_TXRTS
#define ECON2_ETHRST
#define ENC624J600_REG_MAADR1
#define ECON1_RXEN
uint16_t length
Definition: net_mem.h:79
#define FALSE
Definition: os_port.h:46
const NicDriver enc624j600Driver
ENC624J600 driver.
error_t
Error codes.
Definition: error.h:42
#define ENC624J600_REG_EIR
#define ENC624J600_REG_EHT3
ENC624J600 driver context.
#define ENC624J600_REG_MAMXFL
void * address
Definition: net_mem.h:78
void enc624j600DumpPhyReg(NetInterface *interface)
Dump PHY registers for debugging purpose.
#define ESTAT_CLKRDY
#define ENC624J600_REG_ERXFCON
Generic error code.
Definition: error.h:45
uint16_t enc624j600ReadPhyReg(NetInterface *interface, uint8_t address)
Read PHY register.
#define ERXFCON_BCEN
#define NetInterface
Definition: net.h:36
MacAddr addr
MAC address.
Definition: ethernet.h:222
#define ENC624J600_CMD_RRXDATA
#define PHSTAT3_SPDDPX1
void enc624j600UpdateMacConfig(NetInterface *interface)
Adjust MAC configuration parameters for proper operation.
#define PHANA_AD10
error_t enc624j600Init(NetInterface *interface)
ENC624J600 controller initialization.
void enc624j600WriteReg(NetInterface *interface, uint8_t address, uint16_t data)
Write ENC624J600 register.
#define ENC624J600_CMD_WCRU
uint8_t mask
Definition: web_socket.h:317
OsEvent netEvent
Definition: net.c:77
error_t enc624j600UpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
#define EIE_PKTIE
error_t enc624j600SendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset)
Send a packet.
#define MSB(x)
Definition: os_port.h:58
#define ENC624J600_REG_ECON1
#define TRACE_INFO(...)
Definition: debug.h:94
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 PHANA_ADPAUS0
#define MIN(a, b)
Definition: os_port.h:62
#define ENC624J600_REG_MAADR3
#define ENC624J600_REG_MISTAT
#define ESTAT_PHYDPX
void enc624j600WritePhyReg(NetInterface *interface, uint8_t address, uint16_t data)
Write PHY register.
#define ENC624J600_REG_EHT1
error_t enc624j600SoftReset(NetInterface *interface)
Reset ENC624J600 controller.
#define MACON2_DEFER
bool_t enc624j600IrqHandler(NetInterface *interface)
ENC624J600 interrupt service routine.
#define ENC624J600_REG_ETXLEN
#define ENC624J600_CMD_WGPDATA
#define ENC624J600_REG_MIRD
#define TRACE_DEBUG(...)
Definition: debug.h:106
#define ESTAT_PKTCNT
#define ENC624J600_CMD_RCRU
ChunkDesc chunk[]
Definition: net_mem.h:92
#define PHSTAT3_SPDDPX2
#define RSV_RECEIVED_OK
#define ETH_MTU
Definition: ethernet.h:91
uint8_t n
MAC filter table entry.
Definition: ethernet.h:220
#define ENC624J600_REG_MIWR
#define ENC624J600_REG_ERXTAIL
#define ENC624J600_REG_MAADR2
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:107
uint32_t enc624j600CalcCrc(const void *data, size_t length)
CRC calculation using the polynomial 0x4C11DB7.
#define MIREGADR_R8
uint16_t enc624j600ReadReg(NetInterface *interface, uint8_t address)
Read ENC624J600 register.
#define ECON1_PKTDEC
#define ENC624J600_PHY_REG_PHSTAT3
uint8_t * rxBuffer
Receive buffer.
#define PHANA_AD100
void enc624j600WriteBuffer(NetInterface *interface, uint8_t opcode, const NetBuffer *buffer, size_t offset)
Write SRAM buffer.
Ipv6Addr address
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
#define PHANA_AD10FD
#define ENC624J600_REG_MACON2
#define ENC624J600_REG_MIREGADR
#define ERXFCON_HTEN
#define MACON2_R1
#define EIE_LINKIE
uint8_t value[]
Definition: dtls_misc.h:150
unsigned int uint_t
Definition: compiler_port.h:45
#define ENC624J600_CMD_BFCU
TCP/IP stack core.
uint8_t data[]
Definition: dtls_misc.h:176
#define PHANA_AD100FD
void enc624j600Tick(NetInterface *interface)
ENC624J600 timer handler.
NIC driver.
Definition: nic.h:179
#define EIE_TXABTIE
#define ENC624J600_REG_ERXST
void enc624j600ReadBuffer(NetInterface *interface, uint8_t opcode, uint8_t *data, size_t length)
Read SRAM buffer.
#define ERXFCON_CRCEN
#define ENC624J600_REG_EHT4
#define ENC624J600_REG_ECON2
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:56
Success.
Definition: error.h:44
Debugging facilities.
#define ENC624J600_REG_EHT2
#define ENC624J600_REG_MICMD
#define PHANA_ADIEEE0
#define ENC624J600_REG_EUDAST
#define ECON2_STRCH
__start_packed struct @108 MacAddr
MAC address.
#define ENC624J600_PHY_REG_PHANA
#define ENC624J600_RX_BUFFER_START
Ethernet interface.
Definition: nic.h:79
#define EIE_INTIE