# MIOS32_ENC28J60

## Defines
#define | MIOS32_ENC28J60_MUTEX_TAKE {}
#define | MIOS32_ENC28J60_MUTEX_GIVE {}
#define | WCR (0x2<<5)
#define | BFS (0x4<<5)
#define | BFC (0x5<<5)
#define | RCR (0x0<<5)
#define | RBM ((0x1<<5) | 0x1A)
#define | WBM ((0x3<<5) | 0x1A)
#define | SR ((0x7<<5) | 0x1F)
#define | CSN_0 { MIOS32_SPI_RC_PinSet(MIOS32_ENC28J60_SPI, MIOS32_ENC28J60_SPI_RC_PIN, 0); }
#define | CSN_1 { MIOS32_SPI_RC_PinSet(MIOS32_ENC28J60_SPI, MIOS32_ENC28J60_SPI_RC_PIN, 1); }
#define | RAMSIZE 0x2000
#define | RXSTART 0x0000
#define | RXEND 0x0FFF
#define | TXSTART 0x1000
#define | TXEND 0x1fff
#define | RXSTOP ((TXSTART - 2) | 0x0001)
#define | RXSIZE (RXSTOP - RXSTART + 1)
## Functions
struct | __attribute__ ((packed))
s32 | MIOS32_ENC28J60_Init (u32 mode)
s32 | MIOS32_ENC28J60_PowerOn (void)
s32 | MIOS32_ENC28J60_PowerOff (void)
s32 | MIOS32_ENC28J60_CheckAvailable (u8 was_available)
s32 | MIOS32_ENC28J60_LinkAvailable (void)
s32 | MIOS32_ENC28J60_RevIDGet (void)
s32 | MIOS32_ENC28J60_MAC_AddrSet (u8 new_mac_addr[6])
u8 * | MIOS32_ENC28J60_MAC_AddrGet (void)
s32 | MIOS32_ENC28J60_PackageSend (u8 *buffer, u16 len, u8 *buffer2, u16 len2)
s32 | MIOS32_ENC28J60_PackageReceive (u8 *buffer, u16 buffer_size)
s32 | MIOS32_ENC28J60_MACDiscardRx (void)
s32 | MIOS32_ENC28J60_ReadETHReg (u8 address)
s32 | MIOS32_ENC28J60_ReadMACReg (u8 address)
s32 | MIOS32_ENC28J60_ReadPHYReg (u8 reg)
s32 | MIOS32_ENC28J60_WriteReg (u8 address, u8 data)
s32 | MIOS32_ENC28J60_BFCReg (u8 address, u8 data)
s32 | MIOS32_ENC28J60_BFSReg (u8 address, u8 data)
s32 | MIOS32_ENC28J60_WritePHYReg (u8 reg, u16 data)
s32 | MIOS32_ENC28J60_BankSel (u16 reg)
s32 | MIOS32_ENC28J60_SendSystemReset (void)
s32 | MIOS32_ENC28J60_MACGet (void)
s32 | MIOS32_ENC28J60_MACGetArray (u8 *buffer, u16 len)
s32 | MIOS32_ENC28J60_MACPut (u8 value)
s32 | MIOS32_ENC28J60_MACPutArray (u8 *buffer, u16 len)
## Variables
| ENC_PREAMBLE

## Detailed Description

ENC28J60 is accessed via SPI1 (J16) or alternatively via SPI2 (J8/9) A bitbanging solution (for using alternative ports) will be provided later.

The chip has to be supplied with 3.3V!

MIOS32_ENC28J60_Init(0) has to be called only once to initialize the driver.

MIOS32_ENC28J60_CheckAvailable() should be called to connect with the device. If 0 is returned, it can be assumed that no ENC28J60 chip is connected. The function can be called periodically from a low priority task to retry a connection, resp. for an auto-detection during runtime

Most parts of the driver have been taken from ENC28J60.c file of the Microchip TCP/IP stack, and adapted to MIOS32 routines.

philetaylor (07 Jan 10): I have added mutex support. As many functions are not used externally they rely on the mutex being taked/given by the calling function. Please bear this in mind if calling functions directly. Only MIOS32_ENC28J60_Init(), MIOS32_ENC28J60_CheckAvailable() MIOS32_ENC28J60_PackageSend() and MIOS32_ENC28J60_PackageReceive() Will handle mutexes themselves all other functions will not.

## Define Documentation

#define BFC (0x5<<5)

#define BFS (0x4<<5)

#define CSN_0 { MIOS32_SPI_RC_PinSet(MIOS32_ENC28J60_SPI, MIOS32_ENC28J60_SPI_RC_PIN, 0); }

#define CSN_1 { MIOS32_SPI_RC_PinSet(MIOS32_ENC28J60_SPI, MIOS32_ENC28J60_SPI_RC_PIN, 1); }

#define MIOS32_ENC28J60_MUTEX_GIVE {}

#define MIOS32_ENC28J60_MUTEX_TAKE {}

#define RAMSIZE 0x2000

#define RBM ((0x1<<5) | 0x1A)

#define RCR (0x0<<5)

#define RXEND 0x0FFF

#define RXSIZE (RXSTOP - RXSTART + 1)

#define RXSTART 0x0000

#define RXSTOP ((TXSTART - 2) | 0x0001)

#define SR ((0x7<<5) | 0x1F)

#define TXEND 0x1fff

#define TXSTART 0x1000

#define WBM ((0x3<<5) | 0x1A)

#define WCR (0x2<<5)

## Function Documentation

struct __attribute__ | ( | (packed) |  | ) | `[read]`

s32 MIOS32_ENC28J60_BankSel | ( | u16 | reg | ) |

Takes the high byte of a register address and changes the bank select bits in ETHCON1 to match.

Parameters:

  `[in]` | reg | Register address with the high byte containing the two bank select bits.

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_BFCReg | ( | u8 | address,
|  | u8 | data |
| ) |  |  |

Sends the 8 bit BFC opcode/Address byte over the SPI and then sends the data in the next 8 SPI clocks

This routine is almost identical to the MIOS32_ENC28J60_WriteReg() and MIOS32_ENC28J60_BFSReg() functions. It is separate to maximize speed.

MIOS32_ENC28J60_BFCReg() must only be used on ETH registers.

Parameters:

  `[in]` | address | 5 bit address of the register to modify. The top 3 bits must be 0
  `[in]` | data | Byte to be used with the Bit Field Clear operation

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_BFSReg | ( | u8 | address,
|  | u8 | data |
| ) |  |  |

Sends the 8 bit BFS opcode/Address byte over the SPI and then sends the data in the next 8 SPI clocks

This routine is almost identical to the MIOS32_ENC28J60_WriteReg() and MIOS32_ENC28J60_BFCReg() functions. It is separate to maximize speed.

MIOS32_ENC28J60_BFSReg() must only be used on ETH registers.

Parameters:

  `[in]` | address | 5 bit address of the register to modify. The top 3 bits must be 0
  `[in]` | data | Byte to be used with the Bit Field Set operation

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_CheckAvailable | ( | u8 | was_available | ) |

Checks if the chip is still connected by reading the revision ID.
This takes ca. 2 uS

If the ID value is within the range of 0x01..0x1f, MIOS32_ENC28J60_PowerOn() will be called by this function to initialize the device completely.

Example for Connection/Disconnection detection:

     // this function is called each second from a low-priority task
     // If multiple tasks are accessing the ENC28J60 chip, add a semaphore/mutex
     //  to avoid IO access collisions with other tasks!
     u8 enc28j60_available;
     s32 ETHERNET_CheckENC28J60(void)
     {
       // check if ENC28J60 is connected
       u8 prev_enc28j60_available = enc28j60_available;
       enc28j60_available = MIOS32_ENC28J60_CheckAvailable(prev_enc28j60_available);

       if( enc28j60_available && !prev_enc28j60_available ) {
         // ENC28J60 has been connected

         // now it's possible to receive/send packages

       } else if( !enc28j60_available && prev_enc28j60_available ) {
         // ENC28J60 has been disconnected

         // here you can notify your application about this state
       }

       return 0; // no error
     }

Parameters:

  `[in]` | was_available | should only be set if the ENC28J60 was previously available

Returns:
  0 if no response from ENC28J60
  1 if ENC28J60 is accessible

Here is the call graph for this function:

s32 MIOS32_ENC28J60_Init | ( | u32 | mode | ) |

