summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Brassel <nick@tzarc.org>2020-04-13 17:09:50 +1000
committerFlorian Didron <fdidron@users.noreply.github.com>2020-06-12 17:00:27 +0900
commit9fe1c38b4c902dadebfd36168db95d9469589aed (patch)
treedc8c059b129db3adf2e5ef722091921f871f33a6
parentda7b76967e08a76e236f4d5a723c9ff1be3f8c6a (diff)
Fix AVR SPI parameter configuration, remove timeouts due to sync protocol. (#8775)
-rw-r--r--drivers/avr/spi_master.c123
-rw-r--r--drivers/avr/spi_master.h10
-rw-r--r--tmk_core/protocol/lufa/adafruit_ble.cpp10
3 files changed, 78 insertions, 65 deletions
diff --git a/drivers/avr/spi_master.c b/drivers/avr/spi_master.c
index 3f405ddf5c..32cc55c836 100644
--- a/drivers/avr/spi_master.c
+++ b/drivers/avr/spi_master.c
@@ -34,6 +34,10 @@
# define SPI_MISO_PIN B4
#endif
+#ifndef SPI_TIMEOUT
+# define SPI_TIMEOUT 100
+#endif
+
static pin_t currentSlavePin = NO_PIN;
static uint8_t currentSlaveConfig = 0;
static bool currentSlave2X = false;
@@ -47,65 +51,74 @@ void spi_init(void) {
SPCR = (_BV(SPE) | _BV(MSTR));
}
-void spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint8_t divisor) {
- if (currentSlavePin == NO_PIN && slavePin != NO_PIN) {
- if (lsbFirst) {
- currentSlaveConfig |= _BV(DORD);
- }
+bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor) {
+ if (currentSlavePin != NO_PIN || slavePin == NO_PIN) {
+ return false;
+ }
- switch (mode) {
- case 1:
- currentSlaveConfig |= _BV(CPHA);
- break;
- case 2:
- currentSlaveConfig |= _BV(CPOL);
- break;
- case 3:
- currentSlaveConfig |= (_BV(CPOL) | _BV(CPHA));
- break;
- }
+ currentSlaveConfig = 0;
- uint8_t roundedDivisor = 1;
- while (roundedDivisor < divisor) {
- roundedDivisor <<= 1;
- }
+ if (lsbFirst) {
+ currentSlaveConfig |= _BV(DORD);
+ }
- switch (roundedDivisor) {
- case 16:
- currentSlaveConfig |= _BV(SPR0);
- break;
- case 64:
- currentSlaveConfig |= _BV(SPR1);
- break;
- case 128:
- currentSlaveConfig |= (_BV(SPR1) | _BV(SPR0));
- break;
- case 2:
- currentSlave2X = true;
- break;
- case 8:
- currentSlave2X = true;
- currentSlaveConfig |= _BV(SPR0);
- break;
- case 32:
- currentSlave2X = true;
- currentSlaveConfig |= _BV(SPR1);
- break;
- }
+ switch (mode) {
+ case 1:
+ currentSlaveConfig |= _BV(CPHA);
+ break;
+ case 2:
+ currentSlaveConfig |= _BV(CPOL);
+ break;
+ case 3:
+ currentSlaveConfig |= (_BV(CPOL) | _BV(CPHA));
+ break;
+ }
- SPSR |= currentSlaveConfig;
- currentSlavePin = slavePin;
- setPinOutput(currentSlavePin);
- writePinLow(currentSlavePin);
+ uint16_t roundedDivisor = 1;
+ while (roundedDivisor < divisor) {
+ roundedDivisor <<= 1;
+ }
+
+ switch (roundedDivisor) {
+ case 16:
+ currentSlaveConfig |= _BV(SPR0);
+ break;
+ case 64:
+ currentSlaveConfig |= _BV(SPR1);
+ break;
+ case 128:
+ currentSlaveConfig |= (_BV(SPR1) | _BV(SPR0));
+ break;
+ case 2:
+ currentSlave2X = true;
+ break;
+ case 8:
+ currentSlave2X = true;
+ currentSlaveConfig |= _BV(SPR0);
+ break;
+ case 32:
+ currentSlave2X = true;
+ currentSlaveConfig |= _BV(SPR1);
+ break;
}
+
+ SPCR |= currentSlaveConfig;
+ if (currentSlave2X) {
+ SPSR |= _BV(SPI2X);
+ }
+ currentSlavePin = slavePin;
+ setPinOutput(currentSlavePin);
+ writePinLow(currentSlavePin);
+
+ return true;
}
-spi_status_t spi_write(uint8_t data, uint16_t timeout) {
+spi_status_t spi_write(uint8_t data) {
SPDR = data;
uint16_t timeout_timer = timer_read();
while (!(SPSR & _BV(SPIF))) {
- if ((timeout != SPI_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ if ((timer_read() - timeout_timer) >= SPI_TIMEOUT) {
return SPI_STATUS_TIMEOUT;
}
}
@@ -113,12 +126,12 @@ spi_status_t spi_write(uint8_t data, uint16_t timeout) {
return SPDR;
}
-spi_status_t spi_read(uint16_t timeout) {
+spi_status_t spi_read() {
SPDR = 0x00; // Dummy
uint16_t timeout_timer = timer_read();
while (!(SPSR & _BV(SPIF))) {
- if ((timeout != SPI_TIMEOUT_INFINITE) && ((timer_read() - timeout_timer) >= timeout)) {
+ if ((timer_read() - timeout_timer) >= SPI_TIMEOUT) {
return SPI_STATUS_TIMEOUT;
}
}
@@ -126,21 +139,21 @@ spi_status_t spi_read(uint16_t timeout) {
return SPDR;
}
-spi_status_t spi_transmit(const uint8_t *data, uint16_t length, uint16_t timeout) {
+spi_status_t spi_transmit(const uint8_t *data, uint16_t length) {
spi_status_t status = SPI_STATUS_ERROR;
for (uint16_t i = 0; i < length; i++) {
- status = spi_write(data[i], timeout);
+ status = spi_write(data[i]);
}
return status;
}
-spi_status_t spi_receive(uint8_t *data, uint16_t length, uint16_t timeout) {
+spi_status_t spi_receive(uint8_t *data, uint16_t length) {
spi_status_t status = SPI_STATUS_ERROR;
for (uint16_t i = 0; i < length; i++) {
- status = spi_read(timeout);
+ status = spi_read();
if (status > 0) {
data[i] = status;
@@ -155,9 +168,9 @@ void spi_stop(void) {
setPinOutput(currentSlavePin);
writePinHigh(currentSlavePin);
currentSlavePin = NO_PIN;
+ SPSR &= ~(_BV(SPI2X));
SPCR &= ~(currentSlaveConfig);
currentSlaveConfig = 0;
- SPSR = 0;
currentSlave2X = false;
}
}
diff --git a/drivers/avr/spi_master.h b/drivers/avr/spi_master.h
index 0bab2dc24e..b69c1cbd66 100644
--- a/drivers/avr/spi_master.h
+++ b/drivers/avr/spi_master.h
@@ -41,15 +41,15 @@ extern "C" {
#endif
void spi_init(void);
-void spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint8_t divisor);
+bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor);
-spi_status_t spi_write(uint8_t data, uint16_t timeout);
+spi_status_t spi_write(uint8_t data);
-spi_status_t spi_read(uint16_t timeout);
+spi_status_t spi_read(void);
-spi_status_t spi_transmit(const uint8_t *data, uint16_t length, uint16_t timeout);
+spi_status_t spi_transmit(const uint8_t *data, uint16_t length);
-spi_status_t spi_receive(uint8_t *data, uint16_t length, uint16_t timeout);
+spi_status_t spi_receive(uint8_t *data, uint16_t length);
void spi_stop(void);
#ifdef __cplusplus
diff --git a/tmk_core/protocol/lufa/adafruit_ble.cpp b/tmk_core/protocol/lufa/adafruit_ble.cpp
index 764475510d..a9cfc18558 100644
--- a/tmk_core/protocol/lufa/adafruit_ble.cpp
+++ b/tmk_core/protocol/lufa/adafruit_ble.cpp
@@ -152,7 +152,7 @@ static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) {
bool ready = false;
do {
- ready = spi_write(msg->type, 100) != SdepSlaveNotReady;
+ ready = spi_write(msg->type) != SdepSlaveNotReady;
if (ready) {
break;
}
@@ -165,7 +165,7 @@ static bool sdep_send_pkt(const struct sdep_msg *msg, uint16_t timeout) {
if (ready) {
// Slave is ready; send the rest of the packet
- spi_transmit(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len, 100);
+ spi_transmit(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)) + msg->len);
success = true;
}
@@ -205,7 +205,7 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
do {
// Read the command type, waiting for the data to be ready
- msg->type = spi_read(100);
+ msg->type = spi_read();
if (msg->type == SdepSlaveNotReady || msg->type == SdepSlaveOverflow) {
// Release it and let it initialize
spi_stop();
@@ -215,11 +215,11 @@ static bool sdep_recv_pkt(struct sdep_msg *msg, uint16_t timeout) {
}
// Read the rest of the header
- spi_receive(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)), 100);
+ spi_receive(&msg->cmd_low, sizeof(*msg) - (1 + sizeof(msg->payload)));
// and get the payload if there is any
if (msg->len <= SdepMaxPayload) {
- spi_receive(msg->payload, msg->len, 100);
+ spi_receive(msg->payload, msg->len);
}
success = true;
break;