From ae1cb6d0d72b16c7d7c8c2a7194aeb51d8c6642f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 10 Jun 2013 11:43:41 +0000 Subject: [PATCH] DSPI and DMA-MUX support for SPC5xx. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5830 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/Doxyfile_chm | 2 +- docs/Doxyfile_html | 2 +- os/hal/platforms/SPC560Pxx/spc560p_registry.h | 41 ++++-- os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c | 101 ++++++++++++++- os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h | 121 +++++++++++++++++- os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c | 21 ++- os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h | 23 +++- os/kernel/include/ch.h | 6 +- readme.txt | 2 + 9 files changed, 296 insertions(+), 23 deletions(-) diff --git a/docs/Doxyfile_chm b/docs/Doxyfile_chm index c809b3cbe..8b2f242f9 100644 --- a/docs/Doxyfile_chm +++ b/docs/Doxyfile_chm @@ -31,7 +31,7 @@ PROJECT_NAME = ChibiOS/RT # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 2.5.2 +PROJECT_NUMBER = 2.7.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/docs/Doxyfile_html b/docs/Doxyfile_html index 0c1f8acb8..d18b5eb97 100644 --- a/docs/Doxyfile_html +++ b/docs/Doxyfile_html @@ -31,7 +31,7 @@ PROJECT_NAME = ChibiOS/RT # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 2.5.2 +PROJECT_NUMBER = 2.7.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer diff --git a/os/hal/platforms/SPC560Pxx/spc560p_registry.h b/os/hal/platforms/SPC560Pxx/spc560p_registry.h index f4d9462e5..18107f065 100644 --- a/os/hal/platforms/SPC560Pxx/spc560p_registry.h +++ b/os/hal/platforms/SPC560Pxx/spc560p_registry.h @@ -90,6 +90,9 @@ #define SPC5_HAS_DSPI1 TRUE #define SPC5_HAS_DSPI2 TRUE #define SPC5_DSPI_FIFO_DEPTH 5 +#define SPC5_DSPI0_PCTL 4 +#define SPC5_DSPI1_PCTL 5 +#define SPC5_DSPI2_PCTL 6 #define SPC5_DSPI0_TX1_DMA_DEV_ID 1 #define SPC5_DSPI0_TX2_DMA_DEV_ID 0 #define SPC5_DSPI0_RX_DMA_DEV_ID 2 @@ -105,35 +108,47 @@ #define SPC5_DSPI1_TFFF_NUMBER 96 #define SPC5_DSPI2_TFFF_HANDLER vector116 #define SPC5_DSPI2_TFFF_NUMBER 116 -#define SPC5_DSPI0_ENABLE_CLOCK() -#define SPC5_DSPI0_DISABLE_CLOCK() -#define SPC5_DSPI1_ENABLE_CLOCK() -#define SPC5_DSPI1_DISABLE_CLOCK() -#define SPC5_DSPI2_ENABLE_CLOCK() -#define SPC5_DSPI2_DISABLE_CLOCK() +#define SPC5_DSPI0_ENABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI0_PCTL, SPC5_SPI_DSPI0_START_PCTL) +#define SPC5_DSPI0_DISABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI0_PCTL, SPC5_SPI_DSPI0_STOP_PCTL) +#define SPC5_DSPI1_ENABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI1_PCTL, SPC5_SPI_DSPI1_START_PCTL) +#define SPC5_DSPI1_DISABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI1_PCTL, SPC5_SPI_DSPI1_STOP_PCTL) +#define SPC5_DSPI2_ENABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI2_PCTL, SPC5_SPI_DSPI2_START_PCTL) +#define SPC5_DSPI2_DISABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI2_PCTL, SPC5_SPI_DSPI2_STOP_PCTL) #if defined(_SPC560PXX_MEDIUM_) || defined(_SPC560PXX_LARGE_) #define SPC5_HAS_DSPI3 TRUE +#define SPC5_DSPI3_PCTL 7 #define SPC5_DSPI3_TX1_DMA_DEV_ID 7 #define SPC5_DSPI3_TX2_DMA_DEV_ID 0 #define SPC5_DSPI3_RX_DMA_DEV_ID 8 #define SPC5_DSPI3_TFFF_HANDLER vector219 #define SPC5_DSPI3_TFFF_NUMBER 219 -#define SPC5_DSPI3_ENABLE_CLOCK() -#define SPC5_DSPI3_DISABLE_CLOCK() +#define SPC5_DSPI3_ENABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI3_PCTL, SPC5_SPI_DSPI3_START_PCTL) +#define SPC5_DSPI3_DISABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI3_PCTL, SPC5_SPI_DSPI3_STOP_PCTL) #else #define SPC5_HAS_DSPI3 FALSE #endif #if defined(_SPC560PXX_LARGE_) #define SPC5_HAS_DSPI4 TRUE +#define SPC5_DSPI4_PCTL 8 #define SPC5_DSPI4_TX1_DMA_DEV_ID 15 #define SPC5_DSPI4_TX2_DMA_DEV_ID 0 #define SPC5_DSPI4_RX_DMA_DEV_ID 21 #define SPC5_DSPI4_TFFF_HANDLER vector258 #define SPC5_DSPI4_TFFF_NUMBER 258 -#define SPC5_DSPI4_ENABLE_CLOCK() -#define SPC5_DSPI4_DISABLE_CLOCK() +#define SPC5_DSPI4_ENABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI4_PCTL, SPC5_SPI_DSPI4_START_PCTL) +#define SPC5_DSPI4_DISABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_DSPI0_PCTL, SPC5_SPI_DSPI4_STOP_PCTL) #else #define SPC5_HAS_DSPI4 FALSE #endif @@ -279,8 +294,10 @@ #define SPC5_FLEXCAN0_FLEXCAN_BUF_08_11_NUMBER 70 #define SPC5_FLEXCAN0_FLEXCAN_BUF_12_15_NUMBER 71 #define SPC5_FLEXCAN0_FLEXCAN_BUF_16_31_NUMBER 72 -#define SPC5_FLEXCAN0_ENABLE_CLOCK() halSPCSetPeripheralClockMode(SPC5_FLEXCAN0_PCTL, SPC5_CAN_FLEXCAN0_START_PCTL); -#define SPC5_FLEXCAN0_DISABLE_CLOCK() halSPCSetPeripheralClockMode(SPC5_FLEXCAN0_PCTL, SPC5_CAN_FLEXCAN0_STOP_PCTL); +#define SPC5_FLEXCAN0_ENABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_FLEXCAN0_PCTL, SPC5_CAN_FLEXCAN0_START_PCTL) +#define SPC5_FLEXCAN0_DISABLE_CLOCK() \ + halSPCSetPeripheralClockMode(SPC5_FLEXCAN0_PCTL, SPC5_CAN_FLEXCAN0_STOP_PCTL) /** @} */ #endif /* _SPC560P_REGISTRY_H_ */ diff --git a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c index f4c0bef9e..fd7222509 100644 --- a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c +++ b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c @@ -78,6 +78,13 @@ SPIDriver SPID3; SPIDriver SPID4; #endif +/** + * @brief SPID5 driver identifier. + */ +#if SPC5_SPI_USE_DSPI4 || defined(__DOXYGEN__) +SPIDriver SPID5; +#endif + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -186,6 +193,32 @@ static const edma_channel_config_t spi_dspi3_rx_dma_config = { }; #endif /* SPC5_SPI_USE_DSPI3 */ +#if SPC5_SPI_USE_DSPI4 || defined(__DOXYGEN__) +/** + * @brief DMA configuration for DSPI4 TX1. + */ +static const edma_channel_config_t spi_dspi4_tx1_dma_config = { + SPC5_DSPI4_TX1_DMA_DEV_ID, SPC5_SPI_DSPI4_DMA_PRIO, SPC5_SPI_DSPI4_DMA_IRQ_PRIO, + spi_serve_tx_irq, spi_serve_dma_error_irq, &SPID5 +}; + +/** + * @brief DMA configuration for DSPI4 TX2. + */ +static const edma_channel_config_t spi_dspi4_tx2_dma_config = { + SPC5_DSPI4_TX2_DMA_DEV_ID, SPC5_SPI_DSPI4_DMA_PRIO, SPC5_SPI_DSPI4_DMA_IRQ_PRIO, + spi_serve_tx_irq, spi_serve_dma_error_irq, &SPID5 +}; + +/** + * @brief DMA configuration for DSPI4 RX. + */ +static const edma_channel_config_t spi_dspi4_rx_dma_config = { + SPC5_DSPI4_RX_DMA_DEV_ID, SPC5_SPI_DSPI4_DMA_PRIO, SPC5_SPI_DSPI4_DMA_IRQ_PRIO, + spi_serve_rx_irq, spi_serve_dma_error_irq, &SPID5 +}; +#endif /* SPC5_SPI_USE_DSPI4 */ + /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ @@ -699,6 +732,35 @@ CH_IRQ_HANDLER(SPC5_DSPI3_TFFF_HANDLER) { } #endif /* SPC5_SPI_USE_DSPI3 */ +#if SPC5_SPI_USE_DSPI4 || defined(__DOXYGEN__) +#if !defined(SPC5_DSPI4_TFFF_HANDLER) +#error "SPC5_DSPI4_TFFF_HANDLER not defined" +#endif +/** + * @brief DSPI4 TFFF interrupt handler. + * + * @isr + */ +CH_IRQ_HANDLER(SPC5_DSPI4_TFFF_HANDLER) { + + CH_IRQ_PROLOGUE(); + + chSysLockFromIsr(); + + /* Interrupt served and back to DMA mode.*/ + SPC5_DSPI4.RSER.B.TFFFDIRS = 1; + SPC5_DSPI4.SR.B.TFFF = 1; + + /* Pushing last frame.*/ + SPC5_DSPI4.PUSHR.R = (SPID5.config->pushr | SPID5.tx_last | SPC5_PUSHR_EOQ) & + ~SPC5_PUSHR_CONT; + + chSysUnlockFromIsr(); + + CH_IRQ_EPILOGUE(); +} +#endif /* SPC5_SPI_USE_DSPI4 */ + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -717,8 +779,10 @@ void spi_lld_init(void) { SPID1.tx1_channel = EDMA_ERROR; SPID1.tx2_channel = EDMA_ERROR; SPID1.rx_channel = EDMA_ERROR; + SPC5_DSPI0_ENABLE_CLOCK(); SPC5_DSPI0.MCR.R = SPC5_MCR_MSTR | SPC5_MCR_HALT | SPC5_MCR_MDIS | SPC5_SPI_DSPI0_MCR; + SPC5_DSPI0_DISABLE_CLOCK(); INTC.PSR[SPC5_DSPI0_TFFF_NUMBER].R = SPC5_SPI_DSPI0_IRQ_PRIO; #endif /* SPC5_SPI_USE_DSPI0 */ @@ -729,8 +793,10 @@ void spi_lld_init(void) { SPID2.tx1_channel = EDMA_ERROR; SPID2.tx2_channel = EDMA_ERROR; SPID2.rx_channel = EDMA_ERROR; + SPC5_DSPI1_ENABLE_CLOCK(); SPC5_DSPI1.MCR.R = SPC5_MCR_MSTR | SPC5_MCR_HALT | SPC5_MCR_MDIS | SPC5_SPI_DSPI1_MCR; + SPC5_DSPI1_DISABLE_CLOCK(); INTC.PSR[SPC5_DSPI1_TFFF_NUMBER].R = SPC5_SPI_DSPI1_IRQ_PRIO; #endif /* SPC5_SPI_USE_DSPI1 */ @@ -741,22 +807,40 @@ void spi_lld_init(void) { SPID3.tx1_channel = EDMA_ERROR; SPID3.tx2_channel = EDMA_ERROR; SPID3.rx_channel = EDMA_ERROR; + SPC5_DSPI2_ENABLE_CLOCK(); SPC5_DSPI2.MCR.R = SPC5_MCR_MSTR | SPC5_MCR_HALT | SPC5_MCR_MDIS | SPC5_SPI_DSPI2_MCR; + SPC5_DSPI2_DISABLE_CLOCK(); INTC.PSR[SPC5_DSPI2_TFFF_NUMBER].R = SPC5_SPI_DSPI2_IRQ_PRIO; #endif /* SPC5_SPI_USE_DSPI2 */ -#if SPC5_SPI_USE_DSPI03 +#if SPC5_SPI_USE_DSPI3 /* Driver initialization.*/ spiObjectInit(&SPID4); SPID4.dspi = &SPC5_DSPI3; SPID4.tx1_channel = EDMA_ERROR; SPID4.tx2_channel = EDMA_ERROR; SPID4.rx_channel = EDMA_ERROR; + SPC5_DSPI3_ENABLE_CLOCK(); SPC5_DSPI3.MCR.R = SPC5_MCR_MSTR | SPC5_MCR_HALT | SPC5_MCR_MDIS | SPC5_SPI_DSPI3_MCR; + SPC5_DSPI3_DISABLE_CLOCK(); INTC.PSR[SPC5_DSPI3_TFFF_NUMBER].R = SPC5_SPI_DSPI3_IRQ_PRIO; #endif /* SPC5_SPI_USE_DSPI3 */ + +#if SPC5_SPI_USE_DSPI4 + /* Driver initialization.*/ + spiObjectInit(&SPID5); + SPID5.dspi = &SPC5_DSPI4; + SPID5.tx1_channel = EDMA_ERROR; + SPID5.tx2_channel = EDMA_ERROR; + SPID5.rx_channel = EDMA_ERROR; + SPC5_DSPI4_ENABLE_CLOCK(); + SPC5_DSPI4.MCR.R = SPC5_MCR_MSTR | SPC5_MCR_HALT | SPC5_MCR_MDIS | + SPC5_SPI_DSPI4_MCR; + SPC5_DSPI4_DISABLE_CLOCK(); + INTC.PSR[SPC5_DSPI4_TFFF_NUMBER].R = SPC5_SPI_DSPI4_IRQ_PRIO; +#endif /* SPC5_SPI_USE_DSPI4 */ } /** @@ -810,6 +894,15 @@ void spi_lld_start(SPIDriver *spip) { } #endif /* SPC5_SPI_USE_DSPI3 */ +#if SPC5_SPI_USE_DSPI4 + if (&SPID5 == spip) { + SPC5_DSPI4_ENABLE_CLOCK(); + spip->tx1_channel = edmaChannelAllocate(&spi_dspi4_tx1_dma_config); + spip->tx2_channel = edmaChannelAllocate(&spi_dspi4_tx2_dma_config); + spip->rx_channel = edmaChannelAllocate(&spi_dspi4_rx_dma_config); + } +#endif /* SPC5_SPI_USE_DSPI5 */ + chDbgAssert((spip->tx1_channel != EDMA_ERROR) && (spip->tx2_channel != EDMA_ERROR) && (spip->rx_channel != EDMA_ERROR), @@ -870,6 +963,12 @@ void spi_lld_stop(SPIDriver *spip) { SPC5_DSPI3_DISABLE_CLOCK(); } #endif /* SPC5_SPI_USE_DSPI3 */ + +#if SPC5_SPI_USE_DSPI4 + if (&SPID5 == spip) { + SPC5_DSPI4_DISABLE_CLOCK(); + } +#endif /* SPC5_SPI_USE_DSPI4 */ } } diff --git a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h index dd92d06e3..1f4b62572 100644 --- a/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h +++ b/os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h @@ -386,6 +386,116 @@ #if !defined(SPC5_SPI_DSPI3_IRQ_PRIO) || defined(__DOXYGEN__) #define SPC5_SPI_DSPI3_IRQ_PRIO 10 #endif + +/** + * @brief DSPI0 peripheral configuration when started. + * @note The default configuration is 1 (always run) in run mode and + * 2 (only halt) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI0_START_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI0_START_PCTL (SPC5_ME_PCTL_RUN(1) | \ + SPC5_ME_PCTL_LP(2)) +#endif + +/** + * @brief DSPI0 peripheral configuration when stopped. + * @note The default configuration is 0 (never run) in run mode and + * 0 (never run) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI0_STOP_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI0_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \ + SPC5_ME_PCTL_LP(0)) +#endif + +/** + * @brief DSPI1 peripheral configuration when started. + * @note The default configuration is 1 (always run) in run mode and + * 2 (only halt) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI1_START_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI1_START_PCTL (SPC5_ME_PCTL_RUN(1) | \ + SPC5_ME_PCTL_LP(2)) +#endif + +/** + * @brief DSPI1 peripheral configuration when stopped. + * @note The default configuration is 0 (never run) in run mode and + * 0 (never run) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI1_STOP_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI1_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \ + SPC5_ME_PCTL_LP(0)) +#endif + +/** + * @brief DSPI2 peripheral configuration when started. + * @note The default configuration is 1 (always run) in run mode and + * 2 (only halt) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI2_START_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI2_START_PCTL (SPC5_ME_PCTL_RUN(1) | \ + SPC5_ME_PCTL_LP(2)) +#endif + +/** + * @brief DSPI2 peripheral configuration when stopped. + * @note The default configuration is 0 (never run) in run mode and + * 0 (never run) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI2_STOP_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI2_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \ + SPC5_ME_PCTL_LP(0)) +#endif + +/** + * @brief DSPI3 peripheral configuration when started. + * @note The default configuration is 1 (always run) in run mode and + * 2 (only halt) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI3_START_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI3_START_PCTL (SPC5_ME_PCTL_RUN(1) | \ + SPC5_ME_PCTL_LP(2)) +#endif + +/** + * @brief DSPI3 peripheral configuration when stopped. + * @note The default configuration is 0 (never run) in run mode and + * 0 (never run) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI3_STOP_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI3_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \ + SPC5_ME_PCTL_LP(0)) +#endif + +/** + * @brief DSPI4 peripheral configuration when started. + * @note The default configuration is 1 (always run) in run mode and + * 2 (only halt) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI4_START_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI4_START_PCTL (SPC5_ME_PCTL_RUN(1) | \ + SPC5_ME_PCTL_LP(2)) +#endif + +/** + * @brief DSPI4 peripheral configuration when stopped. + * @note The default configuration is 0 (never run) in run mode and + * 0 (never run) in low power mode. The defaults of the run modes + * are defined in @p hal_lld.h. + */ +#if !defined(SPC5_SPI_DSPI4_STOP_PCTL) || defined(__DOXYGEN__) +#define SPC5_SPI_DSPI4_STOP_PCTL (SPC5_ME_PCTL_RUN(0) | \ + SPC5_ME_PCTL_LP(0)) +#endif /** @} */ /*===========================================================================*/ @@ -408,8 +518,13 @@ #error "DSPI3 not present in the selected device" #endif +#if SPC5_SPI_USE_DSPI4 && !SPC5_HAS_DSPI4 +#error "DSPI4 not present in the selected device" +#endif + #if !SPC5_SPI_USE_DSPI0 && !SPC5_SPI_USE_DSPI1 && \ - !SPC5_SPI_USE_DSPI2 && !SPC5_SPI_USE_DSPI3 + !SPC5_SPI_USE_DSPI2 && !SPC5_SPI_USE_DSPI3 && \ + !SPC5_SPI_USE_DSPI4 #error "SPI driver activated but no DSPI peripheral assigned" #endif @@ -547,6 +662,10 @@ extern SPIDriver SPID3; extern SPIDriver SPID4; #endif +#if SPC5_SPI_USE_DSPI4 && !defined(__DOXYGEN__) +extern SPIDriver SPID5; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c index a0538ca78..3561a73e7 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c @@ -1314,12 +1314,22 @@ edma_channel_t edmaChannelAllocate(const edma_channel_config_t *ccfg) { "edmaChannelAllocate"); #if SPC5_EDMA_HAS_MUX - /* TODO: MUX handling.*/ - channel = 0; + /* Searching for a free channel, we have the MUX so any channel is + acceptable.*/ + for (channel = 0; channel < SPC5_EDMA_NCHANNELS; channel++) + if (channels[channel] == NULL) + break; + if (channel >= SPC5_EDMA_NCHANNELS) + return EDMA_ERROR; /* No free channels. */ + + /* Programming the MUX.*/ + SPC5_DMAMUX.CHCONFIG[channel].R = (uint8_t)(0x80 | ccfg->dma_periph); #else /* !SPC5_EDMA_HAS_MUX */ + /* There is no MUX so we can just check that the specified channels is + available.*/ channel = (edma_channel_t)ccfg->dma_periph; if (channels[channel] != NULL) - return EDMA_ERROR; /* Already taken.*/ + return EDMA_ERROR; /* Already taken. */ #endif /* !SPC5_EDMA_HAS_MUX */ /* Associating the configuration to the channel.*/ @@ -1354,6 +1364,11 @@ void edmaChannelRelease(edma_channel_t channel) { /* Enforcing a stop.*/ edmaChannelStop(channel); +#if SPC5_EDMA_HAS_MUX + /* Disabling the MUX slot.*/ + SPC5_DMAMUX.CHCONFIG[channel].R = 0; +#endif + /* Clearing ISR sources for the channel.*/ SPC5_EDMA.CIRQR.R = channel; SPC5_EDMA.CEEIR.R = channel; diff --git a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h index 2830556f5..97437fbac 100644 --- a/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h +++ b/os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h @@ -609,6 +609,22 @@ typedef struct { edma_tcd_t TCD[64]; } edma_t; +#if SPC5_EDMA_HAS_MUX || defined(__DOXYGEN__) +/** + * @brief Type of a DMA-MUX peripheral. + */ +typedef struct { + union { + vuint8_t R; + struct { + vuint8_t ENBL:1; + vuint8_t TRIG:1; + vuint8_t SOURCE:6; + } B; + } CHCONFIG[SPC5_EDMA_NCHANNELS]; +} dma_mux_t; +#endif /* SPC5_EDMA_HAS_MUX */ + /** * @brief DMA callback type. * @@ -650,12 +666,17 @@ typedef struct { /*===========================================================================*/ /** - * @name eDMA units references + * @name Peripherals references + * * @{ */ #if SPC5_HAS_EDMA || defined(__DOXYGEN__) #define SPC5_EDMA (*(edma_t *)0xFFF44000U) #endif + +#if SPC5_EDMA_HAS_MUX || defined(__DOXYGEN__) +#define SPC5_DMAMUX (*(dma_mux_t *)0xFFFDC000UL) +#endif /** @} */ /** diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h index eac0b6500..db7c45501 100644 --- a/os/kernel/include/ch.h +++ b/os/kernel/include/ch.h @@ -40,7 +40,7 @@ /** * @brief Kernel version string. */ -#define CH_KERNEL_VERSION "2.5.2unstable" +#define CH_KERNEL_VERSION "2.7.0unstable" /** * @name Kernel version @@ -54,12 +54,12 @@ /** * @brief Kernel version minor number. */ -#define CH_KERNEL_MINOR 5 +#define CH_KERNEL_MINOR 7 /** * @brief Kernel version patch number. */ -#define CH_KERNEL_PATCH 2 +#define CH_KERNEL_PATCH 0 /** @} */ /** diff --git a/readme.txt b/readme.txt index df99a5009..21820003f 100644 --- a/readme.txt +++ b/readme.txt @@ -93,6 +93,8 @@ (backported to 2.6.0). - FIX: Fixed MS2ST() and US2ST() macros error (bug #415)(backported to 2.6.0, 2.4.4, 2.2.10, NilRTOS). +- NEW: SPI driver for SPC560Pxx, SPC563Mxx, SPC564Axx. +- NEW: DMA-MUX support for SPC5xx devices. *** 2.5.2 *** - FIX: Fixed lwipthread.h should explicitly include lwip/opts.h (bug #414).