mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
SPI: More MR issues fixed, style fixup
This commit is contained in:
parent
bf0c32364a
commit
04b901e629
@ -169,16 +169,6 @@ spi_dev_t *spicommon_hw_for_host(spi_host_device_t host);
|
|||||||
int spicommon_irqsource_for_host(spi_host_device_t host);
|
int spicommon_irqsource_for_host(spi_host_device_t host);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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
|
|
||||||
* by resetting the SPI DMA hardware in case this happens. Unfortunately, the reset knob used for thsi will reset _both_ DMA channels, and
|
|
||||||
* as such can only done safely when both DMA channels are idle. These functions coordinate this.
|
|
||||||
*
|
|
||||||
* Essentially, when a reset is needed, a driver can request this using spicommon_dmaworkaround_req_reset. This is supposed to be called
|
|
||||||
* with an user-supplied function as an argument. If both DMA channels are idle, this call will reset the DMA subsystem and return true.
|
|
||||||
* 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
|
|
||||||
* DMA subsystem and call the callback. The callback is then supposed to be used to continue the SPI drivers activity.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -190,6 +180,15 @@ typedef void(*dmaworkaround_cb_t)(void *arg);
|
|||||||
/**
|
/**
|
||||||
* @brief Request a reset for a certain DMA channel
|
* @brief Request a reset for a certain DMA channel
|
||||||
*
|
*
|
||||||
|
* @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
|
||||||
|
* by resetting the SPI DMA hardware in case this happens. Unfortunately, the reset knob used for thsi will reset _both_ DMA channels, and
|
||||||
|
* as such can only done safely when both DMA channels are idle. These functions coordinate this.
|
||||||
|
*
|
||||||
|
* Essentially, when a reset is needed, a driver can request this using spicommon_dmaworkaround_req_reset. This is supposed to be called
|
||||||
|
* with an user-supplied function as an argument. If both DMA channels are idle, this call will reset the DMA subsystem and return true.
|
||||||
|
* 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
|
||||||
|
* DMA subsystem and call the callback. The callback is then supposed to be used to continue the SPI drivers activity.
|
||||||
|
*
|
||||||
* @param dmachan DMA channel associated with the SPI host that needs a reset
|
* @param dmachan DMA channel associated with the SPI host that needs a reset
|
||||||
* @param cb Callback to call in case DMA channel cannot be reset immediately
|
* @param cb Callback to call in case DMA channel cannot be reset immediately
|
||||||
* @param arg Argument to the callback
|
* @param arg Argument to the callback
|
||||||
|
@ -31,7 +31,7 @@ extern "C"
|
|||||||
#define SPI_DEVICE_TXBIT_LSBFIRST (1<<0) ///< Transmit command/address/data LSB first instead of the default MSB first
|
#define SPI_DEVICE_TXBIT_LSBFIRST (1<<0) ///< Transmit command/address/data LSB first instead of the default MSB first
|
||||||
#define SPI_DEVICE_RXBIT_LSBFIRST (1<<1) ///< Receive data LSB first instead of the default MSB first
|
#define SPI_DEVICE_RXBIT_LSBFIRST (1<<1) ///< Receive data LSB first instead of the default MSB first
|
||||||
#define SPI_DEVICE_BIT_LSBFIRST (SPI_TXBIT_LSBFIRST|SPI_RXBIT_LSBFIRST); ///< Transmit and receive LSB first
|
#define SPI_DEVICE_BIT_LSBFIRST (SPI_TXBIT_LSBFIRST|SPI_RXBIT_LSBFIRST); ///< Transmit and receive LSB first
|
||||||
#define SPI_DEVICE_3WIRE (1<<2) ///< Use spid for both sending and receiving data
|
#define SPI_DEVICE_3WIRE (1<<2) ///< Use MOSI (=spid) for both sending and receiving data
|
||||||
#define SPI_DEVICE_POSITIVE_CS (1<<3) ///< Make CS positive during a transaction instead of negative
|
#define SPI_DEVICE_POSITIVE_CS (1<<3) ///< Make CS positive during a transaction instead of negative
|
||||||
#define SPI_DEVICE_HALFDUPLEX (1<<4) ///< Transmit data before receiving it, instead of simultaneously
|
#define SPI_DEVICE_HALFDUPLEX (1<<4) ///< Transmit data before receiving it, instead of simultaneously
|
||||||
#define SPI_DEVICE_CLK_AS_CS (1<<5) ///< Output clock on CS line if CS is active
|
#define SPI_DEVICE_CLK_AS_CS (1<<5) ///< Output clock on CS line if CS is active
|
||||||
|
@ -59,7 +59,7 @@ struct spi_slave_transaction_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize a SPI bus
|
* @brief Initialize a SPI bus as a slave interface
|
||||||
*
|
*
|
||||||
* @warning For now, only supports HSPI and VSPI.
|
* @warning For now, only supports HSPI and VSPI.
|
||||||
*
|
*
|
||||||
@ -92,10 +92,13 @@ esp_err_t spi_slave_free(spi_host_device_t host);
|
|||||||
/**
|
/**
|
||||||
* @brief Queue a SPI transaction for execution
|
* @brief Queue a SPI transaction for execution
|
||||||
*
|
*
|
||||||
* This will queue a transaction for the master to pick it up. If the queue (specified in ``spi_slave_initialize``)
|
* Queues a SPI transaction to be executed by this slave device. (The transaction queue size was specified when the slave
|
||||||
* is not full, this function will return directly; the actual transaction will be done if there aren't any
|
* device was initialised via spi_slave_initialize.) This function may block if the queue is full (depending on the
|
||||||
* unhandled transactions before it and the master initiates a SPI transaction by pulling down CS and sending out
|
* ticks_to_wait parameter). No SPI operation is directly initiated by this function, the next queued transaction
|
||||||
* clock signals.
|
* will happen when the master initiates a SPI transaction by pulling down CS and sending out clock signals.
|
||||||
|
*
|
||||||
|
* This function hands over ownership of the buffers in ``trans_desc`` to the SPI slave driver; the application is
|
||||||
|
* not to access this memory until ``spi_slave_queue_trans`` is called to hand ownership back to the application.
|
||||||
*
|
*
|
||||||
* @param host SPI peripheral that is acting as a slave
|
* @param host SPI peripheral that is acting as a slave
|
||||||
* @param trans_desc Description of transaction to execute. Not const because we may want to write status back
|
* @param trans_desc Description of transaction to execute. Not const because we may want to write status back
|
||||||
@ -117,8 +120,10 @@ esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transact
|
|||||||
* completed transaction so software can inspect the result and e.g. free the memory or
|
* completed transaction so software can inspect the result and e.g. free the memory or
|
||||||
* re-use the buffers.
|
* re-use the buffers.
|
||||||
*
|
*
|
||||||
|
* It is mandatory to eventually use this function for any transaction queued by ``spi_slave_queue_trans``.
|
||||||
|
*
|
||||||
* @param host SPI peripheral to that is acting as a slave
|
* @param host SPI peripheral to that is acting as a slave
|
||||||
* @param trans_desc Pointer to variable able to contain a pointer to the description of the
|
* @param[out] trans_desc Pointer to variable able to contain a pointer to the description of the
|
||||||
* transaction that is executed
|
* transaction that is executed
|
||||||
* @param ticks_to_wait Ticks to wait until there's a returned item; use portMAX_DELAY to never time
|
* @param ticks_to_wait Ticks to wait until there's a returned item; use portMAX_DELAY to never time
|
||||||
* out.
|
* out.
|
||||||
|
@ -154,25 +154,29 @@ static const spi_signal_conn_t io_signal[3]={
|
|||||||
static bool spi_periph_claimed[3] = {true, false, false};
|
static bool spi_periph_claimed[3] = {true, false, false};
|
||||||
|
|
||||||
//Returns true if this peripheral is successfully claimed, false if otherwise.
|
//Returns true if this peripheral is successfully claimed, false if otherwise.
|
||||||
bool spicommon_periph_claim(spi_host_device_t host) {
|
bool spicommon_periph_claim(spi_host_device_t host)
|
||||||
|
{
|
||||||
bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], false, true);
|
bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], false, true);
|
||||||
if (ret) periph_module_enable(io_signal[host].module);
|
if (ret) periph_module_enable(io_signal[host].module);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns true if this peripheral is successfully freed, false if otherwise.
|
//Returns true if this peripheral is successfully freed, false if otherwise.
|
||||||
bool spicommon_periph_free(spi_host_device_t host) {
|
bool spicommon_periph_free(spi_host_device_t host)
|
||||||
|
{
|
||||||
bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], true, false);
|
bool ret = __sync_bool_compare_and_swap(&spi_periph_claimed[host], true, false);
|
||||||
if (ret) periph_module_disable(io_signal[host].module);
|
if (ret) periph_module_disable(io_signal[host].module);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int spicommon_irqsource_for_host(spi_host_device_t host) {
|
int spicommon_irqsource_for_host(spi_host_device_t host)
|
||||||
|
{
|
||||||
return io_signal[host].irq;
|
return io_signal[host].irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
spi_dev_t *spicommon_hw_for_host(spi_host_device_t host) {
|
spi_dev_t *spicommon_hw_for_host(spi_host_device_t host)
|
||||||
|
{
|
||||||
return io_signal[host].hw;
|
return io_signal[host].hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +188,7 @@ config can be done using the IOMUX instead of using the GPIO matrix.
|
|||||||
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan, int flags, bool *is_native)
|
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan, int flags, bool *is_native)
|
||||||
{
|
{
|
||||||
bool native = true;
|
bool native = true;
|
||||||
bool use_quad=(flags&SPICOMMON_BUSFLAG_QUAD)?true:false;
|
bool use_quad = (flags & SPICOMMON_BUSFLAG_QUAD) != 0;
|
||||||
|
|
||||||
SPI_CHECK(bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num), "spid pin invalid", ESP_ERR_INVALID_ARG);
|
SPI_CHECK(bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num), "spid pin invalid", ESP_ERR_INVALID_ARG);
|
||||||
SPI_CHECK(bus_config->sclk_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->sclk_io_num), "spiclk pin invalid", ESP_ERR_INVALID_ARG);
|
SPI_CHECK(bus_config->sclk_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->sclk_io_num), "spiclk pin invalid", ESP_ERR_INVALID_ARG);
|
||||||
@ -255,7 +259,8 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
|||||||
|
|
||||||
|
|
||||||
//Find any pin with output muxed to ``func`` and reset it to GPIO
|
//Find any pin with output muxed to ``func`` and reset it to GPIO
|
||||||
static void reset_func_to_gpio(int func) {
|
static void reset_func_to_gpio(int func)
|
||||||
|
{
|
||||||
for (int x = 0; x < GPIO_PIN_COUNT; x++) {
|
for (int x = 0; x < GPIO_PIN_COUNT; x++) {
|
||||||
if (GPIO_IS_VALID_GPIO(x) && (READ_PERI_REG(GPIO_FUNC0_OUT_SEL_CFG_REG + (x * 4))&GPIO_FUNC0_OUT_SEL_M) == func) {
|
if (GPIO_IS_VALID_GPIO(x) && (READ_PERI_REG(GPIO_FUNC0_OUT_SEL_CFG_REG + (x * 4))&GPIO_FUNC0_OUT_SEL_M) == func) {
|
||||||
gpio_matrix_out(x, SIG_GPIO_OUT_IDX, false, false);
|
gpio_matrix_out(x, SIG_GPIO_OUT_IDX, false, false);
|
||||||
@ -279,7 +284,8 @@ esp_err_t spicommon_bus_free_io(spi_host_device_t host)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix) {
|
void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix)
|
||||||
|
{
|
||||||
if (!force_gpio_matrix && cs_io_num == io_signal[host].spics0_native && cs_num == 0) {
|
if (!force_gpio_matrix && cs_io_num == io_signal[host].spics0_native && cs_num == 0) {
|
||||||
//The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
|
//The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
|
||||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], 1);
|
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[cs_io_num], 1);
|
||||||
@ -291,7 +297,8 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void spicommon_cs_free(spi_host_device_t host, int cs_io_num) {
|
void spicommon_cs_free(spi_host_device_t host, int cs_io_num)
|
||||||
|
{
|
||||||
if (cs_io_num == 0 && REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spics0_native], MCU_SEL) == 1) {
|
if (cs_io_num == 0 && REG_GET_FIELD(GPIO_PIN_MUX_REG[io_signal[host].spics0_native], MCU_SEL) == 1) {
|
||||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spics0_native], PIN_FUNC_GPIO);
|
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[io_signal[host].spics0_native], PIN_FUNC_GPIO);
|
||||||
}
|
}
|
||||||
@ -299,7 +306,8 @@ void spicommon_cs_free(spi_host_device_t host, int cs_io_num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Set up a list of dma descriptors. dmadesc is an array of descriptors. Data is the buffer to point to.
|
//Set up a list of dma descriptors. dmadesc is an array of descriptors. Data is the buffer to point to.
|
||||||
void spicommon_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx) {
|
void spicommon_setup_dma_desc_links(lldesc_t *dmadesc, int len, const uint8_t *data, bool isrx)
|
||||||
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
while (len) {
|
while (len) {
|
||||||
int dmachunklen = len;
|
int dmachunklen = len;
|
||||||
@ -363,7 +371,8 @@ bool IRAM_ATTR spicommon_dmaworkaround_reset_in_progress()
|
|||||||
return (dmaworkaround_waiting_for_chan != 0);
|
return (dmaworkaround_waiting_for_chan != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) {
|
void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan)
|
||||||
|
{
|
||||||
portENTER_CRITICAL(&dmaworkaround_mux);
|
portENTER_CRITICAL(&dmaworkaround_mux);
|
||||||
dmaworkaround_channels_busy[dmachan] = 0;
|
dmaworkaround_channels_busy[dmachan] = 0;
|
||||||
if (dmaworkaround_waiting_for_chan == dmachan) {
|
if (dmaworkaround_waiting_for_chan == dmachan) {
|
||||||
@ -378,7 +387,8 @@ void IRAM_ATTR spicommon_dmaworkaround_idle(int dmachan) {
|
|||||||
portEXIT_CRITICAL(&dmaworkaround_mux);
|
portEXIT_CRITICAL(&dmaworkaround_mux);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan) {
|
void IRAM_ATTR spicommon_dmaworkaround_transfer_active(int dmachan)
|
||||||
|
{
|
||||||
portENTER_CRITICAL(&dmaworkaround_mux);
|
portENTER_CRITICAL(&dmaworkaround_mux);
|
||||||
dmaworkaround_channels_busy[dmachan] = 1;
|
dmaworkaround_channels_busy[dmachan] = 1;
|
||||||
portEXIT_CRITICAL(&dmaworkaround_mux);
|
portEXIT_CRITICAL(&dmaworkaround_mux);
|
||||||
|
@ -236,7 +236,8 @@ esp_err_t spi_slave_transmit(spi_host_device_t host, spi_slave_transaction_t *tr
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_SLAVE
|
#ifdef DEBUG_SLAVE
|
||||||
static void dumpregs(spi_dev_t *hw) {
|
static void dumpregs(spi_dev_t *hw)
|
||||||
|
{
|
||||||
ets_printf("***REG DUMP ***\n");
|
ets_printf("***REG DUMP ***\n");
|
||||||
ets_printf("mosi_dlen : %08X\n", hw->mosi_dlen.val);
|
ets_printf("mosi_dlen : %08X\n", hw->mosi_dlen.val);
|
||||||
ets_printf("miso_dlen : %08X\n", hw->miso_dlen.val);
|
ets_printf("miso_dlen : %08X\n", hw->miso_dlen.val);
|
||||||
@ -249,7 +250,8 @@ static void dumpregs(spi_dev_t *hw) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dumpll(lldesc_t *ll) {
|
static void dumpll(lldesc_t *ll)
|
||||||
|
{
|
||||||
ets_printf("****LL DUMP****\n");
|
ets_printf("****LL DUMP****\n");
|
||||||
ets_printf("Size %d\n", ll->size);
|
ets_printf("Size %d\n", ll->size);
|
||||||
ets_printf("Len: %d\n", ll->length);
|
ets_printf("Len: %d\n", ll->length);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user