enc28j60 library  1.0
platform agnostic enc28j60 driver with asynchronous IO support and fully compliant with errata
Classes | Macros | Typedefs | Functions
enc28j60.h File Reference

Part of enc28j60 driver. More...

#include <stdint.h>
#include <stdbool.h>
#include "enc28j60-struct.example.h"
Include dependency graph for enc28j60.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  enc28j60_header
 Structure that has to prefix any variable length data when not using advanced SPI driver (that is when ENC28J60_HAS_ADVANCED_DRIVER is not defined). More...
 
struct  enc28j60_ethernet_header
 Ethernet header. More...
 
struct  enc28j60_txstatus
 Structure that contains data parsed from status footer appended by enc28j60 after frame that was transmitted or which transmission was aborted. More...
 
struct  enc28j60_init_struct
 Structure used for initialization of the enc28j60. More...
 

Macros

#define ENC28J60_MAX_FRAMELEN   1500
 Max frame length which the conroller will accept. More...
 
#define ENC28J60_MAX_FRAMELEN_ETH   1518
 Maximum frame length including ethernet header and checksum.
 
#define ENC28J60_MEMORY_SIZE   0x2000
 Size of the enc28j60's memory.
 

Typedefs

typedef struct enc28j60_header enc28j60_header
 Structure that has to prefix any variable length data when not using advanced SPI driver (that is when ENC28J60_HAS_ADVANCED_DRIVER is not defined). More...
 
typedef struct enc28j60_ethernet_header enc28j60_ethernet_header
 Ethernet header.
 
typedef struct enc28j60_txstatus enc28j60_txstatus
 Structure that contains data parsed from status footer appended by enc28j60 after frame that was transmitted or which transmission was aborted.
 
typedef void(* enc28j60_spi_callback) (enc28j60 *instance, int custom_error_code)
 Callback used internally and externally. More...
 
typedef struct enc28j60_init_struct enc28j60_init_struct
 Structure used for initialization of the enc28j60.
 

Functions

int enc28j60_blockingio (enc28j60 *ins, const char *tx, char *rx, unsigned length)
 Performs IO on enc28j60. More...
 
int enc28j60_ensurebank (enc28j60 *ins, uint8_t bank)
 Ensures that correct bank is currently selected. More...
 
int enc28j60_io8 (enc28j60 *ins, uint8_t op, uint8_t reg, uint8_t val, uint8_t *out)
 Performs given IO operation on given 8-bit register until it succeeds or fails with unrepairable error. More...
 
int enc28j60_io16 (enc28j60 *ins, uint8_t op, uint8_t reg, uint16_t val, uint16_t *out)
 Performs given IO operation on given register 16bit until it succeeds or fails with unrepairable error. More...
 
int enc28j60_read8bitreg (enc28j60 *ins, uint8_t reg, uint8_t *content)
 Read value of given 8-bit register and store it in *content if not content is not null. More...
 
int enc28j60_write8bitreg (enc28j60 *ins, uint8_t reg, uint8_t content)
 Write given value content into given 8-bit register. More...
 
int enc28j60_clear8bitreg (enc28j60 *ins, uint8_t reg, uint8_t content)
 Clears bits given by content from given 8-bit register. More...
 
int enc28j60_set8bitreg (enc28j60 *ins, uint8_t reg, uint8_t content)
 Sets bits given by content in given 8-bit register. More...
 
int enc28j60_read16bitreg (enc28j60 *ins, uint8_t reg, uint16_t *content)
 Read value of given 16-bit register and store it in *content if not content is not null. More...
 
int enc28j60_write16bitreg (enc28j60 *ins, uint8_t reg, uint16_t content)
 Write given value content into given 16-bit register. More...
 
int enc28j60_clear16bitreg (enc28j60 *ins, uint8_t reg, uint16_t content)
 Clears bits given by content from given 16-bit register. More...
 
int enc28j60_set16bitreg (enc28j60 *ins, uint8_t reg, uint16_t content)
 Sets bits given by content in given 16-bit register. More...
 
int enc28j60_readphyreg (enc28j60 *ins, uint8_t reg, uint16_t *content)
 Read from PHY register. More...
 
