mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
spi_master: sct mode support set line mode, transaction interval time
support line mode 1-2-4-8 depend on targets. fix sct mode dma descriptor counter compute issue. add conf_bits_len setting API to control interval time.
This commit is contained in:
@@ -296,7 +296,7 @@ static inline void spi_ll_user_start(spi_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
|
||||
{
|
||||
return hw->cmd.val;
|
||||
return hw->cmd.usr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -650,8 +650,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);
|
||||
}
|
||||
|
||||
@@ -1302,13 +1302,27 @@ static inline int spi_ll_get_slave_hd_dummy_bits(spi_line_mode_t line_mode)
|
||||
|
||||
#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, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], bool is_end)
|
||||
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) {
|
||||
@@ -1318,6 +1332,44 @@ static inline void spi_ll_format_conf_phase_conf_buffer(spi_dev_t *hw, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
||||
@@ -298,7 +298,7 @@ static inline void spi_ll_user_start(spi_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
|
||||
{
|
||||
return hw->cmd.val;
|
||||
return hw->cmd.usr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -652,8 +652,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);
|
||||
}
|
||||
|
||||
@@ -1215,13 +1215,27 @@ static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
|
||||
|
||||
#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, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], bool is_end)
|
||||
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) {
|
||||
@@ -1231,6 +1245,44 @@ static inline void spi_ll_format_conf_phase_conf_buffer(spi_dev_t *hw, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
||||
@@ -290,7 +290,7 @@ static inline void spi_ll_user_start(spi_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
|
||||
{
|
||||
return hw->cmd.val;
|
||||
return hw->cmd.usr;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -289,7 +289,7 @@ static inline void spi_ll_user_start(spi_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
|
||||
{
|
||||
return hw->cmd.val;
|
||||
return hw->cmd.usr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -643,8 +643,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);
|
||||
}
|
||||
|
||||
@@ -1207,13 +1207,27 @@ static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
|
||||
|
||||
#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, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], bool is_end)
|
||||
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) {
|
||||
@@ -1223,6 +1237,49 @@ static inline void spi_ll_format_conf_phase_conf_buffer(spi_dev_t *hw, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_OCT_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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_OCT_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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_OCT_M );
|
||||
SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_OCT_M);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the conf buffer for prep phase
|
||||
*
|
||||
@@ -1402,7 +1459,7 @@ __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;
|
||||
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;
|
||||
|
||||
@@ -644,10 +644,10 @@ static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t li
|
||||
hw->ctrl.faddr_quad = (line_mode.addr_lines == 4);
|
||||
hw->ctrl.faddr_oct = (line_mode.addr_lines == 8);
|
||||
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_quad = (line_mode.data_lines == 4);
|
||||
hw->ctrl.fread_oct = (line_mode.data_lines == 8);
|
||||
hw->user.fwrite_dual = (line_mode.data_lines == 2);
|
||||
hw->user.fwrite_quad = (line_mode.data_lines == 4);
|
||||
hw->user.fwrite_oct = (line_mode.data_lines == 8);
|
||||
}
|
||||
|
||||
@@ -1518,13 +1518,43 @@ static inline bool spi_ll_tx_get_empty_err(spi_dev_t *hw)
|
||||
|
||||
#define SPI_LL_SCT_MAGIC_NUMBER (0x2)
|
||||
|
||||
/**
|
||||
* Set conf phase base bits len to HW for segment config trans mode.
|
||||
* need let transaction gap more than approx 2 us under different freq, calculated by driver layer.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param conf_base Conf base bits len.
|
||||
*/
|
||||
static inline void spi_ll_set_conf_base_bitslen(spi_dev_t *hw, uint8_t conf_base)
|
||||
{
|
||||
// 7 bits wide
|
||||
if(conf_base < 128) {
|
||||
hw->slv_wrbuf_dlen.conf_base_bitlen = conf_base;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set conf phase bits len to config buffer 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_format_conf_bitslen_buffer(spi_dev_t *hw, uint32_t conf_bitlen, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX])
|
||||
{
|
||||
//cmd reg: conf_bitlen
|
||||
if (conf_bitlen <= SOC_SPI_SCT_CONF_BITLEN_MAX) {
|
||||
SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_CMD_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_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, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], bool is_end)
|
||||
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) {
|
||||
@@ -1534,6 +1564,49 @@ static inline void spi_ll_format_conf_phase_conf_buffer(spi_dev_t *hw, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_OCT_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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_OCT_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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_OCT_M );
|
||||
SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_OCT_M);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the conf buffer for prep phase
|
||||
*
|
||||
|
||||
@@ -305,7 +305,7 @@ static inline void spi_ll_user_start(spi_dev_t *hw)
|
||||
*/
|
||||
static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
|
||||
{
|
||||
return hw->cmd.val;
|
||||
return hw->cmd.usr;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -661,10 +661,10 @@ static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t li
|
||||
hw->ctrl.faddr_quad = (line_mode.addr_lines == 4);
|
||||
hw->ctrl.faddr_oct = (line_mode.addr_lines == 8);
|
||||
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_quad = (line_mode.data_lines == 4);
|
||||
hw->ctrl.fread_oct = (line_mode.data_lines == 8);
|
||||
hw->user.fwrite_dual = (line_mode.data_lines == 2);
|
||||
hw->user.fwrite_quad = (line_mode.data_lines == 4);
|
||||
hw->user.fwrite_oct = (line_mode.data_lines == 8);
|
||||
}
|
||||
|
||||
@@ -1236,13 +1236,28 @@ static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
|
||||
|
||||
#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, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX], bool is_end)
|
||||
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) {
|
||||
@@ -1252,6 +1267,49 @@ static inline void spi_ll_format_conf_phase_conf_buffer(spi_dev_t *hw, uint32_t
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_OCT_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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_OCT_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;
|
||||
case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_OCT_M );
|
||||
SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_OCT_M);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the conf buffer for prep phase
|
||||
*
|
||||
|
||||
@@ -160,6 +160,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
/* CONF State */
|
||||
bool seg_end; ///< True: this segment is the end; False: this segment isn't the end;
|
||||
uint32_t seg_gap_len; ///< spi clock length of CS inactive on config phase for sct
|
||||
/* PREP State */
|
||||
int cs_setup; ///< Setup time of CS active edge before the first SPI clock
|
||||
/* CMD State */
|
||||
@@ -430,6 +431,17 @@ void spi_hal_sct_load_dma_link(spi_hal_context_t *hal, lldesc_t *rx_seg_head, ll
|
||||
* Deinit SCT mode related registers and hal states
|
||||
*/
|
||||
void spi_hal_sct_deinit(spi_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* Set conf_bitslen to HW for sct.
|
||||
*/
|
||||
#define spi_hal_sct_set_conf_bits_len(hal, conf_len) spi_ll_set_conf_phase_bits_len((hal)->hw, conf_len)
|
||||
|
||||
/**
|
||||
* Set conf_bitslen base to HW for sct, only supported on s2.
|
||||
*/
|
||||
#define spi_hal_sct_setup_conf_base(hal, conf_base) spi_ll_set_conf_base_bitslen((hal)->hw, conf_base)
|
||||
|
||||
#endif //#if SOC_SPI_SCT_SUPPORTED
|
||||
#endif //#if SOC_GPSPI_SUPPORTED
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ void spi_hal_sct_init(spi_hal_context_t *hal)
|
||||
s_sct_reset_dma_link(hal);
|
||||
spi_ll_conf_state_enable(hal->hw, true);
|
||||
spi_ll_set_magic_number(hal->hw, SPI_LL_SCT_MAGIC_NUMBER);
|
||||
spi_ll_disable_int(hal->hw); //trans_done intr enabled in `add device` phase, sct mode shoud use sct_trans_done only
|
||||
spi_ll_enable_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
|
||||
spi_ll_set_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
|
||||
}
|
||||
@@ -77,6 +78,8 @@ void spi_hal_sct_deinit(spi_hal_context_t *hal)
|
||||
spi_ll_conf_state_enable(hal->hw, false);
|
||||
spi_ll_disable_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
|
||||
spi_ll_clear_intr(hal->hw, SPI_LL_INTR_SEG_DONE);
|
||||
spi_ll_clear_int_stat(hal->hw);
|
||||
spi_ll_enable_int(hal->hw); //recover trans_done intr
|
||||
}
|
||||
#endif //#if SOC_SPI_SCT_SUPPORTED
|
||||
|
||||
|
||||
@@ -174,6 +174,7 @@ void spi_hal_sct_init_conf_buffer(spi_hal_context_t *hal, uint32_t conf_buffer[S
|
||||
|
||||
void spi_hal_sct_format_conf_buffer(spi_hal_context_t *hal, const spi_hal_seg_config_t *config, const spi_hal_dev_config_t *dev, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX])
|
||||
{
|
||||
spi_ll_format_line_mode_conf_buff(hal->hw, hal->trans_config.line_mode, conf_buffer);
|
||||
spi_ll_format_prep_phase_conf_buffer(hal->hw, config->cs_setup, conf_buffer);
|
||||
spi_ll_format_cmd_phase_conf_buffer(hal->hw, config->cmd, config->cmd_bits, dev->tx_lsbfirst, conf_buffer);
|
||||
spi_ll_format_addr_phase_conf_buffer(hal->hw, config->addr, config->addr_bits, dev->rx_lsbfirst, conf_buffer);
|
||||
@@ -181,7 +182,11 @@ void spi_hal_sct_format_conf_buffer(spi_hal_context_t *hal, const spi_hal_seg_co
|
||||
spi_ll_format_dout_phase_conf_buffer(hal->hw, config->tx_bitlen, conf_buffer);
|
||||
spi_ll_format_din_phase_conf_buffer(hal->hw, config->rx_bitlen, conf_buffer);
|
||||
spi_ll_format_done_phase_conf_buffer(hal->hw, config->cs_hold, conf_buffer);
|
||||
spi_ll_format_conf_phase_conf_buffer(hal->hw, conf_buffer, config->seg_end);
|
||||
spi_ll_format_conf_phase_conf_buffer(hal->hw, config->seg_end, conf_buffer);
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
// only s2 support update seg_gap_len by conf_buffer
|
||||
spi_ll_format_conf_bitslen_buffer(hal->hw, config->seg_gap_len, conf_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
void spi_hal_sct_load_dma_link(spi_hal_context_t *hal, lldesc_t *rx_seg_head, lldesc_t *tx_seg_head)
|
||||
@@ -275,7 +280,7 @@ spi_hal_dma_desc_status_t spi_hal_sct_link_tx_seg_dma_desc(spi_hal_context_t *ha
|
||||
|
||||
lldesc_t *internal_head = NULL;
|
||||
s_sct_prepare_tx_seg(hal, conf_buffer, send_buffer, buf_len_bytes, &internal_head);
|
||||
*used_desc_num = 1 + lldesc_get_required_num(buf_len_bytes);
|
||||
*used_desc_num += 1 + lldesc_get_required_num(buf_len_bytes);
|
||||
|
||||
return SPI_HAL_DMA_DESC_LINKED;
|
||||
}
|
||||
@@ -331,7 +336,7 @@ spi_hal_dma_desc_status_t spi_hal_sct_link_rx_seg_dma_desc(spi_hal_context_t *ha
|
||||
|
||||
lldesc_t *internal_head = NULL;
|
||||
s_sct_prepare_rx_seg(hal, recv_buffer, buf_len_bytes, &internal_head);
|
||||
*used_desc_num = lldesc_get_required_num(buf_len_bytes);
|
||||
*used_desc_num += lldesc_get_required_num(buf_len_bytes);
|
||||
|
||||
return SPI_HAL_DMA_DESC_LINKED;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user