#include #include "ch32fun.h" #include "ch32v20xhw.h" #include "ethernetif.h" #include "lwip/dhcp.h" #include "lwip/init.h" #include "lwip/netif.h" #include "lwip/timeouts.h" #include "netif/ethernet.h" #include "systick.h" #define LED1_PIN 0 #define LED2_PIN 2 #define RCC_PREDIV1_OFFSET 0 struct netif g_netif; void init_leds() { RCC->APB2PCENR |= RCC_APB2Periph_GPIOA; GPIOA->CFGLR &= ~((0xf << (4 * 0)) | (0xf << (4 * 2))); GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 0); GPIOA->CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP) << (4 * 2); } int main() { SystemInit(); // 1. HSE (32MHz) // 2. PREDIV1 / 4. // 3. PLL source = HSE, PLL x15. // 4. (32MHz / 4) * 15 = 120MHz SYSCLK RCC->INTR = 0x009F0000; RCC->CTLR &= ~(RCC_HSE_ON | RCC_PLLON); RCC->CFGR0 = 0x00000000; RCC->CTLR |= RCC_HSE_ON; int timeout; for (timeout = 10000; timeout > 0; timeout--) { if (RCC->CTLR & RCC_HSERDY) break; // wait for HSE } if (timeout == 0) { printf("Error: HSE failed to start\n"); return -1; } RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; RCC->CFGR2 = ((3) << 0); // PREDIV1 divisor = 3+1 = 4 RCC->CFGR0 |= RCC_PLLSource_HSE_Div1 | RCC_PLLMul_15; RCC->CTLR |= RCC_PLLON; printf("Main PLL enabled. Waiting for lock...\n"); for (timeout = 10000; timeout > 0; timeout--) { if (RCC->CTLR & RCC_PLLRDY) break; } if (timeout == 0) { printf("error: main pll lock failed\n"); return -1; } printf("Main PLL Locked\n"); RCC->CFGR0 = (RCC->CFGR0 & ~RCC_SW) | RCC_SW_PLL; while ((RCC->CFGR0 & RCC_SWS) != RCC_SWS_PLL); printf("SysClock set to 120MHz\n"); systick_init(); init_leds(); lwip_init(); ip_addr_t ipaddr, netmask, gw; IP4_ADDR(&ipaddr, 0, 0, 0, 0); IP4_ADDR(&netmask, 0, 0, 0, 0); IP4_ADDR(&gw, 0, 0, 0, 0); netif_add(&g_netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, ðernet_input); netif_set_default(&g_netif); netif_set_up(&g_netif); dhcp_start(&g_netif); ethernetif_init(&g_netif); uint32_t last_led_toggle = 0; uint32_t last_send_time = 0; int led_state = 0; while (1) { ethernetif_link_poll(&g_netif); if (netif_is_link_up(&g_netif)) { ethernetif_input(&g_netif); } sys_check_timeouts(); // run_tx_test(); uint32_t now = millis(); if (now - last_led_toggle > 500) { if (led_state) { GPIOA->BSHR = (1 << 0); } else { GPIOA->BSHR = (1 << (0 + 16)); } led_state = !led_state; last_led_toggle = now; } static int ip_printed = 0; if (g_netif.ip_addr.addr != 0 && !ip_printed) { printf("IP address assigned: %s\n", ip4addr_ntoa(netif_ip4_addr(&g_netif))); ip_printed = 1; } } }