int enc28j60_writephyreg (enc28j60 *ins, uint8_t reg, uint16_t content)
 Write into PHY register. More...
 
int enc28j60_readrevision (enc28j60 *ins, uint8_t *rev)
 Reads the revision number into *rev. More...
 
int enc28j60_softreset (enc28j60 *ins)
 Sends soft-reset and waits until the enc28j60 is operational again. More...
 
int enc28j60_init (enc28j60 *ins, enc28j60_init_struct *init)
 Initializes the enc28j60. More...
 
int enc28j60_init_bank (enc28j60 *ins)
 Reads the currently selected bank into ins->bank. More...
 
int enc28j60_init_mac (enc28j60 *ins, char mac_addr[6])
 Initializes the MAC address. More...
 
int enc28j60_writewritepointer (enc28j60 *ins, uint16_t ptr)
 Writes the EWRPTL:EWRPTH registers with given value. More...
 
int enc28j60_readwritepointer (enc28j60 *ins, uint16_t *ptr)
 Reads the content of EWRPTL:EWRPTH register into *ptr if ptr is not null. More...
 
int enc28j60_writereadpointer (enc28j60 *ins, uint16_t ptr)
 Writes the ERDPTL:ERDPTH registers with given value. More...
 
int enc28j60_readreadpointer (enc28j60 *ins, uint16_t *ptr)
 Reads the content of ERDPTL:ERDPTH register into *ptr if ptr is not null. More...
 
int enc28j60_init_txbuffer (enc28j60 *ins, uint16_t start, uint16_t length)
 Writes the ETXSTL:ETXSTH and ETXNDL:ETXNDH pointers. More...
 
int enc28j60_write (enc28j60 *ins, uint16_t start_ptr, char *frame, uint16_t length, enc28j60_spi_callback on_finish)
 Writes entire frame into enc28j60's memory. More...
 
int enc28j60_writeframe (enc28j60 *ins, uint8_t control, uint16_t start_ptr, char *frame, uint16_t length, enc28j60_spi_callback on_finish)
 Writes control byte and entire frame into enc28j60's memory. More...
 
int enc28j60_istx (enc28j60 *ins, bool *status)
 Checks whenever the enc28j60 still transmits a frame and writes the corresponding status into *status More...
 
int enc28j60_jointx (enc28j60 *ins)
 Waits until the transmission (if any in progress) finishes and then returns (or in case of unrepairable error it may return sooner). More...
 
int enc28j60_cleartxflags (enc28j60 *ins)
 Clears EIR.TXIF and EIR.TXERIF flags. More...
 
int enc28j60_transmitframe (enc28j60 *ins)
 Sets the ECON1.TXRTS flag in order to start transmission. More...
 
int enc28j60_aftertx (enc28j60 *ins)
 Should be called when transmission finishes in order to avoid bug described in errata #12. More...
 
int enc28j60_readtxstatus (enc28j60 *ins, uint16_t tx_start, uint16_t tx_length, enc28j60_txstatus *status)
 Reads the seven-byte-long status vector written after TXed frame. More...
 
void enc28j60_decrementretries (unsigned *remaining_tries)
 Decrements *remaining_tries (if the pointer is not null) by one. More...
 
bool enc28j60_shouldretransmit (enc28j60_txstatus *status, unsigned remaining_tries)
 Checks for late collision and returns true if late collision happened and remaining_tries is not zero. More...
 
int enc28j60_transmitframeblocking (enc28j60 *ins, uint16_t start_ptr, uint16_t length)
 Writes an ethernet frame of given length into enc28j60's memory starting at given pointer and transmits it with given control flags. More...
 
int enc28j60_read_try (enc28j60 *ins, char *frame, uint16_t length, enc28j60_spi_callback on_finish)
 Try to read from enc28j60's memory. More...
 
int enc28j60_read (enc28j60 *ins, uint16_t ptr, char *rx, uint16_t length, enc28j60_spi_callback on_finish)
 Try to read from enc28j60's memory. More...
 
int enc28j60_readrxframescount (enc28j60 *ins, uint8_t *cnt)
 Reads the number of received frames waiting to be processed in the buffer memory (reds the EPKTCNT register). More...
 
int enc28j60_init_rxbuffer (enc28j60 *ins, uint16_t start, uint16_t end)
 Claims space for RX buffer. More...
 
