From a307096ec027fd73b2589fca27fc5f080c44f957 Mon Sep 17 00:00:00 2001 From: wanlei Date: Fri, 10 Mar 2023 19:31:54 +0800 Subject: [PATCH] spi_master: sct mode supported on c6 --- .../spi/master/main/test_spi_master_sct.c | 52 +-- components/hal/esp32c6/include/hal/spi_ll.h | 328 +++++++++++++++++- .../esp32c6/include/soc/Kconfig.soc_caps.in | 16 + components/soc/esp32c6/include/soc/soc_caps.h | 6 + 4 files changed, 362 insertions(+), 40 deletions(-) diff --git a/components/driver/test_apps/spi/master/main/test_spi_master_sct.c b/components/driver/test_apps/spi/master/main/test_spi_master_sct.c index 915a520b16..6f317d31ab 100644 --- a/components/driver/test_apps/spi/master/main/test_spi_master_sct.c +++ b/components/driver/test_apps/spi/master/main/test_spi_master_sct.c @@ -41,27 +41,16 @@ static void hd_master(void) { spi_device_handle_t handle; - spi_bus_config_t buscfg={ - .mosi_io_num = SPI2_IOMUX_PIN_NUM_MOSI, - .miso_io_num = SPI2_IOMUX_PIN_NUM_MISO, - .sclk_io_num = SPI2_IOMUX_PIN_NUM_CLK, - .quadwp_io_num = -1, - .quadhd_io_num = -1, - .max_transfer_sz = 4092 * 10, - }; + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + buscfg.max_transfer_sz = 4092 * 10; - spi_device_interface_config_t devcfg = { - .command_bits = 8, - .address_bits = 8, - .dummy_bits = 8, - .clock_speed_hz = 10 * 1000, - .duty_cycle_pos = 128, //50% duty cycle - .mode = 0, - .spics_io_num = SPI2_IOMUX_PIN_NUM_CS, - .cs_ena_posttrans = 3, //Keep the CS low 3 cycles after transaction, to stop slave from missing the last bit when CS has less propagation delay than CLK - .queue_size = 3, - .flags = SPI_DEVICE_HALFDUPLEX, - }; + spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); + devcfg.command_bits = 8; + devcfg.address_bits = 8; + devcfg.dummy_bits = 8; + devcfg.clock_speed_hz = 10 * 1000; + devcfg.input_delay_ns = 0; + devcfg.flags = SPI_DEVICE_HALFDUPLEX; TEST_ESP_OK(spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO)); TEST_ESP_OK(spi_bus_add_device(SPI2_HOST, &devcfg, &handle)); @@ -181,26 +170,11 @@ static void hd_master(void) static void hd_slave(void) { - spi_bus_config_t bus_cfg = { - .miso_io_num = SPI2_IOMUX_PIN_NUM_MISO, - .mosi_io_num = SPI2_IOMUX_PIN_NUM_MOSI, - .sclk_io_num = SPI2_IOMUX_PIN_NUM_CLK, - .quadwp_io_num = -1, - .quadhd_io_num = -1, - .max_transfer_sz = 4092 * 4, - }; + spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG(); + spi_slave_hd_slot_config_t slave_hd_cfg = SPI_SLOT_TEST_DEFAULT_CONFIG(); + slave_hd_cfg.dma_chan = SPI_DMA_CH_AUTO, - spi_slave_hd_slot_config_t slave_hd_cfg = { - .spics_io_num = SPI2_IOMUX_PIN_NUM_CS, - .dma_chan = SPI_DMA_CH_AUTO, - .flags = 0, - .mode = 0, - .command_bits = 8, - .address_bits = 8, - .dummy_bits = 8, - .queue_size = 4, - }; - TEST_ESP_OK(spi_slave_hd_init(SPI2_HOST, &bus_cfg, &slave_hd_cfg)); + TEST_ESP_OK(spi_slave_hd_init(SPI2_HOST, &buscfg, &slave_hd_cfg)); spi_slave_hd_data_t *ret_trans = NULL; diff --git a/components/hal/esp32c6/include/hal/spi_ll.h b/components/hal/esp32c6/include/hal/spi_ll.h index 843d0dab21..5e38d292a1 100644 --- a/components/hal/esp32c6/include/hal/spi_ll.h +++ b/components/hal/esp32c6/include/hal/spi_ll.h @@ -644,8 +644,8 @@ static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t li hw->ctrl.faddr_dual = (line_mode.addr_lines == 2); hw->ctrl.faddr_quad = (line_mode.addr_lines == 4); hw->ctrl.fread_dual = (line_mode.data_lines == 2); - hw->user.fwrite_dual = (line_mode.data_lines == 2); hw->ctrl.fread_quad = (line_mode.data_lines == 4); + hw->user.fwrite_dual = (line_mode.data_lines == 2); hw->user.fwrite_quad = (line_mode.data_lines == 4); } @@ -1167,6 +1167,332 @@ static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw) return hw->slave1.slv_last_addr; } + +/*------------------------------------------------------------------------------ + * Segmented-Configure-Transfer + *----------------------------------------------------------------------------*/ +#define SPI_LL_CONF_BUF_SET_BIT(_w, _m) ({ \ + (_w) |= (_m); \ + }) +#define SPI_LL_CONF_BUF_CLR_BIT(_w, _m) ({ \ + (_w) &= ~(_m); \ + }) + +#define SPI_LL_CONF_BUF_SET_FIELD(_w, _f, val) ({ \ + ((_w) = (((_w) & ~((_f##_V) << (_f##_S))) | (((val) & (_f##_V))<<(_f##_S)))); \ + }) + +#define SPI_LL_CONF_BUF_GET_FIELD(_w, _f) ({ \ + (((_w) >> (_f##_S)) & (_f##_V)); \ + }) + +//This offset is 1, for bitmap +#define SPI_LL_CONF_BUFFER_OFFSET (1) +//bitmap must be the first +#define SPI_LL_CONF_BITMAP_POS (0) + +#define SPI_LL_ADDR_REG_POS (0) +#define SPI_LL_CTRL_REG_POS (1) +#define SPI_LL_CLOCK_REG_POS (2) +#define SPI_LL_USER_REG_POS (3) +#define SPI_LL_USER1_REG_POS (4) +#define SPI_LL_USER2_REG_POS (5) +#define SPI_LL_MS_DLEN_REG_POS (6) +#define SPI_LL_MISC_REG_POS (7) +#define SPI_LL_DIN_MODE_REG_POS (8) +#define SPI_LL_DIN_NUM_REG_POS (9) +#define SPI_LL_DOUT_MODE_REG_POS (10) +#define SPI_LL_DMA_CONF_REG_POS (11) +#define SPI_LL_DMA_INT_ENA_REG_POS (12) +#define SPI_LL_DMA_INT_CLR_REG_POS (13) + +#define SPI_LL_SCT_MAGIC_NUMBER (0x2) + +/** + * Set conf phase bits len to HW for segment config trans mode. + * + * @param hw Beginning address of the peripheral registers. + * @param conf_bitlen Value of field conf_bitslen in cmd reg. + */ +static inline void spi_ll_set_conf_phase_bits_len(spi_dev_t *hw, uint32_t conf_bitlen) +{ + if (conf_bitlen <= SOC_SPI_SCT_CONF_BITLEN_MAX) { + hw->cmd.conf_bitlen = conf_bitlen; + } +} + +/** + * Update the conf buffer for conf phase + * + * @param hw Beginning address of the peripheral registers. + * @param is_end Is this transaction the end of this segment. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_conf_phase_conf_buffer(spi_dev_t *hw, bool is_end, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_conf_nxt + if (is_end) { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_CONF_NXT_M); + } else { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_CONF_NXT_M); + } +} + +/** + * Update the line mode of conf buffer for conf phase + * + * @param hw Beginning address of the peripheral registers. + * @param line_mode line mode struct of each phase. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_line_mode_conf_buff(spi_dev_t *hw, spi_line_mode_t line_mode, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] &= ~SPI_LL_ONE_LINE_CTRL_MASK; + conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] &= ~SPI_LL_ONE_LINE_USER_MASK; + + switch (line_mode.cmd_lines) + { + case 2: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_DUAL_M); break; + case 4: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_QUAD_M); break; + default: break; + } + + switch (line_mode.addr_lines) + { + case 2: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_DUAL_M); break; + case 4: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_QUAD_M); break; + default: break; + } + + switch (line_mode.data_lines) + { + case 2: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_DUAL_M ); + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_DUAL_M); + break; + case 4: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_QUAD_M ); + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_QUAD_M); + break; + default: break; + } +} + +/** + * Update the conf buffer for prep phase + * + * @param hw Beginning address of the peripheral registers. + * @param setup CS setup time + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_prep_phase_conf_buffer(spi_dev_t *hw, uint8_t setup, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: cs_setup + if(setup) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_SETUP_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_SETUP_M); + } + + //user1 reg: cs_setup_time + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_SETUP_TIME, setup - 1); +} + +/** + * Update the conf buffer for cmd phase + * + * @param hw Beginning address of the peripheral registers. + * @param cmd Command value + * @param cmdlen Length of the cmd phase + * @param lsbfirst Whether LSB first + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_cmd_phase_conf_buffer(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_command + if (cmdlen) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_M); + } + + //user2 reg: usr_command_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_BITLEN, cmdlen - 1); + + //user2 reg: usr_command_value + if (lsbfirst) { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_VALUE, cmd); + } else { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_VALUE, HAL_SPI_SWAP_DATA_TX(cmd, cmdlen)); + } +} + +/** + * Update the conf buffer for addr phase + * + * @param hw Beginning address of the peripheral registers. + * @param addr Address to set + * @param addrlen Length of the address phase + * @param lsbfirst whether the LSB first feature is enabled. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_addr_phase_conf_buffer(spi_dev_t *hw, uint64_t addr, int addrlen, bool lsbfirst, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_addr + if (addrlen) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_M); + } + + //user1 reg: usr_addr_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_BITLEN, addrlen - 1); + + //addr reg: addr + if (lsbfirst) { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_ADDR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_VALUE, HAL_SWAP32(addr)); + } else { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_ADDR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_VALUE, (addr << (32 - addrlen))); + } +} + +/** + * Update the conf buffer for dummy phase + * + * @param hw Beginning address of the peripheral registers. + * @param dummy_n Dummy cycles used. 0 to disable the dummy phase. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_dummy_phase_conf_buffer(spi_dev_t *hw, int dummy_n, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_dummy + if (dummy_n) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_DUMMY_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_DUMMY_M); + } + + //user1 reg: usr_dummy_cyclelen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_DUMMY_CYCLELEN, dummy_n - 1); +} + +/** + * Update the conf buffer for dout phase + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen output length, in bits. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_dout_phase_conf_buffer(spi_dev_t *hw, int bitlen, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + if (bitlen) { + //user reg: usr_mosi + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MOSI_M); + //dma_conf reg: dma_tx_ena + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_TX_ENA_M); + //ms_dlen reg: ms_data_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_MS_DLEN_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_MS_DATA_BITLEN, bitlen - 1); + } else { + //user reg: usr_mosi + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MOSI_M); + //dma_conf reg: dma_tx_ena + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_TX_ENA_M); + } +} + +/** + * Update the conf buffer for din phase + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen input length, in bits. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_din_phase_conf_buffer(spi_dev_t *hw, int bitlen, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + if (bitlen) { + //user reg: usr_miso + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MISO_M); + //dma_conf reg: dma_rx_ena + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_RX_ENA_M); + //ms_dlen reg: ms_data_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_MS_DLEN_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_MS_DATA_BITLEN, bitlen - 1); + } else { + //user reg: usr_miso + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MISO_M); + //dma_conf reg: dma_rx_ena + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_RX_ENA_M); + } +} + +/** + * Update the conf buffer for done phase + * + * @param hw Beginning address of the peripheral registers. + * @param setup CS hold time + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_done_phase_conf_buffer(spi_dev_t *hw, int hold, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: cs_hold + if(hold) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_HOLD_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_HOLD_M); + } + + //user1 reg: cs_hold_time + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_HOLD_TIME, hold); +} + +/** + * Initialize the conf buffer: + * + * - init bitmap + * - save all register values into the rest of the conf buffer words + * + * @param hw Beginning address of the peripheral registers. + * @param conf_buffer Conf buffer to be updated. + */ +__attribute__((always_inline)) +static inline void spi_ll_init_conf_buffer(spi_dev_t *hw, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + conf_buffer[SPI_LL_CONF_BITMAP_POS] = 0x7FFF | (SPI_LL_SCT_MAGIC_NUMBER << 28); + conf_buffer[SPI_LL_ADDR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->addr.usr_addr_value; + conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->ctrl.val; + conf_buffer[SPI_LL_CLOCK_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->clock.val; + conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->user.val; + conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->user1.val; + conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->user2.val; + conf_buffer[SPI_LL_MS_DLEN_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->ms_dlen.val; + conf_buffer[SPI_LL_MISC_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->misc.val; + conf_buffer[SPI_LL_DIN_MODE_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->din_mode.val; + conf_buffer[SPI_LL_DIN_NUM_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->din_num.val; + conf_buffer[SPI_LL_DOUT_MODE_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dout_mode.val; + conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dma_conf.val; + conf_buffer[SPI_LL_DMA_INT_ENA_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dma_int_ena.val; + conf_buffer[SPI_LL_DMA_INT_CLR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dma_int_clr.val; +} + +/** + * Enable/Disable the conf phase + * + * @param hw Beginning address of the peripheral registers. + * @param enable True: enable; False: disable + */ +static inline void spi_ll_conf_state_enable(spi_dev_t *hw, bool enable) +{ + hw->slave.usr_conf = enable; +} + +/** + * Set Segmented-Configure-Transfer required magic value + * + * @param hw Beginning address of the peripheral registers. + * @param magic_value magic value + */ +static inline void spi_ll_set_magic_number(spi_dev_t *hw, uint8_t magic_value) +{ + hw->slave.dma_seg_magic_value = magic_value; +} + #undef SPI_LL_RST_MASK #undef SPI_LL_UNUSED_INT_MASK diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index fe8eaf5aba..50e474b0a0 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -963,6 +963,22 @@ config SOC_SPI_SUPPORT_CLK_RC_FAST bool default y +config SOC_SPI_SCT_SUPPORTED + bool + default y + +config SOC_SPI_SCT_REG_NUM + int + default 14 + +config SOC_SPI_SCT_BUFFER_NUM_MAX + bool + default y + +config SOC_SPI_SCT_CONF_BITLEN_MAX + hex + default 0x3FFFA + config SOC_MEMSPI_IS_INDEPENDENT bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 9179ab6402..31e6debdac 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -392,6 +392,12 @@ // host_id = 0 -> SPI0/SPI1, host_id = 1 -> SPI2, #define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(host_id) ({(void)host_id; 1;}) +#define SOC_SPI_SCT_SUPPORTED 1 +#define SOC_SPI_SCT_SUPPORTED_PERIPH(PERIPH_NUM) ((PERIPH_NUM==1) ? 1 : 0) //Support Segmented-Configure-Transfer +#define SOC_SPI_SCT_REG_NUM 14 +#define SOC_SPI_SCT_BUFFER_NUM_MAX (1 + SOC_SPI_SCT_REG_NUM) //1-word-bitmap + 14-word-regs +#define SOC_SPI_SCT_CONF_BITLEN_MAX 0x3FFFA //18 bits wide reg + #define SOC_MEMSPI_IS_INDEPENDENT 1 #define SOC_SPI_MAX_PRE_DIVIDER 16