mimxrt: Allow to select cs0 or cs1 for SPI.

Using the keyword argument cs=nnn in the constructor. The cs1
pin has to be defined in mpconfigboard.h.
Note: Only a few boards have the CS1 pin exposed to the connectors.
This commit is contained in:
robert-hh 2022-01-10 18:14:40 +01:00 committed by Damien George
parent 1dc366f901
commit 30380962cf
9 changed files with 50 additions and 17 deletions

View File

@ -27,7 +27,8 @@
#define IOMUX_TABLE_SPI \
{ IOMUXC_GPIO_AD_06_LPSPI1_SCK }, { IOMUXC_GPIO_AD_05_LPSPI1_PCS0 }, \
{ IOMUXC_GPIO_AD_04_LPSPI1_SDO }, { IOMUXC_GPIO_AD_03_LPSPI1_SDI },
{ IOMUXC_GPIO_AD_04_LPSPI1_SDO }, { IOMUXC_GPIO_AD_03_LPSPI1_SDI }, \
{ IOMUXC_GPIO_AD_02_LPSPI1_PCS1 }
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx }
#define DMA_REQ_SRC_TX { 0, kDmaRequestMuxLPSPI1Tx, kDmaRequestMuxLPSPI2Tx }

View File

@ -37,10 +37,13 @@
#define IOMUX_TABLE_SPI \
{ IOMUXC_GPIO_AD_B0_10_LPSPI1_SCK }, { IOMUXC_GPIO_AD_B0_11_LPSPI1_PCS0 }, \
{ IOMUXC_GPIO_AD_B0_12_LPSPI1_SDO }, { IOMUXC_GPIO_AD_B0_13_LPSPI1_SDI }, \
{ 0 }, \
{ 0 }, { 0 }, \
{ 0 }, { 0 }, \
{ 0 }, \
{ IOMUXC_GPIO_AD_B1_12_LPSPI3_SCK }, { IOMUXC_GPIO_AD_B1_13_LPSPI3_PCS0 }, \
{ IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B1_15_LPSPI3_SDI },
{ IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B1_15_LPSPI3_SDI }, \
{ IOMUXC_GPIO_AD_B1_09_LPSPI3_PCS1 } \
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \
kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx }

View File

@ -32,7 +32,8 @@
#define IOMUX_TABLE_SPI \
{ IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK }, { IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0 }, \
{ IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI },
{ IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, \
{ 0 },
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \
kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx }

View File

@ -32,7 +32,8 @@
#define IOMUX_TABLE_SPI \
{ IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK }, { IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0 }, \
{ IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI },
{ IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, \
{ 0 },
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \
kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx }

View File

@ -32,7 +32,8 @@
#define IOMUX_TABLE_SPI \
{ IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK }, { IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0 }, \
{ IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI },
{ IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, \
{ 0 },
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \
kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx }

View File

@ -35,12 +35,16 @@
#define IOMUX_TABLE_SPI \
{ 0 }, { 0 }, \
{ 0 }, { 0 }, \
{ 0 }, \
{ 0 }, { 0 }, \
{ 0 }, { 0 }, \
{ 0 }, \
{ IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK }, { IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0 }, \
{ IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI }, \
{ 0 }, \
{ IOMUXC_GPIO_B1_07_LPSPI4_SCK }, { IOMUXC_GPIO_B1_04_LPSPI4_PCS0 }, \
{ IOMUXC_GPIO_B1_06_LPSPI4_SDO }, { IOMUXC_GPIO_B1_05_LPSPI4_SDI },
{ IOMUXC_GPIO_B1_06_LPSPI4_SDO }, { IOMUXC_GPIO_B1_05_LPSPI4_SDI }, \
{ IOMUXC_GPIO_B1_03_LPSPI4_PCS1 }
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \
kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx }

View File

