mirror of https://github.com/rusefi/ChibiOS.git
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5749 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
edbb1137a3
commit
ec80f9b8a4
|
@ -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
|
||||
|
|
|
@ -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_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_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_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_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_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_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);
|
||||
|
||||
/* 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++;
|
||||
*cp = 0x55;
|
||||
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 8 bits transfers.*/
|
||||
edmaChannelSetup(spip->tx_channel, /* channel. */
|
||||
/* 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.*/
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -115,12 +115,13 @@ int main(void) {
|
|||
for (i = 0; i < sizeof(txbuf); i++)
|
||||
txbuf[i] = (uint8_t)i;
|
||||
|
||||
spiStart(&SPID2, &hs_spicfg); /* Setup transfer parameters. */
|
||||
spiExchange(&SPID2, 4,
|
||||
txbuf, rxbuf); /* Atomic transfer operations. */
|
||||
spiExchange(&SPID2, 512,
|
||||
txbuf, rxbuf); /* Atomic transfer operations. */
|
||||
|
||||
spiStart(&SPID2, &hs_spicfg);
|
||||
spiExchange(&SPID2, 4, txbuf, rxbuf);
|
||||
spiExchange(&SPID2, 4, txbuf, rxbuf);
|
||||
spiExchange(&SPID2, 4, txbuf, rxbuf);
|
||||
spiExchange(&SPID2, 4, txbuf, rxbuf);
|
||||
spiExchange(&SPID2, 512, txbuf, rxbuf);
|
||||
#if 0
|
||||
/*
|
||||
* Starting the transmitter and receiver threads.
|
||||
*/
|
||||
|
@ -128,7 +129,7 @@ int main(void) {
|
|||
NORMALPRIO + 1, spi_thread_1, NULL);
|
||||
chThdCreateStatic(spi_thread_2_wa, sizeof(spi_thread_2_wa),
|
||||
NORMALPRIO + 1, spi_thread_2, NULL);
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Normal main() thread activity, in this demo it does nothing.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue