diff options
author | Keith Packard <keithp@keithp.com> | 2016-06-28 18:39:31 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2016-06-29 19:17:45 -0700 |
commit | 61ad8e5bf428246ac89cad7cb9a1edf2ef735fd5 (patch) | |
tree | 38f8240cda217bd49504afc97b7c6809a1cc60df /src | |
parent | 5866d191cee56949ccab4c154a14604e83163d42 (diff) |
altos/stm: Add better byte-level SPI api
This provides inline functions for sending and receiving individual
bytes, and setup/finish functions to wrap them in. This make the byte
sending respect the SPI hardware interface requirements.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/stm/ao_arch_funcs.h | 42 | ||||
-rw-r--r-- | src/stm/ao_spi_stm.c | 32 |
2 files changed, 64 insertions, 10 deletions
diff --git a/src/stm/ao_arch_funcs.h b/src/stm/ao_arch_funcs.h index 8393898d..a796891d 100644 --- a/src/stm/ao_arch_funcs.h +++ b/src/stm/ao_arch_funcs.h @@ -82,6 +82,12 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index); void ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index); +void +ao_spi_start_bytes(uint8_t spi_index); + +void +ao_spi_stop_bytes(uint8_t spi_index); + static inline void ao_spi_send_byte(uint8_t byte, uint8_t spi_index) { @@ -96,18 +102,34 @@ ao_spi_send_byte(uint8_t byte, uint8_t spi_index) break; } - stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | - (0 << STM_SPI_CR2_RXNEIE) | - (0 << STM_SPI_CR2_ERRIE) | - (0 << STM_SPI_CR2_SSOE) | - (0 << STM_SPI_CR2_TXDMAEN) | - (0 << STM_SPI_CR2_RXDMAEN)); - - /* Clear RXNE */ + while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))) + ; + stm_spi->dr = byte; + while (!(stm_spi->sr & (1 << STM_SPI_SR_RXNE))) + ; (void) stm_spi->dr; +} - while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))); - stm_spi->dr = byte; +static inline uint8_t +ao_spi_recv_byte(uint8_t spi_index) +{ + struct stm_spi *stm_spi; + + switch (AO_SPI_INDEX(spi_index)) { + case 0: + stm_spi = &stm_spi1; + break; + case 1: + stm_spi = &stm_spi2; + break; + } + + while (!(stm_spi->sr & (1 << STM_SPI_SR_TXE))) + ; + stm_spi->dr = 0xff; + while (!(stm_spi->sr & (1 << STM_SPI_SR_RXNE))) + ; + return stm_spi->dr; } void diff --git a/src/stm/ao_spi_stm.c b/src/stm/ao_spi_stm.c index e69c2d7b..214092f6 100644 --- a/src/stm/ao_spi_stm.c +++ b/src/stm/ao_spi_stm.c @@ -204,6 +204,38 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index) } void +ao_spi_start_bytes(uint8_t spi_index) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + + stm_spi->cr2 = ((0 << STM_SPI_CR2_TXEIE) | + (0 << STM_SPI_CR2_RXNEIE) | + (0 << STM_SPI_CR2_ERRIE) | + (0 << STM_SPI_CR2_SSOE) | + (0 << STM_SPI_CR2_TXDMAEN) | + (0 << STM_SPI_CR2_RXDMAEN)); + validate_spi(stm_spi, 5, 0xffff); +} + +void +ao_spi_stop_bytes(uint8_t spi_index) +{ + uint8_t id = AO_SPI_INDEX(spi_index); + struct stm_spi *stm_spi = ao_spi_stm_info[id].stm_spi; + + while ((stm_spi->sr & (1 << STM_SPI_SR_TXE)) == 0) + ; + while (stm_spi->sr & (1 << STM_SPI_SR_BSY)) + ; + /* Clear the OVR flag */ + (void) stm_spi->dr; + (void) stm_spi->sr; + validate_spi(stm_spi, 6, 0xffff); + stm_spi->cr2 = 0; +} + +void ao_spi_send_sync(const void *block, uint16_t len, uint8_t spi_index) { uint8_t id = AO_SPI_INDEX(spi_index); |