spi: shown owner of spi host explicitly

This commit is contained in:
Michael (XIAO Xufeng) 2018-10-05 15:39:32 +08:00
parent 98a80ccdab
commit 9b5d0f3322
5 changed files with 58 additions and 9 deletions

View file

@ -96,9 +96,32 @@ typedef struct {
* Call this if your driver wants to manage a SPI peripheral.
*
* @param host Peripheral to claim
* @param source The caller indentification string.
*
* @return True if peripheral is claimed successfully; false if peripheral already is claimed.
*/
bool spicommon_periph_claim(spi_host_device_t host);
bool spicommon_periph_claim(spi_host_device_t host, const char* source);
// The macro is to keep the back-compatibility of IDF v3.2 and before
// In this way we can call spicommon_periph_claim with two arguments, or the host with the source set to the calling function name
// When two arguments (host, func) are given, __spicommon_periph_claim2 is called
// or if only one arguments (host) is given, __spicommon_periph_claim1 is called
#define spicommon_periph_claim(host...) __spicommon_periph_claim(host, 2, 1)
#define __spicommon_periph_claim(host, source, n, ...) __spicommon_periph_claim ## n(host, source)
#define __spicommon_periph_claim1(host, _) ({ \
char* warning_str = "calling spicommon_periph_claim without source string is deprecated.";\
spicommon_periph_claim(host, __FUNCTION__); })
#define __spicommon_periph_claim2(host, func) spicommon_periph_claim(host, func)
/**
* @brief Check whether the spi periph is in use.
*
* @param host Peripheral to check.
*
* @return True if in use, otherwise false.
*/
bool spicommon_periph_in_use(spi_host_device_t host);
/**
* @brief Return the SPI peripheral so another driver can claim it.
@ -119,6 +142,15 @@ bool spicommon_periph_free(spi_host_device_t host);
*/
bool spicommon_dma_chan_claim(int dma_chan);
/**
* @brief Check whether the spi DMA channel is in use.
*
* @param dma_chan DMA channel to check.
*
* @return True if in use, otherwise false.
*/
bool spicommon_dma_chan_in_use(int dma_chan);
/**
* @brief Return the SPI DMA channel so other driver can claim it, or just to power down DMA.
*

View file

@ -52,19 +52,30 @@ typedef struct spi_device_t spi_device_t;
//Periph 1 is 'claimed' by SPI flash code.
static atomic_bool spi_periph_claimed[3] = { ATOMIC_VAR_INIT(true), ATOMIC_VAR_INIT(false), ATOMIC_VAR_INIT(false)};
static const char* spi_claiming_func[3] = {NULL, NULL, NULL};
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)
bool spicommon_periph_claim(spi_host_device_t host, const char* source)
{
bool false_var = false;
bool ret = atomic_compare_exchange_strong(&spi_periph_claimed[host], &false_var, true);
if (ret) periph_module_enable(spi_periph_signal[host].module);
if (ret) {
spi_claiming_func[host] = source;
periph_module_enable(spi_periph_signal[host].module);
} else {
ESP_EARLY_LOGE(SPI_TAG, "SPI%d already claimed by %s.", host+1, spi_claiming_func[host]);
}
return ret;
}
bool spicommon_periph_in_use(spi_host_device_t host)
{
return atomic_load(&spi_periph_claimed[host]);
}
//Returns true if this peripheral is successfully freed, false if otherwise.
bool spicommon_periph_free(spi_host_device_t host)
{
@ -102,6 +113,12 @@ bool spicommon_dma_chan_claim (int dma_chan)
return ret;
}
bool spicommon_dma_chan_in_use(int dma_chan)
{
assert(dma_chan==1 || dma_chan == 2);
return spi_dma_chan_enabled & DMA_CHANNEL_ENABLED(dma_chan);
}
bool spicommon_dma_chan_free(int dma_chan)
{
assert( dma_chan == 1 || dma_chan == 2 );
@ -190,7 +207,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
if (use_iomux) {
//All SPI iomux pin selections resolve to 1, so we put that here instead of trying to figure
//out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host );
ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host+1);
if (bus_config->mosi_io_num >= 0) {
gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in);
gpio_iomux_out(bus_config->mosi_io_num, FUNC_SPI, false);
@ -214,7 +231,7 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
} else {
//Use GPIO matrix
ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host );
ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host+1);
if (bus_config->mosi_io_num >= 0) {
if (mosi_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT);

View file

@ -234,7 +234,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host, const spi_bus_config_t *bus
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 );
spi_chan_claimed=spicommon_periph_claim(host);
spi_chan_claimed=spicommon_periph_claim(host, "spi master");
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
if ( dma_chan != 0 ) {
@ -498,7 +498,7 @@ Specify ``SPI_DEVICE_NO_DUMMY`` to ignore this checking. Then you can output dat
spihost[host]->hw->ctrl2.mosi_delay_mode = 0;
spihost[host]->hw->ctrl2.mosi_delay_num = 0;
*handle=dev;
ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %dkHz", host, freecs, dev->clk_cfg.eff_clk/1000);
ESP_LOGD(SPI_TAG, "SPI%d: New device added to CS%d, effective clock: %dkHz", host+1, freecs, dev->clk_cfg.eff_clk/1000);
return ESP_OK;
nomem:

View file

@ -110,7 +110,7 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
SPI_CHECK(VALID_HOST(host), "invalid host", ESP_ERR_INVALID_ARG);
SPI_CHECK( dma_chan >= 0 && dma_chan <= 2, "invalid dma channel", ESP_ERR_INVALID_ARG );
spi_chan_claimed=spicommon_periph_claim(host);
spi_chan_claimed=spicommon_periph_claim(host, "spi slave");
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
if ( dma_chan != 0 ) {

View file

@ -626,7 +626,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
Application code should never touch VSPI hardware in this case. We try to stop applications
from doing this using the drivers by claiming the port for ourselves */
periph_module_enable(PERIPH_VSPI_MODULE);
bool r=spicommon_periph_claim(VSPI_HOST);
bool r=spicommon_periph_claim(VSPI_HOST, "psram");
if (!r) {
return ESP_ERR_INVALID_STATE;
}