altos/lpc: Stop sending SETUP IN when the requested size is reached
[fw/altos] / src / lpc / ao_spi_lpc.c
index 05688f5205f205ad72bd3a4861cda3c8d25f7b60..a889137cbb7a4e1f84437f601d76e78f8cc22ce8 100644 (file)
@@ -23,22 +23,26 @@ static struct lpc_ssp * const ao_lpc_ssp[LPC_NUM_SPI] = { &lpc_ssp0, &lpc_ssp1 }
 
 static uint8_t spi_dev_null;
 
+#define tx_busy(lpc_ssp) (lpc_ssp->sr & ((1 << LPC_SSP_SR_BSY) | (1 << LPC_SSP_SR_TNF))) != (1 << LPC_SSP_SR_TNF)
+#define rx_busy(lpc_ssp) (lpc_ssp->sr & ((1 << LPC_SSP_SR_BSY) | (1 << LPC_SSP_SR_RNE))) != (1 << LPC_SSP_SR_RNE)
+
 #define spi_loop(len, put, get) do {                                   \
                while (len--) {                                         \
                        /* Wait for space in the fifo */                \
-                       while ((lpc_ssp->sr & (1 << LPC_SSP_SR_TNF)) == 0) \
+                       while (tx_busy(lpc_ssp))                        \
                                ;                                       \
+                                                                       \
                        /* send a byte */                               \
                        lpc_ssp->dr = put;                              \
                                                                        \
+                       /* Wait for byte to appear in the fifo */       \
+                       while (rx_busy(lpc_ssp))                        \
+                               ;                                       \
+                                                                       \
                        /* recv a byte */                               \
                        get lpc_ssp->dr;                                \
                }                                                       \
-                                                                       \
-               /* Wait for the fifo to drain */                        \
-               while ((lpc_ssp->sr & (1 << LPC_SSP_SR_BSY)))           \
-                       ;                                               \
-       } while (0);
+       } while (0)
 
 void
 ao_spi_send(void *block, uint16_t len, uint8_t id)
@@ -85,24 +89,11 @@ ao_spi_get(uint8_t id, uint32_t speed)
        
        /* Set the clock prescale */
        lpc_ssp->cpsr = speed;
-
-       /* Enable the device */
-       lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) |
-                       (1 << LPC_SSP_CR1_SSE) |
-                       (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) |
-                       (0 << LPC_SSP_CR1_SOD));
 }
 
 void
 ao_spi_put(uint8_t id)
 {
-       struct lpc_ssp  *lpc_ssp = ao_lpc_ssp[id];
-
-       /* Disable the device */
-       lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) |
-                       (0 << LPC_SSP_CR1_SSE) |
-                       (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) |
-                       (0 << LPC_SSP_CR1_SOD));
        ao_mutex_put(&ao_spi_mutex[id]);
 }
 
@@ -117,6 +108,13 @@ ao_spi_channel_init(uint8_t id)
                        (0 << LPC_SSP_CR0_CPOL) |
                        (0 << LPC_SSP_CR0_CPHA) |
                        (0 << LPC_SSP_CR0_SCR));
+
+       /* Enable the device */
+       lpc_ssp->cr1 = ((0 << LPC_SSP_CR1_LBM) |
+                       (1 << LPC_SSP_CR1_SSE) |
+                       (LPC_SSP_CR1_MS_MASTER << LPC_SSP_CR1_MS) |
+                       (0 << LPC_SSP_CR1_SOD));
+
        /* Drain the receive fifo */
        for (d = 0; d < LPC_SSP_FIFOSIZE; d++)
                (void) lpc_ssp->dr;
@@ -127,7 +125,21 @@ ao_spi_init(void)
 {
 #if HAS_SPI_0
        /* Configure pins */
-       lpc_ioconf.pio0_6 = ao_lpc_alternate(LPC_IOCONF_FUNC_SCK0);
+#if SPI_SCK0_P0_6
+       lpc_ioconf.pio0_6 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_6_SCK0);
+#define HAS_SCK0
+#endif
+#if SPI_SCK0_P0_10
+       lpc_ioconf.pio0_10 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_10_SCK0);
+#define HAS_SCK0
+#endif
+#if SPI_SCK0_P1_29
+       lpc_ioconf.pio1_29 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO1_29_SCK0);
+#define HAS_SCK0
+#endif
+#ifndef HAS_SCK0
+#error "No pin specified for SCK0"
+#endif
        lpc_ioconf.pio0_8 = ao_lpc_alternate(LPC_IOCONF_FUNC_MISO0);
        lpc_ioconf.pio0_9 = ao_lpc_alternate(LPC_IOCONF_FUNC_MOSI0);
 
@@ -170,7 +182,7 @@ ao_spi_init(void)
 #endif
 
 #if SPI_MOSI1_P0_21
-       lpc_ioconf.pio1_21 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_21_MOSI1);
+       lpc_ioconf.pio0_21 = ao_lpc_alternate(LPC_IOCONF_FUNC_PIO0_21_MOSI1);
 #define HAS_MOSI1
 #endif
 #if SPI_MOSI1_P1_22
@@ -187,7 +199,8 @@ ao_spi_init(void)
        /* Turn on the clock */
        lpc_scb.ssp1clkdiv = 1;
 
-       /* De-assert reset */
+       /* Reset the device */
+       lpc_scb.presetctrl &= ~(1 << LPC_SCB_PRESETCTRL_SSP1_RST_N);
        lpc_scb.presetctrl |= (1 << LPC_SCB_PRESETCTRL_SSP1_RST_N);
        ao_spi_channel_init(1);
 #endif /* HAS_SPI_1 */