From 9b5d0f33222b0f61ed6f2a729902a148a6e040e2 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Fri, 5 Oct 2018 15:39:32 +0800 Subject: [PATCH] spi: shown owner of spi host explicitly --- components/driver/include/driver/spi_common.h | 34 ++++++++++++++++++- components/driver/spi_common.c | 25 +++++++++++--- components/driver/spi_master.c | 4 +-- components/driver/spi_slave.c | 2 +- components/esp32/spiram_psram.c | 2 +- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/components/driver/include/driver/spi_common.h b/components/driver/include/driver/spi_common.h index 1dae920a5..b2a6c082e 100644 --- a/components/driver/include/driver/spi_common.h +++ b/components/driver/include/driver/spi_common.h @@ -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. * diff --git a/components/driver/spi_common.c b/components/driver/spi_common.c index fbaabaa73..675ad5ca9 100644 --- a/components/driver/spi_common.c +++ b/components/driver/spi_common.c @@ -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); diff --git a/components/driver/spi_master.c b/components/driver/spi_master.c index 95eaa60a7..a29182592 100644 --- a/components/driver/spi_master.c +++ b/components/driver/spi_master.c @@ -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: diff --git a/components/driver/spi_slave.c b/components/driver/spi_slave.c index 5d3026dc6..ddc7ac273 100644 --- a/components/driver/spi_slave.c +++ b/components/driver/spi_slave.c @@ -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 ) { diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index 3a1b7fb27..047fec503 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -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; }