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. * Call this if your driver wants to manage a SPI peripheral.
* *
* @param host Peripheral to claim * @param host Peripheral to claim
* @param source The caller indentification string.
*
* @return True if peripheral is claimed successfully; false if peripheral already is claimed. * @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. * @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); 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. * @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. //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 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 uint8_t spi_dma_chan_enabled = 0;
static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED; static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
//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, const char* source)
{ {
bool false_var = false; bool false_var = false;
bool ret = atomic_compare_exchange_strong(&spi_periph_claimed[host], &false_var, true); 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; 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. //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)
{ {
@ -102,6 +113,12 @@ bool spicommon_dma_chan_claim (int dma_chan)
return ret; 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) bool spicommon_dma_chan_free(int dma_chan)
{ {
assert( dma_chan == 1 || dma_chan == 2 ); 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) { if (use_iomux) {
//All SPI iomux pin selections resolve to 1, so we put that here instead of trying to figure //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. //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) { if (bus_config->mosi_io_num >= 0) {
gpio_iomux_in(bus_config->mosi_io_num, spi_periph_signal[host].spid_in); 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); 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; temp_flag |= SPICOMMON_BUSFLAG_NATIVE_PINS;
} else { } else {
//Use GPIO matrix //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 (bus_config->mosi_io_num >= 0) {
if (mosi_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) { if (mosi_output || (temp_flag&SPICOMMON_BUSFLAG_DUAL)) {
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT); 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(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_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); SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
if ( dma_chan != 0 ) { 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_mode = 0;
spihost[host]->hw->ctrl2.mosi_delay_num = 0; spihost[host]->hw->ctrl2.mosi_delay_num = 0;
*handle=dev; *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; return ESP_OK;
nomem: 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(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_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); SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
if ( dma_chan != 0 ) { 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 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 */ from doing this using the drivers by claiming the port for ourselves */
periph_module_enable(PERIPH_VSPI_MODULE); periph_module_enable(PERIPH_VSPI_MODULE);
bool r=spicommon_periph_claim(VSPI_HOST); bool r=spicommon_periph_claim(VSPI_HOST, "psram");
if (!r) { if (!r) {
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
} }