diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2013-06-10 11:43:41 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2013-06-10 11:43:41 +0000 |
commit | ae1cb6d0d72b16c7d7c8c2a7194aeb51d8c6642f (patch) | |
tree | 3782aa4c9eea5ae0ab1850f651cd1c083a781287 /os/hal | |
parent | fad64409ba2a1ff1948578318a01dd0a49aeff4c (diff) | |
download | ChibiOS-ae1cb6d0d72b16c7d7c8c2a7194aeb51d8c6642f.tar.gz ChibiOS-ae1cb6d0d72b16c7d7c8c2a7194aeb51d8c6642f.tar.bz2 ChibiOS-ae1cb6d0d72b16c7d7c8c2a7194aeb51d8c6642f.zip |
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
Diffstat (limited to 'os/hal')
-rw-r--r-- | os/hal/platforms/SPC560Pxx/spc560p_registry.h | 41 | ||||
-rw-r--r-- | os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.c | 101 | ||||
-rw-r--r-- | os/hal/platforms/SPC5xx/DSPI_v1/spi_lld.h | 121 | ||||
-rw-r--r-- | os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.c | 21 | ||||
-rw-r--r-- | os/hal/platforms/SPC5xx/EDMA_v1/spc5_edma.h | 23 |
5 files changed, 289 insertions, 18 deletions
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
/** @} */
/**
|