From 79ebb49c7e538a07ddbc3e82fd1b824f7877e62e Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Tue, 16 Apr 2024 16:53:52 -0700 Subject: [PATCH 1/5] Fix teensy4 build --- .../TARGET_MIMXRT105x/TARGET_TEENSY_4X/bootdata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/TARGET_TEENSY_4X/bootdata.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/TARGET_TEENSY_4X/bootdata.c index dc5c4271b67..b450ac9ad15 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/TARGET_TEENSY_4X/bootdata.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/TARGET_TEENSY_4X/bootdata.c @@ -40,7 +40,7 @@ */ #include -#include +#include extern void Reset_Handler(void); extern unsigned long _estack; From 3360720cf983fec715da869a6d08492be664beda Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Wed, 17 Apr 2024 15:46:18 -0700 Subject: [PATCH 2/5] Try and fix SCLK clock period issue for MIMXRT, add additional SPI pinmappings --- platform/source/mbed_error.c | 2 ++ platform/source/mbed_sdk_boot.c | 1 + .../TARGET_IMX/spi_api.c | 15 ++++++++++++ .../TARGET_MIMXRT105x/PeripheralPins.c | 24 +++++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/platform/source/mbed_error.c b/platform/source/mbed_error.c index 50c476f6b0e..af888012c7f 100644 --- a/platform/source/mbed_error.c +++ b/platform/source/mbed_error.c @@ -116,6 +116,7 @@ static inline bool mbed_error_is_hw_fault(mbed_error_status_t error_status) error_status == MBED_ERROR_HARDFAULT_EXCEPTION); } +#ifdef MBED_CONF_RTOS_PRESENT static bool mbed_error_is_handler(const mbed_error_ctx *ctx) { bool is_handler = false; @@ -133,6 +134,7 @@ static bool mbed_error_is_handler(const mbed_error_ctx *ctx) } return is_handler; } +#endif //Set an error status with the error handling system static mbed_error_status_t handle_error(mbed_error_status_t error_status, unsigned int error_value, const char *filename, int line_number, void *caller) diff --git a/platform/source/mbed_sdk_boot.c b/platform/source/mbed_sdk_boot.c index 0d0f3b664eb..34f8005412e 100644 --- a/platform/source/mbed_sdk_boot.c +++ b/platform/source/mbed_sdk_boot.c @@ -15,6 +15,7 @@ * limitations under the License. */ +#include "mbed_error.h" #include "mbed_toolchain.h" #include #include diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c index 5ad86970767..d0421df0c6d 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c @@ -97,6 +97,21 @@ void spi_frequency(spi_t *obj, int hz) spibase->TCR = (spibase->TCR & ~LPSPI_TCR_PRESCALE_MASK) | LPSPI_TCR_PRESCALE(tcrPrescaleValue); + // We also need to recalculate the CCR.DBT field, as this register + // controls the length of the half clock cycle between the end of one frame and the start of the next. + // FSL HAL isn't smart enough to do this automatically. + + // Step 1: Get the current SCLK period, in LPSPI functional clock periods, that was calculated by + // LPSPI_MasterSetBaudRate(). This is given by the CCR.SCKDIV bitfield plus 2. + const uint32_t sclkPeriodClocks = ((spibase->CCR & LPSPI_CCR_SCKDIV_MASK) >> LPSPI_CCR_SCKDIV_SHIFT) + 2; + + // Step 2: Divide by 2, rounding up + const uint32_t sclkLowTimeClocks = (sclkPeriodClocks + 1) / 2; + + // Step 3: Set this value into the DBT field. The value used by HW is one higher than the value in the register + // so we have to subtract. + spibase->CCR = (spibase->CCR & ~LPSPI_CCR_DBT_MASK) | LPSPI_CCR_DBT(sclkLowTimeClocks - 1); + /* Enable the LPSPI module */ LPSPI_Enable(spibase, true); } diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c index 20c4076e44d..b7c40c77410 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c @@ -123,23 +123,47 @@ const PinMap PinMap_UART_RX[] = { /************SPI***************/ const PinMap PinMap_SPI_SCLK[] = { + {GPIO_EMC_27, SPI_1, ((0U << DAISY_REG_VALUE_SHIFT) | (0x4F0 << DAISY_REG_SHIFT) | 3)}, {GPIO_SD_B0_00, SPI_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x4F0 << DAISY_REG_SHIFT) | 4)}, + + {GPIO_SD_B1_07, SPI_2, ((0U << DAISY_REG_VALUE_SHIFT) | (0x500 << DAISY_REG_SHIFT) | 4)}, + {GPIO_EMC_00, SPI_2, ((1U << DAISY_REG_VALUE_SHIFT) | (0x500 << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B0_00, SPI_3, ((0U << DAISY_REG_VALUE_SHIFT) | (0x510 << DAISY_REG_SHIFT) | 7)}, + {GPIO_AD_B1_15, SPI_3, ((1U << DAISY_REG_VALUE_SHIFT) | (0x510 << DAISY_REG_SHIFT) | 2)}, + {GPIO_B0_03, SPI_4, ((0U << DAISY_REG_VALUE_SHIFT) | (0x520 << DAISY_REG_SHIFT) | 3)}, + {GPIO_B1_07, SPI_4, ((1U << DAISY_REG_VALUE_SHIFT) | (0x520 << DAISY_REG_SHIFT) | 1)}, {NC , NC , 0} }; const PinMap PinMap_SPI_MOSI[] = { + {GPIO_EMC_28, SPI_1, ((0U << DAISY_REG_VALUE_SHIFT) | (0x4F8 << DAISY_REG_SHIFT) | 3)}, {GPIO_SD_B0_02, SPI_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x4F8 << DAISY_REG_SHIFT) | 4)}, + + {GPIO_SD_B1_08, SPI_2, ((0U << DAISY_REG_VALUE_SHIFT) | (0x508 << DAISY_REG_SHIFT) | 4)}, + {GPIO_EMC_02, SPI_2, ((1U << DAISY_REG_VALUE_SHIFT) | (0x508 << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B0_01, SPI_3, ((0U << DAISY_REG_VALUE_SHIFT) | (0x518 << DAISY_REG_SHIFT) | 7)}, + {GPIO_AD_B1_14, SPI_3, ((1U << DAISY_REG_VALUE_SHIFT) | (0x518 << DAISY_REG_SHIFT) | 2)}, + {GPIO_B0_02, SPI_4, ((0U << DAISY_REG_VALUE_SHIFT) | (0x528 << DAISY_REG_SHIFT) | 3)}, + {GPIO_B1_06, SPI_4, ((1U << DAISY_REG_VALUE_SHIFT) | (0x528 << DAISY_REG_SHIFT) | 1)}, {NC , NC , 0} }; const PinMap PinMap_SPI_MISO[] = { + {GPIO_EMC_29, SPI_1, ((0U << DAISY_REG_VALUE_SHIFT) | (0x4F4 << DAISY_REG_SHIFT) | 3)}, {GPIO_SD_B0_03, SPI_1, ((1U << DAISY_REG_VALUE_SHIFT) | (0x4F4 << DAISY_REG_SHIFT) | 4)}, + + {GPIO_SD_B1_09, SPI_2, ((0U << DAISY_REG_VALUE_SHIFT) | (0x504 << DAISY_REG_SHIFT) | 4)}, + {GPIO_EMC_03, SPI_2, ((1U << DAISY_REG_VALUE_SHIFT) | (0x504 << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B0_02, SPI_3, ((0U << DAISY_REG_VALUE_SHIFT) | (0x514 << DAISY_REG_SHIFT) | 7)}, + {GPIO_AD_B1_13, SPI_3, ((1U << DAISY_REG_VALUE_SHIFT) | (0x514 << DAISY_REG_SHIFT) | 2)}, + {GPIO_B0_01, SPI_4, ((0U << DAISY_REG_VALUE_SHIFT) | (0x524 << DAISY_REG_SHIFT) | 3)}, + {GPIO_B1_05, SPI_4, ((1U << DAISY_REG_VALUE_SHIFT) | (0x524 << DAISY_REG_SHIFT) | 1)}, {NC , NC , 0} }; From 8cac036937f91cb8e65399ac78e4a53646bab191 Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Mon, 22 Apr 2024 12:18:19 -0700 Subject: [PATCH 3/5] Add full UART pinmapping --- .../TARGET_MIMXRT105x/PeripheralPins.c | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c index b7c40c77410..31211fcff89 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralPins.c @@ -109,15 +109,61 @@ const PinMap PinMap_I2C_SCL[] = { /************UART***************/ const PinMap PinMap_UART_TX[] = { {GPIO_AD_B0_12, UART_1, 2}, + + {GPIO_SD_B1_11, UART_2, ((0 << DAISY_REG_VALUE_SHIFT) | (0x530 << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B1_02, UART_2, ((1 << DAISY_REG_VALUE_SHIFT) | (0x530 << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B1_06, UART_3, ((0 << DAISY_REG_VALUE_SHIFT) | (0x53C << DAISY_REG_SHIFT) | 2)}, + {GPIO_EMC_13 , UART_3, ((1 << DAISY_REG_VALUE_SHIFT) | (0x53C << DAISY_REG_SHIFT) | 2)}, + {GPIO_B0_08 , UART_3, ((2 << DAISY_REG_VALUE_SHIFT) | (0x53C << DAISY_REG_SHIFT) | 3)}, + + {GPIO_SD_B1_00, UART_4, ((0 << DAISY_REG_VALUE_SHIFT) | (0x544 << DAISY_REG_SHIFT) | 4)}, + {GPIO_EMC_19 , UART_4, ((1 << DAISY_REG_VALUE_SHIFT) | (0x544 << DAISY_REG_SHIFT) | 2)}, + {GPIO_B1_00 , UART_4, ((2 << DAISY_REG_VALUE_SHIFT) | (0x544 << DAISY_REG_SHIFT) | 2)}, + + {GPIO_EMC_23 , UART_5, ((0 << DAISY_REG_VALUE_SHIFT) | (0x54C << DAISY_REG_SHIFT) | 2)}, + {GPIO_B1_12 , UART_5, ((1 << DAISY_REG_VALUE_SHIFT) | (0x54C << DAISY_REG_SHIFT) | 1)}, + + {GPIO_EMC_25 , UART_6, ((0 << DAISY_REG_VALUE_SHIFT) | (0x554 << DAISY_REG_SHIFT) | 2)}, {GPIO_AD_B0_02, UART_6, ((1 << DAISY_REG_VALUE_SHIFT) | (0x554 << DAISY_REG_SHIFT) | 2)}, + + {GPIO_SD_B1_08, UART_7, ((0 << DAISY_REG_VALUE_SHIFT) | (0x55C << DAISY_REG_SHIFT) | 2)}, + {GPIO_EMC_31 , UART_7, ((1 << DAISY_REG_VALUE_SHIFT) | (0x55C << DAISY_REG_SHIFT) | 2)}, + + {GPIO_SD_B0_04, UART_8, ((0 << DAISY_REG_VALUE_SHIFT) | (0x564 << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B1_10, UART_8, ((1 << DAISY_REG_VALUE_SHIFT) | (0x564 << DAISY_REG_SHIFT) | 2)}, + {GPIO_EMC_38 , UART_8, ((2 << DAISY_REG_VALUE_SHIFT) | (0x564 << DAISY_REG_SHIFT) | 2)}, + {NC , NC , 0} }; const PinMap PinMap_UART_RX[] = { {GPIO_AD_B0_13, UART_1, 2}, + + {GPIO_SD_B1_10, UART_2, ((0 << DAISY_REG_VALUE_SHIFT) | (0x52C << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B1_03, UART_2, ((1 << DAISY_REG_VALUE_SHIFT) | (0x52C << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B1_07, UART_3, ((0 << DAISY_REG_VALUE_SHIFT) | (0x538 << DAISY_REG_SHIFT) | 2)}, + {GPIO_EMC_14 , UART_3, ((1 << DAISY_REG_VALUE_SHIFT) | (0x538 << DAISY_REG_SHIFT) | 2)}, + {GPIO_B0_09 , UART_3, ((2 << DAISY_REG_VALUE_SHIFT) | (0x538 << DAISY_REG_SHIFT) | 3)}, + + {GPIO_SD_B1_01, UART_4, ((0 << DAISY_REG_VALUE_SHIFT) | (0x540 << DAISY_REG_SHIFT) | 4)}, + {GPIO_EMC_20 , UART_4, ((1 << DAISY_REG_VALUE_SHIFT) | (0x540 << DAISY_REG_SHIFT) | 2)}, + {GPIO_B1_01 , UART_4, ((2 << DAISY_REG_VALUE_SHIFT) | (0x540 << DAISY_REG_SHIFT) | 2)}, + + {GPIO_EMC_24 , UART_5, ((0 << DAISY_REG_VALUE_SHIFT) | (0x548 << DAISY_REG_SHIFT) | 2)}, + {GPIO_B1_13 , UART_5, ((1 << DAISY_REG_VALUE_SHIFT) | (0x548 << DAISY_REG_SHIFT) | 1)}, + + {GPIO_EMC_26 , UART_6, ((0 << DAISY_REG_VALUE_SHIFT) | (0x550 << DAISY_REG_SHIFT) | 2)}, {GPIO_AD_B0_03, UART_6, ((1 << DAISY_REG_VALUE_SHIFT) | (0x550 << DAISY_REG_SHIFT) | 2)}, + + {GPIO_SD_B1_09, UART_7, ((0 << DAISY_REG_VALUE_SHIFT) | (0x558 << DAISY_REG_SHIFT) | 2)}, + {GPIO_EMC_32 , UART_7, ((1 << DAISY_REG_VALUE_SHIFT) | (0x558 << DAISY_REG_SHIFT) | 2)}, + + {GPIO_SD_B0_05, UART_8, ((0 << DAISY_REG_VALUE_SHIFT) | (0x560 << DAISY_REG_SHIFT) | 2)}, + {GPIO_AD_B1_11, UART_8, ((1 << DAISY_REG_VALUE_SHIFT) | (0x560 << DAISY_REG_SHIFT) | 2)}, + {GPIO_EMC_39 , UART_8, ((2 << DAISY_REG_VALUE_SHIFT) | (0x560 << DAISY_REG_SHIFT) | 2)}, + {NC , NC , 0} }; From cc4e1ee575ea86fb2595bcd787ed0ffb2c7a6055 Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Fri, 26 Apr 2024 09:56:12 -0700 Subject: [PATCH 4/5] Make more robust to calling spi_format() after spi_frequency() --- hal/include/hal/spi_api.h | 12 +++- .../TARGET_IMX/objects.h | 1 + .../TARGET_IMX/spi_api.c | 72 ++++++++++++++----- .../TARGET_MIMXRT105x/PeripheralNames.h | 2 +- .../TARGET_EVK/PeripheralNames.h | 2 +- 5 files changed, 66 insertions(+), 23 deletions(-) diff --git a/hal/include/hal/spi_api.h b/hal/include/hal/spi_api.h index 011073a02a7..bde0837011b 100644 --- a/hal/include/hal/spi_api.h +++ b/hal/include/hal/spi_api.h @@ -197,7 +197,11 @@ void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap); /** Initialize the SPI peripheral * - * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral + * Configures the pins used by SPI and enables the peripheral. + * + * After this function is called by the driver layer, spi_format() and spi_frequency() will + * be called *before* the SPI bus is used. + * * @param[out] obj The SPI object to initialize * @param[in] pinmap pointer to structure which holds static pinmap */ @@ -205,7 +209,11 @@ void spi_init_direct(spi_t *obj, const spi_pinmap_t *pinmap); /** Initialize the SPI peripheral * - * Configures the pins used by SPI, sets a default format and frequency, and enables the peripheral + * Configures the pins used by SPI and enables the peripheral + * + * After this function is called by the driver layer, spi_format() and spi_frequency() will + * be called *before* the SPI bus is used. + * * @param[out] obj The SPI object to initialize * @param[in] mosi The pin to use for MOSI * @param[in] miso The pin to use for MISO diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h index a45ba97d7ad..574c3ba70e4 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/objects.h @@ -57,6 +57,7 @@ struct i2c_s { struct spi_s { uint32_t instance; uint8_t bits; + uint32_t frequency; }; struct dac_s { diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c index d0421df0c6d..0befd785ca3 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c @@ -32,17 +32,25 @@ static LPSPI_Type *const spi_address[] = LPSPI_BASE_PTRS; extern uint32_t spi_get_clock(void); extern void spi_setup_clock(); -void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) +SPIName spi_get_peripheral_name(PinName mosi, PinName miso, PinName sclk) { - // determine the SPI to use uint32_t spi_mosi = pinmap_peripheral(mosi, PinMap_SPI_MOSI); uint32_t spi_miso = pinmap_peripheral(miso, PinMap_SPI_MISO); uint32_t spi_sclk = pinmap_peripheral(sclk, PinMap_SPI_SCLK); - uint32_t spi_ssel = pinmap_peripheral(ssel, PinMap_SPI_SSEL); uint32_t spi_data = pinmap_merge(spi_mosi, spi_miso); - uint32_t spi_cntl = pinmap_merge(spi_sclk, spi_ssel); - obj->instance = pinmap_merge(spi_data, spi_cntl); + SPIName spi_instance = pinmap_merge(spi_sclk, spi_data); + return spi_instance; +} + +void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel) +{ + // determine the SPI to use + SPIName spi_for_data_lines = spi_get_peripheral_name(mosi, miso, sclk); + uint32_t spi_ssel = pinmap_peripheral(ssel, PinMap_SPI_SSEL); + uint32_t spi_cntl = pinmap_merge(spi_for_data_lines, spi_ssel); + + obj->instance = pinmap_merge(spi_for_data_lines, spi_cntl); MBED_ASSERT((int)obj->instance != NC); // pin out the spi pins @@ -53,6 +61,10 @@ void spi_init(spi_t *obj, PinName mosi, PinName miso, PinName sclk, PinName ssel pinmap_pinout(ssel, PinMap_SPI_SSEL); } + // Default frequency (just so we have something to set if spi_format() is called + // before spi_frequency()) + obj->frequency = 1000000; + spi_setup_clock(); } @@ -61,6 +73,30 @@ void spi_free(spi_t *obj) LPSPI_Deinit(spi_address[obj->instance]); } +/* + * This function updates the `CCR.DBT` bitfield, which controls the length of the half + * clock cycle between the end of one frame and the start of the next when in continuous mode. + * It must be updated whenever the SPI clock frequency is changed. + * + * The MIMXRT HAL does not properly set this register so we end up with clock glitches + * when doing multibyte SPI transfers. + * + * Note: The LPSPI must be disabled when calling this function. + */ +static void mimxrt_spi_update_dbt(LPSPI_Type * spibase) +{ + // Step 1: Get the current SCLK period, in LPSPI functional clock periods, that was calculated by + // LPSPI_MasterSetBaudRate(). This is given by the CCR.SCKDIV bitfield plus 2. + const uint32_t sclkPeriodClocks = ((spibase->CCR & LPSPI_CCR_SCKDIV_MASK) >> LPSPI_CCR_SCKDIV_SHIFT) + 2; + + // Step 2: Divide by 2, rounding up + const uint32_t sclkLowTimeClocks = (sclkPeriodClocks + 1) / 2; + + // Step 3: Set this value into the DBT field. The value used by HW is one higher than the value in the register + // so we have to subtract. + spibase->CCR = (spibase->CCR & ~LPSPI_CCR_DBT_MASK) | LPSPI_CCR_DBT(sclkLowTimeClocks - 1); +} + void spi_format(spi_t *obj, int bits, int mode, int slave) { lpspi_master_config_t master_config; @@ -74,14 +110,21 @@ void spi_format(spi_t *obj, int bits, int mode, int slave) slave_config.cpha = (mode & 0x1) ? kLPSPI_ClockPhaseSecondEdge : kLPSPI_ClockPhaseFirstEdge; LPSPI_SlaveInit(spi_address[obj->instance], &slave_config); } else { + /* Master config */ LPSPI_MasterGetDefaultConfig(&master_config); master_config.bitsPerFrame = (uint32_t)bits;; master_config.cpol = (mode & 0x2) ? kLPSPI_ClockPolarityActiveLow : kLPSPI_ClockPolarityActiveHigh; master_config.cpha = (mode & 0x1) ? kLPSPI_ClockPhaseSecondEdge : kLPSPI_ClockPhaseFirstEdge; master_config.direction = kLPSPI_MsbFirst; + master_config.baudRate = obj->frequency; LPSPI_MasterInit(spi_address[obj->instance], &master_config, spi_get_clock()); + + // Update the DBT field which gets overwritten by LPSPI_MasterInit + LPSPI_Enable(spi_address[obj->instance], false); + mimxrt_spi_update_dbt(spi_address[obj->instance]); + LPSPI_Enable(spi_address[obj->instance], true); } } @@ -97,23 +140,14 @@ void spi_frequency(spi_t *obj, int hz) spibase->TCR = (spibase->TCR & ~LPSPI_TCR_PRESCALE_MASK) | LPSPI_TCR_PRESCALE(tcrPrescaleValue); - // We also need to recalculate the CCR.DBT field, as this register - // controls the length of the half clock cycle between the end of one frame and the start of the next. - // FSL HAL isn't smart enough to do this automatically. - - // Step 1: Get the current SCLK period, in LPSPI functional clock periods, that was calculated by - // LPSPI_MasterSetBaudRate(). This is given by the CCR.SCKDIV bitfield plus 2. - const uint32_t sclkPeriodClocks = ((spibase->CCR & LPSPI_CCR_SCKDIV_MASK) >> LPSPI_CCR_SCKDIV_SHIFT) + 2; - - // Step 2: Divide by 2, rounding up - const uint32_t sclkLowTimeClocks = (sclkPeriodClocks + 1) / 2; - - // Step 3: Set this value into the DBT field. The value used by HW is one higher than the value in the register - // so we have to subtract. - spibase->CCR = (spibase->CCR & ~LPSPI_CCR_DBT_MASK) | LPSPI_CCR_DBT(sclkLowTimeClocks - 1); + // Update the DBT field which gets overwritten by LPSPI_MasterSetBaudRate + mimxrt_spi_update_dbt(spi_address[obj->instance]); /* Enable the LPSPI module */ LPSPI_Enable(spibase, true); + + // Save frequency for later + obj->frequency = hz; } static inline int spi_readable(spi_t * obj) diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralNames.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralNames.h index fcf725a241d..9f2bf4147d8 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralNames.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT105x/PeripheralNames.h @@ -139,7 +139,7 @@ typedef enum { DAC_0 = 0 } DACName; - +#define DEVICE_SPI_COUNT 4 typedef enum { SPI_1 = 1, SPI_2 = 2, diff --git a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1170/TARGET_EVK/PeripheralNames.h b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1170/TARGET_EVK/PeripheralNames.h index 0ee292f6caf..27eed643ee7 100644 --- a/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1170/TARGET_EVK/PeripheralNames.h +++ b/targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_MIMXRT1170/TARGET_EVK/PeripheralNames.h @@ -128,7 +128,7 @@ typedef enum { DAC_0 = 0 } DACName; - +#define DEVICE_SPI_COUNT 3 typedef enum { SPI_1 = 1, SPI_2 = 2, From 17b8868b6be4c0ec484008d66673942a3ac20eef Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Fri, 26 Apr 2024 10:05:05 -0700 Subject: [PATCH 5/5] Fix style --- hal/include/hal/spi_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hal/include/hal/spi_api.h b/hal/include/hal/spi_api.h index bde0837011b..35c8b8a126a 100644 --- a/hal/include/hal/spi_api.h +++ b/hal/include/hal/spi_api.h @@ -201,7 +201,7 @@ void spi_get_capabilities(PinName ssel, bool slave, spi_capabilities_t *cap); * * After this function is called by the driver layer, spi_format() and spi_frequency() will * be called *before* the SPI bus is used. - * + * * @param[out] obj The SPI object to initialize * @param[in] pinmap pointer to structure which holds static pinmap */