int enc28j60_readframe (enc28j60 *ins, char *frame, uint16_t max_length, enc28j60_spi_callback on_finish)
 Reads six-bytes-long header and then reads the frame of given max length into memory location pointed to by frame. More...
 
int enc28j60_advancerxreadpointer (enc28j60 *ins)
 Writes the ERXRDPTL:ERXRDPTH registers-pointer with appropriate value to free up space in the buffer. More...
 
int enc28j60_finishreadframe (enc28j60 *ins)
 Writes the ERXRDPTL:ERXRDPTH registers-pointer with appropriate value to free up space in the buffer and decrements EPKTCNT register by one. More...
 
int enc28j60_receiveframeblocking (enc28j60 *ins, char *frame, uint16_t max_length, enc28j60_tick timeout)
 Wait until there is frame available in the buffer, read it into local memory, do cleanup and return. More...
 
int enc28j60_enablerx (enc28j60 *ins)
 Enable reception of frames. More...
 
int enc28j60_disablerx (enc28j60 *ins)
 Disable reception of frames. More...
 
int enc28j60_discardcrcerrors (enc28j60 *ins, bool discard)
 Discard frames that have invalid CRC checksum present. More...
 
int enc28j60_enablemulticast (enc28j60 *ins, bool enable)
 Enable reception of frames with multicast destination address. More...
 
int enc28j60_enablebroadcast (enc28j60 *ins, bool enable)
 Enable reception of frames with broadcast destination address. More...
 

Detailed Description

Part of enc28j60 driver.

Author
Dalibor Drgon dalib.nosp@m.or.d.nosp@m.rgon@.nosp@m.gmai.nosp@m.l.com
Version
1.0
Date
2020-05-01

Macro Definition Documentation

◆ ENC28J60_MAX_FRAMELEN

#define ENC28J60_MAX_FRAMELEN   1500

Max frame length which the conroller will accept.

Both for RX and TX. This means that we can store up to 5 full frames.

Typedef Documentation

◆ enc28j60_header

Structure that has to prefix any variable length data when not using advanced SPI driver (that is when ENC28J60_HAS_ADVANCED_DRIVER is not defined).

The correct allocation and usage is as follows:

enc28j60 eth1;
//...
static char data[ENC28J60_MAX_FRAME_LENGTH_ETH + sizeof(enc28j60_header)];
enc28j60_receiveframeblocking(&eth1, data, sizeof(data));
printf("Received frame of length %u\n", eth1.length);
char *frame = &data[sizeof(enc28j60_header)];
printf("First byte is %02X, the last is %02X\n", frame[0], frame[eth1.length-1]);

◆ enc28j60_spi_callback

typedef void(* enc28j60_spi_callback) (enc28j60 *instance, int custom_error_code)

Callback used internally and externally.

Accepts pointer to enc28j60 and error code indicating result (0 means success, anything else is treated as error).

Function Documentation

◆ enc28j60_blockingio()

int enc28j60_blockingio ( enc28j60 ins,
const char *  tx,
char *  rx,
unsigned  length 
)

Performs IO on enc28j60.

Internally, this calls enc28j60_spi_transfer() until it succeedes or fails with unrepairable error. Because of this, the request has to be repeatable (has to be read/write to register, cannot be read/write to buffer memory as the read and write pointers get internally incremented) in case the transfer fails and is repeated.

Parameters
insEnc28j60 pointer
txNon-null pointer to buffer to be transmitted
rxPointer where the received data will be saved (can be null)
lengthLength of the tx and rx buffers.
Returns
int Zero on success or non-zero error in case of unrepairable error.

◆ enc28j60_ensurebank()

int enc28j60_ensurebank ( enc28j60 ins,
uint8_t  bank 
)

Ensures that correct bank is currently selected.

Parameters
insEnc28j60 pointer
bankRegister bank to be selected
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_io8()

int enc28j60_io8 ( enc28j60 ins,
uint8_t  op,
uint8_t  reg,
uint8_t  val,
uint8_t *  out 
)

Performs given IO operation on given 8-bit register until it succeeds or fails with unrepairable error.

