#include "gd32f4xx.h" #include "hardware_init.h" #include "led_driver.h" #include "uart_driver.h" #include "systick.h" #include "sdram_manager.h" #include "flash_manager.h" #include "lcd.h" #include "touch.h" #include #include // SDRAM 中分配的测试缓冲区 __attribute__((section(".sdram"))) uint8_t sdram_big_buffer[1024 * 1024]; // ============================================================= // 板级引脚定义 // ============================================================= #define LED1_PORT GPIOE #define LED1_PIN GPIO_PIN_3 #define LED2_PORT GPIOD #define LED2_PIN GPIO_PIN_7 #define LED3_PORT GPIOG #define LED3_PIN GPIO_PIN_3 #define LED4_PORT GPIOA #define LED4_PIN GPIO_PIN_5 // ============================================================= // 早期启动函数(16MHz,无 SysTick) // ============================================================= static void delay_16m(uint32_t ms) { for (volatile uint32_t i = 0; i < ms * 4000U; i++); } static void led_on(uint32_t port, uint32_t pin) { gpio_bit_set(port, pin); } static void led_off(uint32_t port, uint32_t pin) { gpio_bit_reset(port, pin); } static void led_pattern(uint8_t p) { led_off(LED1_PORT, LED1_PIN); led_off(LED2_PORT, LED2_PIN); led_off(LED3_PORT, LED3_PIN); led_off(LED4_PORT, LED4_PIN); if (p & 0x01) led_on(LED1_PORT, LED1_PIN); if (p & 0x02) led_on(LED2_PORT, LED2_PIN); if (p & 0x04) led_on(LED3_PORT, LED3_PIN); if (p & 0x08) led_on(LED4_PORT, LED4_PIN); } static void init_leds(void) { rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_GPIOE); rcu_periph_clock_enable(RCU_GPIOG); rcu_periph_clock_enable(RCU_GPIOD); gpio_mode_set(LED1_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED1_PIN); gpio_output_options_set(LED1_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED1_PIN); gpio_mode_set(LED2_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED2_PIN); gpio_output_options_set(LED2_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED2_PIN); gpio_mode_set(LED3_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED3_PIN); gpio_output_options_set(LED3_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED3_PIN); gpio_mode_set(LED4_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, LED4_PIN); gpio_output_options_set(LED4_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, LED4_PIN); led_off(LED1_PORT, LED1_PIN); led_off(LED2_PORT, LED2_PIN); led_off(LED3_PORT, LED3_PIN); led_off(LED4_PORT, LED4_PIN); } static void init_usart0(void) { rcu_periph_clock_enable(RCU_GPIOA); rcu_periph_clock_enable(RCU_USART0); gpio_af_set(GPIOA, GPIO_AF_7, GPIO_PIN_9 | GPIO_PIN_10); gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_9 | GPIO_PIN_10); gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9); usart_deinit(USART0); usart_baudrate_set(USART0, 9600U); usart_receive_config(USART0, USART_RECEIVE_ENABLE); usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); usart_enable(USART0); } static void uart_putchar(char c) { usart_data_transmit(USART0, (uint8_t)c); while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)); } static void uart_puts(const char *s) { while (*s) uart_putchar(*s++); } static void uart_putdec(uint32_t val) { char buf[16]; int idx = 0; if (val == 0) { uart_puts("0"); return; } while (val > 0) { buf[idx++] = '0' + (val % 10); val /= 10; } while (idx > 0) uart_putchar(buf[--idx]); } // 时钟切换到 168MHz 后重新配置 UART 波特率 static void reinit_usart0_168m(void) { usart_deinit(USART0); usart_baudrate_set(USART0, 9600U); usart_receive_config(USART0, USART_RECEIVE_ENABLE); usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); usart_enable(USART0); } // ============================================================= // 外设测试函数 // ============================================================= static void test_sdram_driver(void) { printf("SDRAM 驱动测试开始...\r\n"); SdramManager &sdram = SdramManager::instance(); RetCode ret = sdram.init(); if (ret != RET_OK) { printf(" SDRAM 初始化失败: 错误码=%d\r\n", ret); return; } printf(" 诊断1: 直接16位指针读写...\r\n"); volatile uint16_t *sram16 = (volatile uint16_t *)0xC0000000; for (uint32_t i = 0; i < 8; i++) sram16[i] = (uint16_t)(0xAA00 + i); __DSB(); delay_1ms(1); bool diag1_ok = true; for (uint32_t i = 0; i < 8; i++) { uint16_t val = sram16[i]; uint16_t expected = (uint16_t)(0xAA00 + i); if (val != expected) { printf(" 16位错误 @ [%lu]: 期望=0x%04X, 读取=0x%04X\r\n", i, expected, val); diag1_ok = false; } } printf(" 诊断1: %s\r\n", diag1_ok ? "通过" : "失败"); printf(" 诊断2: 直接32位指针非零值测试...\r\n"); volatile uint32_t *sram32 = (volatile uint32_t *)0xC0000000; sram32[0] = 0xDEADBEEF; sram32[1] = 0xCAFEBABE; sram32[2] = 0x12345678; sram32[3] = 0x87654321; __DSB(); delay_1ms(1); bool diag2_ok = true; for (uint32_t i = 0; i < 4; i++) { uint32_t val = sram32[i]; uint32_t expected = (i == 0) ? 0xDEADBEEF : (i == 1) ? 0xCAFEBABE : (i == 2) ? 0x12345678 : 0x87654321; if (val != expected) { printf(" 32位错误 @ [%lu]: 期望=0x%08lX, 读取=0x%08lX\r\n", i, expected, val); diag2_ok = false; } } printf(" 诊断2: %s\r\n", diag2_ok ? "通过" : "失败"); printf(" 诊断3: 驱动接口读写...\r\n"); uint32_t write_val = 0xA5A55A5A; uint32_t read_val = 0; ret = sdram.write(64, &write_val, sizeof(write_val)); if (ret != RET_OK) { printf(" 驱动写入失败: %d\r\n", ret); } else { __DSB(); ret = sdram.read(64, &read_val, sizeof(read_val)); if (ret != RET_OK) printf(" 驱动读取失败: %d\r\n", ret); else printf(" 写入=0x%08lX, 读取=0x%08lX, %s\r\n", write_val, read_val, (write_val == read_val) ? "通过" : "失败"); } printf("SDRAM 驱动测试完成\r\n"); } static void test_flash_driver(void) { printf("Flash 驱动测试开始...\r\n"); FlashManager &flash = FlashManager::instance(); RetCode ret = flash.init(); if (ret != RET_OK) { printf(" Flash 初始化失败: %d\r\n", ret); return; } printf(" Flash 信息: 总大小=%lu KB, 扇区大小=%lu KB\r\n", flash.total_size() / 1024, flash.sector_size() / 1024); uint32_t test_address = 0x08000000U + flash.total_size() - flash.sector_size(); printf(" 测试地址: 0x%08lX\r\n", test_address); uint8_t write_buffer[256]; uint8_t read_buffer[256]; for (int i = 0; i < 256; i++) write_buffer[i] = (uint8_t)((i + 0x80) & 0xFF); printf(" 擦除 Flash 扇区...\r\n"); ret = flash.erase(test_address, flash.sector_size()); if (ret != RET_OK) { printf(" Flash 擦除失败: 错误码=%d\r\n", ret); return; } printf(" Flash 擦除成功\r\n"); printf(" 写入 Flash 数据...\r\n"); ret = flash.write(test_address, write_buffer, sizeof(write_buffer)); if (ret != RET_OK) { printf(" Flash 写入失败: %d\r\n", ret); return; } printf(" Flash 写入成功\r\n"); printf(" 读取 Flash 数据...\r\n"); ret = flash.read(test_address, read_buffer, sizeof(read_buffer)); if (ret != RET_OK) { printf(" Flash 读取失败: %d\r\n", ret); return; } printf(" Flash 读取成功\r\n"); bool verify_ok = true; for (int i = 0; i < 256; i++) { if (read_buffer[i] != write_buffer[i]) { verify_ok = false; printf(" 数据错误 @ %d: 写入=%02X, 读取=%02X\r\n", i, write_buffer[i], read_buffer[i]); break; } } if (verify_ok) printf(" Flash 数据验证成功\r\n"); ret = flash.self_test(256); if (ret == RET_OK) printf(" Flash 自测试通过\r\n"); else printf(" Flash 自测试失败: %d\r\n", ret); printf("Flash 驱动测试完成\r\n"); } static void test_lcd(void) { printf("\r\n===== LCD 功能测试 =====\r\n"); printf(" LCD_Init...\r\n"); LCD_Init(); printf(" LCD ID: %s\r\n", lcd_id); delay_1ms(500); uint16_t bands[4] = {RED, GREEN, BLUE, WHITE}; for (int i = 0; i < 4; i++) { int y0 = i * 200; int y1 = y0 + 199; BlockWrite(0, 479, y0, y1); LCD_WriteRAM_Prepare(); for (int p = 0; p < 480 * 200; p++) LCD_WriteRAM(bands[i]); __DSB(); } delay_1ms(3000); printf(" LCD_Clear(BLACK)\r\n"); LCD_Clear(BLACK); delay_1ms(500); printf(" LCD_Clear(RED)\r\n"); LCD_Clear(RED); delay_1ms(500); printf("LCD 测试完成\r\n"); delay_1ms(2000); } static void test_sdram_after_lcd(void) { printf("\r\n===== SDRAM 数据保持验证 (LCD 操作后) =====\r\n"); bool ok = true; volatile uint16_t *sram16 = (volatile uint16_t *)0xC0000000; for (uint32_t i = 0; i < 8; i++) { uint16_t val = sram16[i]; uint16_t expected = (uint16_t)(0xAA00 + i); if (val != expected) { printf(" 16位错误 @ [%lu]: 期望=0x%04X, 读取=0x%04X\r\n", i, expected, val); ok = false; } } volatile uint32_t *sram32 = (volatile uint32_t *)0xC0000000; uint32_t expected_32[4] = {0xDEADBEEF, 0xCAFEBABE, 0x12345678, 0x87654321}; for (uint32_t i = 0; i < 4; i++) { uint32_t val = sram32[i]; if (val != expected_32[i]) { printf(" 32位错误 @ [%lu]: 期望=0x%08lX, 读取=0x%08lX\r\n", i, expected_32[i], val); ok = false; } } printf(" SDRAM 数据保持: %s\r\n", ok ? "通过 (LCD 未影响 SDRAM)" : "失败"); } static void concurrent_loop(void) { printf("\r\n===== 全部外设并发运行 =====\r\n"); LCD_Clear(GREEN); delay_1ms(500); uint32_t counter = 0; volatile uint16_t *sram16 = (volatile uint16_t *)0xC0000000; for (int iter = 0; iter < 10; iter++) { led_on(LED1_PORT, LED1_PIN); led_off(LED2_PORT, LED2_PIN); sram16[100 + iter] = (uint16_t)(iter * 0x1111); __DSB(); uint16_t val = sram16[100 + iter]; printf("[并发] iter=%d, SDRAM[%d]=0x%04X, LED1=ON\r\n", iter, 100 + iter, val); delay_1ms(500); led_off(LED1_PORT, LED1_PIN); led_on(LED2_PORT, LED2_PIN); sram16[200 + iter] = (uint16_t)(iter * 0x2222); __DSB(); val = sram16[200 + iter]; printf("[并发] iter=%d, SDRAM[%d]=0x%04X, LED2=ON\r\n", iter, 200 + iter, val); delay_1ms(500); counter += 2; } printf("\r\n===== 并发测试完成 =====\r\n"); LCD_Clear(BLUE); delay_1ms(1000); } // ============================================================= // Touch 测试 // ============================================================= static void test_touch(void) { printf("\r\n===== Touch 测试 (中断驱动) =====\r\n"); uint8_t ret = GT1151_Init(); if (ret != 0) { printf(" Touch 初始化失败 (ret=%d)\r\n", ret); return; } printf(" Touch 初始化成功,等待触摸中断...\r\n"); LCD_Clear(0x0841); POINT_COLOR = CYAN; LCD_ShowString(10, 10, 460, 24, 16, 0, (uint8_t *)"=== Touch Test (IRQ) ==="); POINT_COLOR = WHITE; LCD_ShowString(10, 35, 460, 24, 16, 0, (uint8_t *)"Touch screen now"); LCD_ShowString(10, 55, 300, 24, 16, 0, (uint8_t *)"IRQ driven, watch UART"); LCD_ShowString(10, 75, 200, 24, 16, 0, (uint8_t *)"X:0 Y:0"); uint16_t last_x = 0xFFFF; uint16_t last_y = 0xFFFF; uint32_t idle_counter = 0; bool was_touching = false; uint32_t iter = 0; g_touch_irq_flag = 0; while (1) { if (g_touch_irq_flag) { g_touch_irq_flag = 0; delay_1ms(5); GT1151_Scan(0); if (tp_dev.sta & TP_PRES_DOWN) { idle_counter = 0; uint16_t x = tp_dev.x[0]; uint16_t y = tp_dev.y[0]; printf("[TOUCH] iter=%lu sta=0x%02X x=%u y=%u\r\n", (unsigned long)iter, tp_dev.sta, x, y); if (x < lcddev.width && y < lcddev.height) { POINT_COLOR = BLACK; LCD_FillRectangle(10, 75, 200, 95); POINT_COLOR = GREEN; char buf[24]; sprintf(buf, "X:%-3d Y:%-3d", x, y); LCD_ShowString(10, 75, 200, 24, 16, 0, (uint8_t *)buf); if (was_touching && last_x != 0xFFFF) { POINT_COLOR = MAGENTA; LCD_DrawLine(last_x, last_y, x, y); } POINT_COLOR = YELLOW; LCD_FillCircle(x, y, 4); last_x = x; last_y = y; was_touching = true; } } else { was_touching = false; last_x = 0xFFFF; last_y = 0xFFFF; } iter++; } else { idle_counter++; delay_1ms(10); if (idle_counter > 500) { printf(" 无触摸超过 5 秒,退出 Touch 测试\r\n"); break; } } } LCD_Clear(BLUE); printf(" Touch 测试完成\r\n"); delay_1ms(500); } // ============================================================= // 主函数 // ============================================================= int main(void) { // ---- 早期启动: 16MHz,原始寄存器操作 ---- init_leds(); led_pattern(0x01); init_usart0(); led_pattern(0x03); uart_puts("\r\n===== LSPi Board Bring-Up =====\r\n"); uart_puts("Early boot: LED + UART at 16MHz\r\n"); uint32_t cs = RCU_CFG0 & RCU_CFG0_SCS; uart_puts("Clock source: "); if (cs == RCU_SCSS_IRC16M) uart_puts("IRC16M (16MHz)\r\n"); else if (cs == RCU_SCSS_HXTAL) uart_puts("HXTAL (25MHz)\r\n"); else if (cs == RCU_SCSS_PLLP) uart_puts("PLL (168MHz)\r\n"); else uart_puts("UNKNOWN\r\n"); uart_puts("SystemCoreClock: "); uart_putdec(SystemCoreClock); uart_puts(" Hz\r\n"); // LED 闪烁验证 for (int i = 0; i < 3; i++) { led_on(LED2_PORT, LED2_PIN); delay_16m(200); led_off(LED2_PORT, LED2_PIN); delay_16m(200); } uart_puts("LED blink OK\r\n"); // ---- 硬件初始化: 切换到 168MHz ---- uart_puts("Initializing hardware...\r\n"); led_pattern(0x05); hardware_init(); reinit_usart0_168m(); cs = RCU_CFG0 & RCU_CFG0_SCS; uart_puts("Clock after init: "); if (cs == RCU_SCSS_PLLP) uart_puts("PLL (168MHz)\r\n"); else uart_puts("UNKNOWN\r\n"); uart_puts("SystemCoreClock: "); uart_putdec(SystemCoreClock); uart_puts(" Hz\r\n"); // ---- C++ 驱动初始化 ---- led_pattern(0x07); LedManager::instance().init_all(); LedManager::instance().led(1).on(); delay_16m(100); LedManager::instance().led(1).off(); uart_puts("LedManager OK\r\n"); led_pattern(0x09); { UartConfig cfg; cfg.baudrate = 9600; UartBus::default_instance().init(cfg); } uart_puts("UartBus init OK\r\n"); // ---- SysTick 配置 ---- led_pattern(0x0B); systick_config(); delay_1ms(500); uart_puts("SysTick OK, delay_1ms available\r\n"); // ---- 外设测试 ---- led_pattern(0x0C); printf("\r\n========================================\r\n"); printf(" LSPi 全外设测试\r\n"); printf("========================================\r\n"); test_sdram_driver(); delay_1ms(500); test_flash_driver(); delay_1ms(500); test_lcd(); delay_1ms(500); test_sdram_after_lcd(); delay_1ms(500); concurrent_loop(); delay_1ms(500); test_touch(); delay_1ms(500); // ---- 主循环 ---- led_pattern(0x0F); printf("\r\n===== 所有外设测试完成 =====\r\n"); printf("系统运行于 168MHz, Flash/SDRAM/LCD/UART/LED 全部正常\r\n"); uint32_t tick = 0; while (1) { led_on(LED4_PORT, LED4_PIN); delay_1ms(250); led_off(LED4_PORT, LED4_PIN); delay_1ms(250); tick++; if (tick % 4 == 0) printf("."); } }