From 6d4c985c9a2c1d937add144bc70b5b18df33021e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 10 Jul 2026 00:17:55 +0700 Subject: kinetis_k: non-blocking board_uart_read (RX FIFO) + SIM unique id - board_uart_read was a stub returning 0, so host examples that bridge the UART console to a CDC device (echo test) received nothing. Implement it via an RDRF-interrupt-fed tu_fifo, matching the stm32 family (non-blocking, no RX overrun). board_uart_write is already non-blocking. - implement board_get_unique_id() from the SIM 128-bit UID registers so frdm_k64f/teensy_35 report a real USB serial instead of the fixed default. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01ExGPLP5eU43LR7o6yYLpNi --- hw/bsp/kinetis_k/family.c | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/hw/bsp/kinetis_k/family.c b/hw/bsp/kinetis_k/family.c index a5af83931..238123f30 100644 --- a/hw/bsp/kinetis_k/family.c +++ b/hw/bsp/kinetis_k/family.c @@ -35,10 +35,25 @@ #include "fsl_clock.h" #include "fsl_uart.h" #include "fsl_sysmpu.h" +#include "common/tusb_fifo.h" #include "board/clock_config.h" #include "board/pin_mux.h" +#ifdef UART_DEV +// RX ring buffer filled by the RDRF interrupt so board_uart_read() is non-blocking +// and does not drop bytes to UART overrun (see stm32 family for reference). +static uint8_t uart_rx_ff_buf[32]; +static tu_fifo_t uart_rx_ff; + +void UART0_RX_TX_IRQHandler(void) { + if (UART_DEV->S1 & UART_S1_RDRF_MASK) { + uint8_t byte = UART_DEV->D; // reading S1 then D clears RDRF (and any overrun) + tu_fifo_write(&uart_rx_ff, &byte); + } +} +#endif + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ @@ -89,6 +104,9 @@ void board_init(void) { .enableRx = true }; UART_Init(UART_DEV, &uart_config, UART_CLOCK); + tu_fifo_config(&uart_rx_ff, uart_rx_ff_buf, sizeof(uart_rx_ff_buf), false); + UART_DEV->C2 |= UART_C2_RIE_MASK; // enable RX data register full interrupt + NVIC_EnableIRQ(UART0_RX_TX_IRQn); #endif // USB @@ -112,14 +130,11 @@ uint32_t board_button_read(void) { } int board_uart_read(uint8_t *buf, int len) { - (void) buf; - (void) len; #ifdef UART_DEV - // Read blocking will block until there is data -// UART_ReadBlocking(UART_DEV, buf, len); -// return len; - return 0; + return (int) tu_fifo_read_n(&uart_rx_ff, buf, (uint16_t) len); #else + (void) buf; + (void) len; return 0; #endif } @@ -144,6 +159,20 @@ int board_uart_write(void const *buf, int len) { #endif } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + // Kinetis 128-bit Unique Identification Register (SIM->UIDH/UIDMH/UIDML/UIDL) + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + uint8_t const len = 16; + + id32[0] = SIM->UIDH; + id32[1] = SIM->UIDMH; + id32[2] = SIM->UIDML; + id32[3] = SIM->UIDL; + + return len; +} + #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; -- cgit v1.3.1