From 689c3b7b6daf125590ce4c54d206e21b9cd96283 Mon Sep 17 00:00:00 2001 From: James Smith Date: Tue, 12 Aug 2025 19:28:06 -0700 Subject: [PATCH] Add si_deinit function --- firmware/libsi/include/si/si.h | 7 ++++- .../libsi/src/platform/efr32/si_efr32_emlib.c | 31 ++++++++++++++++++- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/firmware/libsi/include/si/si.h b/firmware/libsi/include/si/si.h index 2b83ec7..0ada0a3 100644 --- a/firmware/libsi/include/si/si.h +++ b/firmware/libsi/include/si/si.h @@ -145,4 +145,9 @@ void si_read_bytes(uint8_t *buffer, uint8_t max_length, si_byte_cb_t byte_callba * * This function will block until the SI bus is idle. */ -void si_await_bus_idle(void); \ No newline at end of file +void si_await_bus_idle(void); + +/** + * Deinitialize the SI bus. + */ +void si_deinit(void); \ No newline at end of file diff --git a/firmware/libsi/src/platform/efr32/si_efr32_emlib.c b/firmware/libsi/src/platform/efr32/si_efr32_emlib.c index 3168e87..53af118 100644 --- a/firmware/libsi/src/platform/efr32/si_efr32_emlib.c +++ b/firmware/libsi/src/platform/efr32/si_efr32_emlib.c @@ -82,6 +82,7 @@ static uint8_t si_data_port; static uint8_t si_data_pin; static bool si_mode; +static bool si_initialized = false; // RX state static uint16_t rx_edge_timings[2][RX_BUFFER_SIZE]; @@ -146,6 +147,8 @@ void si_init(uint8_t port, uint8_t pin, uint8_t mode, uint32_t rx_freq, uint32_t si_data_port = port; si_data_pin = pin; si_mode = mode; + + si_initialized = true; } void si_write_bytes(const uint8_t *bytes, uint8_t length, si_complete_cb_t callback) @@ -373,4 +376,30 @@ void SI_TX_USART_IRQHandler() // Call the transfer callback with the number of bytes written if (si_xfer.complete_callback) si_xfer.complete_callback(si_xfer.max_length); -} \ No newline at end of file +} + +// Deinitialize SI peripherals +void si_deinit(void) +{ + if (!si_initialized) + return; + + // Disable timers + TIMER_Enable(SI_RX_TIMER, false); + + // Disable USART + USART_Enable(SI_TX_USART, usartDisable); + + // Free DMA channels + DMADRV_FreeChannel(rx_dma_channel); + DMADRV_FreeChannel(tx_dma_channel); + + // Remove peripheral routes + GPIO->TIMERROUTE[SI_RX_TIMER_IDX].ROUTEEN = 0; + GPIO->USARTROUTE[SI_TX_USART_IDX].ROUTEEN = 0; + + // Reset GPIO pin to input (safe state) + GPIO_PinModeSet(si_data_port, si_data_pin, gpioModeInput, 0); + + si_initialized = false; +}