ether2ser 0.1.0
Ethernet <-> synchronous V.24 bridge firmware for RP2040 + W5500
Loading...
Searching...
No Matches
examples/w55_udp_echo/main.c
Go to the documentation of this file.
1/*
2 * ether2ser — Ethernet <-> synchronous V.24 (RS-232/V.28) bridge
3 *
4 * File: src/examples/w55_udp_echo/main.c
5 * Purpose: W5500 UDP echo example.
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 *
9 * Copyright (c) 2026 Florian <f.leuze@outlook.de>
10 */
11
12// Related headers
13
14// Standard library headers
15#include <stdint.h>
16#include <stdio.h>
17
18// Project Headers
19#include "pico/stdio.h"
20#include "pico/time.h"
21#include "socket.h"
22#include "w5500.h"
23#include "wizchip_conf.h"
24#include "wizchip_qspi_pio.h"
25#include "wizchip_spi.h"
26
27// Generated headers
28
29// Access to the WIZnet port layer's SPI handle (defined in wizchip_spi.c)
30extern wiznet_spi_handle_t spi_handle;
31
32#define UDP_SOCK 0
33#define UDP_PORT 6969 // change to 5000 if you prefer
34
35static void w5500_init_no_linkwait(void)
36{
37 // Register PIO-SPI callbacks from the port layer (spi_handle comes from wizchip_spi.h)
38 (*spi_handle)->frame_end();
39 reg_wizchip_spi_cbfunc((*spi_handle)->read_byte, (*spi_handle)->write_byte);
40 reg_wizchip_spiburst_cbfunc((*spi_handle)->read_buffer, (*spi_handle)->write_buffer);
41 reg_wizchip_cs_cbfunc((*spi_handle)->frame_start, (*spi_handle)->frame_end);
42
43 // 2 KB per socket (8 sockets) for TX and RX
44 uint8_t memsize[2][8] = {
45 {2, 2, 2, 2, 2, 2, 2, 2}, // TX buffers
46 {2, 2, 2, 2, 2, 2, 2, 2} // RX buffers
47 };
48
49 if (ctlwizchip(CW_INIT_WIZCHIP, (void*)memsize) == -1)
50 {
51 printf("W5500 init failed (CW_INIT_WIZCHIP)\r\n");
52 }
53}
54
55static void configure_network(void)
56{
57 // Configure network settings
58 wiz_NetInfo net_info = {.mac = {0x02, 0x08, 0xDC, 0x12, 0x34, 0x56}, // MAC address
59 .ip = {192, 168, 29, 11}, // IP address
60 .sn = {255, 255, 255, 0}, // Subnet mask
61 .gw = {192, 168, 29, 1}, // Gateway
62 .dns = {8, 8, 8, 8}, // DNS server
63 .dhcp = NETINFO_STATIC};
64
65 network_initialize(net_info);
66 print_network_information(net_info);
67}
68
69static void run_udp_echo_server(void)
70{
71 // Create a UDP socket bound to our chosen port. This socket will listen for
72 // incoming UDP packets and can send responses back to the source address/port.
73 printf("Starting UDP echo on port %u...\r\n", (unsigned)UDP_PORT);
74
75 // socket() allocates one of the W5500's 8 hardware sockets
76 // Parameters: socket_number, protocol_mode, local_port, flags
77 // Returns: socket_number on success, negative on failure
78 int8_t ret = socket(UDP_SOCK, Sn_MR_UDP, UDP_PORT, 0);
79 if (ret != UDP_SOCK)
80 {
81 printf("socket() failed, ret=%d\r\n", (int)ret);
82 while (true)
83 {
84 sleep_ms(1000);
85 }
86 }
87 printf("Socket opened successfully in blocking mode\r\n");
88
89 // Allocate buffers for UDP packet data and sender information
90 uint8_t recv_buf[2048]; // Payload buffer (max UDP payload in W5500)
91 uint8_t remote_ip[4]; // Remote (sender) IP address
92 uint16_t remote_port; // Remote (sender) port number
93
94 printf("Entering main echo loop (blocking mode)...\r\n");
95
96 // Main echo loop: receive packets and send them back to the sender
97 while (true)
98 {
99 // Blocking receive: waits for a UDP packet to arrive
100 // Returns: number of bytes received (>0), <0 on error
101 // Also fills remote_ip[] and remote_port with sender's address/port
102 int32_t recv_len = recvfrom(UDP_SOCK, recv_buf, sizeof(recv_buf), remote_ip, &remote_port);
103
104 if (recv_len > 0)
105 {
106 // Packet received - log the sender and byte count
107 printf("RX %ld bytes from %u.%u.%u.%u:%u\r\n", (long)recv_len, remote_ip[0],
108 remote_ip[1], remote_ip[2], remote_ip[3], remote_port);
109
110 // Echo the packet back to the sender
111 // Parameters: socket_number, data_buffer, data_length, dest_ip, dest_port
112 int32_t sent_len =
113 sendto(UDP_SOCK, recv_buf, (uint16_t)recv_len, remote_ip, remote_port);
114 if (sent_len < 0)
115 {
116 printf("sendto() error %ld\r\n", (long)sent_len);
117 }
118 }
119 else
120 {
121 // Error occurred during receive
122 printf("recvfrom() error %ld\r\n", (long)recv_len);
123 }
124 }
125}
126
127int main(void)
128{
129 stdio_init_all();
130 sleep_ms(2000);
131
132 printf("==========================================================\r\n");
133 printf("W55RP20-EVB-PICO W5500 Initialization Test\r\n");
134 printf("==========================================================\r\n");
135
136 // Initialize W5500 with more verbose debugging
137 printf("Step 1: Init PIO SPI...\r\n");
138 wizchip_spi_initialize();
139
140 printf("Step 2: Init critical section...\r\n");
141 wizchip_cris_initialize();
142
143 printf("Step 3: Reset W5500...\r\n");
144 wizchip_reset();
145
146 printf("Step 4: Call wizchip_initialize...\r\n");
147 // w5500_init_no_linkwait(); // use this for skip
148 wizchip_initialize();
149
150 printf("Step 5: Verify chip version...\r\n");
151 wizchip_check();
152
153 printf("W5500 initialization successful!\r\n");
154
156
158}
wiznet_spi_handle_t spi_handle
static void w5500_init_no_linkwait(void)
#define UDP_PORT
int main(void)
#define UDP_SOCK
static void configure_network(void)
static void run_udp_echo_server(void)