optimise mavlink SS packet size (#3029)
[ExpressLRS.git] / src / lib / SPIEx / SPIEx.cpp
blobfed60c3df19b894ade334f6e303a8b1991539b67
1 #include "SPIEx.h"
3 #if defined(PLATFORM_ESP32)
4 #include <soc/spi_struct.h>
5 #endif
7 void ICACHE_RAM_ATTR SPIExClass::_transfer(uint8_t cs_mask, uint8_t *data, uint32_t size, bool reading)
9 #if defined(PLATFORM_ESP32)
10 spi_dev_t *spi = *(reinterpret_cast<spi_dev_t**>(bus()));
11 // wait for SPI to become non-busy
12 while(spi->cmd.usr) {}
14 // Set the CS pins which we want controlled by the SPI module for this operation
15 spiDisableSSPins(bus(), ~cs_mask);
16 spiEnableSSPins(bus(), cs_mask);
18 #if defined(PLATFORM_ESP32_S3) || defined(PLATFORM_ESP32_C3)
19 spi->ms_dlen.ms_data_bitlen = (size*8)-1;
20 #else
21 spi->mosi_dlen.usr_mosi_dbitlen = ((size * 8) - 1);
22 spi->miso_dlen.usr_miso_dbitlen = ((size * 8) - 1);
23 #endif
25 // write the data to the SPI FIFO
26 const uint32_t words = (size + 3) / 4;
27 auto * const wordsBuf = reinterpret_cast<uint32_t *>(data);
28 for(int i=0; i<words; i++)
30 spi->data_buf[i] = wordsBuf[i]; //copy buffer to spi fifo
33 #if defined(PLATFORM_ESP32_S3) || defined(PLATFORM_ESP32_C3)
34 spi->cmd.update = 1;
35 while (spi->cmd.update) {}
36 #endif
37 // start the SPI module
38 spi->cmd.usr = 1;
40 if (reading)
42 // wait for SPI write to complete
43 while(spi->cmd.usr) {}
45 for(int i=0; i<words; i++)
47 wordsBuf[i] = spi->data_buf[i]; //copy spi fifo to buffer
50 #elif defined(PLATFORM_ESP8266)
51 // we support only one hardware controlled CS pin, so theres nothing to do to configure it at this point
53 // wait for SPI to become non-busy
54 while(SPI1CMD & SPIBUSY) {}
56 // Set in/out Bits to transfer
57 const uint32_t mask = ~((SPIMMOSI << SPILMOSI) | (SPIMMISO << SPILMISO));
58 const auto bits = (size * 8) - 1;
59 SPI1U1 = ((SPI1U1 & mask) | ((bits << SPILMOSI) | (bits << SPILMISO)));
61 // write the data to the SPI FIFO
62 volatile uint32_t * const fifoPtr = &SPI1W0;
63 const uint8_t outSize = ((size + 3) / 4);
64 uint32_t * const dataPtr = (uint32_t*) data;
65 for(int i=0; i<outSize; i++)
67 fifoPtr[i] = dataPtr[i];
70 // start the SPI module
71 SPI1CMD |= SPIBUSY;
73 if (reading)
75 // wait for SPI write to complete
76 while(SPI1CMD & SPIBUSY) {}
78 // read data from the FIFO back to the application buffer
79 for(int i=0; i<outSize; i++)
81 dataPtr[i] = fifoPtr[i];
84 #endif
87 #if defined(PLATFORM_ESP32_S3) || defined(PLATFORM_ESP32_C3)
88 SPIExClass SPIEx(FSPI);
89 #elif defined(PLATFORM_ESP32)
90 SPIExClass SPIEx(VSPI);
91 #else
92 SPIExClass SPIEx;
93 #endif