Adding an SPI 10M Ethernet Connection

Last Update: May 22, 2024 @ 10:15 Preliminary information, subject to change.

This is an Application Note discussing how an SPI 10M Ethernet PHY (ENC28J60) can be connected to a Decaf board.

All Decaf boards have at least one SPI Master-Slave channel available for external sensors and controls, supported by the USBSPIRead|Write commands. Decaf IOC-235/350/370 boards have a 10M Ethernet module option. The code discussions below are relevent to the Decaf IOC-235V-3 boards.

Design Requirements:

  • maintain USB operations as this is needed to configure IP connectivity parameters, discussed below.
  • Support multiple devices on a LAN.
  • Provide at least a subset of the USBLCD* and I/O commands that can be invoked from another LAN device or remote Webpage. These devices can be running Windows, linux, Raspbian or FreeRTOS.
  • Provide an adequate level of network security that can be set up by the user.
A superceded Decaf-243 with the SPI Ethernet PHY built on to the board. The latest USB firmware (v20.0) has been loaded. This board is functionally equivalent to a Decaf IOC-235V-3 with the 10M network option.
Optional ENC28J60 10M Ethenet PHY module connected to an IOC-235V-3. Firmware V20.1 or later is required for the ENC28J60 module to function.

For the following discussions, “board” assumes that the Ethernet Phy device / module is present, and appropriate firmware has been developed and downloaded.

Connectivity Parameters

