void at91spi_done(struct at91spi_softc *sc, int err) { struct spi_transfer *st; /* called from interrupt handler */ if ((st = sc->sc_transfer) != NULL) { sc->sc_transfer = NULL; DPRINTFN(2, ("%s: st %p finished with error code %d\n", __FUNCTION__, st, err)); spi_done(st, err); } /* make sure we clear these bits out */ sc->sc_wchunk = sc->sc_rchunk = NULL; at91spi_sched(sc); }
/* Generic function to send and receive a byte */ uint8_t spi_rw_byte(uint8_t data_out) { uint8_t data_in ; spi_set_sck(8) ; spi_data_len(8) ; SPI->TX_DATAbits.DATA = data_out ; spi_start() ; while(!spi_done()) { /* Wait */ } data_in = SPI->RX_DATAbits.DATA ; spi_int_clear() ; return data_in ; }
void at91spi_sched(struct at91spi_softc *sc) { struct spi_transfer *st; int err; while ((st = spi_transq_first(&sc->sc_q)) != NULL) { DPRINTFN(2, ("%s: st=%p\n", __FUNCTION__, st)); /* remove the item */ spi_transq_dequeue(&sc->sc_q); /* note that we are working on it */ sc->sc_transfer = st; if ((err = at91spi_select(sc, st->st_slave)) != 0) { spi_done(st, err); continue; } /* setup chunks */ sc->sc_rchunk = sc->sc_wchunk = st->st_chunks; /* now kick the master start to get the chip running */ at91spi_xfer(sc, TRUE); /* enable error interrupts too: */ PUTREG(sc, SPI_IER, SPI_SR_MODF | SPI_SR_OVRES); sc->sc_running = TRUE; return; } DPRINTFN(2, ("%s: nothing to do anymore\n", __FUNCTION__)); PUTREG(sc, SPI_IDR, -1); /* disable interrupts */ at91spi_select(sc, -1); sc->sc_running = FALSE; }