Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some fixes for Teensy4 #272

Merged
merged 5 commits into from
Apr 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions hal/include/hal/spi_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,23 @@ 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
*/
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
Expand Down
2 changes: 2 additions & 0 deletions platform/source/mbed_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
JohnK1987 marked this conversation as resolved.
Show resolved Hide resolved
static bool mbed_error_is_handler(const mbed_error_ctx *ctx)
{
bool is_handler = false;
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions platform/source/mbed_sdk_boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

#include "mbed_error.h"
JohnK1987 marked this conversation as resolved.
Show resolved Hide resolved
#include "mbed_toolchain.h"
#include <stdlib.h>
#include <stdint.h>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct i2c_s {
struct spi_s {
uint32_t instance;
uint8_t bits;
uint32_t frequency;
};

struct dac_s {
Expand Down
59 changes: 54 additions & 5 deletions targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_IMX/spi_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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();
}

Expand All @@ -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;
Expand All @@ -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);
}
}

Expand All @@ -97,8 +140,14 @@ void spi_frequency(spi_t *obj, int hz)

spibase->TCR = (spibase->TCR & ~LPSPI_TCR_PRESCALE_MASK) | LPSPI_TCR_PRESCALE(tcrPrescaleValue);

// 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ typedef enum {
DAC_0 = 0
} DACName;


#define DEVICE_SPI_COUNT 4
typedef enum {
SPI_1 = 1,
SPI_2 = 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,37 +109,107 @@ 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}
};

/************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}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
*/

#include <stdint.h>
#include <mimxrt_flash_info.h>
#include <mimxrt_memory_info.h>

extern void Reset_Handler(void);
extern unsigned long _estack;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ typedef enum {
DAC_0 = 0
} DACName;


#define DEVICE_SPI_COUNT 3
typedef enum {
SPI_1 = 1,
SPI_2 = 2,
Expand Down
Loading