Skip to content
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

Allow for inverted SPI CS logic #23699

Merged
merged 6 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
use struct for extended function
  • Loading branch information
daskygit committed Sep 9, 2024
commit 3d206c57530dbe3b363b6c3faa2c88e4bead8d2b
22 changes: 14 additions & 8 deletions platforms/avr/drivers/spi_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,27 @@ void spi_init(void) {
}

bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
return spi_start_extended(slavePin, lsbFirst, mode, divisor, true);
spi_start_config_t start_config = {0};
start_config.slavePin = slavePin;
start_config.lsbFirst = lsbFirst;
start_config.mode = mode;
start_config.divisor = divisor;
start_config.cs_active_low = true;
return spi_start_extended(&start_config);
}

bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor, bool cs_active_low) {
if (currentSlavePin != NO_PIN || slavePin == NO_PIN) {
bool spi_start_extended(spi_start_config_t *start_config) {
if (currentSlavePin != NO_PIN || start_config->slavePin == NO_PIN) {
return false;
}

currentSlaveConfig = 0;

if (lsbFirst) {
if (start_config->lsbFirst) {
currentSlaveConfig |= _BV(DORD);
}

switch (mode) {
switch (start_config->mode) {
case 1:
currentSlaveConfig |= _BV(CPHA);
break;
Expand All @@ -86,7 +92,7 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
}

uint16_t roundedDivisor = 1;
while (roundedDivisor < divisor) {
while (roundedDivisor < start_config->divisor) {
roundedDivisor <<= 1;
}

Expand Down Expand Up @@ -117,8 +123,8 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
if (currentSlave2X) {
SPSR |= _BV(SPI2X);
}
currentSlavePin = slavePin;
current_cs_active_low = cs_active_low;
currentSlavePin = start_config->slavePin;
current_cs_active_low = start_config->cs_active_low;
gpio_set_pin_output(currentSlavePin);
spi_select();

Expand Down
10 changes: 9 additions & 1 deletion platforms/avr/drivers/spi_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,18 @@ typedef int16_t spi_status_t;
#ifdef __cplusplus
extern "C" {
#endif
typedef struct spi_start_config_t {
pin_t slavePin;
bool lsbFirst;
uint8_t mode;
uint16_t divisor;
bool cs_active_low;
} spi_start_config_t;

void spi_init(void);

bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor, bool cs_active_low);
bool spi_start_extended(spi_start_config_t *start_config);

spi_status_t spi_write(uint8_t data);

Expand Down
56 changes: 31 additions & 25 deletions platforms/chibios/drivers/spi_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ __attribute__((weak)) void spi_init(void) {
}
}

bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor, bool cs_active_low) {
bool spi_start_extended(spi_start_config_t *start_config) {
#if (SPI_USE_MUTUAL_EXCLUSION == TRUE)
spiAcquireBus(&SPI_DRIVER);
#endif // (SPI_USE_MUTUAL_EXCLUSION == TRUE)
Expand All @@ -92,14 +92,14 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
return false;
}
#if SPI_SELECT_MODE != SPI_SELECT_MODE_NONE
if (slavePin == NO_PIN) {
if (start_config->slavePin == NO_PIN) {
return false;
}
#endif

#if !(defined(WB32F3G71xx) || defined(WB32FQ95xx))
uint16_t roundedDivisor = 2;
while (roundedDivisor < divisor) {
while (roundedDivisor < start_config->divisor) {
roundedDivisor <<= 1;
}

Expand All @@ -111,11 +111,11 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
#if defined(K20x) || defined(KL2x)
spiConfig.tar0 = SPIx_CTARn_FMSZ(7) | SPIx_CTARn_ASC(1);

if (lsbFirst) {
if (start_config->lsbFirst) {
spiConfig.tar0 |= SPIx_CTARn_LSBFE;
}

switch (mode) {
switch (start_config->mode) {
case 0:
break;
case 1:
Expand Down Expand Up @@ -160,11 +160,11 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
spiConfig.cr0 = SPI_CR0_SELOEN;
spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode

if (lsbFirst) {
if (start_config->lsbFirst) {
spiConfig.cr1 |= SPI_CR1_FIRSTBIT;
}

switch (mode) {
switch (start_config->mode) {
case 0:
spiConfig.cr1 |= SPI_CR1_FORMAT_MODE0;
break;
Expand All @@ -182,17 +182,17 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
spiConfig.cpr = (roundedDivisor - 1) >> 1;

#elif defined(WB32F3G71xx) || defined(WB32FQ95xx)
if (!lsbFirst) {
osalDbgAssert(lsbFirst != FALSE, "unsupported lsbFirst");
if (!start_config->lsbFirst) {
osalDbgAssert(start_config->lsbFirst != FALSE, "unsupported lsbFirst");
}

if (divisor < 1) {
if (start_config->divisor < 1) {
return false;
}

spiConfig.SPI_BaudRatePrescaler = (divisor << 2);
spiConfig.SPI_BaudRatePrescaler = (start_config->divisor << 2);

switch (mode) {
switch (start_config->mode) {
case 0:
spiConfig.SPI_CPHA = SPI_CPHA_1Edge;
spiConfig.SPI_CPOL = SPI_CPOL_Low;
Expand All @@ -211,8 +211,8 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
break;
}
#elif defined(MCU_RP)
if (lsbFirst) {
osalDbgAssert(lsbFirst == false, "RP2040s PrimeCell SPI implementation does not support sending LSB first.");
if (start_config->lsbFirst) {
osalDbgAssert(start_config->lsbFirst == false, "RP2040s PrimeCell SPI implementation does not support sending LSB first.");
}

// Motorola frame format and 8bit transfer data size.
Expand All @@ -222,7 +222,7 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
// passed divisor to be the only value to divide the input clock by.
spiConfig.SSPCPSR = roundedDivisor; // Even number from 2 to 254

switch (mode) {
switch (start_config->mode) {
case 0:
spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPO; // Clock polarity: low
spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPH; // Clock phase: sample on first edge
Expand All @@ -243,11 +243,11 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
#else
spiConfig.cr1 = 0;

if (lsbFirst) {
if (start_config->lsbFirst) {
spiConfig.cr1 |= SPI_CR1_LSBFIRST;
}

switch (mode) {
switch (start_config->mode) {
case 0:
break;
case 1:
Expand Down Expand Up @@ -290,16 +290,16 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di

spiStarted = true;
#if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
currentSlavePin = slavePin;
current_cs_active_low = cs_active_low;
currentSlavePin = start_config->slavePin;
current_cs_active_low = start_config->cs_active_low;
#endif
#if SPI_SELECT_MODE == SPI_SELECT_MODE_PAD
spiConfig.ssport = PAL_PORT(slavePin);
spiConfig.sspad = PAL_PAD(slavePin);
gpio_set_pin_output(slavePin);
spiConfig.ssport = PAL_PORT(start_config->slavePin);
spiConfig.sspad = PAL_PAD(start_config->slavePin);
gpio_set_pin_output(start_config->slavePin);
#elif SPI_SELECT_MODE == SPI_SELECT_MODE_NONE
if (slavePin != NO_PIN) {
gpio_set_pin_output(slavePin);
if (start_config->slavePin != NO_PIN) {
gpio_set_pin_output(start_config->slavePin);
}
#else
# error "Unsupported SPI_SELECT_MODE"
Expand All @@ -312,7 +312,13 @@ bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t di
}

bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
return spi_start_extended(slavePin, lsbFirst, mode, divisor, true);
spi_start_config_t start_config = {0};
start_config.slavePin = slavePin;
start_config.lsbFirst = lsbFirst;
start_config.mode = mode;
start_config.divisor = divisor;
start_config.cs_active_low = true;
return spi_start_extended(&start_config);
}

spi_status_t spi_write(uint8_t data) {
Expand Down
10 changes: 9 additions & 1 deletion platforms/chibios/drivers/spi_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,18 @@ typedef int16_t spi_status_t;
#ifdef __cplusplus
extern "C" {
#endif
typedef struct spi_start_config_t {
pin_t slavePin;
bool lsbFirst;
uint8_t mode;
uint16_t divisor;
bool cs_active_low;
} spi_start_config_t;

void spi_init(void);

bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
bool spi_start_extended(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor, bool cs_active_low);
bool spi_start_extended(spi_start_config_t *start_config);

spi_status_t spi_write(uint8_t data);

Expand Down