mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-03 03:31:41 +03:00
refactor(driver_spi): spi driver using dma link list driver
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -15,7 +15,6 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h> //for abs()
|
||||
#include "esp_types.h"
|
||||
#include "esp32/rom/lldesc.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/dport_reg.h"
|
||||
@@ -1159,7 +1158,7 @@ static inline void spi_ll_dma_rx_reset(spi_dma_dev_t *dma_in, uint32_t channel)
|
||||
* @param addr Address of the beginning DMA descriptor.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_dma_rx_start(spi_dma_dev_t *dma_in, uint32_t channel, lldesc_t *addr)
|
||||
static inline void spi_ll_dma_rx_start(spi_dma_dev_t *dma_in, uint32_t channel, void *addr)
|
||||
{
|
||||
dma_in->dma_in_link.addr = (int) addr & 0xFFFFF;
|
||||
dma_in->dma_in_link.start = 1;
|
||||
@@ -1224,7 +1223,7 @@ static inline void spi_ll_dma_tx_reset(spi_dma_dev_t *dma_out, uint32_t channel)
|
||||
* @param addr Address of the beginning DMA descriptor.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_dma_tx_start(spi_dma_dev_t *dma_out, uint32_t channel, lldesc_t *addr)
|
||||
static inline void spi_ll_dma_tx_start(spi_dma_dev_t *dma_out, uint32_t channel, void *addr)
|
||||
{
|
||||
dma_out->dma_out_link.addr = (int) addr & 0xFFFFF;
|
||||
dma_out->dma_out_link.start = 1;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/misc.h"
|
||||
@@ -1331,7 +1330,7 @@ static inline void spi_ll_dma_rx_reset(spi_dma_dev_t *dma_in, uint32_t channel)
|
||||
* @param addr Address of the beginning DMA descriptor.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_dma_rx_start(spi_dma_dev_t *dma_in, uint32_t channel, lldesc_t *addr)
|
||||
static inline void spi_ll_dma_rx_start(spi_dma_dev_t *dma_in, uint32_t channel, void *addr)
|
||||
{
|
||||
dma_in->dma_in_link.addr = (int) addr & 0xFFFFF;
|
||||
dma_in->dma_in_link.start = 1;
|
||||
@@ -1423,7 +1422,7 @@ static inline void spi_ll_dma_tx_reset(spi_dma_dev_t *dma_out, uint32_t channel)
|
||||
* @param addr Address of the beginning DMA descriptor.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void spi_ll_dma_tx_start(spi_dma_dev_t *dma_out, uint32_t channel, lldesc_t *addr)
|
||||
static inline void spi_ll_dma_tx_start(spi_dma_dev_t *dma_out, uint32_t channel, void *addr)
|
||||
{
|
||||
dma_out->dma_out_link.addr = (int) addr & 0xFFFFF;
|
||||
dma_out->dma_out_link.start = 1;
|
||||
|
||||
@@ -105,8 +105,6 @@ typedef struct {
|
||||
|
||||
/* address of the hardware */
|
||||
spi_dev_t *dev; ///< Beginning address of the peripheral registers.
|
||||
bool dma_enabled; ///< DMA enabled or not
|
||||
bool append_mode; ///< True for DMA append mode, false for segment mode
|
||||
uint32_t dma_desc_num; ///< Number of the available DMA descriptors. Calculated from ``bus_max_transfer_size``.
|
||||
uint32_t current_eof_addr;
|
||||
spi_slave_hd_hal_desc_append_t *tx_cur_desc; ///< Current TX DMA descriptor that could be linked (set up).
|
||||
@@ -193,14 +191,6 @@ void spi_slave_hd_hal_enable_event_intr(spi_slave_hd_hal_context_t* hal, spi_eve
|
||||
*/
|
||||
void spi_slave_hd_hal_rxdma(spi_slave_hd_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Get the length of total received data
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @return The received length
|
||||
*/
|
||||
int spi_slave_hd_hal_rxdma_seg_get_len(spi_slave_hd_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Prepare hardware for a new dma rx trans
|
||||
*
|
||||
@@ -266,64 +256,6 @@ int spi_slave_hd_hal_get_rxlen(spi_slave_hd_hal_context_t *hal);
|
||||
*/
|
||||
int spi_slave_hd_hal_get_last_addr(spi_slave_hd_hal_context_t *hal);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Append Mode
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/**
|
||||
* @brief Return the finished TX transaction
|
||||
*
|
||||
* @note This API is based on this assumption: the hardware behaviour of current transaction completion is only modified by the its own caller layer.
|
||||
* This means if some other code changed the hardware behaviour (e.g. clear intr raw bit), or the caller call this API without noticing the HW behaviour,
|
||||
* this API will go wrong.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param out_trans Pointer to the caller-defined transaction
|
||||
* @param real_buff_addr Actually data buffer head the HW used
|
||||
* @return 1: Transaction is finished; 0: Transaction is not finished
|
||||
*/
|
||||
bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr);
|
||||
|
||||
/**
|
||||
* @brief Return the finished RX transaction
|
||||
*
|
||||
* @note This API is based on this assumption: the hardware behaviour of current transaction completion is only modified by the its own caller layer.
|
||||
* This means if some other code changed the hardware behaviour (e.g. clear intr raw bit), or the caller call this API without noticing the HW behaviour,
|
||||
* this API will go wrong.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param out_trans Pointer to the caller-defined transaction
|
||||
* @param real_buff_addr Actually data buffer head the HW used
|
||||
* @param out_len Actual number of bytes of received data
|
||||
* @return 1: Transaction is finished; 0: Transaction is not finished
|
||||
*/
|
||||
bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr, size_t *out_len);
|
||||
|
||||
/**
|
||||
* @brief Load the TX DMA descriptors without stopping the DMA
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param data Buffer of the transaction data
|
||||
* @param len Length of the data
|
||||
* @param arg Pointer used by the caller to indicate the transaction. Will be returned by ``spi_slave_hd_hal_get_tx_finished_trans`` when transaction is finished
|
||||
* @return
|
||||
* - ESP_OK: on success
|
||||
* - ESP_ERR_INVALID_STATE: Function called in invalid state.
|
||||
*/
|
||||
esp_err_t spi_slave_hd_hal_txdma_append(spi_slave_hd_hal_context_t *hal, uint8_t *data, size_t len, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Load the RX DMA descriptors without stopping the DMA
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param data Buffer of the transaction data
|
||||
* @param len Length of the data
|
||||
* @param arg Pointer used by the caller to indicate the transaction. Will be returned by ``spi_slave_hd_hal_get_rx_finished_trans`` when transaction is finished
|
||||
* @return
|
||||
* - ESP_OK: on success
|
||||
* - ESP_ERR_INVALID_STATE: Function called in invalid state.
|
||||
*/
|
||||
esp_err_t spi_slave_hd_hal_rxdma_append(spi_slave_hd_hal_context_t *hal, uint8_t *data, size_t len, void *arg);
|
||||
|
||||
#endif //#if SOC_GPSPI_SUPPORTED
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/soc.h" //for SOC_NON_CACHEABLE_OFFSET_SRAM
|
||||
#include "soc/spi_periph.h"
|
||||
#include "hal/spi_slave_hd_hal.h"
|
||||
#include "hal/assert.h"
|
||||
@@ -21,8 +19,6 @@ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_h
|
||||
{
|
||||
spi_dev_t *hw = spi_periph_signal[hal_config->host_id].hw;
|
||||
hal->dev = hw;
|
||||
hal->dma_enabled = hal_config->dma_enabled;
|
||||
hal->append_mode = hal_config->append_mode;
|
||||
hal->tx_cur_desc = hal->dmadesc_tx;
|
||||
hal->rx_cur_desc = hal->dmadesc_rx;
|
||||
hal->tx_dma_head = hal->dmadesc_tx + hal->dma_desc_num - 1;
|
||||
@@ -70,37 +66,6 @@ void spi_slave_hd_hal_init(spi_slave_hd_hal_context_t *hal, const spi_slave_hd_h
|
||||
spi_ll_slave_set_seg_mode(hal->dev, true);
|
||||
}
|
||||
|
||||
#if SOC_NON_CACHEABLE_OFFSET_SRAM
|
||||
#include "hal/cache_ll.h"
|
||||
#define ADDR_DMA_2_CPU(addr) ((typeof(addr))CACHE_LL_L2MEM_NON_CACHE_ADDR(addr))
|
||||
#define ADDR_CPU_2_DMA(addr) ((typeof(addr))CACHE_LL_L2MEM_CACHE_ADDR(addr))
|
||||
#else
|
||||
#define ADDR_DMA_2_CPU(addr) (addr)
|
||||
#define ADDR_CPU_2_DMA(addr) (addr)
|
||||
#endif
|
||||
|
||||
static int s_desc_get_received_len_addr(spi_dma_desc_t* head, spi_dma_desc_t** out_next, void **out_buff_head)
|
||||
{
|
||||
spi_dma_desc_t* desc_cpu = ADDR_DMA_2_CPU(head);
|
||||
int len = 0;
|
||||
if (out_buff_head) {
|
||||
*out_buff_head = desc_cpu->buffer;
|
||||
}
|
||||
while (head) {
|
||||
len += desc_cpu->dw0.length;
|
||||
bool eof = desc_cpu->dw0.suc_eof;
|
||||
desc_cpu = ADDR_DMA_2_CPU(desc_cpu->next);
|
||||
head = head->next;
|
||||
if (eof) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (out_next) {
|
||||
*out_next = head;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
void spi_slave_hd_hal_hw_prepare_rx(spi_slave_hd_hal_context_t *hal)
|
||||
{
|
||||
spi_ll_dma_rx_fifo_reset(hal->dev);
|
||||
@@ -234,41 +199,3 @@ int spi_slave_hd_hal_get_rxlen(spi_slave_hd_hal_context_t *hal)
|
||||
//this is by -byte
|
||||
return spi_ll_slave_get_rx_byte_len(hal->dev);
|
||||
}
|
||||
|
||||
int spi_slave_hd_hal_rxdma_seg_get_len(spi_slave_hd_hal_context_t *hal)
|
||||
{
|
||||
spi_dma_desc_t *desc = hal->dmadesc_rx->desc;
|
||||
return s_desc_get_received_len_addr(desc, NULL, NULL);
|
||||
}
|
||||
|
||||
bool spi_slave_hd_hal_get_tx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr)
|
||||
{
|
||||
if ((uint32_t)hal->tx_dma_head->desc == hal->current_eof_addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//find used paired desc-trans by desc addr
|
||||
hal->tx_dma_head++;
|
||||
if (hal->tx_dma_head >= hal->dmadesc_tx + hal->dma_desc_num) {
|
||||
hal->tx_dma_head = hal->dmadesc_tx;
|
||||
}
|
||||
*out_trans = hal->tx_dma_head->arg;
|
||||
s_desc_get_received_len_addr(hal->tx_dma_head->desc, NULL, real_buff_addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool spi_slave_hd_hal_get_rx_finished_trans(spi_slave_hd_hal_context_t *hal, void **out_trans, void **real_buff_addr, size_t *out_len)
|
||||
{
|
||||
if ((uint32_t)hal->rx_dma_head->desc == hal->current_eof_addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//find used paired desc-trans by desc addr
|
||||
hal->rx_dma_head++;
|
||||
if (hal->rx_dma_head >= hal->dmadesc_rx + hal->dma_desc_num) {
|
||||
hal->rx_dma_head = hal->dmadesc_rx;
|
||||
}
|
||||
*out_trans = hal->rx_dma_head->arg;
|
||||
*out_len = s_desc_get_received_len_addr(hal->rx_dma_head->desc, NULL, real_buff_addr);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user