From ec80f9b8a4b1e82fdc7896c70064c39374522cd1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 23 May 2013 12:19:13 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5749 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/platforms/SPC563Mxx/spc563m_registry.h | 6 +- os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c | 186 +++++++++++++++++++------- os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h | 16 ++- os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c | 42 ------ os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h | 77 +++++++++++ 5 files changed, 228 insertions(+), 99 deletions(-) (limited to 'os') diff --git a/os/hal/platforms/SPC563Mxx/spc563m_registry.h b/os/hal/platforms/SPC563Mxx/spc563m_registry.h index bf3cca0d5..ce606e9d8 100644 --- a/os/hal/platforms/SPC563Mxx/spc563m_registry.h +++ b/os/hal/platforms/SPC563Mxx/spc563m_registry.h @@ -39,9 +39,11 @@ #define SPC5_HAS_DSPI2 TRUE #define SPC5_HAS_DSPI3 FALSE #define SPC5_DSPI_FIFO_DEPTH 16 -#define SPC5_DSPI1_TX_DMA_DEV_ID 12 +#define SPC5_DSPI1_TX1_DMA_DEV_ID 12 +#define SPC5_DSPI1_TX2_DMA_DEV_ID 25 #define SPC5_DSPI1_RX_DMA_DEV_ID 13 -#define SPC5_DSPI2_TX_DMA_DEV_ID 14 +#define SPC5_DSPI2_TX1_DMA_DEV_ID 14 +#define SPC5_DSPI2_TX2_DMA_DEV_ID 26 #define SPC5_DSPI2_RX_DMA_DEV_ID 15 #define SPC5_DSPI1_EOQF_HANDLER vector132 #define SPC5_DSPI1_EOQF_NUMBER 132 diff --git a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c index 6eac93577..9a273f850 100644 --- a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c +++ b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c @@ -15,8 +15,8 @@ */ /** - * @file templates/spi_lld.c - * @brief SPI Driver subsystem low level driver source template. + * @file SPC5xx/DSPI_v1/spi_lld.c + * @brief SPC5xx SPI subsystem low level driver source. * * @addtogroup SPI * @{ @@ -56,8 +56,6 @@ static void spi_serve_dma_error_irq(edma_channel_t channel, SPC5_PUSHR_EOQ | \ SPC5_PUSHR_TXDATA_MASK) -#define DSPI_PUSHR8_ADDRESS(spip) (((uint32_t)&(spip)->dspi->PUSHR.R) + 3) -#define DSPI_PUSHR16_ADDRESS(spip) (((uint32_t)&(spip)->dspi->PUSHR.R) + 2) #define DSPI_POPR8_ADDRESS(spip) (((uint32_t)&(spip)->dspi->POPR.R) + 3) #define DSPI_POPR16_ADDRESS(spip) (((uint32_t)&(spip)->dspi->POPR.R) + 2) @@ -99,10 +97,18 @@ SPIDriver SPID4; #if SPC5_SPI_USE_DSPI0 || defined(__DOXYGEN__) /** - * @brief DMA configuration for DSPI0 TX. + * @brief DMA configuration for DSPI0 TX1. */ -static const edma_channel_config_t spi_dspi0_tx_dma_config = { - SPC5_DSPI0_TX_DMA_DEV_ID, SPC5_SPI_DSPI0_DMA_PRIO, SPC5_SPI_DSPI0_DMA_PRIO, +static const edma_channel_config_t spi_dspi0_tx1_dma_config = { + SPC5_DSPI0_TX1_DMA_DEV_ID, SPC5_SPI_DSPI0_DMA_PRIO, SPC5_SPI_DSPI0_DMA_IRQ_PRIO, + NULL, spi_serve_dma_error_irq, &SPID1 +}; + +/** + * @brief DMA configuration for DSPI0 TX2. + */ +static const edma_channel_config_t spi_dspi0_tx2_dma_config = { + SPC5_DSPI0_TX2_DMA_DEV_ID, SPC5_SPI_DSPI0_DMA_PRIO, SPC5_SPI_DSPI0_DMA_IRQ_PRIO, NULL, spi_serve_dma_error_irq, &SPID1 }; @@ -110,17 +116,25 @@ static const edma_channel_config_t spi_dspi0_tx_dma_config = { * @brief DMA configuration for DSPI0 RX. */ static const edma_channel_config_t spi_dspi0_rx_dma_config = { - SPC5_DSPI0_RX_DMA_DEV_ID, SPC5_SPI_DSPI0_DMA_PRIO, SPC5_SPI_DSPI0_DMA_PRIO, + SPC5_DSPI0_RX_DMA_DEV_ID, SPC5_SPI_DSPI0_DMA_PRIO, SPC5_SPI_DSPI0_DMA_IRQ_PRIO, spi_serve_rx_irq, spi_serve_dma_error_irq, &SPID1 }; #endif /* SPC5_SPI_USE_DSPI0 */ #if SPC5_SPI_USE_DSPI1 || defined(__DOXYGEN__) /** - * @brief DMA configuration for DSPI1 TX. + * @brief DMA configuration for DSPI1 TX1. + */ +static const edma_channel_config_t spi_dspi1_tx1_dma_config = { + SPC5_DSPI1_TX1_DMA_DEV_ID, SPC5_SPI_DSPI1_DMA_PRIO, SPC5_SPI_DSPI1_DMA_IRQ_PRIO, + NULL, spi_serve_dma_error_irq, &SPID2 +}; + +/** + * @brief DMA configuration for DSPI1 TX2. */ -static const edma_channel_config_t spi_dspi1_tx_dma_config = { - SPC5_DSPI1_TX_DMA_DEV_ID, SPC5_SPI_DSPI1_DMA_PRIO, SPC5_SPI_DSPI1_DMA_PRIO, +static const edma_channel_config_t spi_dspi1_tx2_dma_config = { + SPC5_DSPI1_TX2_DMA_DEV_ID, SPC5_SPI_DSPI1_DMA_PRIO, SPC5_SPI_DSPI1_DMA_IRQ_PRIO, NULL, spi_serve_dma_error_irq, &SPID2 }; @@ -128,17 +142,25 @@ static const edma_channel_config_t spi_dspi1_tx_dma_config = { * @brief DMA configuration for DSPI1 RX. */ static const edma_channel_config_t spi_dspi1_rx_dma_config = { - SPC5_DSPI1_RX_DMA_DEV_ID, SPC5_SPI_DSPI1_DMA_PRIO, SPC5_SPI_DSPI1_DMA_PRIO, + SPC5_DSPI1_RX_DMA_DEV_ID, SPC5_SPI_DSPI1_DMA_PRIO, SPC5_SPI_DSPI1_DMA_IRQ_PRIO, spi_serve_rx_irq, spi_serve_dma_error_irq, &SPID2 }; #endif /* SPC5_SPI_USE_DSPI1 */ #if SPC5_SPI_USE_DSPI2 || defined(__DOXYGEN__) /** - * @brief DMA configuration for DSPI2 TX. + * @brief DMA configuration for DSPI2 TX1. */ -static const edma_channel_config_t spi_dspi2_tx_dma_config = { - SPC5_DSPI2_TX_DMA_DEV_ID, SPC5_SPI_DSPI2_DMA_PRIO, SPC5_SPI_DSPI2_DMA_PRIO, +static const edma_channel_config_t spi_dspi2_tx1_dma_config = { + SPC5_DSPI2_TX1_DMA_DEV_ID, SPC5_SPI_DSPI2_DMA_PRIO, SPC5_SPI_DSPI2_DMA_IRQ_PRIO, + NULL, spi_serve_dma_error_irq, &SPID3 +}; + +/** + * @brief DMA configuration for DSPI2 TX2. + */ +static const edma_channel_config_t spi_dspi2_tx2_dma_config = { + SPC5_DSPI2_TX2_DMA_DEV_ID, SPC5_SPI_DSPI2_DMA_PRIO, SPC5_SPI_DSPI2_DMA_IRQ_PRIO, NULL, spi_serve_dma_error_irq, &SPID3 }; @@ -146,17 +168,25 @@ static const edma_channel_config_t spi_dspi2_tx_dma_config = { * @brief DMA configuration for DSPI2 RX. */ static const edma_channel_config_t spi_dspi2_rx_dma_config = { - SPC5_DSPI2_RX_DMA_DEV_ID, SPC5_SPI_DSPI2_DMA_PRIO, SPC5_SPI_DSPI2_DMA_PRIO, + SPC5_DSPI2_RX_DMA_DEV_ID, SPC5_SPI_DSPI2_DMA_PRIO, SPC5_SPI_DSPI2_DMA_IRQ_PRIO, spi_serve_rx_irq, spi_serve_dma_error_irq, &SPID3 }; #endif /* SPC5_SPI_USE_DSPI2 */ #if SPC5_SPI_USE_DSPI3 || defined(__DOXYGEN__) /** - * @brief DMA configuration for DSPI3 TX. + * @brief DMA configuration for DSPI3 TX1. + */ +static const edma_channel_config_t spi_dspi3_tx1_dma_config = { + SPC5_DSPI3_TX1_DMA_DEV_ID, SPC5_SPI_DSPI3_DMA_PRIO, SPC5_SPI_DSPI3_DMA_IRQ_PRIO, + NULL, spi_serve_dma_error_irq, &SPID4 +}; + +/** + * @brief DMA configuration for DSPI3 TX2. */ -static const edma_channel_config_t spi_dspi3_tx_dma_config = { - SPC5_DSPI3_TX_DMA_DEV_ID, SPC5_SPI_DSPI3_DMA_PRIO, SPC5_SPI_DSPI3_DMA_PRIO, +static const edma_channel_config_t spi_dspi3_tx2_dma_config = { + SPC5_DSPI3_TX2_DMA_DEV_ID, SPC5_SPI_DSPI3_DMA_PRIO, SPC5_SPI_DSPI3_DMA_IRQ_PRIO, NULL, spi_serve_dma_error_irq, &SPID4 }; @@ -164,7 +194,7 @@ static const edma_channel_config_t spi_dspi3_tx_dma_config = { * @brief DMA configuration for DSPI3 RX. */ static const edma_channel_config_t spi_dspi3_rx_dma_config = { - SPC5_DSPI3_RX_DMA_DEV_ID, SPC5_SPI_DSPI3_DMA_PRIO, SPC5_SPI_DSPI3_DMA_PRIO, + SPC5_DSPI3_RX_DMA_DEV_ID, SPC5_SPI_DSPI3_DMA_PRIO, SPC5_SPI_DSPI3_DMA_IRQ_PRIO, spi_serve_rx_irq, spi_serve_dma_error_irq, &SPID4 }; #endif /* SPC5_SPI_USE_DSPI3 */ @@ -243,29 +273,47 @@ static void spi_start_dma_rx16(SPIDriver *spip, static void spi_start_dma_tx8(SPIDriver *spip, size_t n, const uint8_t *txbuf) { - uint32_t cmd = spip->config->pushr & ~DSPI_PUSHR_EXCLUDED_BITS; - uint8_t *cp = (uint8_t *)DSPI_PUSHR8_ADDRESS(spip); - /* The first frame is pushed by the CPU, then the DMA is activated to - send the following frames.*/ - spip->dspi->PUSHR.R = cmd | (uint32_t)*txbuf++; - *cp = 0x55; + /* Preparing the TX intermediate buffer with the fixed part.*/ + spip->tx_intbuf = spip->config->pushr & ~DSPI_PUSHR_EXCLUDED_BITS; - /* Setting up TX DMA TCD parameters for 8 bits transfers.*/ - edmaChannelSetup(spip->tx_channel, /* channel. */ + /* The first frame is pushed by the CPU, then the DMA is activated to + send the following frames. This should reduce latency on the operation + start.*/ + spip->dspi->PUSHR.R = spip->tx_intbuf | (uint32_t)*txbuf++; + + /* Setting up TX1 DMA TCD parameters for 8 bits transfers.*/ + edmaChannelSetupLinkedOnMinor( + spip->tx1_channel, /* channel. */ + spip->tx2_channel, /* linkch. */ txbuf, /* src. */ - DSPI_PUSHR8_ADDRESS(spip), /* dst. */ + ((const uint8_t *)&spip->tx_intbuf) + 3, /* dst. */ 1, /* soff, advance by 1. */ 0, /* doff, do not advance. */ 0, /* ssize, 8 bits transfers. */ 0, /* dsize, 8 bits transfers. */ 1, /* nbytes, always one. */ + n/* - 1*/, /* iter. */ + 0, /* slast, no source adjust. */ + 0, /* dlast, no dest.adjust. */ + EDMA_TCD_MODE_DREQ); /* mode. */ + + /* Setting up TX2 DMA TCD parameters for 32 bits transfers.*/ + edmaChannelSetup(spip->tx2_channel, /* channel. */ + &spip->tx_intbuf, /* src. */ + &spip->dspi->PUSHR.R, /* dst. */ + 0, /* soff, do not advance. */ + 0, /* doff, do not advance. */ + 2, /* ssize, 32 bits transfers.*/ + 2, /* dsize, 32 bits transfers.*/ + 4, /* nbytes, always four. */ n - 1, /* iter. */ 0, /* slast, no source adjust. */ 0, /* dlast, no dest.adjust. */ EDMA_TCD_MODE_DREQ); /* mode. */ - edmaChannelStart(spip->tx_channel); + edmaChannelStart(spip->tx1_channel); + edmaChannelStart(spip->tx2_channel); } /** @@ -280,17 +328,20 @@ static void spi_start_dma_tx8(SPIDriver *spip, static void spi_start_dma_tx16(SPIDriver *spip, size_t n, const uint16_t *txbuf) { - uint32_t cmd = spip->config->pushr & ~DSPI_PUSHR_EXCLUDED_BITS; + + /* Preparing the TX intermediate buffer with the fixed part.*/ + spip->tx_intbuf = spip->config->pushr & ~DSPI_PUSHR_EXCLUDED_BITS; /* The first frame is pushed by the CPU, then the DMA is activated to - send the following frames.*/ - spip->dspi->PUSHR.R = cmd | (uint32_t)*txbuf++; + send the following frames. This should reduce latency on the operation + start.*/ + spip->dspi->PUSHR.R = spip->tx_intbuf | (uint32_t)*txbuf++; - /* Setting up TX DMA TCD parameters for 16 bits transfers.*/ - edmaChannelSetup(spip->tx_channel, /* channel. */ + /* Setting up TX1 DMA TCD parameters for 16 bits transfers.*/ + edmaChannelSetup(spip->tx1_channel, /* channel. */ txbuf, /* src. */ - DSPI_PUSHR16_ADDRESS(spip), /* dst. */ - 2, /* soff, advance by 2. */ + ((const uint8_t *)&spip->tx_intbuf) + 2, /* dst. */ + 1, /* soff, advance by 1. */ 0, /* doff, do not advance. */ 1, /* ssize, 16 bits transfers.*/ 1, /* dsize, 16 bits transfers.*/ @@ -298,9 +349,26 @@ static void spi_start_dma_tx16(SPIDriver *spip, n - 1, /* iter. */ 0, /* slast, no source adjust. */ 0, /* dlast, no dest.adjust. */ + EDMA_TCD_MODE_DREQ | + EDMA_TCD_MODE_MELINK | + EDMA_TCD_MODE_MLINKCH(spip->tx2_channel)); /* mode. */ + + /* Setting up TX2 DMA TCD parameters for 32 bits transfers.*/ + edmaChannelSetup(spip->tx2_channel, /* channel. */ + &spip->tx_intbuf, /* src. */ + &spip->dspi->PUSHR.R, /* dst. */ + 0, /* soff, do not advance. */ + 0, /* doff, do not advance. */ + 2, /* ssize, 32 bits transfers.*/ + 2, /* dsize, 32 bits transfers.*/ + 4, /* nbytes, always four. */ + n - 1, /* iter. */ + 0, /* slast, no source adjust. */ + 0, /* dlast, no dest.adjust. */ EDMA_TCD_MODE_DREQ); /* mode. */ - edmaChannelStart(spip->tx_channel); + edmaChannelStart(spip->tx1_channel); + edmaChannelStart(spip->tx2_channel); } /** @@ -377,6 +445,10 @@ static void spi_serve_dma_error_irq(edma_channel_t channel, spip->dspi->MCR.R = SPC5_MCR_MSTR | SPC5_MCR_HALT | SPC5_MCR_CLR_TXF | SPC5_MCR_CLR_RXF; + edmaChannelStop(spip->tx1_channel); + edmaChannelStop(spip->tx2_channel); + edmaChannelStop(spip->rx_channel); + SPC5_SPI_DMA_ERROR_HOOK(spip); } @@ -399,32 +471,36 @@ void spi_lld_init(void) { /* Driver initialization.*/ spiObjectInit(&SPID1); SPID1.dspi = &SPC5_DSPI0; - SPID1.tx_channel = EDMA_ERROR; - SPID1.rx_channel = EDMA_ERROR; + SPID1.tx1_channel = EDMA_ERROR; + SPID1.tx2_channel = EDMA_ERROR; + SPID1.rx_channel = EDMA_ERROR; #endif /* SPC5_SPI_USE_DSPI0 */ #if SPC5_SPI_USE_DSPI1 /* Driver initialization.*/ spiObjectInit(&SPID2); SPID2.dspi = &SPC5_DSPI1; - SPID2.tx_channel = EDMA_ERROR; - SPID2.rx_channel = EDMA_ERROR; + SPID2.tx1_channel = EDMA_ERROR; + SPID2.tx2_channel = EDMA_ERROR; + SPID2.rx_channel = EDMA_ERROR; #endif /* SPC5_SPI_USE_DSPI1 */ #if SPC5_SPI_USE_DSPI2 /* Driver initialization.*/ spiObjectInit(&SPID3); SPID3.dspi = &SPC5_DSPI2; - SPID3.tx_channel = EDMA_ERROR; - SPID3.rx_channel = EDMA_ERROR; + SPID3.tx1_channel = EDMA_ERROR; + SPID3.tx2_channel = EDMA_ERROR; + SPID3.rx_channel = EDMA_ERROR; #endif /* SPC5_SPI_USE_DSPI2 */ #if SPC5_SPI_USE_DSPI03 /* Driver initialization.*/ spiObjectInit(&SPID4); SPID4.dspi = &SPC5_DSPI3; - SPID4.tx_channel = EDMA_ERROR; - SPID4.rx_channel = EDMA_ERROR; + SPID4.tx1_channel = EDMA_ERROR; + SPID4.tx2_channel = EDMA_ERROR; + SPID4.rx_channel = EDMA_ERROR; #endif /* SPC5_SPI_USE_DSPI3 */ } @@ -443,7 +519,8 @@ void spi_lld_start(SPIDriver *spip) { #if SPC5_SPI_USE_DSPI0 if (&SPID1 == spip) { SPC5_DSPI0_ENABLE_CLOCK(); - spip->tx_channel = edmaChannelAllocate(&spi_dspi0_tx_dma_config); + spip->tx1_channel = edmaChannelAllocate(&spi_dspi0_tx1_dma_config); + spip->tx2_channel = edmaChannelAllocate(&spi_dspi0_tx2_dma_config); spip->rx_channel = edmaChannelAllocate(&spi_dspi0_rx_dma_config); } #endif /* SPC5_SPI_USE_DSPI0 */ @@ -451,7 +528,8 @@ void spi_lld_start(SPIDriver *spip) { #if SPC5_SPI_USE_DSPI1 if (&SPID2 == spip) { SPC5_DSPI1_ENABLE_CLOCK(); - spip->tx_channel = edmaChannelAllocate(&spi_dspi1_tx_dma_config); + spip->tx1_channel = edmaChannelAllocate(&spi_dspi1_tx1_dma_config); + spip->tx2_channel = edmaChannelAllocate(&spi_dspi1_tx2_dma_config); spip->rx_channel = edmaChannelAllocate(&spi_dspi1_rx_dma_config); } #endif /* SPC5_SPI_USE_DSPI1 */ @@ -459,7 +537,8 @@ void spi_lld_start(SPIDriver *spip) { #if SPC5_SPI_USE_DSPI2 if (&SPID3 == spip) { SPC5_DSPI2_ENABLE_CLOCK(); - spip->tx_channel = edmaChannelAllocate(&spi_dspi2_tx_dma_config); + spip->tx1_channel = edmaChannelAllocate(&spi_dspi2_tx1_dma_config); + spip->tx2_channel = edmaChannelAllocate(&spi_dspi2_tx2_dma_config); spip->rx_channel = edmaChannelAllocate(&spi_dspi2_rx_dma_config); } #endif /* SPC5_SPI_USE_DSPI2 */ @@ -467,12 +546,13 @@ void spi_lld_start(SPIDriver *spip) { #if SPC5_SPI_USE_DSPI3 if (&SPID4 == spip) { SPC5_DSPI3_ENABLE_CLOCK(); - spip->tx_channel = edmaChannelAllocate(&spi_dspi3_tx_dma_config); + spip->tx1_channel = edmaChannelAllocate(&spi_dspi3_tx1_dma_config); + spip->tx2_channel = edmaChannelAllocate(&spi_dspi3_tx2_dma_config); spip->rx_channel = edmaChannelAllocate(&spi_dspi3_rx_dma_config); } #endif /* SPC5_SPI_USE_DSPI3 */ - chDbgAssert((spip->tx_channel != EDMA_ERROR) && + chDbgAssert((spip->tx1_channel != EDMA_ERROR) && (spip->rx_channel != EDMA_ERROR), "spi_lld_start(), #1", "channel cannot be allocated"); } @@ -496,7 +576,8 @@ void spi_lld_stop(SPIDriver *spip) { if (spip->state == SPI_READY) { /* Releases the allocated EDMA channels.*/ - edmaChannelRelease(spip->tx_channel); + edmaChannelRelease(spip->tx1_channel); + edmaChannelRelease(spip->tx2_channel); edmaChannelRelease(spip->rx_channel); /* Resets the peripheral.*/ @@ -597,6 +678,7 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { /* Starting transfer.*/ + spip->dspi->SR.R = spip->dspi->SR.R; spip->dspi->MCR.B.HALT = 0; /* DMAs require a different setup depending on the frame size.*/ diff --git a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h index 1b0be8208..f16667f90 100644 --- a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h +++ b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h @@ -15,8 +15,8 @@ */ /** - * @file templates/spi_lld.h - * @brief SPI Driver subsystem low level driver header template. + * @file SPC5xx/DSPI_v1/spi_lld.h + * @brief SPC5xx SPI subsystem low level driver header. * * @addtogroup SPI * @{ @@ -420,14 +420,24 @@ struct SPIDriver { * @brief Pointer to the DSPI registers block. */ struct spc5_dspi *dspi; + /** + * @brief EDMA channel used for data memory to memory copy. + */ + edma_channel_t tx1_channel; /** * @brief EDMA channel used for transmit. */ - edma_channel_t tx_channel; + edma_channel_t tx2_channel; /** * @brief EDMA channel used for receive. */ edma_channel_t rx_channel; + /** + * @brief TX intermediate buffer. + * @note This field is written by the TX1 DMA channel and read by the + * TX2 DMA channel. + */ + uint32_t tx_intbuf; }; /*===========================================================================*/ diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c index b48cb1c30..4504afd68 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c @@ -1363,48 +1363,6 @@ void edmaChannelRelease(edma_channel_t channel) { channels[channel] = NULL; } -/** - * @brief EDMA channel setup. - * - * @param[in] channel eDMA channel number - * @param[in] src source address - * @param[in] dst destination address - * @param[in] soff source address offset - * @param[in] doff destination address offset - * @param[in] ssize source transfer size - * @param[in] dsize destination transfer size - * @param[in] nbytes minor loop count - * @param[in] iter major loop count - * @param[in] dlast_sga Last Destination Address Adjustment or - * Scatter Gather Address - * @param[in] slast last source address adjustment - * @param[in] mode LSW of TCD register 7 - */ -void edmaChannelSetupx(edma_channel_t channel, - void *src, - void *dst, - uint32_t soff, - uint32_t doff, - uint32_t ssize, - uint32_t dsize, - uint32_t nbytes, - uint32_t iter, - uint32_t slast, - uint32_t dlast, - uint32_t mode) { - - edma_tcd_t *tcdp = edmaGetTCD(channel); - - tcdp->word[0] = (uint32_t)src; - tcdp->word[1] = (ssize << 24) | (dsize << 16) | soff; - tcdp->word[2] = nbytes; - tcdp->word[3] = slast; - tcdp->word[0] = (uint32_t)dst; - tcdp->word[5] = (iter << 16) | doff; - tcdp->word[6] = dlast; - tcdp->word[7] = (iter << 16) | mode; -} - #endif /* SPC5_HAS_EDMA */ /** @} */ diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h index 1e20b41e7..767eb11ff 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h @@ -44,8 +44,14 @@ #define EDMA_TCD_MODE_INT_END (1U << 1) #define EDMA_TCD_MODE_INT_HALF (1U << 2) #define EDMA_TCD_MODE_DREQ (1U << 3) +#define EDMA_TCD_MODE_SG (1U << 4) +#define EDMA_TCD_MODE_MELINK (1U << 5) #define EDMA_TCD_MODE_ACTIVE (1U << 6) #define EDMA_TCD_MODE_DONE (1U << 7) +#define EDMA_TCD_MODE_MLINKCH_MASK (63U << 8) +#define EDMA_TCD_MODE_MLINKCH(n) ((uint32_t)(n) << 8) +#define EDMA_TCD_MODE_BWC_MASK (3U << 14) +#define EDMA_TCD_MODE_BWC(n) ((uint32_t)(n) << 14) /** @} */ /*===========================================================================*/ @@ -735,6 +741,24 @@ typedef struct { ((tcdp)->word[5] = (((uint32_t)(citer) << 16) | \ ((uint32_t)(doff) << 0))) +/** + * @brief Sets the word 5 fields into a TCD. + * @note Transfers are limited to 511 operations using this modality + * (citer parameter). + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] linkch channel linked on minor loop counter + * @param[in] citer the current outer counter value + * @param[in] doff the destination increment value + * + * @api + */ +#define edmaTCDSetWord5LinkedOnMinor(tcdp, linkch, citer, doff) \ + ((tcdp)->word[5] = (((uint32_t)0x80000000) | \ + ((uint32_t)(linkch) << 25) | \ + ((uint32_t)(citer) << 16) | \ + ((uint32_t)(doff) << 0))) + /** * @brief Sets the word 6 fields into a TCD. * @@ -759,6 +783,24 @@ typedef struct { ((tcdp)->word[7] = (((uint32_t)(biter) << 16) | \ ((uint32_t)(mode) << 0))) +/** + * @brief Sets the word 7 fields into a TCD. + * @note Transfers are limited to 511 operations using this modality + * (biter parameter). + * + * @param[in] tcdp pointer to an @p edma_tcd_t structure + * @param[in] linkch channel linked on minor loop counter + * @param[in] biter the base outer counter value + * @param[in] mode the mode value + * + * @api + */ +#define edmaTCDSetWord7LinkedOnMinor(tcdp, linkch, biter, mode) \ + ((tcdp)->word[7] = (((uint32_t)0x80000000) | \ + ((uint32_t)(linkch) << 25) | \ + ((uint32_t)(biter) << 16) | \ + ((uint32_t)(mode) << 0))) + /** * @brief Starts or restarts an EDMA channel. * @@ -811,6 +853,41 @@ typedef struct { edmaTCDSetWord7(tcdp, iter, mode); \ } +/** + * @brief EDMA channel setup with linked channel on minor loop counter. + * @note Transfers are limited to 511 operations using this modality + * (iter parameter). + * + * @param[in] channel eDMA channel number + * @param[in] linkch channel linked on minor loop counter + * @param[in] src source address + * @param[in] dst destination address + * @param[in] soff source address offset + * @param[in] doff destination address offset + * @param[in] ssize source transfer size + * @param[in] dsize destination transfer size + * @param[in] nbytes minor loop count + * @param[in] iter major loop count + * @param[in] dlast last destination address adjustment + * @param[in] slast last source address adjustment + * @param[in] mode LSW of TCD register 7 + * + * @api + */ +#define edmaChannelSetupLinkedOnMinor(channel, linkch, src, dst, soff, \ + doff, ssize, dsize, nbytes, iter, \ + slast, dlast, mode) { \ + edma_tcd_t *tcdp = edmaGetTCD(channel); \ + edmaTCDSetWord0(tcdp, src); \ + edmaTCDSetWord1(tcdp, ssize, dsize, soff); \ + edmaTCDSetWord2(tcdp, nbytes); \ + edmaTCDSetWord3(tcdp, slast); \ + edmaTCDSetWord4(tcdp, dst); \ + edmaTCDSetWord5LinkedOnMinor(tcdp, linkch, iter, doff); \ + edmaTCDSetWord6(tcdp, dlast); \ + edmaTCDSetWord7LinkedOnMinor(tcdp, linkch, iter, mode); \ +} + /*===========================================================================*/ /* External declarations. */ /*===========================================================================*/ -- cgit v1.2.3