mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'feat/spi_std_timing_and_bit_trans' into 'master'
feat(driver_spi): support adjust master rx to standard timing Closes IDF-11396 See merge request espressif/esp-idf!36058
This commit is contained in:
commit
d78f270b04
@ -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));
|
||||
|
@ -613,6 +613,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.
|
||||
*
|
||||
@ -650,7 +669,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.
|
||||
|
@ -689,6 +689,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.
|
||||
*
|
||||
@ -726,7 +745,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.
|
||||
|
@ -709,6 +709,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.
|
||||
*
|
||||
@ -746,7 +765,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" {
|
||||
@ -688,6 +690,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.
|
||||
*
|
||||
@ -725,7 +747,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.
|
||||
|
@ -745,6 +745,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.
|
||||
*
|
||||
@ -782,7 +801,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.
|
||||
|
@ -688,6 +688,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.
|
||||
*
|
||||
@ -725,7 +744,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;
|
||||
|
||||
/**
|
||||
|
@ -73,6 +73,14 @@ typedef enum {
|
||||
SPI_CMD_HD_INT2 = BIT(9),
|
||||
} spi_command_t;
|
||||
|
||||
/**
|
||||
* @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;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -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.
|
||||
|
21
docs/_static/diagrams/spi/spi_mode0_delay.json
vendored
Normal file
21
docs/_static/diagrams/spi/spi_mode0_delay.json
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"signal": [
|
||||
{
|
||||
"name": "CS",
|
||||
"wave": "10.......1"
|
||||
},
|
||||
{
|
||||
"name": "CLK",
|
||||
"wave": "lnN......l",
|
||||
},
|
||||
{
|
||||
"name": "MISO",
|
||||
"wave": "x22222222x",
|
||||
"phase": 0,
|
||||
"data": "7 6 5 4 3 2 1 0"
|
||||
}
|
||||
],
|
||||
"foot": {
|
||||
"text": "SPI delayed mode 0"
|
||||
}
|
||||
}
|
22
docs/_static/diagrams/spi/spi_mode0_std.json
vendored
Normal file
22
docs/_static/diagrams/spi/spi_mode0_std.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"signal": [
|
||||
{
|
||||
"name": "CS",
|
||||
"wave": "10.......1"
|
||||
},
|
||||
{
|
||||
"name": "CLK",
|
||||
"wave": "l.P.......l",
|
||||
"phase": 0.5
|
||||
},
|
||||
{
|
||||
"name": "MISO",
|
||||
"wave": "x22222222x",
|
||||
"phase": 0,
|
||||
"data": "7 6 5 4 3 2 1 0"
|
||||
}
|
||||
],
|
||||
"foot": {
|
||||
"text": "SPI normal mode 0"
|
||||
}
|
||||
}
|
@ -653,6 +653,26 @@ When a transaction length is short, the cost of the transaction interval is high
|
||||
|
||||
Please note that the ISR is disabled during flash operation by default. To keep sending transactions during flash operations, enable :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` and set :c:macro:`ESP_INTR_FLAG_IRAM` in the member :cpp:member:`spi_bus_config_t::intr_flags`. In this case, all the transactions queued before starting flash operations are handled by the ISR in parallel. Also note that the callback of each Device and their ``callee`` functions should be in IRAM, or your callback will crash due to cache missing. For more details, see :ref:`iram-safe-interrupt-handlers`.
|
||||
|
||||
.. only:: esp32h2
|
||||
|
||||
Timing Tuning
|
||||
-------------
|
||||
|
||||
.. only:: esp32h2
|
||||
|
||||
This feature is supported only on chip revision v1.2 or later.
|
||||
|
||||
To accommodate the timing requirements of different slave devices and improve signal stability, GP-SPI controllers support two sampling modes when receiving data: Sample Phase 0 and Sample Phase 1. These can be configured via :cpp:member:`spi_device_interface_config_t::sample_point`.
|
||||
|
||||
Sample Phase 0 (SPI mode 0):
|
||||
|
||||
.. wavedrom:: /../_static/diagrams/spi/spi_mode0_delay.json
|
||||
|
||||
Sample Phase 1 (SPI mode 0):
|
||||
|
||||
.. wavedrom:: /../_static/diagrams/spi/spi_mode0_std.json
|
||||
|
||||
By default, the driver uses sample phase 0, when the slave device adheres to standard SPI timing specifications, sample phase 0 provides more stable data reception at high clock frequencies.
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
|
@ -653,6 +653,26 @@ GPSPI 外设的时钟源可以通过设置 :cpp:member:`spi_device_handle_t::cfg
|
||||
|
||||
注意,ISR 在 flash 操作期间默认处于禁用状态。要在 flash 操作期间继续发送传输事务,请启用 :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM`,并在 :cpp:member:`spi_bus_config_t::intr_flags` 中设置 :c:macro:`ESP_INTR_FLAG_IRAM`。此时,flash 操作前列队的传输事务将由 ISR 并行处理。此外,每个设备的回调和它们的 ``callee`` 函数都应该在 IRAM 中,避免回调因缓存丢失而崩溃。详情请参阅 :ref:`iram-safe-interrupt-handlers`。
|
||||
|
||||
.. only:: esp32h2
|
||||
|
||||
时序调整
|
||||
--------
|
||||
|
||||
.. only:: esp32h2
|
||||
|
||||
该功能只在芯片版本 v1.2 及以上中支持。
|
||||
|
||||
为了适应不同从设备的时序要求,以及提高信号稳定性, GP-SPI 控制器在接收数据时支持两种采样模式:采样模式 0 和采样模式 1 ,可通过 :cpp:member:`spi_device_interface_config_t::sample_point` 进行配置。
|
||||
|
||||
采样模式 0 ( SPI mode 0 ):
|
||||
|
||||
.. wavedrom:: /../_static/diagrams/spi/spi_mode0_delay.json
|
||||
|
||||
采样模式 1 ( SPI mode 0 ):
|
||||
|
||||
.. wavedrom:: /../_static/diagrams/spi/spi_mode0_std.json
|
||||
|
||||
默认情况下,驱动使用采样模式 0 ,当从设备遵守 SPI 标准时序时,采样模式 0 可以在高时钟频率时更稳定的接收数据。
|
||||
|
||||
.. only:: esp32
|
||||
|
||||
@ -661,7 +681,7 @@ GPSPI 外设的时钟源可以通过设置 :cpp:member:`spi_device_handle_t::cfg
|
||||
时序影响因素
|
||||
---------------------
|
||||
|
||||
如图所示,SCLK 发射沿之后、信号被内部寄存器锁存之前,MISO 线存在延迟。因此,MISO 管脚的设置时间是 SPI 时钟速度的限制因素。当延迟过长时,设置松弛度 < 0,违反了设置时序要求,读取可能有误。
|
||||
如图所示, SCLK 发射沿之后、信号被内部寄存器锁存之前, MISO 线存在延迟。因此, MISO 管脚的设置时间是 SPI 时钟速度的限制因素。当延迟过长时,设置松弛度 < 0 ,违反了设置时序要求,读取可能有误。
|
||||
|
||||
.. image:: /../_static/spi_miso.png
|
||||
:scale: 40 %
|
||||
|
Loading…
x
Reference in New Issue
Block a user