Parameters
insEnc28j60 pointer
opOperation to be performed
regRegister on which the operation will be performed
valValue to be sent
outIf not null, read value will be written here.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_io16()

int enc28j60_io16 ( enc28j60 ins,
uint8_t  op,
uint8_t  reg,
uint16_t  val,
uint16_t *  out 
)

Performs given IO operation on given register 16bit until it succeeds or fails with unrepairable error.

Parameters
insEnc28j60 pointer
opOperation to be performed
regRegister on which the operation will be performed
valValue to be sent
outIf not null, read value will be written here.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_read8bitreg()

int enc28j60_read8bitreg ( enc28j60 ins,
uint8_t  reg,
uint8_t *  content 
)

Read value of given 8-bit register and store it in *content if not content is not null.

Parameters
insEnc28j60 pointer
regRegister from which to read.
contentIf not null, read value will be written here.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_write8bitreg()

int enc28j60_write8bitreg ( enc28j60 ins,
uint8_t  reg,
uint8_t  content 
)

Write given value content into given 8-bit register.

Parameters
insEnc28j60 pointer
regRegister to be modified
contentNew value of the register.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_clear8bitreg()

int enc28j60_clear8bitreg ( enc28j60 ins,
uint8_t  reg,
uint8_t  content 
)

Clears bits given by content from given 8-bit register.

Parameters
insEnc28j60 pointer
regRegister to be modified
contentBits to be cleared
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_set8bitreg()

int enc28j60_set8bitreg ( enc28j60 ins,
uint8_t  reg,
uint8_t  content 
)

Sets bits given by content in given 8-bit register.

Parameters
insEnc28j60 pointer
regRegister to be modified
contentBits to be set
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_read16bitreg()

int enc28j60_read16bitreg ( enc28j60 ins,
uint8_t  reg,
uint16_t *  content 
)

Read value of given 16-bit register and store it in *content if not content is not null.

Parameters
insEnc28j60 pointer
regRegister from which to read.
contentIf not null, read value will be written here.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_write16bitreg()

int enc28j60_write16bitreg ( enc28j60 ins,
uint8_t  reg,
uint16_t  content 
)

Write given value content into given 16-bit register.

Parameters
insEnc28j60 pointer
regRegister to be modified
contentNew value of the register.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_clear16bitreg()

int enc28j60_clear16bitreg ( enc28j60 ins,
uint8_t  reg,
uint16_t  content 
)

Clears bits given by content from given 16-bit register.

Parameters
insEnc28j60 pointer
regRegister to be modified
contentBits to be cleared
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_set16bitreg()

int enc28j60_set16bitreg ( enc28j60 ins,
uint8_t  reg,
uint16_t  content 
)

Sets bits given by content in given 16-bit register.

Parameters
insEnc28j60 pointer
regRegister to be modified
contentBits to be set
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_readphyreg()

int enc28j60_readphyreg ( enc28j60 ins,
uint8_t  reg,
uint16_t *  content 
)

Read from PHY register.

Parameters
insEnc28j60 pointer
regRegister to be read
contentWhere to write the register value
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_writephyreg()

int enc28j60_writephyreg ( enc28j60 ins,
uint8_t  reg,
uint16_t  content 
)

Write into PHY register.

Parameters
insEnc28j60 pointer
regRegister to be written
contentNew value of the register
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_readrevision()

int enc28j60_readrevision ( enc28j60 ins,
uint8_t *  rev 
)

Reads the revision number into *rev.

Parameters
insEnc28j60 pointer
revIf not null, revision number will be stored here.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_softreset()

int enc28j60_softreset ( enc28j60 ins)

Sends soft-reset and waits until the enc28j60 is operational again.

Implementation compliant with errata #2 and #19.

Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_init()

int enc28j60_init ( enc28j60 ins,
enc28j60_init_struct init 
)

Initializes the enc28j60.

Compliant with errata #9.

Parameters
insEnc28j60 pointer
mac_addr6 bytes long MAC address to be set.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_init_bank()

int enc28j60_init_bank ( enc28j60 ins)

Reads the currently selected bank into ins->bank.

Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_init_mac()

int enc28j60_init_mac ( enc28j60 ins,
char  mac_addr[6] 
)

Initializes the MAC address.

