mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 03:00:34 +03:00
Merge branch 'feat/spi_std_timing_and_bit_trans_v5.4' into 'release/v5.4'
feat(driver_spi): support adjust master rx to standard timing (v5.4) See merge request espressif/esp-idf!36399
This commit is contained in:
@@ -78,6 +78,7 @@ typedef struct {
|
||||
delay before the MISO is ready on the line. Leave at 0 unless you know you need a delay. For better timing
|
||||
performance at high frequency (over 8MHz), it's suggest to have the right value.
|
||||
*/
|
||||
spi_sampling_point_t sample_point; ///< Sample point tuning of spi master receiving bit.
|
||||
int spics_io_num; ///< CS GPIO pin for this device, or -1 if not used
|
||||
uint32_t flags; ///< Bitwise OR of SPI_DEVICE_* flags
|
||||
int queue_size; ///< Transaction queue size. This sets how many transactions can be 'in the air' (queued using spi_device_queue_trans but not yet finished using spi_device_get_trans_result) at the same time
|
||||
|
||||
@@ -487,6 +487,10 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
||||
SPI_CHECK(ret == ESP_OK, "assigned clock speed not supported", ret);
|
||||
temp_timing_conf.clock_source = clk_src;
|
||||
temp_timing_conf.source_pre_div = clock_source_div;
|
||||
temp_timing_conf.rx_sample_point = dev_config->sample_point;
|
||||
if (temp_timing_conf.rx_sample_point == SPI_SAMPLING_POINT_PHASE_1) {
|
||||
SPI_CHECK(spi_ll_master_is_rx_std_sample_supported(), "SPI_SAMPLING_POINT_PHASE_1 is not supported on this chip", ESP_ERR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
//Allocate memory for device
|
||||
dev = malloc(sizeof(spi_device_t));
|
||||
|
||||
@@ -611,6 +611,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -648,7 +667,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(SPI1.clock) reg;
|
||||
typeof(SPI1.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -696,6 +696,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -733,7 +752,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -698,6 +698,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -735,7 +754,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -696,6 +696,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -733,7 +752,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -690,6 +690,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -727,7 +746,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -710,6 +710,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -747,7 +766,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -20,11 +20,13 @@
|
||||
#include "esp_types.h"
|
||||
#include "soc/spi_periph.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/chip_revision.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/spi_types.h"
|
||||
#include "soc/pcr_struct.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -689,6 +691,26 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
* This config take effect only when SPI_CLK (pre-div before periph) div >=2
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
hw->clock.clk_edge_sel = (sample_point == SPI_SAMPLING_POINT_PHASE_1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -726,7 +748,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -746,6 +746,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -783,7 +802,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -687,6 +687,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -724,7 +743,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -717,6 +717,25 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs: parameters
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Set the standard clock mode for master.
|
||||
*
|
||||
* @param hw Beginning address of the peripheral registers.
|
||||
* @param enable_std True for std timing, False for half cycle delay sampling.
|
||||
*/
|
||||
static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point)
|
||||
{
|
||||
//This is not supported
|
||||
}
|
||||
|
||||
/**
|
||||
* Get if standard clock mode is supported.
|
||||
*/
|
||||
static inline bool spi_ll_master_is_rx_std_sample_supported(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the clock for master by stored value.
|
||||
*
|
||||
@@ -754,7 +773,7 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
|
||||
*/
|
||||
static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
|
||||
{
|
||||
typeof(GPSPI2.clock) reg;
|
||||
typeof(GPSPI2.clock) reg = {.val = 0};
|
||||
int eff_clk;
|
||||
|
||||
//In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
|
||||
|
||||
@@ -76,6 +76,7 @@ typedef struct {
|
||||
int real_freq; ///< Output of the actual frequency
|
||||
int timing_dummy; ///< Extra dummy needed to compensate the timing
|
||||
int timing_miso_delay; ///< Extra miso delay clocks to compensate the timing
|
||||
spi_sampling_point_t rx_sample_point;///< Sample data follow standard SPI timing in master mode
|
||||
} spi_hal_timing_conf_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,8 +76,15 @@ typedef enum {
|
||||
SPI_CMD_HD_INT2 = BIT(9),
|
||||
} spi_command_t;
|
||||
|
||||
/** @cond */ //Doxy command to hide preprocessor definitions from docs */
|
||||
/**
|
||||
* @brief SPI master RX sample point mode configuration
|
||||
*/
|
||||
typedef enum {
|
||||
SPI_SAMPLING_POINT_PHASE_0, ///< Data sampling point at 50% cycle delayed then standard timing, (default).
|
||||
SPI_SAMPLING_POINT_PHASE_1, ///< Data sampling point follows standard SPI timing in master mode
|
||||
} spi_sampling_point_t;
|
||||
|
||||
/** @cond */ //Doxy command to hide preprocessor definitions from docs */
|
||||
//alias for different chips, deprecated for the chips after esp32s2
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
#define SPI_HOST SPI1_HOST
|
||||
@@ -89,7 +96,6 @@ typedef enum {
|
||||
#define FSPI_HOST SPI2_HOST
|
||||
#define HSPI_HOST SPI3_HOST
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
// The HAL layer for SPI (common part, in iram)
|
||||
// make these functions in a seperate file to make sure all LL functions are in the IRAM.
|
||||
// make these functions in a separate file to make sure all LL functions are in the IRAM.
|
||||
|
||||
#include "hal/spi_hal.h"
|
||||
#include "hal/assert.h"
|
||||
@@ -21,6 +21,7 @@ void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
|
||||
#endif
|
||||
spi_ll_master_set_pos_cs(hw, dev->cs_pin_id, dev->positive_cs);
|
||||
spi_ll_master_set_clock_by_reg(hw, &dev->timing_conf.clock_reg);
|
||||
spi_ll_master_set_rx_timing_mode(hw, dev->timing_conf.rx_sample_point);
|
||||
//Configure bit order
|
||||
spi_ll_set_rx_lsbfirst(hw, dev->rx_lsbfirst);
|
||||
spi_ll_set_tx_lsbfirst(hw, dev->tx_lsbfirst);
|
||||
|
||||
@@ -622,7 +622,15 @@ typedef union {
|
||||
* In the master mode it is pre-divider of spi_clk. Can be configured in CONF state.
|
||||
*/
|
||||
uint32_t clkdiv_pre:4;
|
||||
uint32_t reserved_22:9;
|
||||
uint32_t reserved_22:8;
|
||||
/** clk_edge_sel : R/W; bitpos: [30]; default: 0;
|
||||
* Configures use standard clock sampling edge or delay the sampling edge by half a
|
||||
* cycle in master transfer.
|
||||
* 0: clock sampling edge is delayed by half a cycle.
|
||||
* 1: clock sampling edge is standard.
|
||||
* Can be configured in CONF state. Only support on chip version >= 1.2
|
||||
*/
|
||||
uint32_t clk_edge_sel:1;
|
||||
/** clk_equ_sysclk : R/W; bitpos: [31]; default: 1;
|
||||
* In the master mode 1: spi_clk is equal to system 0: spi_clk is divided from system
|
||||
* clock. Can be configured in CONF state.
|
||||
|
||||
Reference in New Issue
Block a user