@ -27,12 +27,16 @@
#define IOMUX_TABLE_SPI \
{ 0 }, { 0 }, \
{ 0 }, { 0 }, \
{ 0 }, \
{ 0 }, { 0 }, \
{ 0 }, { 0 }, \
{ 0 }, \
{ IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK }, { IOMUXC_GPIO_AD_B0_03_LPSPI3_PCS0 }, \
{ IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B0_02_LPSPI3_SDI }, \
{ 0 }, \
{ IOMUXC_GPIO_B0_03_LPSPI4_SCK }, { IOMUXC_GPIO_B0_00_LPSPI4_PCS0 }, \
{ IOMUXC_GPIO_B0_02_LPSPI4_SDO }, { IOMUXC_GPIO_B0_01_LPSPI4_SDI },
{ IOMUXC_GPIO_B0_02_LPSPI4_SDO }, { IOMUXC_GPIO_B0_01_LPSPI4_SDI }, \
{ 0 },
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \
kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx }

View File

@ -27,12 +27,16 @@
#define IOMUX_TABLE_SPI \
{ IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK }, { IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0 }, \
{ IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO }, { IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI }, \
{ IOMUXC_GPIO_EMC_31_LPSPI1_PCS1 }, \
{ 0 }, { 0 }, \
{ 0 }, { 0 }, \
{ 0 }, \
{ IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK }, { IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0 }, \
{ IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO }, { IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI }, \
{ 0 }, \
{ IOMUXC_GPIO_B0_03_LPSPI4_SCK }, { IOMUXC_GPIO_B0_00_LPSPI4_PCS0 }, \
{ IOMUXC_GPIO_B0_02_LPSPI4_SDO }, { IOMUXC_GPIO_B0_01_LPSPI4_SDI },
{ IOMUXC_GPIO_B0_02_LPSPI4_SDO }, { IOMUXC_GPIO_B0_01_LPSPI4_SDI }, \
{ IOMUXC_GPIO_B1_03_LPSPI4_PCS1 }
#define DMA_REQ_SRC_RX { 0, kDmaRequestMuxLPSPI1Rx, kDmaRequestMuxLPSPI2Rx, \
kDmaRequestMuxLPSPI3Rx, kDmaRequestMuxLPSPI4Rx }

View File