Initializes SPI pins and peripheral to access ENC28J60

Parameters:

  `[in]` | mode | currently only mode 0 supported

Returns:
  < 0 if initialisation failed

Here is the call graph for this function:

s32 MIOS32_ENC28J60_LinkAvailable | ( | void |  | ) |

Returns the PHSTAT1.LLSTAT bit (ethernet cable connected)

Returns:
  0 if ethernet cable not connected
  1 if ethernet cable connected and link available

Here is the call graph for this function:

u8* MIOS32_ENC28J60_MAC_AddrGet | ( | void |  | ) |

Returns the current MAC address

Returns:
  u8 pointer with 6 bytes

s32 MIOS32_ENC28J60_MAC_AddrSet | ( | u8 | new_mac_addr[6] | ) |

Changes the MAC address.

Usually called by MIOS32_ENC28J60_PowerOn(), but could also be used during runtime.

The default MAC address is predefined by MIOS32_ENC28J60_MY_MAC_ADDR[123456] and can be overruled in mios32_config.h if desired.

Parameters:

  `[in]` | new_mac_addr | an array with 6 bytes which define the MAC address. If all bytes are 0 (default), the serial number of STM32 will be taken instead, which should be unique in your private network.

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_MACDiscardRx | ( | void |  | ) |

Marks the last received packet (obtained using MIOS32_ENC28J60_PackageReceive()) as being processed and frees the buffer memory associated with it

It is safe to call this function multiple times between MIOS32_ENC28J60_PackageReceive() calls. Extra packets won't be thrown away until MIOS32_ENC28J60_PackageReceive() makes it available.

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_MACGet | ( | void |  | ) |

Returns the byte pointed to by ERDPT and increments ERDPT so MIOS32_ENC28J60_MACGet() can be called again. The increment will follow the receive buffer wrapping boundary.

EWRPT is incremented after the read.

Returns:
  < 0 on errors
  >= 0: Byte read from the ENC28J60's RAM

Here is the call graph for this function:

s32 MIOS32_ENC28J60_MACGetArray | ( | u8 * | buffer,
|  | u16 | len |
| ) |  |  |

Burst reads several sequential bytes from the data buffer and places them into local memory. With SPI burst support, it performs much faster than multiple MIOS32_ENC28J60_MACGet() calls.

ERDPT is incremented after each byte, following the same rules as MIOS32_ENC28J60_MACGet()

Parameters:

  `[in]` | buffer | target buffer
  `[in]` | len | number of bytes which should be read

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_MACPut | ( | u8 | value | ) |

Outputs the Write Buffer Memory opcode/constant (8 bits) and data to write (8 bits) over the SPI.

EWRPT is incremented after the write.

Parameters:

  `[in]` | value | Byte to write into the ENC28J60 buffer memory

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_MACPutArray | ( | u8 * | buffer,
|  | u16 | len |
| ) |  |  |

writes several sequential bytes to the ENC28J60 RAM. It performs faster than multiple MIOS32_ENC28J60_MACPut() calls.

EWRPT is incremented by len.

Parameters:

  `[in]` | buffer | source buffer
  `[in]` | len | number of bytes which should be written

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_PackageReceive | ( | u8 * | buffer,
|  | u16 | buffer_size |
| ) |  |  |

Receives a package from ENC28J60 chip param[in] buffer Pointer to buffer which gets the playload param[in] buffer_size Max. number of bytes which can be received

Returns:
  < 0 on errors
  -16 if inconsistencies have been detected, and the ENC28J60 device has been reseted
  0 if no package has been received
  > 0 number of received bytes

Here is the call graph for this function:

s32 MIOS32_ENC28J60_PackageSend | ( | u8 * | buffer,
|  | u16 | len,
|  | u8 * | buffer2,
|  | u16 | len2 |
| ) |  |  |

Sends a package to the ENC28J60 chip param[in] buffer Pointer to buffer which contains the playload param[in] len number of bytes which should be sent param[in] buffer2 Pointer to optional second buffer which contains additional playload (can be NULL if no additional data) param[in] len2 number of bytes in second buffer (should be 0 if no additional data)

Returns:
  < 0 on errors
  -16 if previous package hasn't been sent yet (this is checked 1000 times before the function exits)