Parameters
insEnc28j60 pointer
mac_addr6 bytes long MAC address to be set.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_writewritepointer()

int enc28j60_writewritepointer ( enc28j60 ins,
uint16_t  ptr 
)

Writes the EWRPTL:EWRPTH registers with given value.

Parameters
insEnc28j60 pointer
ptrValue to be written into EWRPTL:EWRPTH register
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_readwritepointer()

int enc28j60_readwritepointer ( enc28j60 ins,
uint16_t *  ptr 
)

Reads the content of EWRPTL:EWRPTH register into *ptr if ptr is not null.

Parameters
insEnc28j60 pointer
ptrIf not null, it's where the value of EWRPTL:EWRPTH registers will be written to.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_writereadpointer()

int enc28j60_writereadpointer ( enc28j60 ins,
uint16_t  ptr 
)

Writes the ERDPTL:ERDPTH registers with given value.

Parameters
insEnc28j60 pointer
ptrValue to be written into ERDPTL:ERDPTH register
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_readreadpointer()

int enc28j60_readreadpointer ( enc28j60 ins,
uint16_t *  ptr 
)

Reads the content of ERDPTL:ERDPTH register into *ptr if ptr is not null.

Parameters
insEnc28j60 pointer
ptrIf not null, it's where the value of ERDPTL:ERDPTH registers will be written to.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_init_txbuffer()

int enc28j60_init_txbuffer ( enc28j60 ins,
uint16_t  start,
uint16_t  length 
)

Writes the ETXSTL:ETXSTH and ETXNDL:ETXNDH pointers.

NOTE: The last argument is length and not a pointer to end of the frame.

See also
enc28j60_transmitframe()
Parameters
insEnc28j60 pointer
startWhere the frame starts in buffer memory
lengthHow long the frame is (including the opcode if not using advanced SPI driver)
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_write()

int enc28j60_write ( enc28j60 ins,
uint16_t  start_ptr,
char *  frame,
uint16_t  length,
enc28j60_spi_callback  on_finish 
)

Writes entire frame into enc28j60's memory.

See also
enc28j60_transmitframe()
Parameters
insEnc28j60 pointer
start_ptrWhere the frame starts in enc28j60's memory
frameThe frame to be written.
lengthHow long the frame is
on_finishCallback to be called when the frame is written to the memory. If not null and if the underlying driver supports asynchronous transfer, this function will be asynchronous and this callback will get called once the transfer finishes with appropriate error code. Otherwise this transfer will be blocking and return the appropriate error code.
Returns
int If on_finish callback is not null, zero is returned and error code is passed to on_finish callback. Otherwise if given callback is null, zero is returned on succes and non-zero error in case of unrepairable error.

◆ enc28j60_writeframe()

int enc28j60_writeframe ( enc28j60 ins,
uint8_t  control,
uint16_t  start_ptr,
char *  frame,
uint16_t  length,
enc28j60_spi_callback  on_finish 
)

Writes control byte and entire frame into enc28j60's memory.

See also
enc28j60_transmitframe()
Parameters
insEnc28j60 pointer
controlThe control byte written before the frame. See ENC28J60_PKTCTRL_* macros.
start_ptrWhere the frame starts in enc28j60's memory
frameThe frame to be written.
lengthHow long the frame is
on_finishCallback to be called when the frame is written to the memory. If not null and if the underlying driver supports asynchronous transfer, this function will be asynchronous and this callback will get called once the transfer finishes with appropriate error code. Otherwise this transfer will be blocking and return the appropriate error code.
Returns
int If on_finish callback is not null, zero is returned and error code is passed to on_finish callback. Otherwise if given callback is null, zero is returned on succes and non-zero error in case of unrepairable error.

◆ enc28j60_istx()

int enc28j60_istx ( enc28j60 ins,
bool *  status 
)

Checks whenever the enc28j60 still transmits a frame and writes the corresponding status into *status

The transmission state should be checked before calling enc28j60_transmitframe().

Parameters
insEnc28j60 pointer
statusIf not null, the status (true when still transmitting) will be written here.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_jointx()

int enc28j60_jointx ( enc28j60 ins)

Waits until the transmission (if any in progress) finishes and then returns (or in case of unrepairable error it may return sooner).

