mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
fix(ulp/lp_spi): fix driver bugs and add bus deinit API
The LP SPI driver read and wrote the W0..W15 data buffer registers a whole 32-bit word at a time, which overran the caller's buffer for transfers whose length was not a multiple of four bytes and corrupted the received data. Read and write the data buffer byte-granularly so sub-word transfers no longer alias adjacent bytes. The master transfer also programmed the shared bit-length register from tx_length alone, truncating receive-longer-than-transmit transactions, and always enabled MOSI even on read-only transfers, clocking out stale buffer contents. Size each hardware transaction by max(tx_length, rx_length) and gate MOSI/MISO on the corresponding buffer. The slave path reused the master's single-shot flow, so it re-triggered reg_update after preload (clocking out the previous transaction's data) and offered no way for the caller to publish readiness before the master started the clock. Split the slave transfer into an arm step that preloads the buffer and starts the user phase, and a wait step that blocks on TRANS_DONE and drains only the bytes the master actually clocked in, tracked in software since reg_usr is not a reliable busy indicator in slave mode. Set the LP IO direction for the SPI pads, add lp_core_lp_spi_bus_deinit() to release the LP GPIO pins, and reset the LP SPI peripheral at bus initialization so a stale configuration from a previous run cannot leak into the next.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -104,6 +104,22 @@ esp_err_t lp_core_lp_spi_bus_add_device(lp_spi_host_t host_id, const lp_spi_devi
|
||||
*/
|
||||
esp_err_t lp_core_lp_spi_slave_initialize(lp_spi_host_t host_id, const lp_spi_slave_config_t *slave_config);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the LP SPI bus.
|
||||
*
|
||||
* Performs a module-level hardware reset of the LP SPI peripheral (all
|
||||
* registers return to power-on defaults) and deinitializes the LP GPIO
|
||||
* pins that were configured for SPI signals.
|
||||
*
|
||||
* @param host_id LP SPI host ID (currently unused, only one host exists)
|
||||
* @param bus_config Pointer to the bus configuration that was used during
|
||||
* initialization, so that the same GPIO pins can be
|
||||
* deinitialized. May be NULL to skip GPIO deinit.
|
||||
*
|
||||
* @return ESP_OK on success
|
||||
*/
|
||||
esp_err_t lp_core_lp_spi_bus_deinit(lp_spi_host_t host_id, const lp_spi_bus_config_t *bus_config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user