refactor: UartBus全面重构为USART,支持直接构造即可用
- UartBus -> USART (类名更符合外设命名规范) - 构造函数 USART(UartPort port, uint32_t baudrate) 自动完成GPIO+外设初始化 - 移除default_instance()单例模式,移除init()/deinit()/irq_handler() - 新增reinit(baudrate)支持时钟切换后波特率重新校准 - 新增static setDefault()用于printf路由选择 - 移除UartConfig配置结构体 - 更新iap.h/iap.cpp中UartBus引用为USART - 更新main.cpp使用新USART构造模式
This commit is contained in:
+78
-474
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+48
-78
@@ -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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(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<uint8_t>(ch));
|
||||
return ch;
|
||||
}
|
||||
|
||||
extern "C" int __io_putchar(int ch)
|
||||
{
|
||||
UartBus &uart = UartBus::default_instance();
|
||||
uart.send_byte(static_cast<uint8_t>(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<const uint8_t *>(ptr), static_cast<uint32_t>(len));
|
||||
USART *uart = USART::defaultInstance();
|
||||
if (uart) {
|
||||
uart->send_data(reinterpret_cast<const uint8_t *>(ptr), static_cast<uint32_t>(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)
|
||||
|
||||
+14
-17
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <cstdint>
|
||||
#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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user