@ -53,6 +53,7 @@
#define CS0 (iomux_table[index + 1])
#define SDO (iomux_table[index + 2])
#define SDI (iomux_table[index + 3])
#define CS1 (iomux_table[index + 4])
typedef struct _machine_spi_obj_t {
mp_obj_base_t base;
@ -81,17 +82,25 @@ static const iomux_table_t iomux_table[] = {
static uint16_t dma_req_src_rx[] = DMA_REQ_SRC_RX;
static uint16_t dma_req_src_tx[] = DMA_REQ_SRC_TX;
bool lpspi_set_iomux(int8_t spi, uint8_t drive) {
int index = (spi - 1) * 4;
bool lpspi_set_iomux(int8_t spi, uint8_t drive, uint8_t cs) {
int index = (spi - 1) * 5;
if (SCK.muxRegister != 0) {
IOMUXC_SetPinMux(SCK.muxRegister, SCK.muxMode, SCK.inputRegister, SCK.inputDaisy, SCK.configRegister, 0U);
IOMUXC_SetPinConfig(SCK.muxRegister, SCK.muxMode, SCK.inputRegister, SCK.inputDaisy, SCK.configRegister,
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, drive, SCK.configRegister));
IOMUXC_SetPinMux(CS0.muxRegister, CS0.muxMode, CS0.inputRegister, CS0.inputDaisy, CS0.configRegister, 0U);
IOMUXC_SetPinConfig(CS0.muxRegister, CS0.muxMode, CS0.inputRegister, CS0.inputDaisy, CS0.configRegister,
pin_generate_config(PIN_PULL_UP_100K, PIN_MODE_OUT, drive, CS0.configRegister));
if (cs == 0 && CS0.muxRegister != 0) {
IOMUXC_SetPinMux(CS0.muxRegister, CS0.muxMode, CS0.inputRegister, CS0.inputDaisy, CS0.configRegister, 0U);
IOMUXC_SetPinConfig(CS0.muxRegister, CS0.muxMode, CS0.inputRegister, CS0.inputDaisy, CS0.configRegister,
0x1080u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
} else if (cs == 1 && CS1.muxRegister != 0) {
IOMUXC_SetPinMux(CS1.muxRegister, CS1.muxMode, CS1.inputRegister, CS1.inputDaisy, CS1.configRegister, 0U);
IOMUXC_SetPinConfig(CS1.muxRegister, CS1.muxMode, CS1.inputRegister, CS1.inputDaisy, CS1.configRegister,
0x1080u | drive << IOMUXC_SW_PAD_CTL_PAD_DSE_SHIFT);
} else {
mp_raise_ValueError(MP_ERROR_TEXT("The chosen CS is not available"));
}
IOMUXC_SetPinMux(SDO.muxRegister, SDO.muxMode, SDO.inputRegister, SDO.inputDaisy, SDO.configRegister, 0U);
IOMUXC_SetPinConfig(SDO.muxRegister, SDO.muxMode, SDO.inputRegister, SDO.inputDaisy, SDO.configRegister,
@ -117,7 +126,7 @@ STATIC void machine_spi_print(const mp_print_t *print, mp_obj_t self_in, mp_prin
}
mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_gap_ns, ARG_drive };
enum { ARG_id, ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_gap_ns, ARG_drive, ARG_cs };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_id, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = DEFAULT_SPI_BAUDRATE} },
@ -127,6 +136,7 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
{ MP_QSTR_firstbit, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_FIRSTBIT} },
{ MP_QSTR_gap_ns, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
{ MP_QSTR_drive, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = DEFAULT_SPI_DRIVE} },
{ MP_QSTR_cs, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
};
static bool clk_init = true;
@ -160,7 +170,6 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
CLOCK_SetMux(kCLOCK_LpspiMux, 1); // Clock source is kCLOCK_Usb1PllPfd1Clk
CLOCK_SetDiv(kCLOCK_LpspiDiv, CLOCK_DIVIDER);
}
lpspi_set_iomux(spi_index_table[spi_id], drive);
LPSPI_Reset(self->spi_inst);
LPSPI_Enable(self->spi_inst, false); // Disable first before new settings are applies
@ -176,7 +185,12 @@ mp_obj_t machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n
if (args[ARG_gap_ns].u_int != -1) {
self->master_config->betweenTransferDelayInNanoSec = args[ARG_gap_ns].u_int;
}
uint8_t cs = args[ARG_cs].u_int;
if (cs <= 1) {
self->master_config->whichPcs = cs;
}
LPSPI_MasterInit(self->spi_inst, self->master_config, CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (CLOCK_DIVIDER + 1));
lpspi_set_iomux(spi_index_table[spi_id], drive, cs);
return MP_OBJ_FROM_PTR(self);
}
@ -271,7 +285,7 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8
masterXfer.txData = (uint8_t *)src;
masterXfer.rxData = (uint8_t *)dest;
masterXfer.dataSize = len;
masterXfer.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap;
masterXfer.configFlags = (self->master_config->whichPcs << LPSPI_MASTER_PCS_SHIFT) | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap;
// Reconfigure the TCR, required after switch between DMA vs. non-DMA
LPSPI_Enable(self->spi_inst, false); // Disable first before new settings are applied
@ -317,7 +331,7 @@ STATIC void machine_spi_transfer(mp_obj_base_t *self_in, size_t len, const uint8
masterXfer.txData = (uint8_t *)src;
masterXfer.rxData = (uint8_t *)dest;
masterXfer.dataSize = len;
masterXfer.configFlags = kLPSPI_MasterPcs0 | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap;
masterXfer.configFlags = (self->master_config->whichPcs << LPSPI_MASTER_PCS_SHIFT) | kLPSPI_MasterPcsContinuous | kLPSPI_MasterByteSwap;
LPSPI_MasterTransferBlocking(self->spi_inst, &masterXfer);
}