Merge branch 'bugfix/cpu_clk_disable_spi' into 'master'
spi_master, sdmmc: fix regressions due to peripherals being disabled by default See merge request !1193
This commit is contained in:
commit
51e8f439b8
7 changed files with 126 additions and 7 deletions
|
@ -44,6 +44,11 @@ typedef enum {
|
|||
PERIPH_SPI_MODULE,
|
||||
PERIPH_HSPI_MODULE,
|
||||
PERIPH_VSPI_MODULE,
|
||||
PERIPH_SPI_DMA_MODULE,
|
||||
PERIPH_SDMMC_MODULE,
|
||||
PERIPH_SDIO_SLAVE_MODULE,
|
||||
PERIPH_CAN_MODULE,
|
||||
PERIPH_EMAC_MODULE,
|
||||
} periph_module_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -74,11 +74,30 @@ bool spicommon_periph_claim(spi_host_device_t host);
|
|||
/**
|
||||
* @brief Return the SPI peripheral so another driver can claim it.
|
||||
*
|
||||
* @param host Peripheral to claim
|
||||
* @param host Peripheral to return
|
||||
* @return True if peripheral is returned successfully; false if peripheral was free to claim already.
|
||||
*/
|
||||
bool spicommon_periph_free(spi_host_device_t host);
|
||||
|
||||
/**
|
||||
* @brief Try to claim a SPI DMA channel
|
||||
*
|
||||
* Call this if your driver wants to use SPI with a DMA channnel.
|
||||
*
|
||||
* @param dma_chan channel to claim
|
||||
*
|
||||
* @return True if success; false otherwise.
|
||||
*/
|
||||
bool spicommon_dma_chan_claim(int dma_chan);
|
||||
|
||||
/**
|
||||
* @brief Return the SPI DMA channel so other driver can claim it, or just to power down DMA.
|
||||
*
|
||||
* @param dma_chan channel to return
|
||||
*
|
||||
* @return True if success; false otherwise.
|
||||
*/
|
||||
bool spicommon_dma_chan_free(int dma_chan);
|
||||
|
||||
#define SPICOMMON_BUSFLAG_SLAVE 0 ///< Initialize I/O in slave mode
|
||||
#define SPICOMMON_BUSFLAG_MASTER (1<<0) ///< Initialize I/O in master mode
|
||||
|
@ -170,9 +189,6 @@ spi_dev_t *spicommon_hw_for_host(spi_host_device_t host);
|
|||
*/
|
||||
int spicommon_irqsource_for_host(spi_host_device_t host);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Callback, to be called when a DMA engine reset is completed
|
||||
*/
|
||||
|
|
|
@ -109,6 +109,26 @@ void periph_module_enable(periph_module_t periph)
|
|||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_2);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_2);
|
||||
break;
|
||||
case PERIPH_SPI_DMA_MODULE:
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_DMA_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_DMA_RST);
|
||||
break;
|
||||
case PERIPH_SDMMC_MODULE:
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_SDIO_HOST_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_SDIO_HOST_RST);
|
||||
break;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_SDIOSLAVE_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_SDIO_RST);
|
||||
break;
|
||||
case PERIPH_CAN_MODULE:
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST);
|
||||
break;
|
||||
case PERIPH_EMAC_MODULE:
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_EMAC_EN);
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_EMAC_RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -203,6 +223,26 @@ void periph_module_disable(periph_module_t periph)
|
|||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_CLK_EN_2);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_RST_2);
|
||||
break;
|
||||
case PERIPH_SPI_DMA_MODULE:
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_SPI_DMA_CLK_EN);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_SPI_DMA_RST);
|
||||
break;
|
||||
case PERIPH_SDMMC_MODULE:
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_SDIO_HOST_EN);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_SDIO_HOST_RST);
|
||||
break;
|
||||
case PERIPH_SDIO_SLAVE_MODULE:
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_SDIOSLAVE_EN);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_SDIO_RST);
|
||||
break;
|
||||
case PERIPH_CAN_MODULE:
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_CAN_CLK_EN);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_CAN_RST);
|
||||
break;
|
||||
case PERIPH_EMAC_MODULE:
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_EMAC_EN);
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_CORE_RST_EN_REG, DPORT_EMAC_RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "rom/gpio.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/sdmmc_host.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
#include "sdmmc_private.h"
|
||||
|
||||
#define SDMMC_EVENT_QUEUE_LENGTH 32
|
||||
|
@ -236,6 +237,8 @@ esp_err_t sdmmc_host_init()
|
|||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
periph_module_enable(PERIPH_SDMMC_MODULE);
|
||||
|
||||
// Enable clock to peripheral
|
||||
sdmmc_host_input_clk_enable();
|
||||
|
||||
|
@ -367,6 +370,7 @@ esp_err_t sdmmc_host_deinit()
|
|||
s_event_queue = NULL;
|
||||
sdmmc_host_input_clk_disable();
|
||||
sdmmc_host_transaction_handler_deinit();
|
||||
periph_module_disable(PERIPH_SDMMC_MODULE);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,8 +150,13 @@ static const spi_signal_conn_t io_signal[3] = {
|
|||
}
|
||||
};
|
||||
|
||||
#define DMA_CHANNEL_ENABLED(dma_chan) (BIT(dma_chan-1))
|
||||
|
||||
//Periph 1 is 'claimed' by SPI flash code.
|
||||
static bool spi_periph_claimed[3] = {true, false, false};
|
||||
static uint8_t spi_dma_chan_enabled = 0;
|
||||
static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
|
||||
//Returns true if this peripheral is successfully claimed, false if otherwise.
|
||||
bool spicommon_periph_claim(spi_host_device_t host)
|
||||
|
@ -180,6 +185,39 @@ spi_dev_t *spicommon_hw_for_host(spi_host_device_t host)
|
|||
return io_signal[host].hw;
|
||||
}
|
||||
|
||||
bool spicommon_dma_chan_claim (int dma_chan)
|
||||
{
|
||||
bool ret = false;
|
||||
assert( dma_chan == 1 || dma_chan == 2 );
|
||||
|
||||
portENTER_CRITICAL(&spi_dma_spinlock);
|
||||
if ( !(spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan)) ) {
|
||||
// get the channel only when it's not claimed yet.
|
||||
spi_dma_chan_enabled |= DMA_CHANNEL_ENABLED(dma_chan);
|
||||
ret = true;
|
||||
}
|
||||
periph_module_enable( PERIPH_SPI_DMA_MODULE );
|
||||
portEXIT_CRITICAL(&spi_dma_spinlock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool spicommon_dma_chan_free(int dma_chan)
|
||||
{
|
||||
assert( dma_chan == 1 || dma_chan == 2 );
|
||||
assert( spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan) );
|
||||
|
||||
portENTER_CRITICAL(&spi_dma_spinlock);
|
||||
spi_dma_chan_enabled &= ~DMA_CHANNEL_ENABLED(dma_chan);
|
||||
if ( spi_dma_chan_enabled == 0 ) {
|
||||
//disable the DMA only when all the channels are freed.
|
||||
periph_module_disable( PERIPH_SPI_DMA_MODULE );
|
||||
}
|
||||
portEXIT_CRITICAL(&spi_dma_spinlock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Do the common stuff to hook up a SPI host to a bus defined by a bunch of GPIO pins. Feed it a host number and a
|
||||
bus config struct and it'll set up the GPIO matrix and enable the device. It will set is_native to 1 if the bus
|
||||
|
|
|
@ -108,14 +108,23 @@ static void spi_intr(void *arg);
|
|||
|
||||
esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus_config, int dma_chan)
|
||||
{
|
||||
bool native, claimed;
|
||||
bool native, spi_chan_claimed, dma_chan_claimed;
|
||||
/* ToDo: remove this when we have flash operations cooperating with this */
|
||||
SPI_CHECK(host!=SPI_HOST, "SPI1 is not supported", ESP_ERR_NOT_SUPPORTED);
|
||||
|
||||
SPI_CHECK(host>=SPI_HOST && host<=VSPI_HOST, "invalid host", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
|
||||
|
||||
claimed=spicommon_periph_claim(host);
|
||||
SPI_CHECK(claimed, "host already in use", ESP_ERR_INVALID_STATE);
|
||||
spi_chan_claimed=spicommon_periph_claim(host);
|
||||
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
|
||||
|
||||
if ( dma_chan != 0 ) {
|
||||
dma_chan_claimed=spicommon_dma_chan_claim(dma_chan);
|
||||
if ( !dma_chan_claimed ) {
|
||||
spicommon_periph_free( host );
|
||||
SPI_CHECK(dma_chan_claimed, "dma channel already in use", ESP_ERR_INVALID_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
spihost[host]=malloc(sizeof(spi_host_t));
|
||||
if (spihost[host]==NULL) goto nomem;
|
||||
|
@ -185,6 +194,10 @@ esp_err_t spi_bus_free(spi_host_device_t host)
|
|||
for (x=0; x<NO_CS; x++) {
|
||||
SPI_CHECK(spihost[host]->device[x]==NULL, "not all CSses freed", ESP_ERR_INVALID_STATE);
|
||||
}
|
||||
|
||||
if ( spihost[host]->dma_chan > 0 ) {
|
||||
spicommon_dma_chan_free ( spihost[host]->dma_chan );
|
||||
}
|
||||
spihost[host]->hw->slave.trans_inten=0;
|
||||
spihost[host]->hw->slave.trans_done=0;
|
||||
esp_intr_free(spihost[host]->intr);
|
||||
|
|
|
@ -37,6 +37,8 @@
|
|||
#include "esp_eth.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
#include "emac_common.h"
|
||||
#include "emac_desc.h"
|
||||
|
||||
|
@ -1005,6 +1007,7 @@ esp_err_t esp_eth_init_internal(eth_config_t *config)
|
|||
emac_config.emac_phy_power_enable(true);
|
||||
|
||||
//before set emac reg must enable clk
|
||||
periph_module_enable(PERIPH_EMAC_MODULE);
|
||||
emac_enable_clk(true);
|
||||
REG_SET_FIELD(EMAC_EX_PHYINF_CONF_REG, EMAC_EX_PHY_INTF_SEL, EMAC_EX_PHY_INTF_RMII);
|
||||
|
||||
|
|
Loading…
Reference in a new issue