Merge branch 'feature/spi_little_endien' into 'master'
feature(spi): provide macro to write multi-byte data straightly See merge request idf/esp-idf!2634
This commit is contained in:
commit
52f4ff6220
|
@ -31,6 +31,34 @@ extern "C"
|
||||||
//Maximum amount of bytes that can be put in one DMA descriptor
|
//Maximum amount of bytes that can be put in one DMA descriptor
|
||||||
#define SPI_MAX_DMA_LEN (4096-4)
|
#define SPI_MAX_DMA_LEN (4096-4)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform unsigned integer of length <= 32 bits to the format which can be
|
||||||
|
* sent by the SPI driver directly.
|
||||||
|
*
|
||||||
|
* E.g. to send 9 bits of data, you can:
|
||||||
|
*
|
||||||
|
* uint16_t data = SPI_SWAP_DATA_TX(0x145, 9);
|
||||||
|
*
|
||||||
|
* Then points tx_buffer to ``&data``.
|
||||||
|
*
|
||||||
|
* @param data Data to be sent, can be uint8_t, uint16_t or uint32_t. @param
|
||||||
|
* len Length of data to be sent, since the SPI peripheral sends from the MSB,
|
||||||
|
* this helps to shift the data to the MSB.
|
||||||
|
*/
|
||||||
|
#define SPI_SWAP_DATA_TX(data, len) __builtin_bswap32((uint32_t)data<<(32-len))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transform received data of length <= 32 bits to the format of an unsigned integer.
|
||||||
|
*
|
||||||
|
* E.g. to transform the data of 15 bits placed in a 4-byte array to integer:
|
||||||
|
*
|
||||||
|
* uint16_t data = SPI_SWAP_DATA_RX(*(uint32_t*)t->rx_data, 15);
|
||||||
|
*
|
||||||
|
* @param data Data to be rearranged, can be uint8_t, uint16_t or uint32_t.
|
||||||
|
* @param len Length of data received, since the SPI peripheral writes from
|
||||||
|
* the MSB, this helps to shift the data to the LSB.
|
||||||
|
*/
|
||||||
|
#define SPI_SWAP_DATA_RX(data, len) (__builtin_bswap32(data)>>(32-len))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enum with the three SPI peripherals that are software-accessible in it
|
* @brief Enum with the three SPI peripherals that are software-accessible in it
|
||||||
|
|
|
@ -727,9 +727,12 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
|
||||||
host->hw->user.usr_addr=addrlen?1:0;
|
host->hw->user.usr_addr=addrlen?1:0;
|
||||||
host->hw->user.usr_command=cmdlen?1:0;
|
host->hw->user.usr_command=cmdlen?1:0;
|
||||||
|
|
||||||
// output command will be sent from bit 7 to 0 of command_value, and then bit 15 to 8 of the same register field.
|
/* Output command will be sent from bit 7 to 0 of command_value, and
|
||||||
uint16_t command = trans->cmd << (16-cmdlen); //shift to MSB
|
* then bit 15 to 8 of the same register field. Shift and swap to send
|
||||||
host->hw->user2.usr_command_value = (command>>8)|(command<<8); //swap the first and second byte
|
* more straightly.
|
||||||
|
*/
|
||||||
|
host->hw->user2.usr_command_value = SPI_SWAP_DATA_TX(trans->cmd, cmdlen);
|
||||||
|
|
||||||
// shift the address to MSB of addr (and maybe slv_wr_status) register.
|
// shift the address to MSB of addr (and maybe slv_wr_status) register.
|
||||||
// output address will be sent from MSB to LSB of addr register, then comes the MSB to LSB of slv_wr_status register.
|
// output address will be sent from MSB to LSB of addr register, then comes the MSB to LSB of slv_wr_status register.
|
||||||
if (addrlen>32) {
|
if (addrlen>32) {
|
||||||
|
|
|
@ -167,6 +167,10 @@ memcpy of temporary buffers.
|
||||||
.. note:: Half duplex transactions with both read and write phases are not supported when using DMA. See
|
.. note:: Half duplex transactions with both read and write phases are not supported when using DMA. See
|
||||||
:ref:`spi_known_issues` for details and workarounds.
|
:ref:`spi_known_issues` for details and workarounds.
|
||||||
|
|
||||||
|
Tips
|
||||||
|
""""
|
||||||
|
|
||||||
|
1. Transactions with small amount of data:
|
||||||
Sometimes, the amount of data is very small making it less than optimal allocating a separate buffer
|
Sometimes, the amount of data is very small making it less than optimal allocating a separate buffer
|
||||||
for it. If the data to be transferred is 32 bits or less, it can be stored in the transaction struct
|
for it. If the data to be transferred is 32 bits or less, it can be stored in the transaction struct
|
||||||
itself. For transmitted data, use the ``tx_data`` member for this and set the ``SPI_USE_TXDATA`` flag
|
itself. For transmitted data, use the ``tx_data`` member for this and set the ``SPI_USE_TXDATA`` flag
|
||||||
|
@ -174,6 +178,25 @@ on the transmission. For received data, use ``rx_data`` and set ``SPI_USE_RXDATA
|
||||||
not touch the ``tx_buffer`` or ``rx_buffer`` members, because they use the same memory locations
|
not touch the ``tx_buffer`` or ``rx_buffer`` members, because they use the same memory locations
|
||||||
as ``tx_data`` and ``rx_data``.
|
as ``tx_data`` and ``rx_data``.
|
||||||
|
|
||||||
|
2. Transactions with integers other than uint8_t
|
||||||
|
The SPI peripheral reads and writes the memory byte-by-byte. By default,
|
||||||
|
the SPI works at MSB first mode, each bytes are sent or received from the
|
||||||
|
MSB to the LSB. However, if you want to send data with length which is
|
||||||
|
not multiples of 8 bits, unused bits are sent.
|
||||||
|
|
||||||
|
E.g. you write ``uint8_t data = 0x15`` (00010101B), and set length to
|
||||||
|
only 5 bits, the sent data is ``00010B`` rather than expected ``10101B``.
|
||||||
|
|
||||||
|
Moreover, ESP32 is a little-endian chip whose lowest byte is stored at
|
||||||
|
the very beginning address for uint16_t and uint32_t variables. Hence if
|
||||||
|
a uint16_t is stored in the memory, it's bit 7 is first sent, then bit 6
|
||||||
|
to 0, then comes its bit 15 to bit 8.
|
||||||
|
|
||||||
|
To send data other than uint8_t arrays, macros ``SPI_SWAP_DATA_TX`` is
|
||||||
|
provided to shift your data to the MSB and swap the MSB to the lowest
|
||||||
|
address; while ``SPI_SWAP_DATA_RX`` can be used to swap received data
|
||||||
|
from the MSB to it's correct place.
|
||||||
|
|
||||||
Speed and Timing Considerations
|
Speed and Timing Considerations
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue