diff --git a/app/main.cpp b/app/main.cpp index 0dbd7ca..6d270b6 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -12,439 +12,37 @@ __attribute__((section(".sdram"))) uint8_t sdram_big_buffer[1024 * 1024]; -static void delay_16m(uint32_t ms) -{ - for (volatile uint32_t i = 0; i < ms * 4000U; i++) - ; -} +Led led0(GpioPort::E, 0x08); +Led led1(GpioPort::D, 0x80); +Led led2(GpioPort::G, 0x08); +Led led3(GpioPort::A, 0x20); static void led_pattern(uint8_t p) { - LedManager &lm = LedManager::instance(); - lm.led(0).off(); - lm.led(1).off(); - lm.led(2).off(); - lm.led(3).off(); - if (p & 0x01) - lm.led(0).on(); - if (p & 0x02) - lm.led(1).on(); - if (p & 0x04) - lm.led(2).on(); - if (p & 0x08) - lm.led(3).on(); + led0.off(); + led1.off(); + led2.off(); + led3.off(); + if (p & 0x01) led0.on(); + if (p & 0x02) led1.on(); + if (p & 0x04) led2.on(); + if (p & 0x08) led3.on(); } -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) -{ - Lcd &lcd = Lcd::instance(); - - printf("\r\n===== LCD 功能测试 =====\r\n"); - - printf(" LCD_Init...\r\n"); - lcd.init(); - printf(" LCD ID: %s\r\n", lcd.idString()); - delay_1ms(500); - - uint16_t bands[4] = {Lcd::RED, Lcd::GREEN, Lcd::BLUE, Lcd::WHITE}; - for (int i = 0; i < 4; i++) - { - int y0 = i * 200; - int y1 = y0 + 199; - lcd.blockWrite(0, 479, y0, y1); - lcd.writeRamPrepare(); - for (int p = 0; p < 480 * 200; p++) - lcd.writeRam(bands[i]); - __DSB(); - } - delay_1ms(3000); - - printf(" LCD_Clear(BLACK)\r\n"); - lcd.clear(Lcd::BLACK); - delay_1ms(500); - - printf(" LCD_Clear(RED)\r\n"); - lcd.clear(Lcd::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) -{ - Lcd &lcd = Lcd::instance(); - - printf("\r\n===== 全部外设并发运行 =====\r\n"); - lcd.clear(Lcd::GREEN); - delay_1ms(500); - - uint32_t counter = 0; - volatile uint16_t *sram16 = (volatile uint16_t *)0xC0000000; - - for (int iter = 0; iter < 10; iter++) - { - LedManager::instance().led(0).on(); - LedManager::instance().led(1).off(); - 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); - - LedManager::instance().led(0).off(); - LedManager::instance().led(1).on(); - 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(Lcd::BLUE); - delay_1ms(1000); -} - -static void test_touch(void) -{ - Lcd &lcd = Lcd::instance(); - GT1151 &touch = GT1151::instance(); - - printf("\r\n===== Touch 测试 (多点触控) =====\r\n"); - - RetCode ret = touch.init(); - if (ret != RET_OK) - { - printf(" Touch 初始化失败 (ret=%d)\r\n", ret); - return; - } - printf(" Touch 初始化成功,等待触摸中断...\r\n"); - - static const uint16_t TP_COLORS[5] = { - 0xFFE0, // YELLOW - point 0 - 0x07FF, // CYAN - point 1 - 0xF81F, // MAGENTA - point 2 - 0x07E0, // GREEN - point 3 - 0xF800 // RED - point 4 - }; - - const uint16_t BG_COLOR = 0x0841; - - lcd.clear(BG_COLOR); - lcd.setForeground(Lcd::CYAN); - lcd.showString(10, 10, 460, 24, 16, 0, (uint8_t *)"=== Multi-Touch (5pt) ==="); - lcd.setForeground(Lcd::WHITE); - lcd.showString(10, 30, 460, 24, 16, 0, (uint8_t *)"Touch with up to 5 fingers"); - - for (uint8_t i = 0; i < GT1151::kMaxTouch; i++) - { - lcd.setForeground(TP_COLORS[i]); - char lbl[8]; - sprintf(lbl, "P%d: --", i); - lcd.showString(10, 52 + i * 18, 200, 18, 16, 0, (uint8_t *)lbl); - } - - uint16_t last_x[5]; - uint16_t last_y[5]; - bool was_active[5]; - for (uint8_t i = 0; i < GT1151::kMaxTouch; i++) - { - last_x[i] = 0xFFFF; - last_y[i] = 0xFFFF; - was_active[i] = false; - } - - uint32_t idle_counter = 0; - GT1151::irq_flag = 0; - - while (1) - { - if (GT1151::irq_flag) - { - GT1151::irq_flag = 0; - delay_1ms(5); - - touch.scan(0); - - idle_counter = 0; - - uint8_t sta = touch.status(); - uint8_t active_cnt = touch.activeCount(); - uint8_t mask = sta & 0x1F; - - for (uint8_t i = 0; i < GT1151::kMaxTouch; i++) - { - bool active = (mask & (1 << i)) != 0; - - if (active) - { - uint16_t x = touch.x(i); - uint16_t y = touch.y(i); - - if (x < lcd.width() && y < lcd.height()) - { - lcd.setForeground(TP_COLORS[i]); - char buf[20]; - sprintf(buf, "P%d: X:%-3d Y:%-3d", i, x, y); - lcd.fillRectangle(10, 52 + i * 18, 200, 52 + i * 18 + 17); - lcd.showString(10, 52 + i * 18, 200, 18, 16, 0, (uint8_t *)buf); - - if (was_active[i] && last_x[i] != 0xFFFF) - { - lcd.setForeground(TP_COLORS[i]); - lcd.drawLine(last_x[i], last_y[i], x, y); - } - - lcd.setForeground(TP_COLORS[i]); - lcd.fillCircle(x, y, 5); - - last_x[i] = x; - last_y[i] = y; - was_active[i] = true; - } - } - else - { - if (was_active[i]) - { - lcd.setForeground(BG_COLOR); - lcd.fillCircle(last_x[i], last_y[i], 6); - - lcd.setForeground(TP_COLORS[i]); - lcd.fillRectangle(10, 52 + i * 18, 200, 52 + i * 18 + 17); - lcd.showString(10, 52 + i * 18, 200, 18, 16, 0, (uint8_t *)"released"); - - last_x[i] = 0xFFFF; - last_y[i] = 0xFFFF; - was_active[i] = false; - } - } - } - - printf("[TOUCH] cnt=%d sta=0x%02X", active_cnt, sta); - for (uint8_t i = 0; i < GT1151::kMaxTouch; i++) - { - if (mask & (1 << i)) - printf(" P%d(%u,%u)", i, touch.x(i), touch.y(i)); - } - printf("\r\n"); - } - else - { - idle_counter++; - delay_1ms(10); - if (idle_counter > 500) - { - printf(" 无触摸超过 5 秒,退出 Touch 测试\r\n"); - break; - } - } - } - - lcd.clear(Lcd::BLUE); - printf(" Touch 测试完成\r\n"); - delay_1ms(500); -} +USART uart0(UartPort::_0, 9600); int main(void) { - LedManager::instance().init_all(); + led0.init(); + led1.init(); + led2.init(); + led3.init(); led_pattern(0x01); - { - UartConfig cfg; - cfg.baudrate = 9600; - UartBus::default_instance().init(cfg); - } + USART::setDefault(&uart0); led_pattern(0x03); - printf("\r\n===== LSPi Board Bring-Up =====\r\n"); - printf("Early boot: LED + UART at 16MHz\r\n"); + printf("\r\n===== LSPi Board Boot =====\r\n"); uint32_t cs = RCU_CFG0 & RCU_CFG0_SCS; printf("Clock source: "); @@ -458,84 +56,90 @@ int main(void) printf("UNKNOWN\r\n"); printf("SystemCoreClock: %lu Hz\r\n", SystemCoreClock); - for (int i = 0; i < 3; i++) - { - LedManager::instance().led(1).on(); - delay_16m(200); - LedManager::instance().led(1).off(); - delay_16m(200); - } - printf("LED blink OK\r\n"); - - printf("Initializing hardware...\r\n"); led_pattern(0x05); - HardwareInit::init(); + led_pattern(0x07); - { - UartConfig cfg; - cfg.baudrate = 9600; - UartBus::default_instance().init(cfg); - } + uart0.reinit(9600); cs = RCU_CFG0 & RCU_CFG0_SCS; - printf("Clock after init: "); + printf("System clock switched to: "); if (cs == RCU_SCSS_PLLP) printf("PLL (168MHz)\r\n"); else printf("UNKNOWN\r\n"); printf("SystemCoreClock: %lu Hz\r\n", SystemCoreClock); - led_pattern(0x07); - printf("LedManager OK\r\n"); - led_pattern(0x09); - printf("UartBus init OK\r\n"); - - led_pattern(0x0B); systick_config(); - delay_1ms(500); - printf("SysTick OK, delay_1ms available\r\n"); + delay_1ms(10); - led_pattern(0x0C); - printf("\r\n========================================\r\n"); - printf(" LSPi 全外设测试\r\n"); - printf("========================================\r\n"); + printf("Initializing SDRAM...\r\n"); + led_pattern(0x0B); + { + RetCode ret = SdramManager::instance().init(); + if (ret != RET_OK) { + printf(" SDRAM init failed: %d\r\n", ret); + } else { + printf(" SDRAM init OK\r\n"); + } + } - test_sdram_driver(); - delay_1ms(500); + printf("Initializing Flash...\r\n"); + led_pattern(0x0D); + { + RetCode ret = FlashManager::instance().init(); + if (ret != RET_OK) { + printf(" Flash init failed: %d\r\n", ret); + } else { + printf(" Flash init OK (%lu KB total, %lu KB/sector)\r\n", + FlashManager::instance().total_size() / 1024, + FlashManager::instance().sector_size() / 1024); + } + } - test_flash_driver(); - delay_1ms(500); + printf("Initializing LCD...\r\n"); + { + RetCode ret = Lcd::instance().init(); + if (ret != RET_OK) { + printf(" LCD init failed: %d\r\n", ret); + } else { + printf(" LCD init OK (%s)\r\n", Lcd::instance().idString()); + } + } - test_lcd(); - delay_1ms(500); - - test_sdram_after_lcd(); - delay_1ms(500); - - concurrent_loop(); - delay_1ms(500); - - test_touch(); - delay_1ms(500); + printf("Initializing Touch...\r\n"); + { + RetCode ret = GT1151::instance().init(); + if (ret != RET_OK) { + printf(" Touch init failed: %d\r\n", ret); + } else { + printf(" Touch init OK\r\n"); + } + } led_pattern(0x0F); - printf("\r\n===== 所有外设测试完成 =====\r\n"); - printf("系统运行于 168MHz, Flash/SDRAM/LCD/UART/LED 全部正常\r\n"); + printf("\r\n===== System Ready =====\r\n"); + printf("CPU: 168MHz, SDRAM: 32MB, Flash: 1MB\r\n\r\n"); + + Lcd::instance().clear(Lcd::BLACK); + Lcd::instance().setForeground(Lcd::CYAN); + Lcd::instance().showString(10, 10, 460, 24, 16, 0, (uint8_t *)"LSPi System Ready"); + Lcd::instance().setForeground(Lcd::GRAY); + Lcd::instance().showString(10, 30, 460, 20, 16, 0, (uint8_t *)"168MHz | 32MB SDRAM | 1MB Flash"); uint32_t tick = 0; while (1) { - LedManager::instance().led(3).on(); - delay_1ms(250); - LedManager::instance().led(3).off(); - delay_1ms(250); + led0.toggle(); + delay_1ms(500); tick++; - if (tick % 4 == 0) + if (tick % 10 == 0) { printf("."); - if (tick % 80 == 0) - printf(" [%lu s]\r\n", tick / 4); + } + if (tick % 120 == 0) { + printf(" [%lu s]\r\n", tick / 2); + } } } diff --git a/bsp/device/led/led_driver.cpp b/bsp/device/led/led_driver.cpp index 549fb71..aef6de9 100644 --- a/bsp/device/led/led_driver.cpp +++ b/bsp/device/led/led_driver.cpp @@ -1,13 +1,16 @@ #include "led_driver.h" -Led::Led(GpioBus &bus, uint32_t pin) - : pin_(bus, pin) +Led::Led(GpioPort port, uint32_t pin) + : bus_(port), pin_(bus_, pin) { } RetCode Led::init() { - pin_.init(); + RetCode ret = bus_.init(); + if (ret != RET_OK) return ret; + ret = pin_.init(); + if (ret != RET_OK) return ret; off(); return RET_OK; } @@ -39,18 +42,10 @@ LedManager::LedManager() RetCode LedManager::init_all() { - RetCode ret; - ret = bus_a_.init(); if (ret != RET_OK) return ret; - ret = bus_d_.init(); if (ret != RET_OK) return ret; - ret = bus_e_.init(); if (ret != RET_OK) return ret; - ret = bus_g_.init(); if (ret != RET_OK) return ret; - - for (auto *l : leds_) - { - ret = l->init(); + for (auto *l : leds_) { + RetCode ret = l->init(); if (ret != RET_OK) return ret; } - return RET_OK; } diff --git a/bsp/device/led/led_driver.h b/bsp/device/led/led_driver.h index 52a859e..ed44164 100644 --- a/bsp/device/led/led_driver.h +++ b/bsp/device/led/led_driver.h @@ -7,7 +7,7 @@ class Led { public: - Led(GpioBus &bus, uint32_t pin); + Led(GpioPort port, uint32_t pin); ~Led() = default; Led(const Led &) = delete; @@ -19,8 +19,8 @@ public: void toggle(); private: + GpioBus bus_; GpioPin pin_; - GpioConfig config_; }; class LedManager { @@ -37,17 +37,12 @@ private: LedManager(); static constexpr uint8_t LED_COUNT = 4; - GpioBus bus_a_{GpioPort::A}; - GpioBus bus_d_{GpioPort::D}; - GpioBus bus_e_{GpioPort::E}; - GpioBus bus_g_{GpioPort::G}; + Led led0_{GpioPort::E, 0x08}; + Led led1_{GpioPort::D, 0x80}; + Led led2_{GpioPort::G, 0x08}; + Led led3_{GpioPort::A, 0x20}; - Led led1_{bus_e_, 0x08}; /* PE3 */ - Led led2_{bus_d_, 0x80}; /* PD7 */ - Led led3_{bus_g_, 0x08}; /* PG3 */ - Led led4_{bus_a_, 0x20}; /* PA5 */ - - Led *leds_[LED_COUNT] = {&led1_, &led2_, &led3_, &led4_}; + Led *leds_[LED_COUNT] = {&led0_, &led1_, &led2_, &led3_}; }; #endif diff --git a/drv/uart/uart_driver.cpp b/drv/uart/uart_driver.cpp index dc7c282..5e1120e 100644 --- a/drv/uart/uart_driver.cpp +++ b/drv/uart/uart_driver.cpp @@ -26,32 +26,21 @@ static constexpr uart_hw_config_t uart_hw_map[] = { {UART6, RCU_UART6, GPIOG, RCU_GPIOG, GPIO_PIN_6, GPIO_PIN_7, GPIO_AF_7}, }; -UartBus::UartBus(UartPort port) - : port_(port) -{ -} +USART *USART::default_ = nullptr; -UartBus::~UartBus() -{ - if (initialized_) { - deinit(); - } -} - -RetCode UartBus::init(const UartConfig &config) +USART::USART(UartPort port, uint32_t baudrate) + : port_(port), baudrate_(baudrate) { uint8_t port_idx = static_cast(port_); if (port_idx >= sizeof(uart_hw_map) / sizeof(uart_hw_map[0])) { - return RET_INVALID_PARAM; + return; } const uart_hw_config_t &hw = uart_hw_map[port_idx]; if (hw.uart_base == 0) { - return RET_NOT_SUPPORTED; + return; } - config_ = config; - rcu_periph_clock_enable(hw.rcu_clock); rcu_periph_clock_enable(hw.gpio_rcu); @@ -60,32 +49,29 @@ RetCode UartBus::init(const UartConfig &config) gpio_output_options_set(hw.gpio_port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, hw.tx_pin | hw.rx_pin); usart_deinit(hw.uart_base); - usart_baudrate_set(hw.uart_base, config.baudrate); + usart_baudrate_set(hw.uart_base, baudrate_); usart_receive_config(hw.uart_base, USART_RECEIVE_ENABLE); usart_transmit_config(hw.uart_base, USART_TRANSMIT_ENABLE); usart_enable(hw.uart_base); initialized_ = true; - return RET_OK; } -RetCode UartBus::deinit() +USART::~USART() { - uint8_t port_idx = static_cast(port_); - if (port_idx >= sizeof(uart_hw_map) / sizeof(uart_hw_map[0])) { - return RET_INVALID_PARAM; + if (initialized_) { + uint8_t port_idx = static_cast(port_); + if (port_idx < sizeof(uart_hw_map) / sizeof(uart_hw_map[0])) { + usart_disable(uart_hw_map[port_idx].uart_base); + } + initialized_ = false; + } + if (default_ == this) { + default_ = nullptr; } - - const uart_hw_config_t &hw = uart_hw_map[port_idx]; - - usart_disable(hw.uart_base); - rcu_periph_clock_disable(hw.rcu_clock); - - initialized_ = false; - return RET_OK; } -RetCode UartBus::send_byte(uint8_t data) +RetCode USART::send_byte(uint8_t data) { if (!initialized_) return RET_NOT_INITIALIZED; @@ -99,7 +85,7 @@ RetCode UartBus::send_byte(uint8_t data) return RET_OK; } -RetCode UartBus::send_data(const uint8_t *data, uint32_t len) +RetCode USART::send_data(const uint8_t *data, uint32_t len) { if (!initialized_) return RET_NOT_INITIALIZED; if (data == nullptr || len == 0) return RET_INVALID_PARAM; @@ -116,7 +102,7 @@ RetCode UartBus::send_data(const uint8_t *data, uint32_t len) return RET_OK; } -RetCode UartBus::receive_byte(uint8_t *data, uint32_t timeout_ms) +RetCode USART::receive_byte(uint8_t *data, uint32_t timeout_ms) { if (!initialized_) return RET_NOT_INITIALIZED; if (data == nullptr) return RET_INVALID_PARAM; @@ -141,47 +127,33 @@ RetCode UartBus::receive_byte(uint8_t *data, uint32_t timeout_ms) return RET_OK; } -RetCode UartBus::irq_handler() +void USART::reinit(uint32_t baudrate) { - if (!initialized_) return RET_NOT_INITIALIZED; - return RET_OK; + if (!initialized_) return; + + uint8_t port_idx = static_cast(port_); + if (port_idx >= sizeof(uart_hw_map) / sizeof(uart_hw_map[0])) return; + + const uart_hw_config_t &hw = uart_hw_map[port_idx]; + baudrate_ = baudrate; + + usart_disable(hw.uart_base); + usart_baudrate_set(hw.uart_base, baudrate_); + usart_enable(hw.uart_base); } -UartBus &UartBus::default_instance() +void USART::setDefault(USART *uart) { - static UartBus instance(UartPort::_0); - static bool default_inited = false; - - if (!default_inited) { - UartConfig default_config; - default_config.baudrate = 115200; - instance.init(default_config); - default_inited = true; - } - - return instance; -} - -extern "C" int fputc(int ch, FILE *f) -{ - (void)f; - UartBus &uart = UartBus::default_instance(); - uart.send_byte(static_cast(ch)); - return ch; -} - -extern "C" int __io_putchar(int ch) -{ - UartBus &uart = UartBus::default_instance(); - uart.send_byte(static_cast(ch)); - return ch; + default_ = uart; } extern "C" int _write(int file, char *ptr, int len) { if (file == STDOUT_FILENO || file == STDERR_FILENO) { - UartBus &uart = UartBus::default_instance(); - uart.send_data(reinterpret_cast(ptr), static_cast(len)); + USART *uart = USART::defaultInstance(); + if (uart) { + uart->send_data(reinterpret_cast(ptr), static_cast(len)); + } return len; } errno = EBADF; @@ -245,16 +217,17 @@ extern "C" void _exit(int status) while (1); } +/* C-compatible wrappers for legacy code */ extern "C" { -static UartBus uart_0(UartPort::_0); -static UartBus uart_1(UartPort::_1); -static UartBus uart_2(UartPort::_2); -static UartBus uart_3(UartPort::_3); -static UartBus uart_4(UartPort::_4); -static UartBus uart_5(UartPort::_5); -static UartBus uart_6(UartPort::_6); -static UartBus *uart_instances[] = { +static USART uart_0(UartPort::_0); +static USART uart_1(UartPort::_1); +static USART uart_2(UartPort::_2); +static USART uart_3(UartPort::_3); +static USART uart_4(UartPort::_4); +static USART uart_5(UartPort::_5); +static USART uart_6(UartPort::_6); +static USART *uart_instances[] = { &uart_0, &uart_1, &uart_2, &uart_3, &uart_4, &uart_5, &uart_6, }; static uint8_t uart_inited[7] = {0}; @@ -262,11 +235,8 @@ static uint8_t uart_inited[7] = {0}; int uart_init(uint8_t port, uint32_t baudrate) { if (port >= 7) return -1; - UartConfig cfg; - cfg.baudrate = baudrate; - RetCode ret = uart_instances[port]->init(cfg); - uart_inited[port] = (ret == RET_OK) ? 1 : 0; - return uart_inited[port] ? 0 : -1; + uart_inited[port] = 1; + return 0; } int uart_send_byte(uint8_t port, uint8_t data) diff --git a/drv/uart/uart_driver.h b/drv/uart/uart_driver.h index fc4b746..b150089 100644 --- a/drv/uart/uart_driver.h +++ b/drv/uart/uart_driver.h @@ -10,34 +10,31 @@ enum class UartPort : uint8_t { MAX }; -struct UartConfig { - uint32_t baudrate = 115200; - uint8_t data_bits = 8; - uint8_t stop_bits = 1; - uint8_t parity = 0; -}; - -class UartBus { +class USART { public: - explicit UartBus(UartPort port); - ~UartBus(); + USART(UartPort port, uint32_t baudrate = 115200); + ~USART(); - UartBus(const UartBus &) = delete; - UartBus &operator=(const UartBus &) = delete; + USART(const USART &) = delete; + USART &operator=(const USART &) = delete; - RetCode init(const UartConfig &config); - RetCode deinit(); RetCode send_byte(uint8_t data); RetCode send_data(const uint8_t *data, uint32_t len); RetCode receive_byte(uint8_t *data, uint32_t timeout_ms); - RetCode irq_handler(); + void reinit(uint32_t baudrate); - static UartBus &default_instance(); + UartPort port() const { return port_; } + bool is_initialized() const { return initialized_; } + + static void setDefault(USART *uart); + static USART *defaultInstance() { return default_; } private: UartPort port_; - UartConfig config_; + uint32_t baudrate_; bool initialized_ = false; + + static USART *default_; }; #endif diff --git a/libs/common/iap/iap.cpp b/libs/common/iap/iap.cpp index a481e9f..d2baba1 100644 --- a/libs/common/iap/iap.cpp +++ b/libs/common/iap/iap.cpp @@ -56,7 +56,7 @@ RetCode Iap::init() return RET_OK; } -RetCode Iap::receiveFirmware(UartBus &uart, uint32_t timeout_ms) +RetCode Iap::receiveFirmware(USART &uart, uint32_t timeout_ms) { if (!initialized_) return RET_NOT_INITIALIZED; @@ -231,12 +231,12 @@ uint32_t Iap::bootFlagRead(void) // 潩潩潩潩潩 Ymodem Receive 潩潩潩潩潩 -void Iap::ymodemSend(UartBus &uart, uint8_t b) +void Iap::ymodemSend(USART &uart, uint8_t b) { uart.send_byte(b); } -int Iap::ymodemRead(UartBus &uart, uint32_t timeout_ms) +int Iap::ymodemRead(USART &uart, uint32_t timeout_ms) { uint8_t b; RetCode ret = uart.receive_byte(&b, timeout_ms); @@ -245,7 +245,7 @@ int Iap::ymodemRead(UartBus &uart, uint32_t timeout_ms) return (int)b; } -RetCode Iap::ymodemReceive(UartBus &uart, uint32_t timeout_ms) +RetCode Iap::ymodemReceive(USART &uart, uint32_t timeout_ms) { uint8_t pkt_buf[YM_PACKET_SIZE_1024 + YM_PACKET_OVERHEAD]; uint32_t total_received = 0; @@ -430,7 +430,7 @@ RetCode Iap::ymodemReceive(UartBus &uart, uint32_t timeout_ms) return RET_TIMEOUT; } -int Iap::ymodemReadPacket(UartBus &uart, uint8_t *buf, uint32_t timeout_ms) +int Iap::ymodemReadPacket(USART &uart, uint8_t *buf, uint32_t timeout_ms) { int byte = ymodemRead(uart, timeout_ms); if (byte < 0) diff --git a/libs/common/iap/iap.h b/libs/common/iap/iap.h index 51ba35f..e9fd4a6 100644 --- a/libs/common/iap/iap.h +++ b/libs/common/iap/iap.h @@ -4,7 +4,7 @@ #include #include "common_types.h" -class UartBus; +class USART; #define IAP_APP_BASE_ADDR 0x08010000U #define IAP_BOOTLOADER_SIZE (64U * 1024U) @@ -17,7 +17,7 @@ public: RetCode init(); - RetCode receiveFirmware(UartBus &uart, uint32_t timeout_ms = 120000); + RetCode receiveFirmware(USART &uart, uint32_t timeout_ms = 120000); RetCode programFirmware(uint32_t flash_addr); @@ -41,10 +41,10 @@ private: static RetCode backupDomainEnable(void); - RetCode ymodemReceive(UartBus &uart, uint32_t timeout_ms); - int ymodemReadPacket(UartBus &uart, uint8_t *buf, uint32_t timeout_ms); - void ymodemSend(UartBus &uart, uint8_t b); - int ymodemRead(UartBus &uart, uint32_t timeout_ms); + RetCode ymodemReceive(USART &uart, uint32_t timeout_ms); + int ymodemReadPacket(USART &uart, uint8_t *buf, uint32_t timeout_ms); + void ymodemSend(USART &uart, uint8_t b); + int ymodemRead(USART &uart, uint32_t timeout_ms); static uint16_t crc16(const uint8_t *data, uint32_t len);