---
title: "STM Lesson 91. LAN. W5500. HTTP Server. Part 1"
url: "https://maker.wiznet.io/teddy/projects/stm-lesson-91-lan-w5500-http-server-part-1/"
markdown_url: "https://maker.wiznet.io/teddy/projects/stm-lesson-91-lan-w5500-http-server-part-1/md"
type: "UCC: User Created Content"
author: "Narod stream"
author_url: "https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-1/"
editor: "WIZnet"
editor_url: "https://maker.wiznet.io/"
original_author: "Narod stream"
original_url: "https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-1/"
published: "2023-08-02"
language: "en"
likes: 0
views: 326
comments: 0
source: "WIZnet Makers (https://maker.wiznet.io/)"
---

# STM Lesson 91. LAN. W5500. HTTP Server. Part 1

> STM Lesson 91. LAN. W5500. HTTP Server. Part 1

Original author: Narod stream (source: https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-1/)

## Article

## **LAN. W5500. HTTP server**

Today we will continue the topic of working with LAN. For these purposes only, we will take another chip — **W5500**. This chip was developed by the company **Wiznet** and it is interesting in that, in addition to the physical and channel levels, it includes a whole hardware stack of TCP / IP protocols. Also compared to microcircuit **ENC28J60**, with which we worked for a long time, consistently and carefully studying the work of protocols at various levels, **W5500** has much greater computing abilities. The total memory for the — 32 kilobytes of reading and writing buffers, and the buffers are also divided into sockets that allow you to work simultaneously with multiple connections.

I would like to note that in this manufacturer, in addition to this chip, in the LAN-microschem with a finished stack, there are several more similar chips that vary in power, by connection interface and by many other parameters.

The W5500 chip differs from its counterparts in that it has only an interface for communication with the controller and for transferring data between it and the controller **SPI**. Some other microchips of this line also have a parallel interface for communication, which allows for a faster exchange between this chip and MK. But then the W5500, unlike other chips of this line, is more convenient for widespread use due to the fact that the case has fewer legs, which makes it easier to install on the board.

I would also like to note that the chip is already operating in more advanced modes at the physical level than ENC28J60. It supports the following modes:

10BT Half-duplex,

10BT Full-duplex,

100BT Half-duplex,

100BT Full-duplex.

The mode is also supported **Auto-negotiation**, which allows you to automatically switch speed depending on the speed of the device with which the LAN is exchanged.

Mode **auto-mdix** unfortunately not implemented in the chip. This, if you know, is a mode that allows you to connect devices with a direct cable without using routers, switches and scrolls. This costs connecting them with a cross-over cable. And if the device to which we connect this chip to LAN supports this mode, then we can safely use a direct cable.

Well, now the most important thing.

What are the protocols from the TCP / IP chip stack supported by the hardware?

Here is their list: **TCP, UDP, ICMP, IPv4, ARP, IGMP, PPPoE**.

And we will get acquainted with all the other charms and pitfalls as this chip is programmed in our project.

As a video from the topic of the lesson, our project will be aimed at organizing a small server **HTTP**, which will support so far only one connection. I think for a start it's not bad. Since we went to a similar server on a chip that we considered earlier for a good dozen lessons.

We will use this chip for the project in the form of an inexpensive ( as they say, folk ) module, which can be quite purchased at a price of approx. 5 dollars. I think this is a ridiculous price for such a module. Manufacturer — **Waveshare**, whose products we use very often. He looks like this

