summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2026-07-10 00:17:55 +0700
committerhathach <[email protected]>2026-07-17 17:26:04 +0700
commit6d4c985c9a2c1d937add144bc70b5b18df33021e (patch)
tree3c62591c72e48244dcfe36177f522e2fe1b30ae5
parent439a60a87f4039beba5a1d202b7ff6f9d93745dc (diff)
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) <[email protected]> Claude-Session: https://claude.ai/code/session_01ExGPLP5eU43LR7o6yYLpNi
-rw-r--r--hw/bsp/kinetis_k/family.c41
1 files 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;