From 78a09c8ad3fb8c03fa23a3e819c69dac9281547e Mon Sep 17 00:00:00 2001 From: Vladimir Smitka Date: Fri, 16 Oct 2026 20:50:45 +0000 Subject: [PATCH 1/2] Use the selected LPSPI clock source on i.MX RT Most i.MX RT chips feed LPSPI from PLL2, but the driver assumed PLL3 PFD0, so SPI ran about 10% faster than requested and reported the wrong frequency. --- ports/mimxrt10xx/common-hal/busio/SPI.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index 0fd54e3e779..b61073124d5 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -19,7 +19,15 @@ #if IMXRT11XX #define LPSPI_MASTER_CLK_FREQ (24000000) #else -#define LPSPI_MASTER_CLK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (CLOCK_GetDiv(kCLOCK_LpspiDiv) + 1)) +#define LPSPI_MASTER_CLK_FREQ (lpspi_clock_freq()) + +static uint32_t lpspi_clock_freq(void) { + // Indexed by the LPSPI_CLK_SEL mux setting. + static const clock_name_t sources[] = { + kCLOCK_Usb1PllPfd1Clk, kCLOCK_Usb1PllPfd0Clk, kCLOCK_SysPllClk, kCLOCK_SysPllPfd2Clk + }; + return CLOCK_GetFreq(sources[CLOCK_GetMux(kCLOCK_LpspiMux)]) / (CLOCK_GetDiv(kCLOCK_LpspiDiv) + 1); +} #endif #define MAX_SPI_BUSY_RETRIES 100 From 2f39165f21471644b982fa6b5c1b34c6ca074cc2 Mon Sep 17 00:00:00 2001 From: Vladimir Smitka Date: Fri, 16 Oct 2026 20:50:51 +0000 Subject: [PATCH 2/2] Skip SPI reinit when the settings are unchanged configure() compared the requested frequency with the achieved one and had a misplaced parenthesis in the bits check, so it reinitialized LPSPI on every transaction. --- ports/mimxrt10xx/common-hal/busio/SPI.c | 6 ++++-- ports/mimxrt10xx/common-hal/busio/SPI.h | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index b61073124d5..b37fbb84556 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -177,6 +177,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Always start at 250khz which is what SD cards need. They are sensitive to // SPI bus noise before they are put into SPI mode. config.baudRate = 250000; + self->target_frequency = config.baudRate; LPSPI_MasterInit(self->spi, &config, LPSPI_MASTER_CLK_FREQ); LPSPI_Enable(self->spi, false); uint32_t tcrPrescaleValue; @@ -227,8 +228,8 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, if ((polarity == common_hal_busio_spi_get_polarity(self)) && (phase == common_hal_busio_spi_get_phase(self)) && - (bits == ((self->spi->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT)) + 1 && - (baudrate == common_hal_busio_spi_get_frequency(self))) { + (bits == ((self->spi->TCR & LPSPI_TCR_FRAMESZ_MASK) >> LPSPI_TCR_FRAMESZ_SHIFT) + 1) && + (baudrate == self->target_frequency)) { return true; } @@ -254,6 +255,7 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, LPSPI_Enable(self->spi, false); self->baudrate = LPSPI_MasterSetBaudRate(self->spi, baudrate, LPSPI_MASTER_CLK_FREQ, &tcrPrescaleValue); LPSPI_Enable(self->spi, true); + self->target_frequency = baudrate; return true; } diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.h b/ports/mimxrt10xx/common-hal/busio/SPI.h index d86489428ec..111c71f94f1 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.h +++ b/ports/mimxrt10xx/common-hal/busio/SPI.h @@ -17,6 +17,7 @@ typedef struct { LPSPI_Type *spi; bool has_lock; uint32_t baudrate; + uint32_t target_frequency; const mcu_periph_obj_t *clock; const mcu_periph_obj_t *mosi; const mcu_periph_obj_t *miso;