Here is the call graph for this function:

s32 MIOS32_ENC28J60_PowerOff | ( | void |  | ) |

Disconnects from ENC28J60

Returns:
  < 0 on errors

Todo:
  not implemented yet

s32 MIOS32_ENC28J60_PowerOn | ( | void |  | ) |

Connects to ENC28J60 chip

Returns:
  < 0 if initialisation sequence failed
  -16 if clock not ready after system reset
  -17 if unsupported revision ID

Here is the call graph for this function:

s32 MIOS32_ENC28J60_ReadETHReg | ( | u8 | address | ) |

Sends the 8 bit RCR opcode/Address byte over the SPI and then retrives the register contents in the next 8 SPI clocks.

This routine cannot be used to access MAC/MII or PHY registers. Use MIOS32_ENC28J60_ReadMACReg() or MIOS32_ENC28J60_ReadPHYReg() for that purpose.

Parameters:

  `[in]` | address | 5 bit address of the ETH control register to read from.

Returns:
  < 0 on errors
  >= 0: Byte read from the Ethernet controller's ETH register.

Here is the call graph for this function:

s32 MIOS32_ENC28J60_ReadMACReg | ( | u8 | address | ) |

Sends the 8 bit RCR opcode/Address byte as well as a dummy byte over the SPI and then retrives the register contents in the last 8 SPI clocks.

This routine cannot be used to access ETH or PHY registers. Use MIOS32_ENC28J60_ReadETHReg() or MIOS32_ENC28J60_ReadPHYReg() for that purpose.

Parameters:

  `[in]` | address | 5 bit address of the MAC or MII register to read from.

Returns:
  < 0 on errors
  >= 0: Byte read from the Ethernet controller's MAC/MII register.

Here is the call graph for this function:

s32 MIOS32_ENC28J60_ReadPHYReg | ( | u8 | reg | ) |

Performs an MII read operation. While in progress, it simply polls the MII BUSY bit wasting time (10.24us).

This routine cannot be used to access ETH or PHY registers. Use MIOS32_ENC28J60_ReadETHReg() or MIOS32_ENC28J60_ReadPHYReg() for that purpose.

Parameters:

  `[in]` | reg | Address of the PHY register to read from.

Returns:
  < 0 on errors
  >= 0: u16 read from the Ethernet controller's MAC/MII register.

Here is the call graph for this function:

s32 MIOS32_ENC28J60_RevIDGet | ( | void |  | ) |

Returns ENC28J60 Revision ID
Value is only valid if MIOS32_ENC28J60_PowerOn() passed without errors.

Returns:
  revision id (8-bit value)

s32 MIOS32_ENC28J60_SendSystemReset | ( | void |  | ) |

Sends the System Reset SPI command to the Ethernet controller. It resets all register contents (except for ECOCON) and returns the device to the power on default state.

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_WritePHYReg | ( | u8 | reg,
|  | u16 | data |
| ) |  |  |

Performs an MII write operation.

While in progress, it simply polls the MII BUSY bit wasting time.

Alters bank bits to point to Bank 3

Parameters:

  `[in]` | reg | Address of the PHY register to write to.
  `[in]` | data | 16 bits of data to write to PHY register.

Returns:
  < 0 on errors

Here is the call graph for this function:

s32 MIOS32_ENC28J60_WriteReg | ( | u8 | address,
|  | u8 | data |
| ) |  |  |

Sends the 8 bit WCR opcode/Address byte over the SPI and then sends the data in the next 8 SPI clocks

This routine is almost identical to the MIOS32_ENC28J60_BFCReg() and MIOS32_ENC28J60_BFSReg() functions. It is separate to maximize speed.

Unlike the MIOS32_ENC28J60_ReadETHReg/MIOS32_ENC28J60_ReadMACReg functions, MIOS32_ENC28J60_WriteReg() can write to any ETH or MAC register. Writing to PHY registers must be accomplished with MIOS32_ENC28J60_WritePHYReg().

Parameters:

  `[in]` | address | 5 bit address of the ETH, MAC, or MII register to modify. The top 3 bits must be 0
  `[in]` | data | Byte to be written into register

Returns:
  < 0 on errors

Here is the call graph for this function:

## Variable Documentation

ENC_PREAMBLE