These sections will guide you through a series of steps from configuring development environment to running LwIP examples using the WIZnet's ethernet products.
- Development environment configuration
- Hardware requirements
- LwIP example structure
- LwIP example testing
- How to use port directory
To test the LwIP examples, the development environment must be configured to use Raspberry Pi Pico, W5100S-EVB-Pico, W5500-EVB-Pico, W55RP20-EVB-Pico, W5100S-EVB-Pico2 or W5500-EVB-Pico2.
These examples were tested after configuring the development environment on Windows. Please refer to 'Chapter 3: Installing the Raspberry Pi Pico VS Code Extension' in the document below and configure accordingly.
Visual Studio Code was used during development and testing of LwIP examples, the guide document in each directory was prepared also base on development with Visual Studio Code. Please refer to corresponding document.
The LwIP examples use Raspberry Pi Pico and WIZnet Ethernet HAT - ethernet I/O module built on WIZnet's W5100S ethernet chip, W5100S-EVB-Pico - ethernet I/O module built on RP2040 and WIZnet's W5100S ethernet chip, W5500-EVB-Pico and W55RP20-EVB-Pico - ethernet I/O module built on RP2040 and WIZnet's W5500 ethernet chip, W5100S-EVB-Pico2 - ethernet I/O module built on RP2350 and WIZnet's W5100S ethernet chip or W5100S-EVB-Pico2 - ethernet I/O module built on RP2350 and WIZnet's W5100S ethernet chip.
- Raspberry Pi Pico or Raspberry Pi Pico2& WIZnet Ethernet HAT
- W5100S-EVB-Pico
- W5500-EVB-Pico
- W55RP20-EVB-Pico
- W5100S-EVB-Pico2
- W5500-EVB-Pico2
Examples are available at 'WIZnet-PICO-LWIP-C/examples/' directory. As of now, following examples are provided.
Note that ioLibrary_Driver, pico-sdk, pico-extras are needed to run LwIP examples.
- ioLibrary_Driver library is applicable to WIZnet's W5x00 ethernet chip.
- pico-sdk is made available by Pico to enable developers to build software applications for the Pico platform.
- pico-extras provides additional useful functions not provided by pico-sdk.
Libraries are located in the 'WIZnet-PICO-LWIP-C/libraries/' directory.
If you want to modify the code that MCU-dependent and use a MCU other than RP2040, you can modify it in the 'WIZnet-PICO-LWIP-C/port/' directory.
port is located in the 'WIZnet-PICO-LWIP-C/port/' directory.
- Download
If the LwIP examples are cloned, the library set as a submodule is an empty directory. Therefore, if you want to download the library set as a submodule together, clone the LwIP examples with the following Git command.
/* Change directory */
// change to the directory to clone
cd [user path]
// e.g.
cd D:/WIZnet-PICO
/* Clone */
git clone --recurse-submodules https://github.com/WIZnet-ioNIC/WIZnet-PICO-LWIP-C.git
With Visual Studio Code, the library set as a submodule is automatically downloaded, so it doesn't matter whether the library set as a submodule is an empty directory or not, so refer to it.
- Setup board
Setup the board in 'CMakeLists.txt' in 'WIZnet-PICO-LWIP-C/' directory according to the evaluation board to be used referring to the following.
- WIZnet Ethernet HAT
- W5100S-EVB-Pico
- W5500-EVB-Pico
- W55RP20-EVB-Pico
- W5100S-EVB-Pico2
- W5500-EVB-Pico2
For example, when using WIZnet Ethernet HAT or W5100S-EVB-Pico :
# Set board
set(BOARD_NAME WIZnet_Ethernet_HAT)
When using W5500-EVB-Pico :
# Set board
set(BOARD_NAME W5500_EVB_PICO)
When using W55RP20-EVB-Pico :
# Set board
set(BOARD_NAME W55RP20_EVB_PICO)
When using W5100S_EVB_PICO2 :
# Set board
set(BOARD_NAME W5100S_EVB_PICO2)
When using W5500_EVB_PICO2 :
# Set board
set(BOARD_NAME W5500_EVB_PICO2)
- Test
Please refer to 'README.md' in each example directory to find detail guide for testing LwIP examples.
※ If the board pauses when rebooting using W55RP20-EVB-Pico, patch it as follows.
// Patch git apply ./patches/0001_pico_sdk_clocks.patch
We moved the MCU dependent code to the port directory. The tree of port is shown below.
WIZnet-PICO-LWIP-C
┣ port
┣ ioLibrary_Driver
┃ ┣ inc
┃ ┃ ┣ w5x00_gpio_irq.h
┃ ┃ ┣ w5x00_spi.h
┃ ┃ ┣ wiznet_spi_pio.h
┃ ┃ ┗ wiznet_spi.h
┃ ┗ src
┃ ┃ ┣ w5x00_gpio_irq.c
┃ ┃ ┣ w5x00_spi.c
┃ ┃ ┣ wiznet_spi_pio.c
┃ ┃ ┗ wiznet_spi_pio.pio
┣ lwip
┃ ┣ lwipopts.h
┃ ┣ w5x00_lwip.c
┃ ┗ w5x00_lwip.h
┣ timer
┃ ┣ timer.c
┃ ┗ timer.h
┣ CMakeLists.txt
┗ port_common.h
- ioLibrary_Driver
If you want to change things related to SPI, such as the SPI port number and SPI read/write function, or GPIO port number and function related to interrupt or use a different MCU without using the RP2040, you need to change the code in the 'WIZnet-PICO-LWIP-C/port/ioLibrary_Driver/' directory. Here is information about functions.
/* W5x00 */
/*! \brief Set CS pin
* \ingroup w5x00_spi
*
* Set chip select pin of spi0 to low(Active low).
*
* \param none
*/
static inline void wizchip_select(void);
/*! \brief Set CS pin
* \ingroup w5x00_spi
*
* Set chip select pin of spi0 to high(Inactive high).
*
* \param none
*/
static inline void wizchip_deselect(void);
/*! \brief Read from an SPI device, blocking
* \ingroup w5x00_spi
*
* Set spi_read_blocking function.
* Read byte from SPI to rx_data buffer.
* Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate.
*
* \param none
*/
static uint8_t wizchip_read(void);
/*! \brief Write to an SPI device, blocking
* \ingroup w5x00_spi
*
* Set spi_write_blocking function.
* Write byte from tx_data buffer to SPI device.
* Blocks until all data is transferred. No timeout, as SPI hardware always transfers at a known data rate.
*
* \param tx_data Buffer of data to write
*/
static void wizchip_write(uint8_t tx_data);
#ifdef USE_SPI_DMA
/*! \brief Configure all DMA parameters and optionally start transfer
* \ingroup w5x00_spi
*
* Configure all DMA parameters and read from DMA
*
* \param pBuf Buffer of data to read
* \param len element count (each element is of size transfer_data_size)
*/
static void wizchip_read_burst(uint8_t *pBuf, uint16_t len);
/*! \brief Configure all DMA parameters and optionally start transfer
* \ingroup w5x00_spi
*
* Configure all DMA parameters and write to DMA
*
* \param pBuf Buffer of data to write
* \param len element count (each element is of size transfer_data_size)
*/
static void wizchip_write_burst(uint8_t *pBuf, uint16_t len);
#endif
/*! \brief Enter a critical section
* \ingroup w5x00_spi
*
* Set ciritical section enter blocking function.
* If the spin lock associated with this critical section is in use, then this
* method will block until it is released.
*
* \param none
*/
static void wizchip_critical_section_lock(void);
/*! \brief Release a critical section
* \ingroup w5x00_spi
*
* Set ciritical section exit function.
* Release a critical section.
*
* \param none
*/
static void wizchip_critical_section_unlock(void);
/*! \brief Initialize SPI instances and Set DMA channel
* \ingroup w5x00_spi
*
* Set GPIO to spi0.
* Puts the SPI into a known state, and enable it.
* Set DMA channel completion channel.
*
* \param none
*/
void wizchip_spi_initialize(void);
/*! \brief Initialize a critical section structure
* \ingroup w5x00_spi
*
* The critical section is initialized ready for use.
* Registers callback function for critical section for WIZchip.
*
* \param none
*/
void wizchip_cris_initialize(void);
/*! \brief W5x00 chip reset
* \ingroup w5x00_spi
*
* Set a reset pin and reset.
*
* \param none
*/
void wizchip_reset(void);
/*! \brief Initialize WIZchip
* \ingroup w5x00_spi
*
* Set callback function to read/write byte using SPI.
* Set callback function for WIZchip select/deselect.
* Set memory size of W5x00 chip and monitor PHY link status.
*
* \param none
*/
void wizchip_initialize(void);
/*! \brief Check chip version
* \ingroup w5x00_spi
*
* Get version information.
*
* \param none
*/
void wizchip_check(void);
/* Network */
/*! \brief Initialize network
* \ingroup w5x00_spi
*
* Set network information.
*
* \param net_info network information.
*/
void network_initialize(wiz_NetInfo net_info);
/*! \brief Print network information
* \ingroup w5x00_spi
*
* Print network information about MAC address, IP address, Subnet mask, Gateway, DHCP and DNS address.
*
* \param net_info network information.
*/
void print_network_information(wiz_NetInfo net_info);
/* GPIO */
/*! \brief Initialize w5x00 gpio interrupt callback function
* \ingroup w5x00_gpio_irq
*
* Add a w5x00 interrupt callback.
*
* \param socket socket number
* \param callback the gpio interrupt callback function
*/
void wizchip_gpio_interrupt_initialize(uint8_t socket, void (*callback)(void));
/*! \brief Assign gpio interrupt callback function
* \ingroup w5x00_gpio_irq
*
* GPIO interrupt callback function.
*
* \param gpio Which GPIO caused this interrupt
* \param events Which events caused this interrupt. See \ref gpio_set_irq_enabled for details.
*/
static void wizchip_gpio_interrupt_callback(uint gpio, uint32_t events);
- timer
If you want to change things related to the timer. Also, if you use a different MCU without using the RP2040, you need to change the code in the 'WIZnet-PICO-LWIP-C/port/timer/' directory. Here is information about functions.
/* Timer */
/*! \brief Initialize timer callback function
* \ingroup timer
*
* Add a repeating timer that is called repeatedly at the specified interval in microseconds.
*
* \param callback the repeating timer callback function
*/
void wizchip_1ms_timer_initialize(void (*callback)(void));
/*! \brief Assign timer callback function
* \ingroup timer
*
* 1ms timer callback function.
*
* \param t Information about a repeating timer
*/
bool wizchip_1ms_timer_callback(struct repeating_timer *t);
/* Delay */
/*! \brief Wait for the given number of milliseconds before returning
* \ingroup timer
*
* This method attempts to perform a lower power sleep (using WFE) as much as possible.
*
* \param ms the number of milliseconds to sleep
*/
void wizchip_delay_ms(uint32_t ms);