altos/stm: Add better byte-level SPI api
authorKeith Packard <keithp@keithp.com>
Wed, 29 Jun 2016 01:39:31 +0000 (18:39 -0700)
committerKeith Packard <keithp@keithp.com>
Thu, 30 Jun 2016 02:17:45 +0000 (19:17 -0700)
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>
src/stm/ao_arch_funcs.h
src/stm/ao_spi_stm.c

index 8393898de33d47b0272574eb3e8e591048ad41a9..a796891d53b24b9fe4b40179ecee94543029a0eb 100644 (file)
@@ -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
index e69c2d7b8dc4932202ec87d0df5f05dd360b90a6..214092f6bb75922ca075bd404766416b650637e1 100644 (file)
@@ -203,6 +203,38 @@ ao_spi_send_fixed(uint8_t value, uint16_t len, uint8_t spi_index)
        ao_spi_run(id, 3, len);
 }
 
+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)
 {