![image02](https://narodstream.ru/wp-content/uploads/2017/09/image02.jpg)

The controller for our project we will use **STM32F401RET6**, which is located on the same payment **NUCLEO-F401RE**.

Launch the project generator **Cube mx** and create a new project there by choosing the STM32F401RETx controller.

Set up tact from ST-Link

![image00](https://narodstream.ru/wp-content/uploads/2017/09/image00-1.png)

Turn on the debugger

![image01](https://narodstream.ru/wp-content/uploads/2017/09/image01-1.png)

Also turn on the SPI interface to connect our module

![image03](https://narodstream.ru/wp-content/uploads/2017/09/image03.png)

We will use the documents for transferring the client in the form of files located on the Micro-SD map. Since our controller supports hardware SDIO, we will turn it on

![image04](https://narodstream.ru/wp-content/uploads/2017/09/image04.png)

Accordingly, turn on FATFS

![image05](https://narodstream.ru/wp-content/uploads/2017/09/image05.png)

Turn on USART for convenient project debugging in real time

![image06](https://narodstream.ru/wp-content/uploads/2017/09/image06.png)

Also turn on the legs** PB1 **and **PB6** on exit is appropriate for **RESET **and **CS **module. It was these legs that were selected for ease of connection according to the Nucleo board

![image07](https://narodstream.ru/wp-content/uploads/2017/09/image07.png) ![image08](https://narodstream.ru/wp-content/uploads/2017/09/image08.png)

Now configure the parameters in the section **Clock configuration **( click on the image enlargement picture )

[![image09_500](https://narodstream.ru/wp-content/uploads/2017/09/image09_500.png)](https://narodstream.ru/wp-content/uploads/2017/09/image09.png)

Let's move to the section **Configuration**.

Set first **SPI1. **Turn on the divider 4 so far, which will allow working with the SPI bus at a speed of 18 megahertz ( megabit per second )

![image10](https://narodstream.ru/wp-content/uploads/2017/09/image10.png)

The chip supports the frequency of operation on the SPI bus to 80 megahertz, but this is only theoretically, practically checked to 33.3. It is written in the technical documentation. I really put a divider 2, which corresponded to 36 MHz, and the module normally transmitted and accepted everything. But we will not take risks. You can always try. And then suddenly there will be some glitches because of this, and we will begin to think badly about our code.

Now **USART**

![image11](https://narodstream.ru/wp-content/uploads/2017/09/image11.png)

Further **Fatfs**. As usual, include support for long names and long sectors

![image12](https://narodstream.ru/wp-content/uploads/2017/09/image12.png)

Also add a little speed to the work of GPIO service legs

![image13](https://narodstream.ru/wp-content/uploads/2017/09/image13.png)

Well, which is almost the most important thing for the correct work, since we do not have retractable resistors in the SD module, we will pull them to certain tire legs **SDIO**

![image14](https://narodstream.ru/wp-content/uploads/2017/09/image14.png)

Now go to the project settings window and select Keil as the programming environment, and also give the project a name **W5500_HTTPS**

![image29](https://narodstream.ru/wp-content/uploads/2017/09/image29.png)

We save the settings, generate the project, open it in Keil, configure the programmer to the auto-cutting, and also configure the code optimization to level 1.

Let's try to assemble the project.

If everything is going well, then we will begin to compose the code.

Our project, of course, may not be assembled due to the lack of a file **ccsbcs.c**. Take it and connect it from the project [**lesson**](https://narodstream.ru/stm-urok-89-lan-enc28j60-tcp-web-server-podklyuchaem-kartu-sd/)** 79ENC28J60_HTTPS_SD**.

Now the project is likely to get together.

Next, create two files **net.h** and **net.c** to control the LAN interface as follows:

**net.h**

`**#ifndef**``** __NET_H**`

`**#define**``** __NET_H**`

`**//--------------------------------------------------**`

`**#include**````**"stm32f4xx_hal.h"**`

`**#include**````**<string.h>**`

`**#include**````**<stdlib.h>**`

`**#include**````**<stdint.h>**`

`**//--------------------------------------------------**`

`**#define**``** IP_ADDR {192,168,1,197}**`

`**#define**``** IP_GATE {192,168,1,1}**`

`**#define**``** IP_MASK {255,255,255,0}**`

`**#define**``** LOCAL_PORT 80**`

`**//--------------------------------------------------**`

`**#define**``** be16toword(a) ((((a)>>8)&0xff)|(((a)<<8)&0xff00))**`

`**//--------------------------------------------------**`

`**#endif**````**/* __NET_H */**`

**net.c**

`**#include**````**"net.h"**`

`**//-----------------------------------------------**`

`**extern**````**UART_HandleTypeDef**``** huart2;**`

`**//-----------------------------------------------**`

`**uint8_t**``** ipaddr[4]=IP_ADDR;**`

`**uint8_t**``** ipgate[4]=IP_GATE;**`

`**uint8_t**``** ipmask[4]=IP_MASK;**`

`**uint16_t**``** local_port = LOCAL_PORT;**`

`**char**``** str1[60]={0};**`

`**//-----------------------------------------------**`

In file** main.c** also connect this library

`/* USER CODE BEGIN Includes */`

`**#include**````**"net.h"**`

`/* USER CODE END Includes */`

In file **net.c** we will create a hollow function of receiving network packages

`char``str1[60]={0};`

`**//-----------------------------------------------**`

`**void**``** packet_receive(**``**void**``**)**`

`**{**`

`**}**`

`**//-----------------------------------------------**`

Below we write another function for network exchange, in which we call the previous

`**//-----------------------------------------------**`

`**void**``** net_poll(**``**void**``**)**`

`**{**`

`** packet_receive();**`

`**}**`

`**//-----------------------------------------------**`

### 

We create a prototype for this function and call it in the endless cycle of the main function module **main ( )**

`/* USER CODE BEGIN 3 */`

`**net_poll();**`

`}`

`/* USER CODE END 3 */`

Create also in the file **net.c** initialization function

`**//-----------------------------------------------**`

`**void**``** net_ini(**``**void**``**)**`

`**{**`

`**}**`

`**//-----------------------------------------------**`

Create a prototype for it and call it in the main module in the function **main ( )**

/`* USER CODE BEGIN 2 */`

`**net_ini();**`

`/* USER CODE END 2 */`

Create 2 more files as well **w5500.h** and **w5500.c** for a lower level of communication with a chip with the following content

**w5500.h**

`**#ifndef**``** W5500_H_**`

`**#define**``** W5500_H_**`

`**//--------------------------------------------------**`

`**#include**````**"stm32f4xx_hal.h"**`

`**#include**````**<string.h>**`

`**#include**````**<stdlib.h>**`

`**#include**````**<stdint.h>**`

`**#include**````**"fatfs.h"**`

`**//--------------------------------------------------**`

`**#define**``** CS_GPIO_PORT GPIOB**`

`**#define**``** CS_PIN GPIO_PIN_6**`

`**#define**``** SS_SELECT() HAL_GPIO_WritePin(CS_GPIO_PORT, CS_PIN, GPIO_PIN_RESET)**`

`**#define**``** SS_DESELECT() HAL_GPIO_WritePin(CS_GPIO_PORT, CS_PIN, GPIO_PIN_SET)**`

`**//--------------------------------------------------**`

`**#define**``** MAC_ADDR {0x00,0x15,0x42,0xBF,0xF0,0x51}**`

`**//--------------------------------------------------**`

`**#define**``** be16toword(a) ((((a)>>8)&0xff)|(((a)<<8)&0xff00))**`

`**//--------------------------------------------------**`

`**#endif**````**/* W5500_H_ */**`

**w5500.c**

`**#include**````**"w5500.h"**`

`**//-----------------------------------------------**`

`**extern**````**SPI_HandleTypeDef**``** hspi1;**`

`**extern**````**UART_HandleTypeDef**``** huart2;**`

`**//-----------------------------------------------**`

`**extern**````**char**``** str1[60];**`

`**//-----------------------------------------------**`

`**uint8_t**``** macaddr[6]=MAC_ADDR;**`

`**extern**````**uint8_t**``** ipaddr[4];**`

`**extern**````**uint8_t**``** ipgate[4];**`

`**extern**````**uint8_t**``** ipmask[4];**`

`**extern**````**uint16_t**``** local_port;**`

`**//-----------------------------------------------**`

`**static**````**void**``** Error (**``**void**``**)**`

`**{**`

`**HAL_UART_Transmit(&huart2,(**``**uint8_t**``***)**``**"Error!rn"**``**,8,0x1000);**`

`**}**`

`**//-----------------------------------------------**`

Before we begin to write the initialization function, we will get to know the organization of memory a little. First, there are two types of registers. One type — is general purpose registers. It stores settings and properties that are common to all sockets. And the second type of — is the registers for sockets, which store the settings and properties for a particular socket.

And memory is organized as follows. In total, 32 kilobytes are reserved for the data of memory, half of which is reserved for accepted data, and the other half is — for those sent. Each half is divided by default into 8 parts — into 2 kilobytes. Each part is designed for a certain socket. At our request, the boundaries of these buffers can move. For example, we can take 9 kilobytes to zero socket, and one at a time or whatever we like. Until we leave everything by default and touch it. And in general, as I wrote above, we will work with only one socket, although we will organize some variables, arrays and structures to work with several sockets, so to speak for the future ( growth ).

This is about memory. Now, by how generally the data is transmitted via the interface of the SPI chip. There are several ways to transfer and receive data. But they are divided into two types. This is sending and receiving a fixed amount of bytes of data ( 1, 2 or 4 bytes ) and sending and receiving data of a variable size. We will need both ways, so let's see how this is done at all.

Recording a variable length data packet to the SPI bus

![image16](https://narodstream.ru/wp-content/uploads/2017/09/image16.png)

First, we pass the 16-bit memory address ( register ), respectively, the first byte — senior, the second — junior. Then we transfer the operation code, which we will consider in more detail below, and only then — data one after another. The chip will find out about the end of the data transfer on the raised ChipSelect leg.

Now about the byte of the operation code that looks like this

![image17](https://narodstream.ru/wp-content/uploads/2017/09/image17.png)

Bits **BSB ( Block Select Bits )** — this is a pointer to the block with which we work. The first 3 bits — BSB4-BSB2 — contain on the socket number, and the last two — memory unit.

Accordingly, the register block common to all sockets has the number 00000

For example, these numbers have socket blocks 0

![image18](https://narodstream.ru/wp-content/uploads/2017/09/image18.png)

And here are those, for example — socket 6

![image19](https://narodstream.ru/wp-content/uploads/2017/09/image19.png)

Bit **RWB ( Read / Write Access Mode Bit )** operation code is responsible for the type of operation. If it is 1 — then this is a record, and if 0 — reading.

A bit pair **OM ( Operation Mode )** just responsible for the type of transmission / reception, that is, a fixed data length will be an exchange or variable. These are their options

![image20](https://narodstream.ru/wp-content/uploads/2017/09/image20-1.png)

Next mode — reading data of variable length from SPI bus

![image22](https://narodstream.ru/wp-content/uploads/2017/09/image22-1.png)

Here we also first transfer 2 bytes of the register address ( memory ), then transfer the opcode with the reset read / write bit, according to which the chip finds out that we want to transfer data from it, and will begin to transfer information from memory to us from this address, until we stop this process by lifting the CS leg.

Well, the modes of reading and recording data of a fixed length work in the same way, only the transmission / reception of a strict number of bytes.

Well, we will get acquainted with the registers themselves as the code of our project is written.

B [**next part**](https://narodstream.ru/stm-urok-91-lan-w5500-http-server-chast-2/) lesson we will write the function of initializing the chip, and also begin to write the function of receiving and processing network packages.

[Embedded media](https://www.youtube.com/embed/W85Zaysv2PY)

---

Source: https://maker.wiznet.io/teddy/projects/stm-lesson-91-lan-w5500-http-server-part-1/
