Mercurial > nand-ecoscentric
changeset 3299:99686efcd5ba
Optimised receiving of messages that fit in FIFO. Add clock gating.
Fix race condition bug in dspi_transaction_end(). [ Bugzilla 1001815 ]
| author | vae |
|---|---|
| date | Sun, 07 Apr 2013 16:33:02 +0000 |
| parents | fff0cdf83b21 |
| children | 4486b48763e2 |
| files | packages/devs/spi/freescale/dspi/current/ChangeLog packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c |
| diffstat | 5 files changed, 56 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/devs/spi/freescale/dspi/current/ChangeLog +++ b/packages/devs/spi/freescale/dspi/current/ChangeLog @@ -1,9 +1,19 @@ -2013-02-06 Stefan Singer <stefan.singer@freescale.com> - + Ilija Kocho <ilijak@siva.com.mk> +2013-04-01 Ilija Kocho <ilijak@siva.com.mk> + + * include/spi_freescale_dspi.h, include/spi_freescale_busses.inl + * include/spi_freescale_dspi_io.h, src/spi_freescale_dspi.c: + Optimised receiving of messages that fit in FIFO. Add clock gating. + Fix race condition bug in dspi_transaction_end(). [ Bugzilla 1001815 ] - * enhanced endianness support for devices with big and little endian - * added support for MPC5xxx in addition to Kinetis - * extended support for up to 8 DSPIs +2013-02-06 Stefan Singer <stefan.singer@freescale.com> + Ilija Kocho <ilijak@siva.com.mk> + + * include/spi_freescale_dspi.h, include/spi_freescale_busses.inl + * include/spi_freescale_dspi_io.h, include/spi_freescale_dspi_bd.h, + * src/spi_freescale_dspi.c: + enhanced endianness support for devices with big and little endian + added support for MPC5xxx in addition to Kinetis + extended support for up to 8 DSPIs (see Bugzilla 1001752). 2012-12-28 Ilija Kocho <ilijak@siva.com.mk>
--- a/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h +++ b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi.h @@ -123,6 +123,7 @@ typedef struct cyg_spi_freescale_dspi_bu cyg_uint32 mcr_opt ; // Module Configuratyon Register options const cyg_uint32* spi_pin_list_p; // List of GPIOs used by the SPI interface. const cyg_uint32* cs_pin_list_p; // List of GPIOs used as chip selects. + cyg_uint16 clk_gate; // Clock gate cyg_uint8 cs_pin_num; // Number of chip selects for this bus. } cyg_spi_freescale_dspi_bus_setup_t;
--- a/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl +++ b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_buses.inl @@ -157,6 +157,7 @@ static const cyg_spi_freescale_dspi_bus_ .intr_prio = CYGNUM_DEVS_SPI_FREESCALE_DSPI ## __bus ## _ISR_PRI, \ .spi_pin_list_p = spi ## __bus ## _pins, \ .cs_pin_list_p = spi ## __bus ## _cs_pins, \ + .clk_gate = CYGHWR_IO_FREESCALE_DSPI ## __bus ## _CLK, \ .cs_pin_num = sizeof(spi ## __bus ## _cs_pins)/ \ sizeof(spi ## __bus ## _cs_pins[0]), \ .mcr_opt = CYGHWR_FREESCALE_DSPI ## __bus ## _MCR_PCSSE | \
--- a/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h +++ b/packages/devs/spi/freescale/dspi/current/include/spi_freescale_dspi_io.h @@ -275,9 +275,10 @@ CYG_MACRO_END // Borrow following macros from HAL -// CYGADDR_IO_SPI_FREESCALE_DSPI0_P -// CYGADDR_IO_SPI_FREESCALE_DSPI1_P -// CYGADDR_IO_SPI_FREESCALE_DSPI2_P +// CYGADDR_IO_SPI_FREESCALE_DSPIx_P + +// CYGHWR_IO_CLOCK_ENABLE(__clkgate) +// CYGHWR_IO_FREESCALE_DSPIx_CLK // CYGHWR_IO_FREESCALE_DSPI_PIN(__pin)
--- a/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c +++ b/packages/devs/spi/freescale/dspi/current/src/spi_freescale_dspi.c @@ -155,12 +155,14 @@ dspi_status_clear(cyghwr_devs_freescale_ static inline void dspi_fifo_clear(cyghwr_devs_freescale_dspi_t* dspi_p) { + DEBUG2_PRINTF(" Fifo Clear\n"); dspi_p->mcr |= FREESCALE_DSPI_MCR_CLR_RXF_M | FREESCALE_DSPI_MCR_CLR_TXF_M; } static inline void dspi_fifo_drain(cyghwr_devs_freescale_dspi_t* dspi_p) { + DEBUG2_PRINTF(" Fifo Drain\n"); dspi_p->sr |= FREESCALE_DSPI_SR_RFDF_M; } @@ -207,7 +209,7 @@ static cyg_uint32 dspi_dma_ISR(cyg_vecto edma_p = dma_set_p->edma_p; cyg_drv_isr_lock(); - + // Disable the Tx DMA channel and DSPI IRQ. hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, TX)); DSPI_IRQ_DISABLE(dspi_p); @@ -412,7 +414,8 @@ static void dspi_bus_setup(cyg_spi_frees cyghwr_hal_freescale_edma_t* edma_p; cyg_uint32 dma_chan_i; - // Get the clock frequency from HAL. + // Set up the clocking. + CYGHWR_IO_CLOCK_ENABLE(spi_bus_p->setup_p->clk_gate); spi_bus_p->clock_freq = CYGHWR_IO_SPI_FREESCALE_DSPI_CLOCK; DEBUG1_PRINTF("DSPI BUS %p: SysClk=%d\n", spi_bus_p, spi_bus_p->clock_freq); @@ -750,11 +753,16 @@ static void spi_transaction_do (cyg_spi_ DEBUG2_PRINTF("DSPI: transaction: count=%d drop_cs=%d\n", count, drop_cs); // Set up peripheral CS field. DSPI automatically asserts and deasserts CS - pushr = dspi_chip_select_set( + pushr = +#ifndef CYGOPT_DEVS_SPI_FREESCALE_DSPI_TICK_ONLY_DROPS_CS + // Compatibility option + // eCos Reference Manual states that CS should drop prior to sending + // ticks, but other SPI drivers do not touch the CS. + tick_only ? dspi_p->pushr & 0x87FF0000 : +#endif + dspi_chip_select_set( #ifdef CYGOPT_DEVS_SPI_FREESCALE_DSPI_TICK_ONLY_DROPS_CS - // eCos Reference Manual states that CS should - // drop prior to send ticks, but other drivers - // (so far do not) touch the CS. + // Compatibility option. See comment above. tick_only ? -1 : #endif dspi_device->dev_num, @@ -767,8 +775,18 @@ static void spi_transaction_do (cyg_spi_ pushque_n = dspi_bus->pushque_n; if(bus_16bit) txfifo_n *= 2; - - if((dma_set_p=dspi_bus->setup_p->dma_set_p)) { + + if(count <= txfifo_n){ + // If byte count fits in the FIFO don't bother with DMA. + if((dma_set_p = dspi_bus->setup_p->dma_set_p)) { + edma_p = dma_set_p->edma_p; + hal_freescale_edma_erq_disable(edma_p, SPI_DMA_CHAN_I(dma_set_p, RX)); + } + dma_set_p = NULL; + } else { + dma_set_p = dspi_bus->setup_p->dma_set_p; + } + if(dma_set_p) { edma_p = dma_set_p->edma_p; // Set up the DMA channels. dma_chan_rx_i = SPI_DMA_CHAN_I(dma_set_p, RX); @@ -841,19 +859,24 @@ static void spi_transaction_do (cyg_spi_ while((dspi_p->sr & FREESCALE_DSPI_SR_RFDF_M)); } else { // No DMA - "manually" drain Rx FIFO - DEBUG2_PRINTF("DSPI FIFO: 'Manually' drain Rx fifo\n"); + DEBUG2_PRINTF("DSPI FIFO: 'Manually' drain Rx fifo rx_data=%p bus_16bit=%d\n", + rx_data, bus_16bit); #if DEBUG_SPI >= 3 cyghwr_devs_freescale_dspi_diag(dspi_bus); #endif if(rx_data) { if(bus_16bit) { cyg_uint16* rx_data16 = (cyg_uint16*) rx_data; - while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) + while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) { + DEBUG2_PRINTF(" Fifo Pull16\n"); *rx_data16++ = dspi_p->popr; + } rx_data = (cyg_uint8*) rx_data16; } else { - while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) + while(dspi_p->sr & FREESCALE_DSPI_SR_RXCTR_M) { + DEBUG2_PRINTF(" Fifo Pull\n"); *rx_data++ = dspi_p->popr; + } } } else { dspi_fifo_drain(dspi_p); @@ -995,9 +1018,9 @@ static void dspi_transaction_end(cyg_spi if(dspi_device->chip_sel){ // Clear peripheral CS by executing a dummy 4 bit transfer. + DSPI_EOQ_CLEAR(dspi_p); dspi_p->pushr = PUSHR_NULL | FREESCALE_DSPI_PUSHR_EOQ_M | FREESCALE_DSPI_PUSHR_CTAS(1); - DSPI_EOQ_CLEAR(dspi_p); while(!(dspi_p->sr & FREESCALE_DSPI_SR_EOQF_M)); dspi_device->chip_sel = 0; }
