Skip to content

SPI - Allow detaching of some SPI pins without stopping SPI #9117

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 95 additions & 46 deletions cores/esp32/esp32-hal-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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];

Expand Down
8 changes: 4 additions & 4 deletions cores/esp32/esp32-hal-spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
12 changes: 7 additions & 5 deletions libraries/SPI/src/SPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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;
}
Expand Down