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