Internally just uses enc28j60_istx().

See also
enc28j60_istx()
Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

TODO: When there is not enough current during transmission, the enc28j60 bugs and ECON1.TXRTS remainins set infinitely. Make sure to add some protection against that, by for example time out.

◆ enc28j60_cleartxflags()

int enc28j60_cleartxflags ( enc28j60 ins)

Clears EIR.TXIF and EIR.TXERIF flags.

Should be called after a frame finishes transmission or before starting new transmission.

Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_transmitframe()

int enc28j60_transmitframe ( enc28j60 ins)

Sets the ECON1.TXRTS flag in order to start transmission.

Before calling this make sure that there is no ongoing tranmission already taking place (by calling eithet enc28j60_istx() or enc28j60_jointx()).

Example usage (using advanced SPI driver. If you are not using version with advanced SPI driver, simply change the type of tx_frame from char* to enc28j60_header*):

int writeandtransmitframeblocking(uint16_t tx_start, char *tx_frame, uint16_t tx_length) {
enc28j60_writeframe(&eth1, 0, tx_start, tx_frame, tx_length, NULL);
enc28j60_init_txbuffer(&eth1, tx_start, tx_length);
unsigned remaining_retries = 16;
do {
enc28j60_readtxstatus(&eth1, tx_start, tx_length, &status);
enc28j60_decrementretries(&remaining_retries);
} while(enc28j60_shouldretransmit(&status, remaining_retries));
}
See also
enc28j60_cleartxflags()
enc28j60_istx()
enc28j60_jointx()
enc28j60_readtxstatus()
enc28j60_decrementretries()
enc28j60_shouldretransmit()
enc28j60_transmitframeblocking()
Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_aftertx()

int enc28j60_aftertx ( enc28j60 ins)

Should be called when transmission finishes in order to avoid bug described in errata #12.

NOTE: Make sure to call this before enc28j60_cleartxflags().

Example usage (using advanced SPI driver. If you are not using version with advanced SPI driver, simply change the type of tx_frame from char* to enc28j60_header*):

enc28j60 eth1;
int transmitframeblocking(uint16_t tx_start, char *tx_frame, uint16_t tx_length) {
enc28j60_writeframe(&eth1, 0, tx_start, tx_frame, tx_length, NULL);
enc28j60_init_txbuffer(&eth1, tx_start, tx_length);
unsigned remaining_retries = 16;
do {
enc28j60_readtxstatus(&eth1, tx_start, tx_length, &status);
enc28j60_decrementretries(&remaining_retries);
} while(enc28j60_shouldretransmit(&status, remaining_retries));
}
See also
enc28j60_transmitframe()
Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_readtxstatus()

int enc28j60_readtxstatus ( enc28j60 ins,
uint16_t  tx_start,
uint16_t  tx_length,
enc28j60_txstatus status 
)

Reads the seven-byte-long status vector written after TXed frame.

Useful to determine whenever ENC28J60_TXSTATUS_LATE_COLLISION happened because of errata #15.

See also
enc28j60_transmitframe()
Parameters
insEnc28j60 pointer
tx_startWhere the frame starts in enc28j60's memory
tx_lengthHow long the frame is (including the opcode if not using advanced SPI driver)
statusWhere the parsed data will be written to.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_decrementretries()

void enc28j60_decrementretries ( unsigned *  remaining_tries)

Decrements *remaining_tries (if the pointer is not null) by one.

Added just for better readability?

Parameters
remaining_triesPointing to variable to be decremented by one.

◆ enc28j60_shouldretransmit()

bool enc28j60_shouldretransmit ( enc28j60_txstatus status,
unsigned  remaining_tries 
)

Checks for late collision and returns true if late collision happened and remaining_tries is not zero.

Otherwise returns false.

This function was added so that code that is compliant with advice for errata #13 can be easily written.

See also
enc28j60_transmitframe()
Parameters
statusRead status used for status checking
remaining_triesHow many retries are there remaing
Returns
true When late collision happened and remaing_tries != 0
false When late collision did not happen or remaining_tries == 0

◆ enc28j60_transmitframeblocking()

int enc28j60_transmitframeblocking ( enc28j60 ins,
uint16_t  start_ptr,
uint16_t  length 
)

