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 interrupción, si se usa el modo de interrupción, 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 );
- / * Configuración de inicialización 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 configuración STM32 SPI1 * /
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // SPI se establece en dúplex completo bidireccional de dos líneas
- 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 transmisión 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 periférico de acuerdo con los parámetros 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
- // Función de escritura SPI
- void SPI1WriteByte ( uint8_t TxData )
- {
- while ((SPI1-> SR & SPI_I2S_FLAG_TXE) == 0); // Esperando que el área de envío esté vacía
- SPI1-> DR = TxData; // Enviar un byte
- while ((SPI1-> SR & SPI_I2S_FLAG_RXNE) == 0); // Espera recibir un byte
- SPI1->DR;
- }
- // Función de lectura SPI
- uint8_t SPI1ReadByte ( void )
- {
- while ((SPI1-> SR & SPI_I2S_FLAG_TXE) == 0); // Esperando que el área de envío esté vacía
- SPI1-> DR = 0xFF; // Envía un reloj con datos vacíos para generar datos de entrada
- while ((SPI1-> SR & SPI_I2S_FLAG_RXNE) == 0); // Espera recibir un byte
- return SPI1->DR;
- }
- // Función de selección de chip
- void SPI1_CS_Select ( void )
- {
- GPIO_ResetBits ( W5500_SCS_PORT, W5500_SCS );
- }
- // Función de cancelación de selección de chip
- void SPI1_CS_Deselect ( void )
- {
- GPIO_SetBits ( W5500_SCS_PORT, W5500_SCS );
- }
- // Ingrese a la función de sección crítica
- void SPI_CrisEnter ( void )
- {
- __set_PRIMASK ( 1 );
- }
- // Salir de la función de sección crítica
- void SPI_CrisExit ( void )
- {
- __set_PRIMASK ( 0 );
- }
2.2.6 Initialize network settings
MAC、IP、Netmask、Gateway、DNS
- // Configurar los parámetros 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}; ///< Source Mac Address
- uint8_t ip[4] = {192, 168, 86, 150}; ///< Source IP Address
- uint8_t sn[4] = {255, 255, 255, 0}; ///< Subnet Mask
- uint8_t gw[4] = {192, 168, 86, 1}; ///< Gateway IP Address
- uint8_t dns[4] = {8, 8, 8, 8}; ///< 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; //< 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 (); // Inicialización de la función de retardo
- NVIC_PriorityGroupConfig (NVIC_PriorityGroup_2); // Establecer grupo de prioridad de interrupción 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
COMMENTS