spi_common_internal.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  1. /*
  2. * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. // Internal header, don't use it in the user code
  7. #pragma once
  8. #include <esp_intr_alloc.h>
  9. #include "driver/spi_common.h"
  10. #include "freertos/FreeRTOS.h"
  11. #include "hal/spi_types.h"
  12. #include "hal/dma_types.h"
  13. #include "soc/gdma_channel.h"
  14. #include "esp_pm.h"
  15. #if SOC_GDMA_SUPPORTED
  16. #include "esp_private/gdma.h"
  17. #endif
  18. #ifdef __cplusplus
  19. extern "C"
  20. {
  21. #endif
  22. #ifdef CONFIG_SPI_MASTER_ISR_IN_IRAM
  23. #define SPI_MASTER_ISR_ATTR IRAM_ATTR
  24. #else
  25. #define SPI_MASTER_ISR_ATTR
  26. #endif
  27. #ifdef CONFIG_SPI_MASTER_IN_IRAM
  28. #define SPI_MASTER_ATTR IRAM_ATTR
  29. #else
  30. #define SPI_MASTER_ATTR
  31. #endif
  32. #define BUS_LOCK_DEBUG 0
  33. #if BUS_LOCK_DEBUG
  34. #define BUS_LOCK_DEBUG_EXECUTE_CHECK(x) assert(x)
  35. #else
  36. #define BUS_LOCK_DEBUG_EXECUTE_CHECK(x)
  37. #endif
  38. #if SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB
  39. #define DMA_DESC_MEM_ALIGN_SIZE 4
  40. #define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel
  41. typedef dma_descriptor_align4_t spi_dma_desc_t;
  42. #else
  43. #define DMA_DESC_MEM_ALIGN_SIZE 8
  44. #define SPI_GDMA_NEW_CHANNEL gdma_new_axi_channel
  45. typedef dma_descriptor_align8_t spi_dma_desc_t;
  46. #endif
  47. struct spi_bus_lock_t;
  48. struct spi_bus_lock_dev_t;
  49. /// Handle to the lock of an SPI bus
  50. typedef struct spi_bus_lock_t* spi_bus_lock_handle_t;
  51. /// Handle to lock of one of the device on an SPI bus
  52. typedef struct spi_bus_lock_dev_t* spi_bus_lock_dev_handle_t;
  53. /// Background operation control function
  54. typedef void (*bg_ctrl_func_t)(void*);
  55. /// Attributes of an SPI bus
  56. typedef struct {
  57. spi_bus_config_t bus_cfg; ///< Config used to initialize the bus
  58. uint32_t flags; ///< Flags (attributes) of the bus
  59. int max_transfer_sz; ///< Maximum length of bytes available to send
  60. bool dma_enabled; ///< To enable DMA or not
  61. uint16_t internal_mem_align_size; ///< Buffer align byte requirement for internal memory
  62. int tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same
  63. int rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same
  64. int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx.
  65. spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX
  66. spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX
  67. spi_bus_lock_handle_t lock;
  68. #ifdef CONFIG_PM_ENABLE
  69. esp_pm_lock_handle_t pm_lock; ///< Power management lock
  70. #endif
  71. } spi_bus_attr_t;
  72. /// Destructor called when a bus is deinitialized.
  73. typedef esp_err_t (*spi_destroy_func_t)(void*);
  74. /**
  75. * @brief Try to claim a SPI peripheral
  76. *
  77. * Call this if your driver wants to manage a SPI peripheral.
  78. *
  79. * @param host Peripheral to claim
  80. * @param source The caller indentification string.
  81. *
  82. * @return True if peripheral is claimed successfully; false if peripheral already is claimed.
  83. */
  84. bool spicommon_periph_claim(spi_host_device_t host, const char* source);
  85. /**
  86. * @brief Check whether the spi periph is in use.
  87. *
  88. * @param host Peripheral to check.
  89. *
  90. * @return True if in use, otherwise false.
  91. */
  92. bool spicommon_periph_in_use(spi_host_device_t host);
  93. /**
  94. * @brief Return the SPI peripheral so another driver can claim it.
  95. *
  96. * @param host Peripheral to return
  97. *
  98. * @return True if peripheral is returned successfully; false if peripheral was free to claim already.
  99. */
  100. bool spicommon_periph_free(spi_host_device_t host);
  101. /**
  102. * @brief Alloc DMA for SPI
  103. *
  104. * @param host_id SPI host ID
  105. * @param dma_chan DMA channel to be used
  106. * @param[out] out_actual_tx_dma_chan Actual TX DMA channel (if you choose to assign a specific DMA channel, this will be the channel you assigned before)
  107. * @param[out] out_actual_rx_dma_chan Actual RX DMA channel (if you choose to assign a specific DMA channel, this will be the channel you assigned before)
  108. *
  109. * @return
  110. * - ESP_OK: On success
  111. * - ESP_ERR_NO_MEM: No enough memory
  112. * - ESP_ERR_NOT_FOUND: There is no available DMA channel
  113. */
  114. esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan);
  115. /**
  116. * @brief Free DMA for SPI
  117. *
  118. * @param host_id SPI host ID
  119. *
  120. * @return
  121. * - ESP_OK: On success
  122. */
  123. esp_err_t spicommon_dma_chan_free(spi_host_device_t host_id);
  124. #if SOC_GDMA_SUPPORTED
  125. /**
  126. * @brief Get SPI GDMA Handle for GMDA Supported Chip
  127. *
  128. * @param host_id SPI host ID
  129. * @param gdma_handle GDMA Handle to Return
  130. * @param gdma_direction GDMA Channel Direction in Enum
  131. * - GDMA_CHANNEL_DIRECTION_TX
  132. * - GDMA_CHANNEL_DIRECTION_RX
  133. *
  134. * @return
  135. * - ESP_OK: On success
  136. */
  137. esp_err_t spicommon_gdma_get_handle(spi_host_device_t host_id, gdma_channel_handle_t *gdma_handle, gdma_channel_direction_t gdma_direction);
  138. #endif
  139. /**
  140. * @brief Connect a SPI peripheral to GPIO pins
  141. *
  142. * This routine is used to connect a SPI peripheral to the IO-pads and DMA channel given in
  143. * the arguments. Depending on the IO-pads requested, the routing is done either using the
  144. * IO_mux or using the GPIO matrix.
  145. *
  146. * @param host SPI peripheral to be routed
  147. * @param bus_config Pointer to a spi_bus_config struct detailing the GPIO pins
  148. * @param flags Combination of SPICOMMON_BUSFLAG_* flags, set to ensure the pins set are capable with some functions:
  149. * - ``SPICOMMON_BUSFLAG_MASTER``: Initialize I/O in master mode
  150. * - ``SPICOMMON_BUSFLAG_SLAVE``: Initialize I/O in slave mode
  151. * - ``SPICOMMON_BUSFLAG_IOMUX_PINS``: Pins set should match the iomux pins of the controller.
  152. * - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``:
  153. * Make sure SCLK/MISO/MOSI is/are set to a valid GPIO. Also check output capability according to the mode.
  154. * - ``SPICOMMON_BUSFLAG_DUAL``: Make sure both MISO and MOSI are output capable so that DIO mode is capable.
  155. * - ``SPICOMMON_BUSFLAG_WPHD`` Make sure WP and HD are set to valid output GPIOs.
  156. * - ``SPICOMMON_BUSFLAG_QUAD``: Combination of ``SPICOMMON_BUSFLAG_DUAL`` and ``SPICOMMON_BUSFLAG_WPHD``.
  157. * - ``SPICOMMON_BUSFLAG_IO4_IO7``: Make sure spi data4 ~ spi data7 are set to valid output GPIOs.
  158. * - ``SPICOMMON_BUSFLAG_OCTAL``: Combination of ``SPICOMMON_BUSFLAG_QUAL`` and ``SPICOMMON_BUSFLAG_IO4_IO7``.
  159. * @param[out] flags_o A SPICOMMON_BUSFLAG_* flag combination of bus abilities will be written to this address.
  160. * Leave to NULL if not needed.
  161. * - ``SPICOMMON_BUSFLAG_IOMUX_PINS``: The bus is connected to iomux pins.
  162. * - ``SPICOMMON_BUSFLAG_SCLK``, ``SPICOMMON_BUSFLAG_MISO``, ``SPICOMMON_BUSFLAG_MOSI``: The bus has
  163. * CLK/MISO/MOSI connected.
  164. * - ``SPICOMMON_BUSFLAG_DUAL``: The bus is capable with DIO mode.
  165. * - ``SPICOMMON_BUSFLAG_WPHD`` The bus has WP and HD connected.
  166. * - ``SPICOMMON_BUSFLAG_QUAD``: Combination of ``SPICOMMON_BUSFLAG_DUAL`` and ``SPICOMMON_BUSFLAG_WPHD``.
  167. * - ``SPICOMMON_BUSFLAG_IO4_IO7``: The bus has spi data4 ~ spi data7 connected.
  168. * - ``SPICOMMON_BUSFLAG_OCTAL``: Combination of ``SPICOMMON_BUSFLAG_QUAL`` and ``SPICOMMON_BUSFLAG_IO4_IO7``.
  169. * @return
  170. * - ESP_ERR_INVALID_ARG if parameter is invalid
  171. * - ESP_OK on success
  172. */
  173. esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, uint32_t flags, uint32_t *flags_o);
  174. /**
  175. * @brief Free the IO used by a SPI peripheral
  176. *
  177. * @param bus_cfg Bus config struct which defines which pins to be used.
  178. *
  179. * @return
  180. * - ESP_ERR_INVALID_ARG if parameter is invalid
  181. * - ESP_OK on success
  182. */
  183. esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg);
  184. /**
  185. * @brief Initialize a Chip Select pin for a specific SPI peripheral
  186. *
  187. * @param host SPI peripheral
  188. * @param cs_io_num GPIO pin to route
  189. * @param cs_num CS id to route
  190. * @param force_gpio_matrix If true, CS will always be routed through the GPIO matrix. If false,
  191. * if the GPIO number allows it, the routing will happen through the IO_mux.
  192. */
  193. void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix);
  194. /**
  195. * @brief Free a chip select line
  196. *
  197. * @param cs_gpio_num CS gpio num to free
  198. */
  199. void spicommon_cs_free_io(int cs_gpio_num);
  200. /**
  201. * @brief Check whether all pins used by a host are through IOMUX.
  202. *
  203. * @param host SPI peripheral
  204. *
  205. * @return false if any pins are through the GPIO matrix, otherwise true.
  206. */
  207. bool spicommon_bus_using_iomux(spi_host_device_t host);
  208. /**
  209. * @brief Get the IRQ source for a specific SPI host
  210. *
  211. * @param host The SPI host
  212. *
  213. * @return The hosts IRQ source
  214. */
  215. int spicommon_irqsource_for_host(spi_host_device_t host);
  216. /**
  217. * @brief Get the IRQ source for a specific SPI DMA
  218. *
  219. * @param host The SPI host
  220. *
  221. * @return The hosts IRQ source
  222. */
  223. int spicommon_irqdma_source_for_host(spi_host_device_t host);
  224. /**
  225. * Callback, to be called when a DMA engine reset is completed
  226. */
  227. typedef void(*dmaworkaround_cb_t)(void *arg);
  228. #if CONFIG_IDF_TARGET_ESP32
  229. //This workaround is only for esp32
  230. /**
  231. * @brief Request a reset for a certain DMA channel
  232. *
  233. * @note In some (well-defined) cases in the ESP32 (at least rev v.0 and v.1), a SPI DMA channel will get confused. This can be remedied
  234. * by resetting the SPI DMA hardware in case this happens. Unfortunately, the reset knob used for thsi will reset _both_ DMA channels, and
  235. * as such can only done safely when both DMA channels are idle. These functions coordinate this.
  236. *
  237. * Essentially, when a reset is needed, a driver can request this using spicommon_dmaworkaround_req_reset. This is supposed to be called
  238. * with an user-supplied function as an argument. If both DMA channels are idle, this call will reset the DMA subsystem and return true.
  239. * If the other DMA channel is still busy, it will return false; as soon as the other DMA channel is done, however, it will reset the
  240. * DMA subsystem and call the callback. The callback is then supposed to be used to continue the SPI drivers activity.
  241. *
  242. * @param dmachan DMA channel associated with the SPI host that needs a reset
  243. * @param cb Callback to call in case DMA channel cannot be reset immediately
  244. * @param arg Argument to the callback
  245. *
  246. * @return True when a DMA reset could be executed immediately. False when it could not; in this
  247. * case the callback will be called with the specified argument when the logic can execute
  248. * a reset, after that reset.
  249. */
  250. bool spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg);
  251. /**
  252. * @brief Check if a DMA reset is requested but has not completed yet
  253. *
  254. * @return True when a DMA reset is requested but hasn't completed yet. False otherwise.
  255. */
  256. bool spicommon_dmaworkaround_reset_in_progress(void);
  257. /**
  258. * @brief Mark a DMA channel as idle.
  259. *
  260. * A call to this function tells the workaround logic that this channel will
  261. * not be affected by a global SPI DMA reset.
  262. */
  263. void spicommon_dmaworkaround_idle(int dmachan);
  264. /**
  265. * @brief Mark a DMA channel as active.
  266. *
  267. * A call to this function tells the workaround logic that this channel will
  268. * be affected by a global SPI DMA reset, and a reset like that should not be attempted.
  269. */
  270. void spicommon_dmaworkaround_transfer_active(int dmachan);
  271. #endif //#if CONFIG_IDF_TARGET_ESP32
  272. /*******************************************************************************
  273. * Bus attributes
  274. ******************************************************************************/
  275. /**
  276. * @brief Set bus lock for the main bus, called by startup code.
  277. *
  278. * @param lock The lock to be used by the main SPI bus.
  279. */
  280. void spi_bus_main_set_lock(spi_bus_lock_handle_t lock);
  281. /**
  282. * @brief Get the attributes of a specified SPI bus.
  283. *
  284. * @param host_id The specified host to get attribute
  285. * @return (Const) Pointer to the attributes
  286. */
  287. const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id);
  288. /**
  289. * @brief Register a function to a initialized bus to make it called when deinitializing the bus.
  290. *
  291. * @param host_id The SPI bus to register the destructor.
  292. * @param f Destructor to register
  293. * @param arg The argument to call the destructor
  294. * @return Always ESP_OK.
  295. */
  296. esp_err_t spi_bus_register_destroy_func(spi_host_device_t host_id,
  297. spi_destroy_func_t f, void *arg);
  298. /*******************************************************************************
  299. * SPI Bus Lock for arbitration among SPI master (intr, polling) trans, SPI flash operations and
  300. * flash/psram cache access.
  301. *
  302. * NON-PUBLIC API. Don't use it directly in applications.
  303. *
  304. * There is the main lock corresponding to an SPI bus, of which several devices (holding child
  305. * locks) attaching to it. Each of the device is STRONGLY RECOMMENDED to be used in only one task
  306. * to avoid concurrency issues.
  307. *
  308. * Terms:
  309. * - BG operations (BackGround operations) means some transaction that will not immediately /
  310. * explicitly be sent in the task. It can be some cache access, or interrupt transactions.
  311. *
  312. * - Operation: usage of the bus, for example, do SPI transactions.
  313. *
  314. * - Acquiring processor: the task or the ISR that is allowed to use the bus. No operations will be
  315. * performed if there is no acquiring processor. A processor becomes the acquiring processor if
  316. * it ask for that when no acquiring processor exist, otherwise it has to wait for the acquiring
  317. * processor to handle over the role to it. The acquiring processor will and will only assign one
  318. * acquiring processor in the waiting list (if not empty) when it finishes its operation.
  319. *
  320. * - Acquiring device: the only device allowed to use the bus. Operations can be performed in
  321. * either the BG or the task. When there's no acquiring device, only the ISR is allowed to be the
  322. * acquiring processor and perform operations on the bus.
  323. *
  324. * When a device wants to perform operations, it either:
  325. * 1. Acquire the bus, and operate in the task (e.g. polling transactions of SPI master, and SPI flash
  326. * operations)
  327. *
  328. * 2. Request a BG operation. And the ISR will be enabled at proper time.
  329. *
  330. * For example if a task wants to send an interrupt transaction, it prepares the data in the task,
  331. * call `spi_bus_lock_bg_request`, and handle sending in the ISR.
  332. *
  333. * 3. When a device has already acquired the bus, BG operations are also allowed. After the
  334. * `spi_bus_lock_bg_request` is called, call `spi_bus_lock_wait_bg_done` before operations in task
  335. * again to wait until BG operations are done.
  336. *
  337. * Any device may try to invoke the ISR (by `spi_bus_lock_bg_request`). The ISR will be invoked and
  338. * become the acquiring processor immediately when the bus is not acquired by other processors. Any
  339. * device may also try to acquire the bus (by `spi_bus_lock_acquire_start`). The device will become
  340. * the acquiring processor immediately when the bus is not acquired and there is no request active.
  341. *
  342. * The acquiring processor must be aware of its acquiring role, and properly transfer the acquiring
  343. * processor to other tasks or ISR when they have nothing else to do. Before picking a new
  344. * acquiring processor, a new acquiring device must be picked first, if there are other devices,
  345. * asking to be acquiring device. After that, the new acquiring processor is picked by the sequence
  346. * below:
  347. *
  348. * 1. If there is an acquiring device:
  349. * 1.1 The ISR, if acquiring device has active BG requests
  350. * 1.2 The task of the device, if no active BG request for the device
  351. * 2. The ISR, if there's no acquiring device, but any BG request is active
  352. * 3. No one becomes the acquiring processor
  353. *
  354. * The API also helps on the arbitration of SPI cs lines. The bus is initialized with a cs_num
  355. * argument. When attaching devices onto the bus with `spi_bus_lock_register_dev`, it will allocate
  356. * devices with different device ID according to the flags given. If the ID is smaller than the
  357. * cs_num given when bus is initialized, error will be returned.
  358. *
  359. * Usage:
  360. * * Initialization:
  361. * 1. Call `spi_bus_init_lock` to register a lock for a bus.
  362. * 2. Call `spi_bus_lock_set_bg_control` to prepare BG enable/disable functions for
  363. * the lock.
  364. * 3. Call `spi_bus_lock_register_dev` for each devices that may make use of the
  365. * bus, properly store the returned handle, representing those devices.
  366. *
  367. * * Acquiring:
  368. * 1. Call `spi_bus_lock_acquire_start` when a device wants to use the bus
  369. * 2. Call `spi_bus_lock_touch` to mark the bus as touched by this device. Also check if the bus
  370. * has been touched by other devices.
  371. * 3. (optional) Do something on the bus...
  372. * 4. (optional) Call `spi_bus_lock_bg_request` to inform and invoke the BG. See ISR below about
  373. * ISR operations.
  374. * 5. (optional) If `spi_bus_lock_bg_request` is done, you have to call `spi_bus_lock_wait_bg_done`
  375. * before touching the bus again, or do the following steps.
  376. * 6. Call `spi_bus_lock_acquire_end` to release the bus to other devices.
  377. *
  378. * * ISR:
  379. * 1. Call `spi_bus_lock_bg_entry` when entering the ISR, run or skip the closure for the previous
  380. * operation according to the return value.
  381. * 2. Call `spi_bus_lock_get_acquiring_dev` to get the acquiring device. If there is no acquiring
  382. * device, call `spi_bus_lock_bg_check_dev_acq` to check and update a new acquiring device.
  383. * 3. Call `spi_bus_lock_bg_check_dev_req` to check for request of the desired device. If the
  384. * desired device is not requested, go to step 5.
  385. * 4. Check, start operation for the desired device and go to step 6; otherwise if no operations
  386. * can be performed, call `spi_bus_lock_bg_clear_req` to clear the request for this device. If
  387. * `spi_bus_lock_bg_clear_req` is called and there is no BG requests active, goto step 6.
  388. * 5. (optional) If the device is the acquiring device, go to step 6, otherwise
  389. * find another desired device, and go back to step 3.
  390. * 6. Call `spi_bus_lock_bg_exit` to try quitting the ISR. If failed, go back to step 2 to look for
  391. * a new request again. Otherwise, quit the ISR.
  392. *
  393. * * Deinitialization (optional):
  394. * 1. Call `spi_bus_lock_unregister_dev` for each device when they are no longer needed.
  395. * 2. Call `spi_bus_deinit_lock` to release the resources occupied by the lock.
  396. *
  397. * Some technical details:
  398. *
  399. * The child-lock of each device will have its own Binary Semaphore, which allows the task serving
  400. * this device (task A) being blocked when it fail to become the acquiring processor while it's
  401. * calling `spi_bus_lock_acquire_start` or `spi_bus_lock_wait_bg_done`. If it is blocked, there
  402. * must be an acquiring processor (either the ISR or another task (task B)), is doing transaction
  403. * on the bus. After that, task A will get unblocked and become the acquiring processor when the
  404. * ISR call `spi_bus_lock_bg_resume_acquired_dev`, or task B call `spi_bus_lock_acquire_end`.
  405. *
  406. * When the device wants to send ISR transaction, it should call `spi_bus_lock_bg_request` after
  407. * the data is prepared. This function sets a request bit in the critical resource. The ISR will be
  408. * invoked and become the new acquiring processor, when:
  409. *
  410. * 1. A task calls `spi_bus_lock_bg_request` while there is no acquiring processor;
  411. * 2. A tasks calls `spi_bus_lock_bg_request` while the task is the acquiring processor. Then the
  412. * acquiring processor is handled over to the ISR;
  413. * 3. A tasks who is the acquiring processor release the bus by calling `spi_bus_lock_acquire_end`,
  414. * and the ISR happens to be the next acquiring processor.
  415. *
  416. * The ISR will check (by `spi_bus_lock_bg_check_dev_req`) and clear a request bit (by
  417. * `spi_bus_lock_bg_clear_req`) after it confirm that all the requests of the corresponding device
  418. * are served. The request bit supports being written to recursively, which means, the task don't
  419. * need to wait for `spi_bus_lock_bg_clear_req` before call another `spi_bus_lock_bg_request`. The
  420. * API will handle the concurrency conflicts properly.
  421. *
  422. * The `spi_bus_lock_bg_exit` (together with `spi_bus_lock_bg_entry` called before)` is responsible
  423. * to ensure ONE and ONLY ONE of the following will happen when the ISR try to give up its
  424. * acquiring processor rule:
  425. *
  426. * 1. ISR quit, no any task unblocked while the interrupt disabled, and none of the BG bits is
  427. * active.
  428. * 2. ISR quit, there is an acquiring device, and the acquiring processor is passed to the task
  429. * serving the acquiring device by unblocking the task.
  430. * 3. The ISR failed to quit and have to try again.
  431. ******************************************************************************/
  432. #define DEV_NUM_MAX 6 ///< Number of devices supported by this lock
  433. /// Lock configuration struct
  434. typedef struct {
  435. int host_id; ///< SPI host id
  436. int cs_num; ///< Physical cs numbers of the host
  437. } spi_bus_lock_config_t;
  438. /// Child-lock configuration struct
  439. typedef struct {
  440. uint32_t flags; ///< flags for the lock, OR-ed of `SPI_BUS_LOCK_DEV_*` flags.
  441. #define SPI_BUS_LOCK_DEV_FLAG_CS_REQUIRED BIT(0) ///< The device needs a physical CS pin.
  442. } spi_bus_lock_dev_config_t;
  443. /************* Common *********************/
  444. /**
  445. * Initialize a lock for an SPI bus.
  446. *
  447. * @param out_lock Output of the handle to the lock
  448. * @return
  449. * - ESP_ERR_NO_MEM: if memory exhausted
  450. * - ESP_OK: if success
  451. */
  452. esp_err_t spi_bus_init_lock(spi_bus_lock_handle_t *out_lock, const spi_bus_lock_config_t *config);
  453. /**
  454. * Free the resources used by an SPI bus lock.
  455. *
  456. * @note All attached devices should have been unregistered before calling this
  457. * funciton.
  458. *
  459. * @param lock Handle to the lock to free.
  460. */
  461. void spi_bus_deinit_lock(spi_bus_lock_handle_t lock);
  462. /**
  463. * @brief Get the corresponding lock according to bus id.
  464. *
  465. * @param host_id The bus id to get the lock
  466. * @return The lock handle
  467. */
  468. spi_bus_lock_handle_t spi_bus_lock_get_by_id(spi_host_device_t host_id);
  469. /**
  470. * @brief Configure how the SPI bus lock enable the background operation.
  471. *
  472. * @note The lock will not try to stop the background operations, but wait for
  473. * The background operations finished indicated by `spi_bus_lock_bg_resume_acquired_dev`.
  474. *
  475. * @param lock Handle to the lock to set
  476. * @param bg_enable The enabling function
  477. * @param bg_disable The disabling function, set to NULL if not required
  478. * @param arg Argument to pass to the enabling/disabling function.
  479. */
  480. void spi_bus_lock_set_bg_control(spi_bus_lock_handle_t lock, bg_ctrl_func_t bg_enable,
  481. bg_ctrl_func_t bg_disable, void *arg);
  482. /**
  483. * Attach a device onto an SPI bus lock. The returning handle is used to perform
  484. * following requests for the attached device.
  485. *
  486. * @param lock SPI bus lock to attach
  487. * @param out_dev_handle Output handle corresponding to the device
  488. * @param flags requirement of the device, bitwise OR of SPI_BUS_LOCK_FLAG_* flags
  489. *
  490. * @return
  491. * - ESP_ERR_NOT_SUPPORTED: if there's no hardware resources for new devices.
  492. * - ESP_ERR_NO_MEM: if memory exhausted
  493. * - ESP_OK: if success
  494. */
  495. esp_err_t spi_bus_lock_register_dev(spi_bus_lock_handle_t lock,
  496. spi_bus_lock_dev_config_t *config,
  497. spi_bus_lock_dev_handle_t *out_dev_handle);
  498. /**
  499. * Detach a device from its bus and free the resources used
  500. *
  501. * @param dev_handle Handle to the device.
  502. */
  503. void spi_bus_lock_unregister_dev(spi_bus_lock_dev_handle_t dev_handle);
  504. /**
  505. * @brief Get the parent bus lock of the device
  506. *
  507. * @param dev_handle Handle to the device to get bus lock
  508. * @return The bus lock handle
  509. */
  510. spi_bus_lock_handle_t spi_bus_lock_get_parent(spi_bus_lock_dev_handle_t dev_handle);
  511. /**
  512. * @brief Get the device ID of a lock.
  513. *
  514. * The callers should allocate CS pins according to this ID.
  515. *
  516. * @param dev_handle Handle to the device to get ID
  517. * @return ID of the device
  518. */
  519. int spi_bus_lock_get_dev_id(spi_bus_lock_dev_handle_t dev_handle);
  520. /**
  521. * @brief The device request to touch bus registers. Can only be called by the acquiring processor.
  522. *
  523. * Also check if the registers has been touched by other devices.
  524. *
  525. * @param dev_handle Handle to the device to operate the registers
  526. * @return true if there has been other devices touching SPI registers.
  527. * The caller may need to do a full-configuration. Otherwise return
  528. * false.
  529. */
  530. bool spi_bus_lock_touch(spi_bus_lock_dev_handle_t dev_handle);
  531. /************* Acquiring service *********************/
  532. /**
  533. * Acquiring the SPI bus for exclusive use. Will also wait for the BG to finish all requests of
  534. * this device before it returns.
  535. *
  536. * After successfully return, the caller becomes the acquiring processor.
  537. *
  538. * @note For the main flash bus, `bg_disable` will be called to disable the cache.
  539. *
  540. * @param dev_handle Handle to the device request for acquiring.
  541. * @param wait Time to wait until timeout or succeed, must be `portMAX_DELAY` for now.
  542. * @return
  543. * - ESP_OK: on success
  544. * - ESP_ERR_INVALID_ARG: timeout is not portMAX_DELAY
  545. */
  546. esp_err_t spi_bus_lock_acquire_start(spi_bus_lock_dev_handle_t dev_handle, TickType_t wait);
  547. /**
  548. * Release the bus acquired. Will pass the acquiring processor to other blocked
  549. * processors (tasks or ISR), and cause them to be unblocked or invoked.
  550. *
  551. * The acquiring device may also become NULL if no device is asking for acquiring.
  552. * In this case, the BG may be invoked if there is any BG requests.
  553. *
  554. * If the new acquiring device has BG requests, the BG will be invoked before the
  555. * task is resumed later after the BG finishes all requests of the new acquiring
  556. * device. Otherwise the task of the new acquiring device will be resumed immediately.
  557. *
  558. * @param dev_handle Handle to the device releasing the bus.
  559. * @return
  560. * - ESP_OK: on success
  561. * - ESP_ERR_INVALID_STATE: the device hasn't acquired the lock yet
  562. */
  563. esp_err_t spi_bus_lock_acquire_end(spi_bus_lock_dev_handle_t dev_handle);
  564. /**
  565. * Get the device acquiring the bus.
  566. *
  567. * @note Return value is not stable as the acquiring processor may change
  568. * when this function is called.
  569. *
  570. * @param lock Lock of SPI bus to get the acquiring device.
  571. * @return The argument corresponding to the acquiring device, see
  572. * `spi_bus_lock_register_dev`.
  573. */
  574. spi_bus_lock_dev_handle_t spi_bus_lock_get_acquiring_dev(spi_bus_lock_handle_t lock);
  575. /************* BG (Background, for ISR or cache) service *********************/
  576. /**
  577. * Call by a device to request a BG operation.
  578. *
  579. * Depending on the bus lock state, the BG operations may be resumed by this
  580. * call, or pending until BG operations allowed.
  581. *
  582. * Cleared by `spi_bus_lock_bg_clear_req` in the BG.
  583. *
  584. * @param dev_handle The device requesting BG operations.
  585. * @return always ESP_OK
  586. */
  587. esp_err_t spi_bus_lock_bg_request(spi_bus_lock_dev_handle_t dev_handle);
  588. /**
  589. * Wait until the ISR has finished all the BG operations for the acquiring device.
  590. * If any `spi_bus_lock_bg_request` for this device has been called after
  591. * `spi_bus_lock_acquire_start`, this function must be called before any operation
  592. * in the task.
  593. *
  594. * @note Can only be called when bus acquired by this device.
  595. *
  596. * @param dev_handle Handle to the device acquiring the bus.
  597. * @param wait Time to wait until timeout or succeed, must be `portMAX_DELAY` for now.
  598. * @return
  599. * - ESP_OK: on success
  600. * - ESP_ERR_INVALID_STATE: The device is not the acquiring bus.
  601. * - ESP_ERR_INVALID_ARG: Timeout is not portMAX_DELAY.
  602. */
  603. esp_err_t spi_bus_lock_wait_bg_done(spi_bus_lock_dev_handle_t dev_handle, TickType_t wait);
  604. /**
  605. * Handle interrupt and closure of last operation. Should be called at the beginning of the ISR,
  606. * when the ISR is acting as the acquiring processor.
  607. *
  608. * @param lock The SPI bus lock
  609. *
  610. * @return false if the ISR has already touched the HW, should run closure of the
  611. * last operation first; otherwise true if the ISR just start operating
  612. * on the HW, closure should be skipped.
  613. */
  614. bool spi_bus_lock_bg_entry(spi_bus_lock_handle_t lock);
  615. /**
  616. * Handle the scheduling of other acquiring devices, and control of HW operation
  617. * status.
  618. *
  619. * If no BG request is found, call with `wip=false`. This function will return false,
  620. * indicating there is incoming BG requests for the current acquiring device (or
  621. * for all devices if there is no acquiring device) and the ISR needs retry.
  622. * Otherwise may schedule a new acquiring processor (unblock the task) if there
  623. * is, and return true.
  624. *
  625. * Otherwise if a BG request is started in this ISR, call with `wip=true` and the
  626. * function will enable the interrupt to make the ISR be called again when the
  627. * request is done.
  628. *
  629. * This function is safe and should still be called when the ISR just lost its acquiring processor
  630. * role, but hasn't quit.
  631. *
  632. * @note This function will not change acquiring device. The ISR call
  633. * `spi_bus_lock_bg_update_acquiring` to check for new acquiring device,
  634. * when acquiring devices need to be served before other devices.
  635. *
  636. * @param lock The SPI bus lock.
  637. * @param wip Whether an operation is being executed when quitting the ISR.
  638. * @param do_yield[out] Not touched when no yielding required, otherwise set
  639. * to pdTRUE.
  640. * @return false if retry is required, indicating that there is pending BG request.
  641. * otherwise true and quit ISR is allowed.
  642. */
  643. bool spi_bus_lock_bg_exit(spi_bus_lock_handle_t lock, bool wip, BaseType_t* do_yield);
  644. /**
  645. * Check whether there is device asking for the acquiring device, and the desired
  646. * device for the next operation is also recommended.
  647. *
  648. * @note Must be called when the ISR is acting as the acquiring processor, and
  649. * there is no acquiring device.
  650. *
  651. * @param lock The SPI bus lock.
  652. * @param out_dev_lock The recommended device for hte next operation. It's the new
  653. * acquiring device when found, otherwise a device that has active BG request.
  654. *
  655. * @return true if the ISR need to quit (new acquiring device has no active BG
  656. * request, or no active BG requests for all devices when there is no
  657. * acquiring device), otherwise false.
  658. */
  659. bool spi_bus_lock_bg_check_dev_acq(spi_bus_lock_handle_t lock, spi_bus_lock_dev_handle_t *out_dev_lock);
  660. /**
  661. * Check if the device has BG requests. Must be called when the ISR is acting as
  662. * the acquiring processor.
  663. *
  664. * @note This is not stable, may become true again when a task request for BG
  665. * operation (by `spi_bus_lock_bg_request`).
  666. *
  667. * @param dev_lock The device to check.
  668. * @return true if the device has BG requests, otherwise false.
  669. */
  670. bool spi_bus_lock_bg_check_dev_req(spi_bus_lock_dev_handle_t dev_lock);
  671. /**
  672. * Clear the pending BG operation request of a device after served. Must be
  673. * called when the ISR is acting as the acquiring processor.
  674. *
  675. * @note When the return value is true, the ISR will lost the acquiring processor role. Then
  676. * `spi_bus_lock_bg_exit` must be called and checked before calling all other functions that
  677. * require to be called when the ISR is the acquiring processor again.
  678. *
  679. * @param dev_handle The device whose request is served.
  680. * @return True if no pending requests for the acquiring device, or for all devices
  681. * if there is no acquiring device. Otherwise false. When the return value is
  682. * true, the ISR is no longer the acquiring processor.
  683. */
  684. bool spi_bus_lock_bg_clear_req(spi_bus_lock_dev_handle_t dev_lock);
  685. /**
  686. * Check if there is any active BG requests.
  687. *
  688. * @param lock The SPI bus lock.
  689. * @return true if any device has active BG requst, otherwise false.
  690. */
  691. bool spi_bus_lock_bg_req_exist(spi_bus_lock_handle_t lock);
  692. /*******************************************************************************
  693. * Variable and APIs for the OS to initialize the locks for the main chip
  694. ******************************************************************************/
  695. /// The lock for the main bus
  696. extern const spi_bus_lock_handle_t g_main_spi_bus_lock;
  697. /**
  698. * @brief Initialize the main SPI bus, called during chip startup.
  699. *
  700. * @return always ESP_OK
  701. */
  702. esp_err_t spi_bus_lock_init_main_bus(void);
  703. /// The lock for the main flash device
  704. extern const spi_bus_lock_dev_handle_t g_spi_lock_main_flash_dev;
  705. /**
  706. * @brief Initialize the main flash device, called during chip startup.
  707. *
  708. * @return
  709. * - ESP_OK: if success
  710. * - ESP_ERR_NO_MEM: memory exhausted
  711. */
  712. esp_err_t spi_bus_lock_init_main_dev(void);
  713. #ifdef __cplusplus
  714. }
  715. #endif