mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-07 17:08:49 +00:00
spi_slave: improve the timing configuration
SPI Slave =========== - Correct the configuration of mode 0~3 using new config in the TRM - Split the workaround for DMA in mode 0/2 out of normal config, to make it clear. - Update timing and speed document for the SPI slave. Resolves https://github.com/espressif/esp-idf/issues/1346, https://github.com/espressif/esp-idf/issues/2393
This commit is contained in:
committed by
Michael (XIAO Xufeng)
parent
d9c5016e08
commit
58955a79a2
@@ -13,8 +13,10 @@ connected SPI master.
|
||||
The spi_slave driver
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The spi_slave driver allows using the HSPI and/or VSPI peripheral as a full-duplex SPI slave. It can make
|
||||
use of DMA to send/receive transactions of arbitrary length.
|
||||
The spi_slave driver allows using the HSPI and/or VSPI peripheral as a
|
||||
full-duplex SPI slave. It can send/receive transactions within 64 bytes, or
|
||||
make use of DMA to send/receive transactions longer than that. However, there
|
||||
are some `known issues <spi_dma_known_issues>`_ when the DMA is enabled.
|
||||
|
||||
Terminology
|
||||
^^^^^^^^^^^
|
||||
@@ -47,6 +49,54 @@ starts sending out clock pulses on the CLK line: every clock pulse causes a data
|
||||
the master to the slave on the MOSI line and vice versa on the MISO line. At the end of the transaction,
|
||||
the master makes CS high again.
|
||||
|
||||
.. note:: The SPI slave peripheral relies on the control of software very
|
||||
much. The master shouldn't start a transaction when the slave hasn't prepared
|
||||
for it. Using one more GPIO as the handshake signal to sync is a good idea.
|
||||
For more details, see :ref:`transaction_interval`.
|
||||
|
||||
GPIO matrix and IOMUX
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Most peripheral signals in ESP32 can connect directly to a specific GPIO,
|
||||
which is called its IOMUX pin. When a peripheral signal is routed to a pin
|
||||
other than its IOMUX pin, ESP32 uses the less direct GPIO matrix to make this
|
||||
connection.
|
||||
|
||||
If the driver is configured with all SPI signals set to their specific IOMUX
|
||||
pins (or left unconnected), it will bypass the GPIO matrix. If any SPI signal
|
||||
is configured to a pin other than its IOMUx pin, the driver will
|
||||
automatically route all the signals via the GPIO Matrix. The GPIO matrix
|
||||
samples all signals at 80MHz and sends them between the GPIO and the
|
||||
peripheral.
|
||||
|
||||
When the GPIO matrix is used, setup time of MISO is more easily violated,
|
||||
since the output delay of MISO signal is increased.
|
||||
|
||||
.. note:: More details about influence of output delay on the maximum clock
|
||||
frequency, see :ref:`timing_considerations` below.
|
||||
|
||||
IOMUX pins for SPI controllers are as below:
|
||||
|
||||
+----------+------+------+
|
||||
| Pin Name | HSPI | VSPI |
|
||||
+ +------+------+
|
||||
| | GPIO Number |
|
||||
+==========+======+======+
|
||||
| CS0* | 15 | 5 |
|
||||
+----------+------+------+
|
||||
| SCLK | 14 | 18 |
|
||||
+----------+------+------+
|
||||
| MISO | 12 | 19 |
|
||||
+----------+------+------+
|
||||
| MOSI | 13 | 23 |
|
||||
+----------+------+------+
|
||||
| QUADWP | 2 | 22 |
|
||||
+----------+------+------+
|
||||
| QUADHD | 4 | 21 |
|
||||
+----------+------+------+
|
||||
|
||||
note * Only the first device attaching to the bus can use CS0 pin.
|
||||
|
||||
Using the spi_slave driver
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -85,6 +135,73 @@ Warning: Due to a design peculiarity in the ESP32, if the amount of bytes sent b
|
||||
of the transmission queues in the slave driver, in bytes, is not both larger than eight and dividable by
|
||||
four, the SPI hardware can fail to write the last one to seven bytes to the receive buffer.
|
||||
|
||||
Speed and Timing considerations
|
||||
-------------------------------
|
||||
|
||||
.. _transaction_interval:
|
||||
|
||||
Transaction interval
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The SPI slave is designed as s general purpose device controlled by the CPU.
|
||||
Different from dedicated devices, CPU-based SPI slave doesn't have too much
|
||||
pre-defined registers. All transactions should be triggered by the CPU, which
|
||||
means the response speed would not be real-time, and there'll always be
|
||||
noticeable intervals between transfers.
|
||||
|
||||
During the transaction intervals, the device is not prepared for
|
||||
transactions, the response is not meaningful at all. It is suggested to use
|
||||
:cpp:func:`spi_slave_queue_trans` with :cpp:func:`spi_slave_get_trans_result`
|
||||
to shorten the interval to half the case when using
|
||||
:cpp:func:`spi_slave_transmit`.
|
||||
|
||||
The master should always wait for the slave to be ready to start new
|
||||
transactions. Suggested way is to use a gpio by the slave to indicate whether
|
||||
it's ready. The example is in :example:`peripherals/spi_slave`.
|
||||
|
||||
SCLK frequency requirement
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The spi slave is designed to work under 10MHz or lower. The clock and data
|
||||
cannot be recognized or received correctly if the clock is too fast or
|
||||
doesn't have a 50% duty cycle.
|
||||
|
||||
Moreover, there are more requirements if the data meets the timing
|
||||
requirement:
|
||||
|
||||
- Read (MOSI):
|
||||
Given that the MOSI is valid right at the launch edge, the slave can
|
||||
read data correctly. Luckily, it's usually the case for most masters.
|
||||
|
||||
- Write (MISO):
|
||||
To meet the requirement that MISO is stable before the next latch edge of
|
||||
SPI clock, the output delay of MISO signal should be shorter than half a
|
||||
clock. The output delay and frequency limitation (given that the clock is
|
||||
balanced) of different cases are as below :
|
||||
|
||||
+-------------+---------------------------+------------------------+
|
||||
| | Output delay of MISO (ns) | Freq. limit (MHZ) |
|
||||
+=============+===========================+========================+
|
||||
| IOMUX | 43.75 | <11.4 |
|
||||
+-------------+---------------------------+------------------------+
|
||||
| GPIO matrix | 68.75 | <7.2 |
|
||||
+-------------+---------------------------+------------------------+
|
||||
|
||||
Note:
|
||||
1. Random error will happen if the frequency exactly equals the
|
||||
limitation
|
||||
2. The clock uncertainty between master and slave (12.5ns) is
|
||||
included.
|
||||
3. The output delay is measured under ideal case (free of load). When
|
||||
the loading of MISO pin is too heavy, the output delay will be longer,
|
||||
and the maximum allowed frequency will be lower.
|
||||
|
||||
There is an exceptions: The frequency is allowed to be higher if the
|
||||
master has more toleration for the MISO setup time, e.g. latch data at
|
||||
the next edge than expected, or configurable latching time.
|
||||
|
||||
.. _spi_dma_known_issues:
|
||||
|
||||
Restrictions and Known issues
|
||||
-------------------------------
|
||||
|
||||
@@ -96,6 +213,17 @@ Restrictions and Known issues
|
||||
Also, master should write lengths which are a multiple of 4 bytes. Data
|
||||
longer than that will be discarded.
|
||||
|
||||
2. Furthurmore, the DMA requires a spi mode 1/3 timing. When using spi mode
|
||||
0/2, the MISO signal has to output half a clock earlier to meet the timing.
|
||||
The new timing is as below:
|
||||
|
||||
.. image:: /../_static/spi_slave_miso_dma.png
|
||||
|
||||
The hold time after the latch edge is 68.75ns (when GPIO matrix is
|
||||
bypassed), no longer half a SPI clock. The master should sample immediately
|
||||
at the latch edge, or communicate in mode 1/3. Or just initial the spi
|
||||
slave without DMA.
|
||||
|
||||
Application Example
|
||||
-------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user