Repo for ESP32 Weather Station Development
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

355 lignes
16KB

  1. // Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. // http://www.apache.org/licenses/LICENSE-2.0
  7. //
  8. // Unless required by applicable law or agreed to in writing, software
  9. // distributed under the License is distributed on an "AS IS" BASIS,
  10. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. // See the License for the specific language governing permissions and
  12. // limitations under the License.
  13. #ifndef _DRIVER_SPI_MASTER_LOBO_H_
  14. #define _DRIVER_SPI_MASTER_LOBO_H_
  15. #include "esp_err.h"
  16. #include "freertos/FreeRTOS.h"
  17. #include "freertos/semphr.h"
  18. #include "soc/spi_struct.h"
  19. #include "esp_intr_alloc.h"
  20. #include "esp32/rom/lldesc.h"
  21. #ifdef __cplusplus
  22. extern "C"
  23. {
  24. #endif
  25. //Maximum amount of bytes that can be put in one DMA descriptor
  26. #define SPI_MAX_DMA_LEN (4096-4)
  27. /**
  28. * @brief Enum with the three SPI peripherals that are software-accessible in it
  29. */
  30. typedef enum {
  31. TFT_SPI_HOST=0, ///< SPI1, SPI; Cannot be used in this driver!
  32. TFT_HSPI_HOST=1, ///< SPI2, HSPI
  33. TFT_VSPI_HOST=2 ///< SPI3, VSPI
  34. } spi_lobo_host_device_t;
  35. /**
  36. * @brief This is a configuration structure for a SPI bus.
  37. *
  38. * You can use this structure to specify the GPIO pins of the bus. Normally, the driver will use the
  39. * GPIO matrix to route the signals. An exception is made when all signals either can be routed through
  40. * the IO_MUX or are -1. In that case, the IO_MUX is used, allowing for >40MHz speeds.
  41. */
  42. typedef struct {
  43. int mosi_io_num; ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used.
  44. int miso_io_num; ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used.
  45. int sclk_io_num; ///< GPIO pin for Spi CLocK signal, or -1 if not used.
  46. int quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal which is used as D2 in 4-bit communication modes, or -1 if not used.
  47. int quadhd_io_num; ///< GPIO pin for HD (HolD) signal which is used as D3 in 4-bit communication modes, or -1 if not used.
  48. int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4094 if 0.
  49. } spi_lobo_bus_config_t;
  50. #define LB_SPI_DEVICE_TXBIT_LSBFIRST (1<<0) ///< Transmit command/address/data LSB first instead of the default MSB first
  51. #define LB_SPI_DEVICE_RXBIT_LSBFIRST (1<<1) ///< Receive data LSB first instead of the default MSB first
  52. #define LB_SPI_DEVICE_BIT_LSBFIRST (SPI_TXBIT_LSBFIRST|SPI_RXBIT_LSBFIRST); ///< Transmit and receive LSB first
  53. #define LB_SPI_DEVICE_3WIRE (1<<2) ///< Use spiq for both sending and receiving data
  54. #define LB_SPI_DEVICE_POSITIVE_CS (1<<3) ///< Make CS positive during a transaction instead of negative
  55. #define LB_SPI_DEVICE_HALFDUPLEX (1<<4) ///< Transmit data before receiving it, instead of simultaneously
  56. #define LB_SPI_DEVICE_CLK_AS_CS (1<<5) ///< Output clock on CS line if CS is active
  57. #define SPI_ERR_OTHER_CONFIG 7001
  58. typedef struct spi_lobo_transaction_t spi_lobo_transaction_t;
  59. typedef void(*spi_lobo_transaction_cb_t)(spi_lobo_transaction_t *trans);
  60. /**
  61. * @brief This is a configuration for a SPI slave device that is connected to one of the SPI buses.
  62. */
  63. typedef struct {
  64. uint8_t command_bits; ///< Amount of bits in command phase (0-16)
  65. uint8_t address_bits; ///< Amount of bits in address phase (0-64)
  66. uint8_t dummy_bits; ///< Amount of dummy bits to insert between address and data phase
  67. uint8_t mode; ///< SPI mode (0-3)
  68. uint8_t duty_cycle_pos; ///< Duty cycle of positive clock, in 1/256th increments (128 = 50%/50% duty). Setting this to 0 (=not setting it) is equivalent to setting this to 128.
  69. uint8_t cs_ena_pretrans; ///< Amount of SPI bit-cycles the cs should be activated before the transmission (0-16). This only works on half-duplex transactions.
  70. uint8_t cs_ena_posttrans; ///< Amount of SPI bit-cycles the cs should stay active after the transmission (0-16)
  71. int clock_speed_hz; ///< Clock speed, in Hz
  72. int spics_io_num; ///< CS GPIO pin for this device, handled by hardware; set to -1 if not used
  73. int spics_ext_io_num; ///< CS GPIO pin for this device, handled by software (spi_lobo_device_select/spi_lobo_device_deselect); only used if spics_io_num=-1
  74. uint32_t flags; ///< Bitwise OR of LB_SPI_DEVICE_* flags
  75. spi_lobo_transaction_cb_t pre_cb; ///< Callback to be called before a transmission is started. This callback from 'spi_lobo_transfer_data' function.
  76. spi_lobo_transaction_cb_t post_cb; ///< Callback to be called after a transmission has completed. This callback from 'spi_lobo_transfer_data' function.
  77. uint8_t selected; ///< **INTERNAL** 1 if the device's CS pin is active
  78. } spi_lobo_device_interface_config_t;
  79. #define LB_SPI_TRANS_MODE_DIO (1<<0) ///< Transmit/receive data in 2-bit mode
  80. #define LB_SPI_TRANS_MODE_QIO (1<<1) ///< Transmit/receive data in 4-bit mode
  81. #define LB_SPI_TRANS_MODE_DIOQIO_ADDR (1<<2) ///< Also transmit address in mode selected by SPI_MODE_DIO/SPI_MODE_QIO
  82. #define LB_SPI_TRANS_USE_RXDATA (1<<3) ///< Receive into rx_data member of spi_lobo_transaction_t instead into memory at rx_buffer.
  83. #define LB_SPI_TRANS_USE_TXDATA (1<<4) ///< Transmit tx_data member of spi_lobo_transaction_t instead of data at tx_buffer. Do not set tx_buffer when using this.
  84. /**
  85. * This structure describes one SPI transmission
  86. */
  87. struct spi_lobo_transaction_t {
  88. uint32_t flags; ///< Bitwise OR of LB_SPI_TRANS_* flags
  89. uint16_t command; ///< Command data. Specific length was given when device was added to the bus.
  90. uint64_t address; ///< Address. Specific length was given when device was added to the bus.
  91. size_t length; ///< Total data length to be transmitted to the device, in bits; if 0, no data is transmitted
  92. size_t rxlength; ///< Total data length to be received from the device, in bits; if 0, no data is received
  93. void *user; ///< User-defined variable. Can be used to store eg transaction ID or data to be used by pre_cb and/or post_cb callbacks.
  94. union {
  95. const void *tx_buffer; ///< Pointer to transmit buffer, or NULL for no MOSI phase
  96. uint8_t tx_data[4]; ///< If SPI_USE_TXDATA is set, data set here is sent directly from this variable.
  97. };
  98. union {
  99. void *rx_buffer; ///< Pointer to receive buffer, or NULL for no MISO phase
  100. uint8_t rx_data[4]; ///< If SPI_USE_RXDATA is set, data is received directly to this variable
  101. };
  102. };
  103. #define NO_CS 3 // Number of CS pins per SPI host
  104. #define NO_DEV 6 // Number of spi devices per SPI host; more than 3 devices can be attached to the same bus if using software CS's
  105. #define SPI_SEMAPHORE_WAIT 2000 // Time in ms to wait for SPI mutex
  106. typedef struct spi_lobo_device_t spi_lobo_device_t;
  107. typedef struct {
  108. spi_lobo_device_t *device[NO_DEV];
  109. intr_handle_t intr;
  110. spi_dev_t *hw;
  111. //spi_lobo_transaction_t *cur_trans;
  112. int cur_device;
  113. lldesc_t *dmadesc_tx;
  114. lldesc_t *dmadesc_rx;
  115. bool no_gpio_matrix;
  116. int dma_chan;
  117. int max_transfer_sz;
  118. QueueHandle_t spi_lobo_bus_mutex;
  119. spi_lobo_bus_config_t cur_bus_config;
  120. } spi_lobo_host_t;
  121. struct spi_lobo_device_t {
  122. spi_lobo_device_interface_config_t cfg;
  123. spi_lobo_host_t *host;
  124. spi_lobo_bus_config_t bus_config;
  125. spi_lobo_host_device_t host_dev;
  126. };
  127. typedef spi_lobo_device_t* spi_lobo_device_handle_t; ///< Handle for a device on a SPI bus
  128. typedef spi_lobo_host_t* spi_lobo_host_handle_t;
  129. typedef spi_lobo_device_interface_config_t* spi_lobo_device_interface_config_handle_t;
  130. /**
  131. * @brief Add a device. This allocates a CS line for the device, allocates memory for the device structure and hooks
  132. * up the CS pin to whatever is specified.
  133. *
  134. * This initializes the internal structures for a device, plus allocates a CS pin on the indicated SPI master
  135. * peripheral and routes it to the indicated GPIO. All SPI master devices have three hw CS pins and can thus control
  136. * up to three devices. Software handled CS pin can also be used for additional devices on the same SPI bus.
  137. *
  138. * ### If selected SPI host device bus is not yet initialized, it is initialized first with 'bus_config' function ###
  139. *
  140. * @note While in general, speeds up to 80MHz on the dedicated SPI pins and 40MHz on GPIO-matrix-routed pins are
  141. * supported, full-duplex transfers routed over the GPIO matrix only support speeds up to 26MHz.
  142. *
  143. * @param host SPI peripheral to allocate device on (HSPI or VSPI)
  144. * @param dev_config SPI interface protocol config for the device
  145. * @param bus_config Pointer to a spi_lobo_bus_config_t struct specifying how the host device bus should be initialized
  146. * @param handle Pointer to variable to hold the device handle
  147. * @return
  148. * - ESP_ERR_INVALID_ARG if parameter is invalid
  149. * - ESP_ERR_NOT_FOUND if host doesn't have any free CS slots
  150. * - ESP_ERR_NO_MEM if out of memory
  151. * - ESP_OK on success
  152. */
  153. esp_err_t spi_lobo_bus_add_device(spi_lobo_host_device_t host, spi_lobo_bus_config_t *bus_config, spi_lobo_device_interface_config_t *dev_config, spi_lobo_device_handle_t *handle);
  154. /**
  155. * @brief Remove a device from the SPI bus. If after removal no other device is attached to the spi bus device, it is freed.
  156. *
  157. * @param handle Device handle to free
  158. * @return
  159. * - ESP_ERR_INVALID_ARG if parameter is invalid
  160. * - ESP_ERR_INVALID_STATE if device already is freed
  161. * - ESP_OK on success
  162. */
  163. esp_err_t spi_lobo_bus_remove_device(spi_lobo_device_handle_t handle);
  164. /**
  165. * @brief Return the actuall SPI bus speed for the spi device in Hz
  166. *
  167. * Some frequencies cannot be set, for example 30000000 will actually set SPI clock to 26666666 Hz
  168. *
  169. * @param handle Device handle obtained using spi_lobo_bus_add_device
  170. *
  171. * @return
  172. * - actuall SPI clock
  173. */
  174. uint32_t spi_lobo_get_speed(spi_lobo_device_handle_t handle);
  175. /**
  176. * @brief Set the new clock speed for the device, return the actuall SPI bus speed set, in Hz
  177. * This function can be used after the device is initialized
  178. *
  179. * Some frequencies cannot be set, for example 30000000 will actually set SPI clock to 26666666 Hz
  180. *
  181. * @param handle Device handle obtained using spi_lobo_bus_add_device
  182. * @param speed New device spi clock to be set in Hz
  183. *
  184. * @return
  185. * - actuall SPI clock
  186. * - 0 if speed cannot be set
  187. */
  188. uint32_t spi_lobo_set_speed(spi_lobo_device_handle_t handle, uint32_t speed);
  189. /**
  190. * @brief Select spi device for transmission
  191. *
  192. * It configures spi bus with selected spi device parameters if previously selected device was different than the current
  193. * If device's spics_io_num=-1 and spics_ext_io_num > 0 'spics_ext_io_num' pin is set to active state (low)
  194. *
  195. * spi bus device's semaphore is taken before selecting the device
  196. *
  197. * @param handle Device handle obtained using spi_lobo_bus_add_device
  198. * @param force configure spi bus even if the previous device was the same
  199. *
  200. * @return
  201. * - ESP_ERR_INVALID_ARG if parameter is invalid
  202. * - ESP_OK on success
  203. */
  204. esp_err_t spi_lobo_device_select(spi_lobo_device_handle_t handle, int force);
  205. /**
  206. * @brief De-select spi device
  207. *
  208. * If device's spics_io_num=-1 and spics_ext_io_num > 0 'spics_ext_io_num' pin is set to inactive state (high)
  209. *
  210. * spi bus device's semaphore is given after selecting the device
  211. *
  212. * @param handle Device handle obtained using spi_lobo_bus_add_device
  213. *
  214. * @return
  215. * - ESP_ERR_INVALID_ARG if parameter is invalid
  216. * - ESP_OK on success
  217. */
  218. esp_err_t spi_lobo_device_deselect(spi_lobo_device_handle_t handle);
  219. /**
  220. * @brief Check if spi bus uses native spi pins
  221. *
  222. * @param handle Device handle obtained using spi_lobo_bus_add_device
  223. *
  224. * @return
  225. * - true if native spi pins are used
  226. * - false if spi pins are routed through gpio matrix
  227. */
  228. bool spi_lobo_uses_native_pins(spi_lobo_device_handle_t handle);
  229. /**
  230. * @brief Get spi bus native spi pins
  231. *
  232. * @param handle Device handle obtained using spi_lobo_bus_add_device
  233. *
  234. * @return
  235. * places spi bus native pins in provided pointers
  236. */
  237. void spi_lobo_get_native_pins(int host, int *sdi, int *sdo, int *sck);
  238. /**
  239. * @brief Transimit and receive data to/from spi device based on transaction data
  240. *
  241. * TRANSMIT 8-bit data to spi device from 'trans->tx_buffer' or 'trans->tx_data' (trans->lenght/8 bytes)
  242. * and RECEIVE data to 'trans->rx_buffer' or 'trans->rx_data' (trans->rx_length/8 bytes)
  243. * Lengths must be 8-bit multiples!
  244. * If trans->rx_buffer is NULL or trans->rx_length is 0, only transmits data
  245. * If trans->tx_buffer is NULL or trans->length is 0, only receives data
  246. * If the device is in duplex mode (LB_SPI_DEVICE_HALFDUPLEX flag NOT set), data are transmitted and received simultaneously.
  247. * If the device is in half duplex mode (LB_SPI_DEVICE_HALFDUPLEX flag IS set), data are received after transmission
  248. * 'address', 'command' and 'dummy bits' are transmitted before data phase IF set in device's configuration
  249. * and IF 'trans->length' and 'trans->rx_length' are NOT both 0
  250. * If device was not previously selected, it will be selected before transmission and deselected after transmission.
  251. *
  252. * @param handle Device handle obtained using spi_lobo_bus_add_device
  253. *
  254. * @param trans Pointer to variable containing the description of the transaction that is executed
  255. *
  256. * @return
  257. * - ESP_ERR_INVALID_ARG if parameter is invalid
  258. * - ESP error code if device cannot be selected
  259. * - ESP_OK on success
  260. *
  261. */
  262. esp_err_t spi_lobo_transfer_data(spi_lobo_device_handle_t handle, spi_lobo_transaction_t *trans);
  263. /*
  264. * SPI transactions uses the semaphore (taken in select function) to protect the transfer
  265. */
  266. esp_err_t spi_lobo_device_TakeSemaphore(spi_lobo_device_handle_t handle);
  267. void spi_lobo_device_GiveSemaphore(spi_lobo_device_handle_t handle);
  268. /**
  269. * @brief Setup a DMA link chain
  270. *
  271. * This routine will set up a chain of linked DMA descriptors in the array pointed to by
  272. * ``dmadesc``. Enough DMA descriptors will be used to fit the buffer of ``len`` bytes in, and the
  273. * descriptors will point to the corresponding positions in ``buffer`` and linked together. The
  274. * end result is that feeding ``dmadesc[0]`` into DMA hardware results in the entirety ``len`` bytes
  275. * of ``data`` being read or written.
  276. *
  277. * @param dmadesc Pointer to array of DMA descriptors big enough to be able to convey ``len`` bytes
  278. * @param len Length of buffer
  279. * @param data Data buffer to use for DMA transfer
  280. * @param isrx True if data is to be written into ``data``, false if it's to be read from ``data``.
  281. */
  282. void spi_lobo_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx);
  283. /**
  284. * @brief Check if a DMA reset is requested but has not completed yet
  285. *
  286. * @return True when a DMA reset is requested but hasn't completed yet. False otherwise.
  287. */
  288. bool spi_lobo_dmaworkaround_reset_in_progress();
  289. /**
  290. * @brief Mark a DMA channel as idle.
  291. *
  292. * A call to this function tells the workaround logic that this channel will
  293. * not be affected by a global SPI DMA reset.
  294. */
  295. void spi_lobo_dmaworkaround_idle(int dmachan);
  296. /**
  297. * @brief Mark a DMA channel as active.
  298. *
  299. * A call to this function tells the workaround logic that this channel will
  300. * be affected by a global SPI DMA reset, and a reset like that should not be attempted.
  301. */
  302. void spi_lobo_dmaworkaround_transfer_active(int dmachan);
  303. #ifdef __cplusplus
  304. }
  305. #endif
  306. #endif