As manufactured, the board has a default static IP address (, a default MAC address and a base URL. All of these have to be unique within a single LAN, so a set of USB command (a.k.a Reports) have been created, and are discussed below.

The board appears as a network node on the LAN, and broadcasts a simple network server page or pages which can accept commands. For Decaf boards, this are typically LCD draw instructions to create a user interface, control a digital output, or acquire a digital or analog input value.

As mentioned above, the USBSetNetworkParams command sets the required board unique IPaddress, MAC and BaseURL. These values are written to the board Flash memory, and will remain until changed or reset by the user, via the USB port. A PiXCL 20 app has been created to perform the board setup. Source for this app is downloadable from the Support Pages.

During the setup, testing and commissioning phases of LAN sensors and controls, the USBEnableNetworkServer command is available. Disabling a specific board from a LAN might be done when new firmware has to be downloaded.

Security Issues

Any network installation, even a LAN, must provide a level of security that makes it difficult for bad actors to access it. It has to be assumed that attempts to hack the network WILL be made.

Specifying the Server Page(s)

The board server has to broadcast a user defined page when accessed, in the same way as a traditional web page. The USBSetNetworkServerPage command provides a way to define up to seven unique pages. These are typically simple HTML forms. JavaScript code is not supported by the board, but is possible, as all the server has to do is present the page (HTML or JavaScript) to the calling browser. Server pages can be read back (useful during the development phase) over the board COM port.

Two IOC-235V-3 modules connected to the LAN.

The image above shows two IOC-235V-3 modules with beta-level firmware that specifies board unique MAC and static URL. Both boards respond to a ping command, see the screenshot below.

Console screen showing three Decaf 10NET devices on the LAN responding to a ping request.

The first device, is an older Decaf IOC-2 board with a ENC28J60 module, built to test the firmware development without any LCD code.

Static IP addresses and Router DHCP

Most LAN nodes are host computers (e.g. Windows, linux, Raspbian) that support DHCP, and the LAN router will dynamically assign a unique IPv4 address to each. If the computer’s MAC is used to inform the router to assign (i.e. reserve) it a specific IPv4 address every time it appears on the network.

Decaf boards with the 10NET option enabled are currently coded with a static IPv4 address, so the router will not list these in its DHCP Table. This behavior is normal and correct.

What happens if a 10NET device MAC is used to reserve a specific IPv4 address? Does this then appear in the router DHCP Table? Good question! Answer: No, it does not.

Code issues in MX and TS

The ENC28J60 module is an SPI device, so either SPI1 or SPI2 (on the STM32F103 series) has to be enabled. The IOC-235V-3 development boards use SPI2.


static void MX_SPI2_Init(void)
 /* SPI2 parameter configuration*/
   hspi2.Instance = SPI2;
   hspi2.Init.Mode = SPI_MODE_MASTER;
   hspi2.Init.Direction = SPI_DIRECTION_2LINES;
   hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
   hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
   hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
   hspi2.Init.NSS = SPI_NSS_SOFT;
   hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
   hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
   hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
   hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
   hspi2.Init.CRCPolynomial = 10;
   if (HAL_SPI_Init(&hspi2) != HAL_OK)


void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
    if(hspi->Instance == SPI2)
        /* Peripheral clock enable */
      /* __HAL_AFIO_REMAP_SPI2_ENABLE(); */
     /**SPI2 GPIO Configuration
       PB12     ------> SPI2_NSS
       PB13     ------> SPI2_SCK
       PB14     ------> SPI2_MISO 
       PB15     ------> SPI2_MOSI  */
     GPIO_InitStruct.Pin = /* GPIO_PIN_12|*/ 
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
     GPIO_InitStruct.Pin = GPIO_PIN_14;
     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

The GPIO_InitStruct.Mode requires the AF (Alternate Function) setting. You may be tempted to use __HAL_AFIO_REMAP_SPI2_ENABLE(); macro as well. Don’t: the result is that the SPI communications to the ENC28J60 are blocked.

Note also here, for our example, that SPI2_NSS is not handled here, as it is done in MX_GPIO_Init(); See also hspi2.Init.NSS = SPI_NSS_SOFT; above. SPI2 is also used to access on-board EEPROM.

Initializing the ENC28J60

The setup command sequences are written via SPI which set the PHY clock frequency, the MAC and IPv4 addresses and starts the device. If this works, the PHY will return the chip version numbers. These numbers can also be used to test if the PHY is present.

An example of a Server Page

Firmware test of a server page that loads an image from the PiXCL website, and presents a form to control board LEDs and write commands to the LCD.
Initial Web app accessing two IOC-235V-3 boards. App created with the libraries.

The firmware is being updated to support the generation of a JSON (JavaScriptObjectNotation) array that contains the current state of the digital and analog I/O ports on the Decaf board. The above app screen shot was created with the p5js libraries (written in JavaScript), and runs on any browser. p5js has a ‘loadJSON(…)’ command that can access any URL on the LAN, and waits for a JSON array string to be returned.

The Decaf IOC board implements standard port 80 (HTTP) access. When a browser accesses (say,, the board firmware responds with one of the standard or user defined pages stored in the board.

The Decaf IOC board also implements standard port 8080 (HTTP Proxy) access. If a browser accesses (say), the board returns the JSON array string.

The p5js app queries the boards every few seconds (adjustable in code) and updates the display accordingly. The board is still powered via the USB port, and may be locally controlled by an app on the PC (Windows 10, linux or Raspbian). The p5js app (and board firmware) will be updated to send commands to the board e.g. turn on digital outputs (say, connected to relays and similar), and create updated user screens on the board LCD, based on the data decoded from a JSON data array.

Questions or comments? Great! Contact me and I’ll get back to you soon.

What about a 100M network connection?

The ENC28J60 is a 10Mb/s device, which is quite adequate for sending and receiving the small packets of data and commands used by the Decaf boards. A 10/100 Mb/s module is available that uses the DP83848 chip: I am looking into using this or an equivalent for future projects that use the 168MHz Cortex-M4 mcu. The available DP83848 modules have more pins than the ENC28J60, so a new connector PCB is required.

The IOC-M-411 board also includes the ENC28J60 module.

Other Application Notes

Custom USB HID using STM32CubeMX and TrueStudio.

Calibrating the Decaf Real Time Clock.

Interfacing LCD Modules: the LCD_Init problem. 

Comparing graphics speed: M4 vs. M3

Interrupt Vector Relocation : Cortex-M3

Timer4 PWM not working: STM32F103VE

Adding an SPI LCD to the IOC-M-2

 Since you are here, do please have a look around the website. These similar devices might be of interest.

Decaf IOC-2xe  Decaf IOC-M-2  Decaf IOC-235  Decaf IOC-280Z-4   Decaf IOC-350   Decaf IOC-370 

Copyright © 2024 PiXCL Automation Tech Notes, Canada. All Rights Reserved.