Writes an ethernet frame of given length into enc28j60's memory starting at given pointer and transmits it with given control flags.

Compliant with errata #12, #13 and #15.

The functionality of this function can be summarised by the following code (not including the error checks for simplicity and readability and not including enc28j60 pointer but using static enc28j60 instance instead):

enc28j60 eth1;
int transmitframeblocking(uint16_t tx_start, uint16_t tx_length) {
unsigned remaining_retries = 16;
do {
enc28j60_readtxstatus(&eth1, tx_start, tx_length, &status);
enc28j60_decrementretries(&remaining_retries);
} while(enc28j60_shouldretransmit(&status, remaining_retries));
}

Example usage (without error checks):

enc28j60_writeframe(&eth1, 0, tx_start, tx_frame, tx_frame_length, NULL);
enc28j60_init_txbuffer(&eth1, tx_start, tx_frame_length);
enc28j60_transmitframeblocking(&eth1, tx_start, tx_frame_length);
See also
enc28j60_transmitframe()
Parameters
insEnc28j60 pointer
start_ptrWhere the frame starts in enc28j60's memory
lengthHow long the frame is (including the opcode if not using advanced SPI driver)
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_read_try()

int enc28j60_read_try ( enc28j60 ins,
char *  frame,
uint16_t  length,
enc28j60_spi_callback  on_finish 
)

Try to read from enc28j60's memory.

If callback is present and underlying SPI driver supports it, this request is asynchronous. In case of any error, no retrying will be done and resulting error code will be immediately returned (or passed via a callback) to the user.

Do not forget to set read pointer by calling enc28j60_writereadpointer()

See also
enc28j60_writereadpointer()
Parameters
insEnc28j60 pointer
frameThe data will be read there.
lengthLength of the data to read.
on_finishCallback, optional, may be null. If not null and the underlying SPI driver supports asynchronous requests, the request will be asynchronous, the resulting error code will be handled over to given callback and zero will be returned. Otherwise if the SPI driver does not support asynchronous operation, or this callback is null, we will operate in synchronous mode and resulting error code will be returned.
Returns
int Zero on succes or non-zero error in case of error.

◆ enc28j60_read()

int enc28j60_read ( enc28j60 ins,
uint16_t  ptr,
char *  rx,
uint16_t  length,
enc28j60_spi_callback  on_finish 
)

Try to read from enc28j60's memory.

If callback is present and underlying SPI driver supports it, this request is asynchronous. In case of any repairable error, we will retry until either succeding or failing with unrepairable error.

