---
title: "Porting the latest ioLibrary_Driver to W5500 based on STM32F103RCT6"
url: "https://maker.wiznet.io/teju/projects/Porting-the-latest-ioLibraryDriver-to-W5500-based-on-STM32F103RCT6/"
markdown_url: "https://maker.wiznet.io/teju/projects/Porting-the-latest-ioLibraryDriver-to-W5500-based-on-STM32F103RCT6/md"
type: "UCC: User Created Content"
author: "teju"
author_url: "https://maker.wiznet.io/teju/"
original_author: "teju"
original_url: "https://programmerclick.com/article/73151336966/"
published: "2022-02-26"
language: "en"
hardware: ["STMicroelectronics STM32F103RCT6", "W5500 Ethernet Master Extension"]
likes: 0
views: 262
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# Porting the latest ioLibrary_Driver to W5500 based on STM32F103RCT6

> Porting the latest ioLibrary_Driver to W5500 based on STM32F103RCT6

Original author: teju (source: https://programmerclick.com/article/73151336966/)

## Components

- **STMicroelectronics STM32F103RCT6** x 1 ([docs](https://estore.st.com/en/stm32f103rct6-cpn.html))
- **W5500 Ethernet Master Extension** x 1

## Article

1.ioLibrary_Driver ? ? ? 1.1?Overview The ioLibrary means “Internet Offload Library” for WIZnet chip.?It includes drivers and application protocols.?The driver (ioLibrary) can be used for the application design of WIZnet TCP/IP chips as??W5500?, W5300, W5200, W5100??W5100S?. 1.2 ioLibrary download Official?GitHub?download link:?https://github.com/Wiznet/ioLibrary_Driver 2. How to add ioLibrary_Driver to your project Next, I will introduce how to port ioLiberary to STM32F103 project ? ?2.1 Hardware preparation Atom MiniSTM32 point development board (other development boards can be used), the chip is STM32F103RCT6. W5500 module (Treasure X sells many). download?ioLiberary_Driver?Source code, as shown: Copy the source code of a serial port experiment into the Punctual Atom MiniSTM32 data (you can create it yourself, the purpose of the copy is to save time). 2.2 Code transplant 2.2.1??Copy the source code of ioLiberary_Driver to the project directory 2.2.2??Add three files socket.c, wizchip_conf.c, w5500.c to the project Add 3 C files socket.c, wizchip_conf.c, w5500.c as shown in the figure to create a new group "W5500". Add the corresponding header file directory to Include Paths. 2.2.3?Then open wizchip_conf.h to find line 75 (different versions may be different, you can search directly) Modify #define _WIZCHIP_????????????????????? W5100S?? // W5100, W5100S, W5200, W5300, W5500 for #define _WIZCHIP_????????????????????? W5500?? // W5100, W5100S, W5200, W5300, W5500 As shown: Compile the code and continue to the next step with 0 errors and 0 warnings.?If there is an error, please resolve the error first. 2.2.4?Configure the SPI related code-behind to perform basic code such as reading and writing W5500?with?STM32F103?is through?SPI?interface communication, so you need to set the lower layer?SPI?function pin and?SPI?operating mode. The hardware connections are as follows: PA3 -> W5500_RST ????PA4 -> W5500_SCS ????PA5 -> W5500_SCK ??? PA6 -> W5500_MISO ??? PA7 -> W5500_MOSI PA8 -> W5500_INT (no se usa en modo sin interrupcion, si se usa el modo de interrupcion, se recomienda usar otros puertos, la mini placa se usa como luz LED) Increase spi initialization code: static void W5500_SPI_Init ( void ) { GPIO_InitTypeDef GPIO_InitStructure; SPI_InitTypeDef SPI_InitStructure; RCC_APB2PeriphClockCmd ( RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO, ENABLE ); / * Inicializar el pin CS * / GPIO_InitStructure.GPIO_Pin = W5500_SCS; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init ( W5500_SCS_PORT, &GPIO_InitStructure ); GPIO_SetBits ( W5500_SCS_PORT, W5500_SCS ); / * Configuracion de inicializacion del pin W5500_RST * / GPIO_InitStructure.GPIO_Pin = W5500_RST; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init ( W5500_RST_PORT, &GPIO_InitStructure ); GPIO_SetBits ( W5500_RST_PORT, W5500_RST ); / * Inicializar pines SCK, MISO, MOSI * / GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init ( GPIOA, &GPIO_InitStructure ); GPIO_SetBits ( GPIOA, GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 ); / * Inicializar la configuracion STM32 SPI1 * / SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI se establece en duplex completo bidireccional de dos lineas SPI_InitStructure.SPI_Mode = SPI_Mode_Master; // Establecer como SPI maestro SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; // SPI enviando y recibiendo estructura de trama de 8 bits SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; // reloj flotante bajo SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; // Los datos se capturan en el primer borde del reloj SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; // NSS es administrado por pines externos SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; // El valor del preescalador de velocidad en baudios es 2 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; // La transmision de datos comienza desde el bit MSB SPI_InitStructure.SPI_CRCPolynomial = 7; // El polinomio CRC es 7 SPI_Init (SPI1, & SPI_InitStructure); // Inicializar el registro SPI1 del periferico de acuerdo con los parametros especificados en SPI_InitStruct SPI_Cmd (SPI1, ENABLE); // STM32 habilita SPI1 } 2.2.5?Register callback function In the wizchip_conf.h file, there are several callback registration functions to register the underlying data processing methods void reg_wizchip_cris_cbfunc(void(*cris_en)(void), void(*cris_ex)(void)); void reg_wizchip_cs_cbfunc(void(*cs_sel)(void), void(*cs_desel)(void)); void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), void (*bus_wb)(uint32_t addr, iodata_t wb)); void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), void (*spi_wb)(uint8_t wb)); We need to implement and register // Funcion de escritura SPI void SPI1WriteByte ( uint8_t TxData ) { while ((SPI1-> SR & SPI_I2S_FLAG_TXE) == 0); // Esperando que el area de envio este vacia SPI1-> DR = TxData; // Enviar un byte while ((SPI1-> SR & SPI_I2S_FLAG_RXNE) == 0); // Espera recibir un byte SPI1->DR; } // Funcion de lectura SPI uint8_t SPI1ReadByte ( void ) { while ((SPI1-> SR & SPI_I2S_FLAG_TXE) == 0); // Esperando que el area de envio este vacia SPI1-> DR = 0xFF; // Envia un reloj con datos vacios para generar datos de entrada while ((SPI1-> SR & SPI_I2S_FLAG_RXNE) == 0); // Espera recibir un byte return SPI1->DR; } // Funcion de seleccion de chip void SPI1_CS_Select ( void ) { GPIO_ResetBits ( W5500_SCS_PORT, W5500_SCS ); } // Funcion de cancelacion de seleccion de chip void SPI1_CS_Deselect ( void ) { GPIO_SetBits ( W5500_SCS_PORT, W5500_SCS ); } // Ingrese a la funcion de seccion critica void SPI_CrisEnter ( void ) { __set_PRIMASK ( 1 ); } // Salir de la funcion de seccion critica void SPI_CrisExit ( void ) { __set_PRIMASK ( 0 ); } 2.2.6?Initialize network settings MAC、IP、Netmask、Gateway、DNS // Configurar los parametros de la red void W5500_Network_Init ( void ) { uint8_t chipid[6]; wiz_NetInfo gWIZNETINFO; wiz_NetTimeout w_NetTimeout; uint8_t mac[6] = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}; ///&lt; Source Mac Address uint8_t ip[4] = {192, 168, 86, 150}; ///&lt; Source IP Address uint8_t sn[4] = {255, 255, 255, 0}; ///&lt; Subnet Mask uint8_t gw[4] = {192, 168, 86, 1}; ///&lt; Gateway IP Address uint8_t dns[4] = {8, 8, 8, 8}; ///&lt; DNS server IP Address memcpy ( gWIZNETINFO.ip, ip, 4 ); memcpy ( gWIZNETINFO.sn, sn, 4 ); memcpy ( gWIZNETINFO.gw, gw, 4 ); memcpy ( gWIZNETINFO.mac, mac, 6 ); memcpy ( gWIZNETINFO.dns, dns, 4 ); gWIZNETINFO.dhcp = NETINFO_STATIC; //&lt; 1 - Static, 2 - DHCP ctlnetwork ( CN_SET_NETINFO, ( void* ) &gWIZNETINFO ); ctlnetwork ( CN_GET_NETINFO, ( void* ) &gWIZNETINFO ); // Display Network Information ctlwizchip ( CW_GET_ID, ( void* ) chipid ); printf ( "rn=== %s NET CONF ===rn", ( char* ) chipid ); printf ( "MAC: %02X:%02X:%02X:%02X:%02X:%02Xrn", gWIZNETINFO.mac[0], gWIZNETINFO.mac[1], gWIZNETINFO.mac[2], gWIZNETINFO.mac[3], gWIZNETINFO.mac[4], gWIZNETINFO.mac[5] ); printf ( "SIP: %d.%d.%d.%drn", gWIZNETINFO.ip[0], gWIZNETINFO.ip[1], gWIZNETINFO.ip[2], gWIZNETINFO.ip[3] ); printf ( "GAR: %d.%d.%d.%drn", gWIZNETINFO.gw[0], gWIZNETINFO.gw[1], gWIZNETINFO.gw[2], gWIZNETINFO.gw[3] ); printf ( "SUB: %d.%d.%d.%drn", gWIZNETINFO.sn[0], gWIZNETINFO.sn[1], gWIZNETINFO.sn[2], gWIZNETINFO.sn[3] ); printf ( "DNS: %d.%d.%d.%drn", gWIZNETINFO.dns[0], gWIZNETINFO.dns[1], gWIZNETINFO.dns[2], gWIZNETINFO.dns[3] ); printf ( "======================rn" ); wizchip_init ( NULL, NULL ); w_NetTimeout.retry_cnt = 50; w_NetTimeout.time_100us = 1000; wizchip_settimeout ( &w_NetTimeout ); } At this point, the main transplant procedure has been completed. 2.3 Test ? ? ? 2.3.1?Add loopback test file will be?ioLibrary_DriverApplication?In the folder?loopback.c?Add files to the project And add header file directory to?Include Paths 2.3.2?Add the main program code Add the following code to the main program int main ( void ) { uint8_t dest_ip[4] = {192, 168, 86, 99}; uint16_t dest_port = 8080; uint8_t dataBuffer[DATA_BUF_SIZE] = {0x0}; delay_init (); // Inicializacion de la funcion de retardo NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2); // Establecer grupo de prioridad de interrupcion 2 uart_init (115200); // El puerto serie se inicializa a 115200 printf ( "usart inited ......" ); LED_Init (); // Inicializar la interfaz de hardware conectada al LED printf ( "LED inited ......" ); W5500_Init(); printf ( "W5500 inited ......" ); W5500_Init(); /* Infinite loop */ while ( 1 ) { loopback_tcpc ( 0x0, dataBuffer, dest_ip, dest_port ); LED0 = 0; delay_ms ( 50 ); LED0 = 1; delay_ms ( 50 ); } } ? 2.3.3?Compile the program and download it to the development board. The standard library may be missing during the build process.?Atomic projects will generally be placed in the full library and added as needed.?So if the standard library is missing here, just add it. Download the program to the development board, plug in the W5500 module, set the computer's ip to 192.168.86.99, and connect it directly with a network cable (connection via router is also possible). 2.3.4?Test network connectivity: Open the command window and run the command ping 192.168.86.150 -t This means that W5500 has started normally. 2.3.5?Plug connection test The loopback code is to configure w5500 as a socket client and keep trying to connect to the server 192.168.86.99:8080 Open the network wizard on the computer, open the server port 8080, if everything is normal, the socket will connect automatically

---

Source: https://maker.wiznet.io/teju/projects/Porting-the-latest-ioLibraryDriver-to-W5500-based-on-STM32F103RCT6/
