From 1c932112aaf4e3d587e30288898ade035dda5a06 Mon Sep 17 00:00:00 2001 From: Jan Prochazka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 16 Jan 2024 14:46:24 +0100 Subject: [PATCH 1/5] feature(spi): Allow detach of some SPI pins --- cores/esp32/esp32-hal-spi.c | 141 ++++++++++++++++++++++++------------ cores/esp32/esp32-hal-spi.h | 8 +- libraries/SPI/src/SPI.cpp | 12 +-- 3 files changed, 106 insertions(+), 55 deletions(-) diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index 4388d0d60c9..bc256fb6adf 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -177,36 +177,73 @@ static spi_t _spi_bus_array[] = { static bool spiDetachBus(void * bus){ uint8_t spi_num = (int)bus - 1; spi_t * spi = &_spi_bus_array[spi_num]; - if(spi->dev->clock.val != 0){ - log_d("Stopping SPI BUS"); + + if(spi->dev->clock.val == 0){ + log_d("SPI bus already stopped"); + return true; + } + else if(spi->sck == -1 || (spi->miso == -1 && spi->mosi == -1)){ + log_d("Stopping SPI bus"); spiStopBus(spi); + + if(spi->sck != -1){ + spiDetachSCK(spi); + } + if(spi->miso != -1){ + spiDetachMISO(spi); + } + if(spi->mosi != -1){ + spiDetachMOSI(spi); + } + if(spi->ss != -1){ + spiDetachSS(spi); + } + spi = NULL; + return true; } + return true; +} + +static bool spiDetachBus_SCK(void * bus){ + uint8_t spi_num = (int)bus - 1; + spi_t * spi = &_spi_bus_array[spi_num]; if(spi->sck != -1){ - log_d("SPI detach SCK pin %d",spi->sck); - spiDetachSCK(spi,spi->sck); + spiDetachSCK(spi); + spiDetachBus(bus); } + return true; +} + +static bool spiDetachBus_MISO(void * bus){ + uint8_t spi_num = (int)bus - 1; + spi_t * spi = &_spi_bus_array[spi_num]; if(spi->miso != -1){ - log_d("SPI detach MISO pin %d",spi->miso); - spiDetachMISO(spi,spi->miso); + spiDetachMISO(spi); + spiDetachBus(bus); } + return true; +} + +static bool spiDetachBus_MOSI(void * bus){ + uint8_t spi_num = (int)bus - 1; + spi_t * spi = &_spi_bus_array[spi_num]; if(spi->mosi != -1){ - log_d("SPI detach MOSI pin %d",spi->mosi); - spiDetachMOSI(spi,spi->mosi); + spiDetachMOSI(spi); + spiDetachBus(bus); } + return true; +} + +static bool spiDetachBus_SS(void * bus){ + uint8_t spi_num = (int)bus - 1; + spi_t * spi = &_spi_bus_array[spi_num]; if(spi->ss != -1){ - log_d("SPI detach SS pin %d",spi->ss); - spiDetachSS(spi,spi->ss); - } - //set SPI to NULL, as all pins are already detached - if(spi->sck == -1 && spi->miso == -1 && spi->mosi == -1 && spi->ss == -1){ - log_d("Set spi handle to NULL"); - spi = NULL; - return true; + spiDetachSS(spi); + spiDetachBus(bus); } - return false; + return true; } - bool spiAttachSCK(spi_t * spi, int8_t sck) { if(!spi || sck < 0) { @@ -220,7 +257,7 @@ bool spiAttachSCK(spi_t * spi, int8_t sck) pinMatrixOutAttach(sck, SPI_CLK_IDX(spi->num), false, false); spi->sck = sck; if(!perimanSetPinBus(sck, ESP32_BUS_TYPE_SPI_MASTER_SCK, (void *)(spi->num+1), spi->num, -1)){ - spiDetachBus((void *)(spi->num+1)); + spiDetachBus_SCK((void *)(spi->num+1)); log_e("Failed to set pin bus to SPI for pin %d", sck); return false; } @@ -242,7 +279,7 @@ bool spiAttachMISO(spi_t * spi, int8_t miso) spi->miso = miso; SPI_MUTEX_UNLOCK(); if(!perimanSetPinBus(miso, ESP32_BUS_TYPE_SPI_MASTER_MISO, (void *)(spi->num+1), spi->num, -1)){ - spiDetachBus((void *)(spi->num+1)); + spiDetachBus_MISO((void *)(spi->num+1)); log_e("Failed to set pin bus to SPI for pin %d", miso); return false; } @@ -262,43 +299,52 @@ bool spiAttachMOSI(spi_t * spi, int8_t mosi) pinMatrixOutAttach(mosi, SPI_MOSI_IDX(spi->num), false, false); spi->mosi = mosi; if(!perimanSetPinBus(mosi, ESP32_BUS_TYPE_SPI_MASTER_MOSI, (void *)(spi->num+1), spi->num, -1)){ - spiDetachBus((void *)(spi->num+1)); + spiDetachBus_MOSI((void *)(spi->num+1)); log_e("Failed to set pin bus to SPI for pin %d", mosi); return false; } return true; } -bool spiDetachSCK(spi_t * spi, int8_t sck) +bool spiDetachSCK(spi_t * spi) { - if(!spi || sck < 0) { + if(!spi) { return false; } - pinMatrixOutDetach(sck, false, false); - spi->sck = -1; - perimanClearPinBus(sck); + int8_t sck = spi->sck; + if(sck != -1) { + pinMatrixOutDetach(sck, false, false); + spi->sck = -1; + perimanClearPinBus(sck); + } return true; } -bool spiDetachMISO(spi_t * spi, int8_t miso) +bool spiDetachMISO(spi_t * spi) { - if(!spi || miso < 0) { + if(!spi) { return false; } - pinMatrixInDetach(SPI_MISO_IDX(spi->num), false, false); - spi->miso = -1; - perimanClearPinBus(miso); + int8_t miso = spi->miso; + if(miso != -1) { + pinMatrixInDetach(SPI_MISO_IDX(spi->num), false, false); + spi->miso = -1; + perimanClearPinBus(miso); + } return true; } -bool spiDetachMOSI(spi_t * spi, int8_t mosi) +bool spiDetachMOSI(spi_t * spi) { - if(!spi || mosi < 0) { + if(!spi) { return false; } - pinMatrixOutDetach(mosi, false, false); - spi->mosi = -1; - perimanClearPinBus(mosi); + int8_t mosi = spi->mosi; + if(mosi != -1) { + pinMatrixOutDetach(mosi, false, false); + spi->mosi = -1; + perimanClearPinBus(mosi); + } return true; } @@ -316,21 +362,24 @@ bool spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss) spiEnableSSPins(spi, (1 << cs_num)); spi->ss = ss; if(!perimanSetPinBus(ss, ESP32_BUS_TYPE_SPI_MASTER_CS, (void *)(spi->num+1), spi->num, -1)){ - spiDetachBus((void *)(spi->num+1)); + spiDetachBus_SS((void *)(spi->num+1)); log_e("Failed to set pin bus to SPI for pin %d", ss); return false; } return true; } -bool spiDetachSS(spi_t * spi, int8_t ss) +bool spiDetachSS(spi_t * spi) { - if(!spi || ss < 0) { + if(!spi) { return false; } - pinMatrixOutDetach(ss, false, false); - spi->ss = -1; - perimanClearPinBus(ss); + int8_t ss = spi->ss; + if(ss != -1) { + pinMatrixOutDetach(ss, false, false); + spi->ss = -1; + perimanClearPinBus(ss); + } return true; } @@ -578,10 +627,10 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ return NULL; } - perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_SCK, spiDetachBus); - perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_MISO, spiDetachBus); - perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_MOSI, spiDetachBus); - perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_CS, spiDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_SCK, spiDetachBus_SCK); + perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_MISO, spiDetachBus_MISO); + perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_MOSI, spiDetachBus_MOSI); + perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_CS, spiDetachBus_SS); spi_t * spi = &_spi_bus_array[spi_num]; diff --git a/cores/esp32/esp32-hal-spi.h b/cores/esp32/esp32-hal-spi.h index 63ab88bcd33..ef7cfc5425a 100644 --- a/cores/esp32/esp32-hal-spi.h +++ b/cores/esp32/esp32-hal-spi.h @@ -72,13 +72,13 @@ void spiStopBus(spi_t * spi); bool spiAttachSCK(spi_t * spi, int8_t sck); bool spiAttachMISO(spi_t * spi, int8_t miso); bool spiAttachMOSI(spi_t * spi, int8_t mosi); -bool spiDetachSCK(spi_t * spi, int8_t sck); -bool spiDetachMISO(spi_t * spi, int8_t miso); -bool spiDetachMOSI(spi_t * spi, int8_t mosi); +bool spiDetachSCK(spi_t * spi); +bool spiDetachMISO(spi_t * spi); +bool spiDetachMOSI(spi_t * spi); //Attach/Detach SS pin to SPI_CSx signal bool spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss); -bool spiDetachSS(spi_t * spi, int8_t ss); +bool spiDetachSS(spi_t * spi); //Enable/Disable SPI_CSx pins void spiEnableSSPins(spi_t * spi, uint8_t cs_mask); diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index 251cc48c4fe..a87b9f8dbe3 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -124,15 +124,17 @@ void SPIClass::end() if(!_spi) { return; } - spiDetachSCK(_spi, _sck); + spiDetachSCK(_spi); if(_miso >= 0){ - spiDetachMISO(_spi, _miso); + spiDetachMISO(_spi); } if(_mosi >= 0){ - spiDetachMOSI(_spi, _mosi); + spiDetachMOSI(_spi); } setHwCs(false); - spiStopBus(_spi); + if(spiGetClockDiv(_spi) != 0) { + spiStopBus(_spi); + } _spi = NULL; } @@ -146,7 +148,7 @@ void SPIClass::setHwCs(bool use) spiSSEnable(_spi); } else if(!use && _use_hw_ss) { spiSSDisable(_spi); - spiDetachSS(_spi, _ss); + spiDetachSS(_spi); } _use_hw_ss = use; } From cb86fb3ccf093de6ba5a4824f5be9e4c4ad1d504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:11:07 +0100 Subject: [PATCH 2/5] fix(spi): Remove unnecessary check Co-authored-by: Lucas Saavedra Vaz <32426024+lucasssvaz@users.noreply.github.com> --- cores/esp32/esp32-hal-spi.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index bc256fb6adf..ebba64f0c2c 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -186,18 +186,10 @@ static bool spiDetachBus(void * bus){ log_d("Stopping SPI bus"); spiStopBus(spi); - if(spi->sck != -1){ - spiDetachSCK(spi); - } - if(spi->miso != -1){ - spiDetachMISO(spi); - } - if(spi->mosi != -1){ - spiDetachMOSI(spi); - } - if(spi->ss != -1){ - spiDetachSS(spi); - } + spiDetachSCK(spi); + spiDetachMISO(spi); + spiDetachMOSI(spi); + spiDetachSS(spi); spi = NULL; return true; } From 21b7a4197ba184c6c1968b5ccd9579e9a0bb6107 Mon Sep 17 00:00:00 2001 From: Jan Prochazka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:46:53 +0100 Subject: [PATCH 3/5] feat(spi): Rename CS pin to SS to match Arduino standard --- cores/esp32/esp32-hal-periman.c | 2 +- cores/esp32/esp32-hal-periman.h | 2 +- cores/esp32/esp32-hal-spi.c | 26 +++++++++++++------------- cores/esp32/esp32-hal-spi.h | 24 ++++++++++++------------ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c index 5c9c3ceccbd..dd3a2f32a21 100644 --- a/cores/esp32/esp32-hal-periman.c +++ b/cores/esp32/esp32-hal-periman.c @@ -78,7 +78,7 @@ const char* perimanGetTypeName(peripheral_bus_type_t type) { case ESP32_BUS_TYPE_SPI_MASTER_SCK: return "SPI_MASTER_SCK"; case ESP32_BUS_TYPE_SPI_MASTER_MISO: return "SPI_MASTER_MISO"; case ESP32_BUS_TYPE_SPI_MASTER_MOSI: return "SPI_MASTER_MOSI"; - case ESP32_BUS_TYPE_SPI_MASTER_CS: return "SPI_MASTER_CS"; + case ESP32_BUS_TYPE_SPI_MASTER_SS: return "SPI_MASTER_SS"; #endif #if SOC_SDMMC_HOST_SUPPORTED case ESP32_BUS_TYPE_SDMMC_CLK: return "SDMMC_CLK"; diff --git a/cores/esp32/esp32-hal-periman.h b/cores/esp32/esp32-hal-periman.h index 42833b4bab1..aa3de699502 100644 --- a/cores/esp32/esp32-hal-periman.h +++ b/cores/esp32/esp32-hal-periman.h @@ -77,7 +77,7 @@ typedef enum { ESP32_BUS_TYPE_SPI_MASTER_SCK, // IO is used as SPI master SCK pin ESP32_BUS_TYPE_SPI_MASTER_MISO, // IO is used as SPI master MISO pin ESP32_BUS_TYPE_SPI_MASTER_MOSI, // IO is used as SPI master MOSI pin - ESP32_BUS_TYPE_SPI_MASTER_CS, // IO is used as SPI master CS pin + ESP32_BUS_TYPE_SPI_MASTER_SS, // IO is used as SPI master SS pin #endif #if SOC_SDMMC_HOST_SUPPORTED ESP32_BUS_TYPE_SDMMC_CLK, // IO is used as SDMMC CLK pin diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index ebba64f0c2c..225bdf38ebe 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -340,20 +340,20 @@ bool spiDetachMOSI(spi_t * spi) return true; } -bool spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss) +bool spiAttachSS(spi_t * spi, uint8_t ss_num, int8_t ss) { - if(!spi || ss < 0 || cs_num > 2) { + if(!spi || ss < 0 || ss_num > 2) { return false; } - void * bus = perimanGetPinBus(ss, ESP32_BUS_TYPE_SPI_MASTER_CS); + void * bus = perimanGetPinBus(ss, ESP32_BUS_TYPE_SPI_MASTER_SS); if(bus != NULL && !perimanClearPinBus(ss)){ return false; } pinMode(ss, OUTPUT); - pinMatrixOutAttach(ss, SPI_SS_IDX(spi->num, cs_num), false, false); - spiEnableSSPins(spi, (1 << cs_num)); + pinMatrixOutAttach(ss, SPI_SS_IDX(spi->num, ss_num), false, false); + spiEnableSSPins(spi, (1 << ss_num)); spi->ss = ss; - if(!perimanSetPinBus(ss, ESP32_BUS_TYPE_SPI_MASTER_CS, (void *)(spi->num+1), spi->num, -1)){ + if(!perimanSetPinBus(ss, ESP32_BUS_TYPE_SPI_MASTER_SS, (void *)(spi->num+1), spi->num, -1)){ spiDetachBus_SS((void *)(spi->num+1)); log_e("Failed to set pin bus to SPI for pin %d", ss); return false; @@ -375,30 +375,30 @@ bool spiDetachSS(spi_t * spi) return true; } -void spiEnableSSPins(spi_t * spi, uint8_t cs_mask) +void spiEnableSSPins(spi_t * spi, uint8_t ss_mask) { if(!spi) { return; } SPI_MUTEX_LOCK(); #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 - spi->dev->misc.val &= ~(cs_mask & SPI_CS_MASK_ALL); + spi->dev->misc.val &= ~(ss_mask & SPI_SS_MASK_ALL); #else - spi->dev->pin.val &= ~(cs_mask & SPI_CS_MASK_ALL); + spi->dev->pin.val &= ~(ss_mask & SPI_SS_MASK_ALL); #endif SPI_MUTEX_UNLOCK(); } -void spiDisableSSPins(spi_t * spi, uint8_t cs_mask) +void spiDisableSSPins(spi_t * spi, uint8_t ss_mask) { if(!spi) { return; } SPI_MUTEX_LOCK(); #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 - spi->dev->misc.val |= (cs_mask & SPI_CS_MASK_ALL); + spi->dev->misc.val |= (ss_mask & SPI_SS_MASK_ALL); #else - spi->dev->pin.val |= (cs_mask & SPI_CS_MASK_ALL); + spi->dev->pin.val |= (ss_mask & SPI_SS_MASK_ALL); #endif SPI_MUTEX_UNLOCK(); } @@ -622,7 +622,7 @@ spi_t * spiStartBus(uint8_t spi_num, uint32_t clockDiv, uint8_t dataMode, uint8_ perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_SCK, spiDetachBus_SCK); perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_MISO, spiDetachBus_MISO); perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_MOSI, spiDetachBus_MOSI); - perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_CS, spiDetachBus_SS); + perimanSetBusDeinit(ESP32_BUS_TYPE_SPI_MASTER_SS, spiDetachBus_SS); spi_t * spi = &_spi_bus_array[spi_num]; diff --git a/cores/esp32/esp32-hal-spi.h b/cores/esp32/esp32-hal-spi.h index ef7cfc5425a..2c0a6329dc9 100644 --- a/cores/esp32/esp32-hal-spi.h +++ b/cores/esp32/esp32-hal-spi.h @@ -54,10 +54,10 @@ extern "C" { #define SPI_MODE2 2 #define SPI_MODE3 3 -#define SPI_CS0 0 -#define SPI_CS1 1 -#define SPI_CS2 2 -#define SPI_CS_MASK_ALL 0x7 +#define SPI_SS0 0 +#define SPI_SS1 1 +#define SPI_SS2 2 +#define SPI_SS_MASK_ALL 0x7 #define SPI_LSBFIRST 0 #define SPI_MSBFIRST 1 @@ -76,21 +76,21 @@ bool spiDetachSCK(spi_t * spi); bool spiDetachMISO(spi_t * spi); bool spiDetachMOSI(spi_t * spi); -//Attach/Detach SS pin to SPI_CSx signal -bool spiAttachSS(spi_t * spi, uint8_t cs_num, int8_t ss); +//Attach/Detach SS pin to SPI_SSx signal +bool spiAttachSS(spi_t * spi, uint8_t ss_num, int8_t ss); bool spiDetachSS(spi_t * spi); -//Enable/Disable SPI_CSx pins -void spiEnableSSPins(spi_t * spi, uint8_t cs_mask); -void spiDisableSSPins(spi_t * spi, uint8_t cs_mask); +//Enable/Disable SPI_SSx pins +void spiEnableSSPins(spi_t * spi, uint8_t ss_mask); +void spiDisableSSPins(spi_t * spi, uint8_t ss_mask); -//Enable/Disable hardware control of SPI_CSx pins +//Enable/Disable hardware control of SPI_SSx pins void spiSSEnable(spi_t * spi); void spiSSDisable(spi_t * spi); -//Activate enabled SPI_CSx pins +//Activate enabled SPI_SSx pins void spiSSSet(spi_t * spi); -//Deactivate enabled SPI_CSx pins +//Deactivate enabled SPI_SSx pins void spiSSClear(spi_t * spi); void spiWaitReady(spi_t * spi); From 81995a913e4a2ef01e6e52221e2a41ede960e5b6 Mon Sep 17 00:00:00 2001 From: Jan Prochazka <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Thu, 18 Jan 2024 13:49:00 +0100 Subject: [PATCH 4/5] fix(spi): Remove unnecessary checks --- libraries/SPI/src/SPI.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libraries/SPI/src/SPI.cpp b/libraries/SPI/src/SPI.cpp index a87b9f8dbe3..17142b38c60 100644 --- a/libraries/SPI/src/SPI.cpp +++ b/libraries/SPI/src/SPI.cpp @@ -125,12 +125,8 @@ void SPIClass::end() return; } spiDetachSCK(_spi); - if(_miso >= 0){ - spiDetachMISO(_spi); - } - if(_mosi >= 0){ - spiDetachMOSI(_spi); - } + spiDetachMISO(_spi); + spiDetachMOSI(_spi); setHwCs(false); if(spiGetClockDiv(_spi) != 0) { spiStopBus(_spi); From 5385a50515023dfc2155ad40099cd1a0b69cd825 Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 18 Jan 2024 16:47:03 +0200 Subject: [PATCH 5/5] remove lock from spiAttackMISO --- cores/esp32/esp32-hal-spi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/cores/esp32/esp32-hal-spi.c b/cores/esp32/esp32-hal-spi.c index 225bdf38ebe..26cb5c873ee 100644 --- a/cores/esp32/esp32-hal-spi.c +++ b/cores/esp32/esp32-hal-spi.c @@ -265,11 +265,9 @@ bool spiAttachMISO(spi_t * spi, int8_t miso) if(bus != NULL && !perimanClearPinBus(miso)){ return false; } - SPI_MUTEX_LOCK(); pinMode(miso, INPUT); pinMatrixInAttach(miso, SPI_MISO_IDX(spi->num), false); spi->miso = miso; - SPI_MUTEX_UNLOCK(); if(!perimanSetPinBus(miso, ESP32_BUS_TYPE_SPI_MASTER_MISO, (void *)(spi->num+1), spi->num, -1)){ spiDetachBus_MISO((void *)(spi->num+1)); log_e("Failed to set pin bus to SPI for pin %d", miso);