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