Parameters
insEnc28j60 pointer
ptrWhere to start reading from (pointer to enc28j60's memory)
frameThe data will be read there.
lengthLength of the data to read.
on_finishCallback, optional, may be null. If not null and the underlying SPI driver supports asynchronous requests, the request will be asynchronous, the resulting error code will be handled over to given callback and zero will be returned. Otherwise if the SPI driver does not support asynchronous operation, or this callback is null, we will operate in synchronous mode and resulting error code will be returned.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_readrxframescount()

int enc28j60_readrxframescount ( enc28j60 ins,
uint8_t *  cnt 
)

Reads the number of received frames waiting to be processed in the buffer memory (reds the EPKTCNT register).

NOTE: Use this to check whenever there are any frames in the rx buffer.

Parameters
insEnc28j60 pointer
cntIf not null, the number of packets read will be written here.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_init_rxbuffer()

int enc28j60_init_rxbuffer ( enc28j60 ins,
uint16_t  start,
uint16_t  end 
)

Claims space for RX buffer.

NOTE: To be compliant with errata #5, make sure that the buffer starts at address 0000h.

Parameters
insEnc28j60 pointer
startStart (first byte pointer) of the RX buffer.
endEnd (last byte pointer) of the RX buffer.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_readframe()

int enc28j60_readframe ( enc28j60 ins,
char *  frame,
uint16_t  max_length,
enc28j60_spi_callback  on_finish 
)

Reads six-bytes-long header and then reads the frame of given max length into memory location pointed to by frame.

Also updates enc28j60.rxstatus (see ENC28J60_RXSTATUS_* flags for testing) and fills enc28j60.length with the original length.

Before calling, make sure that there is frame in the buffer by checking the value read from enc28j60_readrxframescount(), otherwise corruption of localy stored pointers will happen and garbage will be read from enc28j60's memory.

See also
enc28j60_receiveframeblocking()
enc28j60_enablerx()
enc28j60_finishreadframe()
Parameters
insEnc28j60 pointer
frameThe frame will be read there.
max_lengthMax length of the frame.
on_finishCallback, optional, may be null. If not null and the underlying SPI driver supports asynchronous requests, the request will be asynchronous, the resulting error code will be handled over to given callback and zero will be returned. Otherwise if the SPI driver does not support asynchronous operation, or this callback is null, we will operate in synchronous mode and resulting error code will be returned.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_advancerxreadpointer()

int enc28j60_advancerxreadpointer ( enc28j60 ins)

Writes the ERXRDPTL:ERXRDPTH registers-pointer with appropriate value to free up space in the buffer.

Compliant with errata #14.

Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_finishreadframe()

int enc28j60_finishreadframe ( enc28j60 ins)

Writes the ERXRDPTL:ERXRDPTH registers-pointer with appropriate value to free up space in the buffer and decrements EPKTCNT register by one.

Should be called after frame is received and read from the buffer.

Internally uses enc28j60_advancerxreadpointer(), compliant with errata #14.

See also
enc28j60_receiveframeblocking()
enc28j60_enablerx()
enc28j60_readframe()
Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_receiveframeblocking()

int enc28j60_receiveframeblocking ( enc28j60 ins,
char *  frame,
uint16_t  max_length,
enc28j60_tick  timeout 
)

Wait until there is frame available in the buffer, read it into local memory, do cleanup and return.

If timeout is not zero, the time spent waiting will be limited to given number of ticks. Also updates enc28j60.rxstatus (see ENC28J60_RXSTATUS_* flags for testing) and fills enc28j60.length with the original length.

If you don't want this functioon to block, make sure to check number of received frames by calling enc28j60_readrxframescount(). If there is at least one frame in the memory stored already, this function won't block.

The functionality with timeout=0 is as following (not including error checks):

void receiveframeblocking(enc28j60 *ins, char *frame, uint16_t frame_len) {
uint8_t cnt;
do {
// Loop until we have received any frame
} while(cnt == 0);
enc28j60_readframe(ins, frame, frame_len, NULL);
}
See also
enc28j60_enablerx()
enc28j60_readframe()
enc28j60_finishreadframe()
Parameters
insEnc28j60 pointer
frameWhere the frame will be written to.
max_lengthMaximum length of the frame
timeoutTimeout - how many ticks to wait at max before returning. If zero, the enc28j60 will wait infinitely long for a frame.
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_enablerx()

int enc28j60_enablerx ( enc28j60 ins)

Enable reception of frames.

Sets ECON1.RXEN bit in order to enable reception of ethernet frames.

See also
enc28j60_receiveframeblocking()
enc28j60_readframe()
enc28j60_finishreadframe()
enc28j60_disablerx()
Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_disablerx()

int enc28j60_disablerx ( enc28j60 ins)

Disable reception of frames.

Clear ECON1.RXEN bit and waits until ESTAT.RXBUSY is clearead.

See also
enc28j60_enablerx()
Parameters
insEnc28j60 pointer
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_discardcrcerrors()

int enc28j60_discardcrcerrors ( enc28j60 ins,
bool  discard 
)

Discard frames that have invalid CRC checksum present.

Parameters
insEnc28j60 pointer
discardtrue to discard packets with invalid CRC, false to keep them
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_enablemulticast()

int enc28j60_enablemulticast ( enc28j60 ins,
bool  enable 
)

Enable reception of frames with multicast destination address.

Parameters
insEnc28j60 pointer
discardtrue to enable reception of frames with multicast destination, false to ignore them
Returns
int Zero on succes or non-zero error in case of unrepairable error.

◆ enc28j60_enablebroadcast()

int enc28j60_enablebroadcast ( enc28j60 ins,
bool  enable 
)

Enable reception of frames with broadcast destination address.

Parameters
insEnc28j60 pointer
discardtrue to enable reception of frames with broadcast destination, false to ignore them
Returns
int Zero on succes or non-zero error in case of unrepairable error.