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