spi_common_internal.h 32 KB

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