diff --git a/drivers/avr/spi_master.c b/drivers/avr/spi_master.c index 3f405ddf5cd8..32cc55c8361b 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 0bab2dc24ebb..b69c1cbd66e3 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 764475510d34..a9cfc18558c9 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;