spi_common_internal.h 31 KB

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