diff --git a/src/port/stm32h563/README.md b/src/port/stm32h563/README.md index c40c215..7add454 100644 --- a/src/port/stm32h563/README.md +++ b/src/port/stm32h563/README.md @@ -27,7 +27,7 @@ sudo apt install gcc-arm-none-eabi openocd ```bash cd src/port/stm32h563 -make TZEN=0 +make ``` This produces `app.elf` and `app.bin` for use with TZEN=0 (TrustZone disabled). @@ -94,7 +94,7 @@ picocom -b 115200 /dev/ttyACM0 ## Example Output -When the firmware boots successfully, you should see output similar to: +When the firmware boots successfully with DHCP (default), you should see output similar to: ``` === wolfIP STM32H563 Echo Server === @@ -113,11 +113,35 @@ Entering main loop. Ready for connections! Loop starting... ``` +When static IP is enabled, the output will show "Setting IP configuration:" instead of "DHCP configuration received:". + The "PHY link: UP" message indicates the Ethernet PHY has established a link with the network. ## Network Configuration -The example configures the following static IP: +The example can be configured to use either DHCP or static IP. By default, DHCP is enabled. + +### DHCP Configuration (Default) + +By default, the device uses DHCP to automatically obtain IP address, subnet mask, gateway, and DNS server from a DHCP server on the network. The obtained configuration will be displayed on the serial console. + +**Note:** When DHCP is enabled, the device will wait up to 30 seconds for a DHCP server response during initialization. If no DHCP server is available, the device will timeout and continue without network configuration. + +### Static IP Configuration + +To use static IP instead of DHCP, set `WOLFIP_ENABLE_DHCP` to `0` in `config.h`: + +```c +#define WOLFIP_ENABLE_DHCP 0 +``` + +Or compile with: + +```bash +make CFLAGS+="-DWOLFIP_ENABLE_DHCP=0" +``` + +When static IP is enabled, the example configures the following: | Setting | Value | |---------|-------| diff --git a/src/port/stm32h563/config.h b/src/port/stm32h563/config.h index eebf072..4f7e121 100644 --- a/src/port/stm32h563/config.h +++ b/src/port/stm32h563/config.h @@ -48,9 +48,17 @@ #define WOLFIP_ENABLE_LOOPBACK 0 #endif +#ifndef WOLFIP_ENABLE_DHCP +#define WOLFIP_ENABLE_DHCP 1 +#endif + +#if WOLFIP_ENABLE_DHCP +#define DHCP +#else #define WOLFIP_IP "192.168.12.11" #define WOLFIP_NETMASK "255.255.255.0" #define WOLFIP_GW "192.168.12.1" #define WOLFIP_STATIC_DNS_IP "9.9.9.9" +#endif #endif diff --git a/src/port/stm32h563/main.c b/src/port/stm32h563/main.c index e50f9ef..68dbcc6 100644 --- a/src/port/stm32h563/main.c +++ b/src/port/stm32h563/main.c @@ -230,6 +230,34 @@ static void uart_puthex(uint32_t val) } } +static void uart_putdec(uint32_t val) +{ + char buf[12]; + int i = 0; + if (val == 0) { + uart_putc('0'); + return; + } + while (val > 0 && i < 11) { + buf[i++] = '0' + (val % 10); + val /= 10; + } + while (i > 0) { + uart_putc(buf[--i]); + } +} + +static void uart_putip4(ip4 ip) +{ + uart_putdec((ip >> 24) & 0xFF); + uart_putc('.'); + uart_putdec((ip >> 16) & 0xFF); + uart_putc('.'); + uart_putdec((ip >> 8) & 0xFF); + uart_putc('.'); + uart_putdec(ip & 0xFF); +} + /* Configure GPIO pin for Ethernet alternate function (AF11) */ static void gpio_eth_pin(uint32_t base, uint32_t pin) { @@ -420,14 +448,66 @@ int main(void) uart_puts("\n"); } - uart_puts("Setting IP configuration:\n"); - uart_puts(" IP: " WOLFIP_IP "\n"); - uart_puts(" Mask: " WOLFIP_NETMASK "\n"); - uart_puts(" GW: " WOLFIP_GW "\n"); - wolfIP_ipconfig_set(IPStack, - atoip4(WOLFIP_IP), - atoip4(WOLFIP_NETMASK), - atoip4(WOLFIP_GW)); +#ifdef DHCP + { + uint32_t dhcp_start_tick; + uint32_t dhcp_timeout; + + dhcp_timeout = 30000; /* 30 seconds timeout */ + + (void)wolfIP_poll(IPStack, tick); + if (dhcp_client_init(IPStack) >= 0) { + /* Poll immediately to send the DHCP discover packet */ + (void)wolfIP_poll(IPStack, tick); + tick++; + delay(1000); + (void)wolfIP_poll(IPStack, tick); + tick++; + delay(1000); + + /* Wait for DHCP to complete - poll frequently */ + dhcp_start_tick = tick; + while (!dhcp_bound(IPStack)) { + /* Poll the stack - this processes received packets and sends pending data */ + (void)wolfIP_poll(IPStack, tick); + /* Increment tick counter (approximate 1ms per iteration) */ + tick++; + /* Small delay to allow Ethernet DMA to work */ + delay(1000); + /* Check for timeout */ + if ((tick - dhcp_start_tick) > dhcp_timeout) + break; + } + if (dhcp_bound(IPStack)) { + ip4 ip = 0, nm = 0, gw = 0; + wolfIP_ipconfig_get(IPStack, &ip, &nm, &gw); + uart_puts("DHCP configuration received:\n"); + uart_puts(" IP: "); + uart_putip4(ip); + uart_puts("\n Mask: "); + uart_putip4(nm); + uart_puts("\n GW: "); + uart_putip4(gw); + uart_puts("\n"); + } + } + } +#else + { + ip4 ip = atoip4(WOLFIP_IP); + ip4 nm = atoip4(WOLFIP_NETMASK); + ip4 gw = atoip4(WOLFIP_GW); + uart_puts("Setting IP configuration:\n"); + uart_puts(" IP: "); + uart_putip4(ip); + uart_puts("\n Mask: "); + uart_putip4(nm); + uart_puts("\n GW: "); + uart_putip4(gw); + uart_puts("\n"); + wolfIP_ipconfig_set(IPStack, ip, nm, gw); + } +#endif uart_puts("Creating TCP socket on port 7...\n"); listen_fd = wolfIP_sock_socket(IPStack, AF_INET, IPSTACK_SOCK_STREAM, 0); diff --git a/src/wolfip.c b/src/wolfip.c index c4ccdb9..45db54b 100644 --- a/src/wolfip.c +++ b/src/wolfip.c @@ -1235,15 +1235,18 @@ static void udp_try_recv(struct wolfIP *s, unsigned int if_idx, struct wolfIP_ud return; for (i = 0; i < MAX_UDPSOCKETS; i++) { struct tsocket *t = &s->udpsockets[i]; - if (t->src_port == ee16(udp->dst_port) && t->dst_port == ee16(udp->src_port) && + uint32_t expected_len; + if (t->src_port == ee16(udp->dst_port) && (t->dst_port == 0 || t->dst_port == ee16(udp->src_port)) && (((t->local_ip == 0) && DHCP_IS_RUNNING(s)) || - (t->local_ip == dst_ip && t->remote_ip != local_ip)) ) { + (t->local_ip == dst_ip && (t->remote_ip == 0 || t->remote_ip != local_ip))) ) { if (t->local_ip == 0) t->if_idx = (uint8_t)if_idx; /* UDP datagram sanity checks */ - if ((int)frame_len != ee16(udp->len) + IP_HEADER_LEN + ETH_HEADER_LEN) + /* Allow some tolerance for padding/alignment (up to 4 bytes) */ + expected_len = ee16(udp->len) + IP_HEADER_LEN + ETH_HEADER_LEN; + if ((int)frame_len < (int)expected_len) return; /* Insert into socket buffer */ fifo_push(&t->sock.udp.rxbuf, udp, frame_len);