X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Farm%2Fdrv%2Fspi_dma_at91.c;h=57ed2fbd7203365246ff10cdf8da67e99c0a41e7;hb=f1fab319eb3fe91c157b3a9564841aef62a03554;hp=2c6a9308abea753b9aef134d19acb7aa07bbd63e;hpb=911d2706a86d326786bfe721dcc3d63aeade7f28;p=bertos.git diff --git a/bertos/cpu/arm/drv/spi_dma_at91.c b/bertos/cpu/arm/drv/spi_dma_at91.c index 2c6a9308..57ed2fbd 100644 --- a/bertos/cpu/arm/drv/spi_dma_at91.c +++ b/bertos/cpu/arm/drv/spi_dma_at91.c @@ -32,19 +32,21 @@ * * \brief SPI driver with DMA. * - * \version $Id$ * \author Francesco Sacchi * \author Luca Ottaviano */ -#include "cfg/cfg_spi_dma.h" +#include -#include "spi_dma_at91.h" +#include "cfg/cfg_spi_dma.h" #include "hw/hw_spi_dma.h" +#include #include + #include #include + #include #include @@ -52,43 +54,6 @@ #include /* memset */ -static uint8_t tx_fifo_buffer[CONFIG_SPI_DMA_TXBUFSIZE]; -static FIFOBuffer tx_fifo; -static KFileFifo kfifo; - - -INLINE void spi_dma_startTx(void) -{ - if (fifo_isempty(&tx_fifo)) - return; - - if (SPI0_SR & BV(SPI_TXBUFE)) - { - SPI0_PTCR = BV(PDC_TXTDIS); - SPI0_TPR = (reg32_t)tx_fifo.head; - if (tx_fifo.head < tx_fifo.tail) - SPI0_TCR = tx_fifo.tail - tx_fifo.head; - else - SPI0_TCR = tx_fifo.end - tx_fifo.head + 1; - - SPI0_PTCR = BV(PDC_TXTEN); - } -} - -static DECLARE_ISR(spi0_dma_write_irq_handler) -{ - SPI_DMA_STROBE_ON(); - /* Pop sent chars from FIFO */ - tx_fifo.head = (uint8_t *)SPI0_TPR; - if (tx_fifo.head > tx_fifo.end) - tx_fifo.head = tx_fifo.begin; - - spi_dma_startTx(); - - AIC_EOICR = 0; - SPI_DMA_STROBE_OFF(); -} - void spi_dma_setclock(uint32_t rate) { @@ -98,41 +63,11 @@ void spi_dma_setclock(uint32_t rate) SPI0_CSR0 |= DIV_ROUND(CPU_FREQ, rate) << SPI_SCBR_SHIFT; } -static size_t spi_dma_write(UNUSED_ARG(struct KFile *, fd), const void *_buf, size_t size) -{ - size_t count, total_wr = 0; - const uint8_t *buf = (const uint8_t *) _buf; - - // copy buffer to internal fifo - while (size) - { - #if CONFIG_SPI_DMA_TX_TIMEOUT != -1 - ticks_t start = timer_clock(); - while (fifo_isfull(&tx_fifo) && (timer_clock() - start < ms_to_ticks(CONFIG_SPI_DMA_TX_TIMEOUT))) - cpu_relax(); - - if (fifo_isfull(&tx_fifo)) - break; - #else - while (fifo_isfull(&tx_fifo)) - cpu_relax(); - #endif /* CONFIG_SPI_DMA_TX_TIMEOUT */ - - // FIXME: improve copy performance - count = kfile_write(&kfifo.fd, buf, size); - size -= count; - buf += count; - total_wr += count; - spi_dma_startTx(); - } - - return total_wr; -} static int spi_dma_flush(UNUSED_ARG(struct KFile *, fd)) { - /* Wait FIFO flush */ - while (!fifo_isempty(&tx_fifo)) + /* Wait for DMA to finish */ + while (!(SPI0_SR & BV(SPI_TXBUFE))) cpu_relax(); /* Wait until last bit has been shifted out */ @@ -142,12 +77,17 @@ static int spi_dma_flush(UNUSED_ARG(struct KFile *, fd)) return 0; } -static DECLARE_ISR(spi0_dma_read_irq_handler) +static size_t spi_dma_write(struct KFile *fd, const void *_buf, size_t size) { - /* do nothing */ - AIC_EOICR = 0; + SPI0_PTCR = BV(PDC_TXTDIS); + SPI0_TPR = (reg32_t)_buf; + SPI0_TCR = size; + SPI0_PTCR = BV(PDC_TXTEN); + spi_dma_flush(fd); + return size; } + /* * Dummy buffer used to transmit 0xff chars while receiving data. * This buffer is completetly constant and the compiler should allocate it @@ -155,16 +95,11 @@ static DECLARE_ISR(spi0_dma_read_irq_handler) */ static const uint8_t tx_dummy_buf[CONFIG_SPI_DMA_MAX_RX] = { [0 ... (CONFIG_SPI_DMA_MAX_RX - 1)] = 0xFF }; -static size_t spi_dma_read(struct KFile *fd, void *_buf, size_t size) +static size_t spi_dma_read(UNUSED_ARG(struct KFile *, fd), void *_buf, size_t size) { size_t count, total_rx = 0; uint8_t *buf = (uint8_t *)_buf; - spi_dma_flush(fd); - - /* Dummy irq handler that do nothing */ - AIC_SVR(SPI0_ID) = spi0_dma_read_irq_handler; - while (size) { count = MIN(size, (size_t)CONFIG_SPI_DMA_MAX_RX); @@ -192,15 +127,12 @@ static size_t spi_dma_read(struct KFile *fd, void *_buf, size_t size) } SPI0_PTCR = BV(PDC_RXTDIS) | BV(PDC_TXTDIS); - /* set write irq handler back in place */ - AIC_SVR(SPI0_ID) = spi0_dma_write_irq_handler; - return total_rx; } #define SPI_DMA_IRQ_PRIORITY 4 -void spi_dma_init(SpiDmaAt91 *spi) +void spi_dma_init(SpiDma *spi) { /* Disable PIO on SPI pins */ PIOA_PDR = BV(SPI0_SPCK) | BV(SPI0_MOSI) | BV(SPI0_MISO); @@ -223,27 +155,16 @@ void spi_dma_init(SpiDmaAt91 *spi) /* Disable all irqs */ SPI0_IDR = 0xFFFFFFFF; - /* Set the vector. */ - AIC_SVR(SPI0_ID) = spi0_dma_write_irq_handler; - /* Initialize to edge triggered with defined priority. */ - AIC_SMR(SPI0_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED | SPI_DMA_IRQ_PRIORITY; - /* Enable the USART IRQ */ - AIC_IECR = BV(SPI0_ID); + /* Enable SPI clock. */ PMC_PCER = BV(SPI0_ID); - /* Enable interrupt on tx buffer empty */ - SPI0_IER = BV(SPI_ENDTX); - /* Enable SPI */ SPI0_CR = BV(SPI_SPIEN); - DB(spi->fd._type = KFT_SPIDMAAT91); + DB(spi->fd._type = KFT_SPIDMA); spi->fd.write = spi_dma_write; spi->fd.read = spi_dma_read; spi->fd.flush = spi_dma_flush; - fifo_init(&tx_fifo, tx_fifo_buffer, sizeof(tx_fifo_buffer)); - kfilefifo_init(&kfifo, &tx_fifo); - SPI_DMA_STROBE_INIT(); }