diff options
| author | Dasky <32983009+daskygit@users.noreply.github.com> | 2024-09-09 23:44:35 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-10 08:44:35 +1000 |
| commit | 2c7bf34d09247c2f306f0068e34a2a3a4f3f58e1 (patch) | |
| tree | 63052adc2c43f2e676bed9dc4957f961f3cb4eff | |
| parent | 3aaa086ac8a50ed7fc501c2dc93c1d195b63dcc3 (diff) | |
Allow for inverted SPI CS logic (#23699)
| -rw-r--r-- | platforms/avr/drivers/spi_master.c | 84 | ||||
| -rw-r--r-- | platforms/avr/drivers/spi_master.h | 9 | ||||
| -rw-r--r-- | platforms/chibios/drivers/spi_master.c | 96 | ||||
| -rw-r--r-- | platforms/chibios/drivers/spi_master.h | 9 |
4 files changed, 128 insertions, 70 deletions
diff --git a/platforms/avr/drivers/spi_master.c b/platforms/avr/drivers/spi_master.c index 74b847c71a..ba7d782ab0 100644 --- a/platforms/avr/drivers/spi_master.c +++ b/platforms/avr/drivers/spi_master.c | |||
| @@ -36,9 +36,18 @@ | |||
| 36 | # define SPI_TIMEOUT 100 | 36 | # define SPI_TIMEOUT 100 |
| 37 | #endif | 37 | #endif |
| 38 | 38 | ||
| 39 | static pin_t currentSlavePin = NO_PIN; | 39 | static pin_t current_slave_pin = NO_PIN; |
| 40 | static uint8_t currentSlaveConfig = 0; | 40 | static bool current_cs_active_low = true; |
| 41 | static bool currentSlave2X = false; | 41 | static uint8_t current_slave_config = 0; |
| 42 | static bool current_slave_2x = false; | ||
| 43 | |||
| 44 | static inline void spi_select(void) { | ||
| 45 | gpio_write_pin(current_slave_pin, current_cs_active_low ? 0 : 1); | ||
| 46 | } | ||
| 47 | |||
| 48 | static inline void spi_unselect(void) { | ||
| 49 | gpio_write_pin(current_slave_pin, current_cs_active_low ? 1 : 0); | ||
| 50 | } | ||
| 42 | 51 | ||
| 43 | void spi_init(void) { | 52 | void spi_init(void) { |
| 44 | gpio_write_pin_high(SPI_SS_PIN); | 53 | gpio_write_pin_high(SPI_SS_PIN); |
| @@ -50,63 +59,74 @@ void spi_init(void) { | |||
| 50 | } | 59 | } |
| 51 | 60 | ||
| 52 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | 61 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { |
| 53 | if (currentSlavePin != NO_PIN || slavePin == NO_PIN) { | 62 | spi_start_config_t start_config = {0}; |
| 63 | start_config.slave_pin = slavePin; | ||
| 64 | start_config.lsb_first = lsbFirst; | ||
| 65 | start_config.mode = mode; | ||
| 66 | start_config.divisor = divisor; | ||
| 67 | start_config.cs_active_low = true; | ||
| 68 | return spi_start_extended(&start_config); | ||
| 69 | } | ||
| 70 | |||
| 71 | bool spi_start_extended(spi_start_config_t *start_config) { | ||
| 72 | if (current_slave_pin != NO_PIN || start_config->slave_pin == NO_PIN) { | ||
| 54 | return false; | 73 | return false; |
| 55 | } | 74 | } |
| 56 | 75 | ||
| 57 | currentSlaveConfig = 0; | 76 | current_slave_config = 0; |
| 58 | 77 | ||
| 59 | if (lsbFirst) { | 78 | if (start_config->lsb_first) { |
| 60 | currentSlaveConfig |= _BV(DORD); | 79 | current_slave_config |= _BV(DORD); |
| 61 | } | 80 | } |
| 62 | 81 | ||
| 63 | switch (mode) { | 82 | switch (start_config->mode) { |
| 64 | case 1: | 83 | case 1: |
| 65 | currentSlaveConfig |= _BV(CPHA); | 84 | current_slave_config |= _BV(CPHA); |
| 66 | break; | 85 | break; |
| 67 | case 2: | 86 | case 2: |
| 68 | currentSlaveConfig |= _BV(CPOL); | 87 | current_slave_config |= _BV(CPOL); |
| 69 | break; | 88 | break; |
| 70 | case 3: | 89 | case 3: |
| 71 | currentSlaveConfig |= (_BV(CPOL) | _BV(CPHA)); | 90 | current_slave_config |= (_BV(CPOL) | _BV(CPHA)); |
| 72 | break; | 91 | break; |
| 73 | } | 92 | } |
| 74 | 93 | ||
| 75 | uint16_t roundedDivisor = 1; | 94 | uint16_t roundedDivisor = 1; |
| 76 | while (roundedDivisor < divisor) { | 95 | while (roundedDivisor < start_config->divisor) { |
| 77 | roundedDivisor <<= 1; | 96 | roundedDivisor <<= 1; |
| 78 | } | 97 | } |
| 79 | 98 | ||
| 80 | switch (roundedDivisor) { | 99 | switch (roundedDivisor) { |
| 81 | case 16: | 100 | case 16: |
| 82 | currentSlaveConfig |= _BV(SPR0); | 101 | current_slave_config |= _BV(SPR0); |
| 83 | break; | 102 | break; |
| 84 | case 64: | 103 | case 64: |
| 85 | currentSlaveConfig |= _BV(SPR1); | 104 | current_slave_config |= _BV(SPR1); |
| 86 | break; | 105 | break; |
| 87 | case 128: | 106 | case 128: |
| 88 | currentSlaveConfig |= (_BV(SPR1) | _BV(SPR0)); | 107 | current_slave_config |= (_BV(SPR1) | _BV(SPR0)); |
| 89 | break; | 108 | break; |
| 90 | case 2: | 109 | case 2: |
| 91 | currentSlave2X = true; | 110 | current_slave_2x = true; |
| 92 | break; | 111 | break; |
| 93 | case 8: | 112 | case 8: |
| 94 | currentSlave2X = true; | 113 | current_slave_2x = true; |
| 95 | currentSlaveConfig |= _BV(SPR0); | 114 | current_slave_config |= _BV(SPR0); |
| 96 | break; | 115 | break; |
| 97 | case 32: | 116 | case 32: |
| 98 | currentSlave2X = true; | 117 | current_slave_2x = true; |
| 99 | currentSlaveConfig |= _BV(SPR1); | 118 | current_slave_config |= _BV(SPR1); |
| 100 | break; | 119 | break; |
| 101 | } | 120 | } |
| 102 | 121 | ||
| 103 | SPCR |= currentSlaveConfig; | 122 | SPCR |= current_slave_config; |
| 104 | if (currentSlave2X) { | 123 | if (current_slave_2x) { |
| 105 | SPSR |= _BV(SPI2X); | 124 | SPSR |= _BV(SPI2X); |
| 106 | } | 125 | } |
| 107 | currentSlavePin = slavePin; | 126 | current_slave_pin = start_config->slave_pin; |
| 108 | gpio_set_pin_output(currentSlavePin); | 127 | current_cs_active_low = start_config->cs_active_low; |
| 109 | gpio_write_pin_low(currentSlavePin); | 128 | gpio_set_pin_output(current_slave_pin); |
| 129 | spi_select(); | ||
| 110 | 130 | ||
| 111 | return true; | 131 | return true; |
| 112 | } | 132 | } |
| @@ -168,13 +188,13 @@ spi_status_t spi_receive(uint8_t *data, uint16_t length) { | |||
| 168 | } | 188 | } |
| 169 | 189 | ||
| 170 | void spi_stop(void) { | 190 | void spi_stop(void) { |
| 171 | if (currentSlavePin != NO_PIN) { | 191 | if (current_slave_pin != NO_PIN) { |
| 172 | gpio_set_pin_output(currentSlavePin); | 192 | gpio_set_pin_output(current_slave_pin); |
| 173 | gpio_write_pin_high(currentSlavePin); | 193 | spi_unselect(); |
| 174 | currentSlavePin = NO_PIN; | 194 | current_slave_pin = NO_PIN; |
| 175 | SPSR &= ~(_BV(SPI2X)); | 195 | SPSR &= ~(_BV(SPI2X)); |
| 176 | SPCR &= ~(currentSlaveConfig); | 196 | SPCR &= ~(current_slave_config); |
| 177 | currentSlaveConfig = 0; | 197 | current_slave_config = 0; |
| 178 | currentSlave2X = false; | 198 | current_slave_2x = false; |
| 179 | } | 199 | } |
| 180 | } | 200 | } |
diff --git a/platforms/avr/drivers/spi_master.h b/platforms/avr/drivers/spi_master.h index 8a30f47ae4..ebbf7ddeab 100644 --- a/platforms/avr/drivers/spi_master.h +++ b/platforms/avr/drivers/spi_master.h | |||
| @@ -41,9 +41,18 @@ typedef int16_t spi_status_t; | |||
| 41 | #ifdef __cplusplus | 41 | #ifdef __cplusplus |
| 42 | extern "C" { | 42 | extern "C" { |
| 43 | #endif | 43 | #endif |
| 44 | typedef struct spi_start_config_t { | ||
| 45 | pin_t slave_pin; | ||
| 46 | bool lsb_first; | ||
| 47 | uint8_t mode; | ||
| 48 | uint16_t divisor; | ||
| 49 | bool cs_active_low; | ||
| 50 | } spi_start_config_t; | ||
| 51 | |||
| 44 | void spi_init(void); | 52 | void spi_init(void); |
| 45 | 53 | ||
| 46 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor); | 54 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor); |
| 55 | bool spi_start_extended(spi_start_config_t *start_config); | ||
| 47 | 56 | ||
| 48 | spi_status_t spi_write(uint8_t data); | 57 | spi_status_t spi_write(uint8_t data); |
| 49 | 58 | ||
diff --git a/platforms/chibios/drivers/spi_master.c b/platforms/chibios/drivers/spi_master.c index fcdbc9ecf0..cbe765e233 100644 --- a/platforms/chibios/drivers/spi_master.c +++ b/platforms/chibios/drivers/spi_master.c | |||
| @@ -19,13 +19,33 @@ | |||
| 19 | #include "timer.h" | 19 | #include "timer.h" |
| 20 | 20 | ||
| 21 | static bool spiStarted = false; | 21 | static bool spiStarted = false; |
| 22 | |||
| 23 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE | 22 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE |
| 24 | static pin_t currentSlavePin; | 23 | static pin_t current_slave_pin = NO_PIN; |
| 24 | static bool current_cs_active_low = true; | ||
| 25 | #endif | 25 | #endif |
| 26 | 26 | ||
| 27 | static SPIConfig spiConfig; | 27 | static SPIConfig spiConfig; |
| 28 | 28 | ||
| 29 | static inline void spi_select(void) { | ||
| 30 | spiSelect(&SPI_DRIVER); | ||
| 31 | |||
| 32 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE | ||
| 33 | if (current_slave_pin != NO_PIN) { | ||
| 34 | gpio_write_pin(current_slave_pin, current_cs_active_low ? 0 : 1); | ||
| 35 | } | ||
| 36 | #endif | ||
| 37 | } | ||
| 38 | |||
| 39 | static inline void spi_unselect(void) { | ||
| 40 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE | ||
| 41 | if (current_slave_pin != NO_PIN) { | ||
| 42 | gpio_write_pin(current_slave_pin, current_cs_active_low ? 1 : 0); | ||
| 43 | } | ||
| 44 | #endif | ||
| 45 | |||
| 46 | spiUnselect(&SPI_DRIVER); | ||
| 47 | } | ||
| 48 | |||
| 29 | __attribute__((weak)) void spi_init(void) { | 49 | __attribute__((weak)) void spi_init(void) { |
| 30 | static bool is_initialised = false; | 50 | static bool is_initialised = false; |
| 31 | if (!is_initialised) { | 51 | if (!is_initialised) { |
| @@ -63,7 +83,7 @@ __attribute__((weak)) void spi_init(void) { | |||
| 63 | } | 83 | } |
| 64 | } | 84 | } |
| 65 | 85 | ||
| 66 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | 86 | bool spi_start_extended(spi_start_config_t *start_config) { |
| 67 | #if (SPI_USE_MUTUAL_EXCLUSION == TRUE) | 87 | #if (SPI_USE_MUTUAL_EXCLUSION == TRUE) |
| 68 | spiAcquireBus(&SPI_DRIVER); | 88 | spiAcquireBus(&SPI_DRIVER); |
| 69 | #endif // (SPI_USE_MUTUAL_EXCLUSION == TRUE) | 89 | #endif // (SPI_USE_MUTUAL_EXCLUSION == TRUE) |
| @@ -71,16 +91,15 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 71 | if (spiStarted) { | 91 | if (spiStarted) { |
| 72 | return false; | 92 | return false; |
| 73 | } | 93 | } |
| 74 | |||
| 75 | #if SPI_SELECT_MODE != SPI_SELECT_MODE_NONE | 94 | #if SPI_SELECT_MODE != SPI_SELECT_MODE_NONE |
| 76 | if (slavePin == NO_PIN) { | 95 | if (start_config->slave_pin == NO_PIN) { |
| 77 | return false; | 96 | return false; |
| 78 | } | 97 | } |
| 79 | #endif | 98 | #endif |
| 80 | 99 | ||
| 81 | #if !(defined(WB32F3G71xx) || defined(WB32FQ95xx)) | 100 | #if !(defined(WB32F3G71xx) || defined(WB32FQ95xx)) |
| 82 | uint16_t roundedDivisor = 2; | 101 | uint16_t roundedDivisor = 2; |
| 83 | while (roundedDivisor < divisor) { | 102 | while (roundedDivisor < start_config->divisor) { |
| 84 | roundedDivisor <<= 1; | 103 | roundedDivisor <<= 1; |
| 85 | } | 104 | } |
| 86 | 105 | ||
| @@ -92,11 +111,11 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 92 | #if defined(K20x) || defined(KL2x) | 111 | #if defined(K20x) || defined(KL2x) |
| 93 | spiConfig.tar0 = SPIx_CTARn_FMSZ(7) | SPIx_CTARn_ASC(1); | 112 | spiConfig.tar0 = SPIx_CTARn_FMSZ(7) | SPIx_CTARn_ASC(1); |
| 94 | 113 | ||
| 95 | if (lsbFirst) { | 114 | if (start_config->lsb_first) { |
| 96 | spiConfig.tar0 |= SPIx_CTARn_LSBFE; | 115 | spiConfig.tar0 |= SPIx_CTARn_LSBFE; |
| 97 | } | 116 | } |
| 98 | 117 | ||
| 99 | switch (mode) { | 118 | switch (start_config->mode) { |
| 100 | case 0: | 119 | case 0: |
| 101 | break; | 120 | break; |
| 102 | case 1: | 121 | case 1: |
| @@ -141,11 +160,11 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 141 | spiConfig.cr0 = SPI_CR0_SELOEN; | 160 | spiConfig.cr0 = SPI_CR0_SELOEN; |
| 142 | spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode | 161 | spiConfig.cr1 = SPI_CR1_MODE | 8; // 8 bits and in master mode |
| 143 | 162 | ||
| 144 | if (lsbFirst) { | 163 | if (start_config->lsb_first) { |
| 145 | spiConfig.cr1 |= SPI_CR1_FIRSTBIT; | 164 | spiConfig.cr1 |= SPI_CR1_FIRSTBIT; |
| 146 | } | 165 | } |
| 147 | 166 | ||
| 148 | switch (mode) { | 167 | switch (start_config->mode) { |
| 149 | case 0: | 168 | case 0: |
| 150 | spiConfig.cr1 |= SPI_CR1_FORMAT_MODE0; | 169 | spiConfig.cr1 |= SPI_CR1_FORMAT_MODE0; |
| 151 | break; | 170 | break; |
| @@ -163,17 +182,17 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 163 | spiConfig.cpr = (roundedDivisor - 1) >> 1; | 182 | spiConfig.cpr = (roundedDivisor - 1) >> 1; |
| 164 | 183 | ||
| 165 | #elif defined(WB32F3G71xx) || defined(WB32FQ95xx) | 184 | #elif defined(WB32F3G71xx) || defined(WB32FQ95xx) |
| 166 | if (!lsbFirst) { | 185 | if (!start_config->lsb_first) { |
| 167 | osalDbgAssert(lsbFirst != FALSE, "unsupported lsbFirst"); | 186 | osalDbgAssert(start_config->lsb_first != FALSE, "unsupported lsb_first"); |
| 168 | } | 187 | } |
| 169 | 188 | ||
| 170 | if (divisor < 1) { | 189 | if (start_config->divisor < 1) { |
| 171 | return false; | 190 | return false; |
| 172 | } | 191 | } |
| 173 | 192 | ||
| 174 | spiConfig.SPI_BaudRatePrescaler = (divisor << 2); | 193 | spiConfig.SPI_BaudRatePrescaler = (start_config->divisor << 2); |
| 175 | 194 | ||
| 176 | switch (mode) { | 195 | switch (start_config->mode) { |
| 177 | case 0: | 196 | case 0: |
| 178 | spiConfig.SPI_CPHA = SPI_CPHA_1Edge; | 197 | spiConfig.SPI_CPHA = SPI_CPHA_1Edge; |
| 179 | spiConfig.SPI_CPOL = SPI_CPOL_Low; | 198 | spiConfig.SPI_CPOL = SPI_CPOL_Low; |
| @@ -192,8 +211,8 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 192 | break; | 211 | break; |
| 193 | } | 212 | } |
| 194 | #elif defined(MCU_RP) | 213 | #elif defined(MCU_RP) |
| 195 | if (lsbFirst) { | 214 | if (start_config->lsb_first) { |
| 196 | osalDbgAssert(lsbFirst == false, "RP2040s PrimeCell SPI implementation does not support sending LSB first."); | 215 | osalDbgAssert(start_config->lsb_first == false, "RP2040s PrimeCell SPI implementation does not support sending LSB first."); |
| 197 | } | 216 | } |
| 198 | 217 | ||
| 199 | // Motorola frame format and 8bit transfer data size. | 218 | // Motorola frame format and 8bit transfer data size. |
| @@ -203,7 +222,7 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 203 | // passed divisor to be the only value to divide the input clock by. | 222 | // passed divisor to be the only value to divide the input clock by. |
| 204 | spiConfig.SSPCPSR = roundedDivisor; // Even number from 2 to 254 | 223 | spiConfig.SSPCPSR = roundedDivisor; // Even number from 2 to 254 |
| 205 | 224 | ||
| 206 | switch (mode) { | 225 | switch (start_config->mode) { |
| 207 | case 0: | 226 | case 0: |
| 208 | spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPO; // Clock polarity: low | 227 | spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPO; // Clock polarity: low |
| 209 | spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPH; // Clock phase: sample on first edge | 228 | spiConfig.SSPCR0 &= ~SPI_SSPCR0_SPH; // Clock phase: sample on first edge |
| @@ -224,11 +243,11 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 224 | #else | 243 | #else |
| 225 | spiConfig.cr1 = 0; | 244 | spiConfig.cr1 = 0; |
| 226 | 245 | ||
| 227 | if (lsbFirst) { | 246 | if (start_config->lsb_first) { |
| 228 | spiConfig.cr1 |= SPI_CR1_LSBFIRST; | 247 | spiConfig.cr1 |= SPI_CR1_LSBFIRST; |
| 229 | } | 248 | } |
| 230 | 249 | ||
| 231 | switch (mode) { | 250 | switch (start_config->mode) { |
| 232 | case 0: | 251 | case 0: |
| 233 | break; | 252 | break; |
| 234 | case 1: | 253 | case 1: |
| @@ -271,31 +290,37 @@ bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | |||
| 271 | 290 | ||
| 272 | spiStarted = true; | 291 | spiStarted = true; |
| 273 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE | 292 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE |
| 274 | currentSlavePin = slavePin; | 293 | current_slave_pin = start_config->slave_pin; |
| 294 | current_cs_active_low = start_config->cs_active_low; | ||
| 275 | #endif | 295 | #endif |
| 276 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_PAD | 296 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_PAD |
| 277 | spiConfig.ssport = PAL_PORT(slavePin); | 297 | spiConfig.ssport = PAL_PORT(start_config->slave_pin); |
| 278 | spiConfig.sspad = PAL_PAD(slavePin); | 298 | spiConfig.sspad = PAL_PAD(start_config->slave_pin); |
| 279 | gpio_set_pin_output(slavePin); | 299 | gpio_set_pin_output(start_config->slave_pin); |
| 280 | #elif SPI_SELECT_MODE == SPI_SELECT_MODE_NONE | 300 | #elif SPI_SELECT_MODE == SPI_SELECT_MODE_NONE |
| 281 | if (slavePin != NO_PIN) { | 301 | if (start_config->slave_pin != NO_PIN) { |
| 282 | gpio_set_pin_output(slavePin); | 302 | gpio_set_pin_output(start_config->slave_pin); |
| 283 | } | 303 | } |
| 284 | #else | 304 | #else |
| 285 | # error "Unsupported SPI_SELECT_MODE" | 305 | # error "Unsupported SPI_SELECT_MODE" |
| 286 | #endif | 306 | #endif |
| 287 | 307 | ||
| 288 | spiStart(&SPI_DRIVER, &spiConfig); | 308 | spiStart(&SPI_DRIVER, &spiConfig); |
| 289 | spiSelect(&SPI_DRIVER); | 309 | spi_select(); |
| 290 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE | ||
| 291 | if (slavePin != NO_PIN) { | ||
| 292 | gpio_write_pin_low(slavePin); | ||
| 293 | } | ||
| 294 | #endif | ||
| 295 | 310 | ||
| 296 | return true; | 311 | return true; |
| 297 | } | 312 | } |
| 298 | 313 | ||
| 314 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) { | ||
| 315 | spi_start_config_t start_config = {0}; | ||
| 316 | start_config.slave_pin = slavePin; | ||
| 317 | start_config.lsb_first = lsbFirst; | ||
| 318 | start_config.mode = mode; | ||
| 319 | start_config.divisor = divisor; | ||
| 320 | start_config.cs_active_low = true; | ||
| 321 | return spi_start_extended(&start_config); | ||
| 322 | } | ||
| 323 | |||
| 299 | spi_status_t spi_write(uint8_t data) { | 324 | spi_status_t spi_write(uint8_t data) { |
| 300 | uint8_t rxData; | 325 | uint8_t rxData; |
| 301 | spiExchange(&SPI_DRIVER, 1, &data, &rxData); | 326 | spiExchange(&SPI_DRIVER, 1, &data, &rxData); |
| @@ -322,12 +347,7 @@ spi_status_t spi_receive(uint8_t *data, uint16_t length) { | |||
| 322 | 347 | ||
| 323 | void spi_stop(void) { | 348 | void spi_stop(void) { |
| 324 | if (spiStarted) { | 349 | if (spiStarted) { |
| 325 | #if SPI_SELECT_MODE == SPI_SELECT_MODE_NONE | 350 | spi_unselect(); |
| 326 | if (currentSlavePin != NO_PIN) { | ||
| 327 | gpio_write_pin_high(currentSlavePin); | ||
| 328 | } | ||
| 329 | #endif | ||
| 330 | spiUnselect(&SPI_DRIVER); | ||
| 331 | spiStop(&SPI_DRIVER); | 351 | spiStop(&SPI_DRIVER); |
| 332 | spiStarted = false; | 352 | spiStarted = false; |
| 333 | } | 353 | } |
diff --git a/platforms/chibios/drivers/spi_master.h b/platforms/chibios/drivers/spi_master.h index 6a3ce481f1..4ad6144091 100644 --- a/platforms/chibios/drivers/spi_master.h +++ b/platforms/chibios/drivers/spi_master.h | |||
| @@ -75,9 +75,18 @@ typedef int16_t spi_status_t; | |||
| 75 | #ifdef __cplusplus | 75 | #ifdef __cplusplus |
| 76 | extern "C" { | 76 | extern "C" { |
| 77 | #endif | 77 | #endif |
| 78 | typedef struct spi_start_config_t { | ||
| 79 | pin_t slave_pin; | ||
| 80 | bool lsb_first; | ||
| 81 | uint8_t mode; | ||
| 82 | uint16_t divisor; | ||
| 83 | bool cs_active_low; | ||
| 84 | } spi_start_config_t; | ||
| 85 | |||
| 78 | void spi_init(void); | 86 | void spi_init(void); |
| 79 | 87 | ||
| 80 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor); | 88 | bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor); |
| 89 | bool spi_start_extended(spi_start_config_t *start_config); | ||
| 81 | 90 | ||
| 82 | spi_status_t spi_write(uint8_t data); | 91 | spi_status_t spi_write(uint8_t data); |
| 83 | 92 | ||
