-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 (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; \
- } \
- } while (0);
+static inline void
+ao_lpc_ssp_recv(struct lpc_ssp *lpc_ssp, struct ao_lpc_ssp_state *state)
+{
+ while ((lpc_ssp->sr & (1 << LPC_SSP_SR_RNE)) &&
+ state->rx_count)
+ {
+ /* RX ready, read a byte */
+ *state->rx = lpc_ssp->dr;
+ state->rx += state->rx_inc;
+ state->rx_count--;
+ }
+}
+
+static void
+ao_lpc_ssp_isr(struct lpc_ssp *lpc_ssp, struct ao_lpc_ssp_state *state)
+{
+ ao_lpc_ssp_recv(lpc_ssp, state);
+ while ((lpc_ssp->sr & (1 << LPC_SSP_SR_TNF)) &&
+ state->tx_count)
+ {
+ /* TX ready, write a byte */
+ lpc_ssp->dr = *state->tx;
+ state->tx += state->tx_inc;
+ state->tx_count--;
+ ao_lpc_ssp_recv(lpc_ssp, state);
+ }
+ if (!state->rx_count) {
+ lpc_ssp->imsc &= ~(1 << LPC_SSP_IMSC_TXIM);
+ ao_wakeup(state);
+ }
+}
+
+void
+lpc_ssp0_isr(void)
+{
+ ao_lpc_ssp_isr(&lpc_ssp0, &ao_lpc_ssp_state[0]);
+}
+
+void
+lpc_ssp1_isr(void)
+{
+ ao_lpc_ssp_isr(&lpc_ssp1, &ao_lpc_ssp_state[1]);
+}
+
+static void
+ao_spi_run(struct lpc_ssp *lpc_ssp, struct ao_lpc_ssp_state *state)
+{
+ ao_arch_block_interrupts();
+ lpc_ssp->imsc = (1 << LPC_SSP_IMSC_TXIM);
+ while (state->rx_count)
+ ao_sleep(state);
+ ao_arch_release_interrupts();
+}
+
+static uint8_t ao_spi_tx_dummy = 0xff;
+static uint8_t ao_spi_rx_dummy;