From c6f5c2669fc095ec3e97d42ec64e172da97b9648 Mon Sep 17 00:00:00 2001 From: edolomb Date: Sun, 1 Oct 2017 16:05:00 +0000 Subject: Added spi FLEXCOM git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10737 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c | 374 ++++++++++++++++++++++++++---- os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h | 193 ++++++++++++++- 2 files changed, 519 insertions(+), 48 deletions(-) (limited to 'os/hal/ports/SAMA/LLD/SPIv1') diff --git a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c b/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c index 17081f4eb..351d61671 100644 --- a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c +++ b/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.c @@ -75,6 +75,41 @@ SPIDriver SPID0; SPIDriver SPID1; #endif +/** + * @brief SPI FLEXCOM0 driver identifier. + */ +#if SAMA_SPI_USE_FLEXCOM0 || defined(__DOXYGEN__) +SPIDriver SPIFLEXD0; +#endif + +/** + * @brief SPI FLEXCOM1 driver identifier. + */ +#if SAMA_SPI_USE_FLEXCOM1 || defined(__DOXYGEN__) +SPIDriver SPIFLEXD1; +#endif + +/** + * @brief SPI FLEXCOM2 driver identifier. + */ +#if SAMA_SPI_USE_FLEXCOM2 || defined(__DOXYGEN__) +SPIDriver SPIFLEXD2; +#endif + +/** + * @brief SPI FLEXCOM3 driver identifier. + */ +#if SAMA_SPI_USE_FLEXCOM3 || defined(__DOXYGEN__) +SPIDriver SPIFLEXD3; +#endif + +/** + * @brief SPI FLEXCOM4 driver identifier. + */ +#if SAMA_SPI_USE_FLEXCOM4 || defined(__DOXYGEN__) +SPIDriver SPIFLEXD4; +#endif + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -206,6 +241,161 @@ void spi_lld_init(void) { XDMAC_CC_DAM_FIXED_AM | XDMAC_CC_PERID(PERID_SPI1_TX); #endif /* SAMA_SPI_USE_SPI1 */ + +#if SAMA_SPI_USE_FLEXCOM0 + /* Driver initialization.*/ + spiObjectInit(&SPIFLEXD0); + SPIFLEXD0.spi = FCOMSPI0; + SPIFLEXD0.flexcom = FLEXCOM0; + SPIFLEXD0.dmarx = NULL; + SPIFLEXD0.dmatx = NULL; + SPIFLEXD0.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_PER2MEM | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF0 | + XDMAC_CC_SAM_FIXED_AM | + XDMAC_CC_DAM_INCREMENTED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM0_RX); + SPIFLEXD0.txdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_MEM2PER | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF0 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_INCREMENTED_AM | + XDMAC_CC_DAM_FIXED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM0_TX); +#endif /* SAMA_SPI_USE_FLEXCOM0 */ + +#if SAMA_SPI_USE_FLEXCOM1 + /* Driver initialization.*/ + spiObjectInit(&SPIFLEXD1); + SPIFLEXD1.spi = FCOMSPI1; + SPIFLEXD1.flexcom = FLEXCOM1; + SPIFLEXD1.dmarx = NULL; + SPIFLEXD1.dmatx = NULL; + SPIFLEXD1.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_PER2MEM | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF0 | + XDMAC_CC_SAM_FIXED_AM | + XDMAC_CC_DAM_INCREMENTED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM1_RX); + SPIFLEXD1.txdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_MEM2PER | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF0 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_INCREMENTED_AM | + XDMAC_CC_DAM_FIXED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM1_TX); +#endif /* SAMA_SPI_USE_FLEXCOM1 */ + +#if SAMA_SPI_USE_FLEXCOM2 + /* Driver initialization.*/ + spiObjectInit(&SPIFLEXD2); + SPIFLEXD2.spi = FCOMSPI2; + SPIFLEXD2.flexcom = FLEXCOM2; + SPIFLEXD2.dmarx = NULL; + SPIFLEXD2.dmatx = NULL; + SPIFLEXD2.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_PER2MEM | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF0 | + XDMAC_CC_SAM_FIXED_AM | + XDMAC_CC_DAM_INCREMENTED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM2_RX); + SPIFLEXD2.txdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_MEM2PER | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF0 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_INCREMENTED_AM | + XDMAC_CC_DAM_FIXED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM2_TX); +#endif /* SAMA_SPI_USE_FLEXCOM2 */ + +#if SAMA_SPI_USE_FLEXCOM3 + /* Driver initialization.*/ + spiObjectInit(&SPIFLEXD3); + SPIFLEXD3.spi = FCOMSPI3; + SPIFLEXD3.flexcom = FLEXCOM3; + SPIFLEXD3.dmarx = NULL; + SPIFLEXD3.dmatx = NULL; + SPIFLEXD3.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_PER2MEM | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF0 | + XDMAC_CC_SAM_FIXED_AM | + XDMAC_CC_DAM_INCREMENTED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM3_RX); + SPIFLEXD3.txdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_MEM2PER | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF0 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_INCREMENTED_AM | + XDMAC_CC_DAM_FIXED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM3_TX); +#endif /* SAMA_SPI_USE_FLEXCOM3 */ + +#if SAMA_SPI_USE_FLEXCOM4 + /* Driver initialization.*/ + spiObjectInit(&SPIFLEXD4); + SPIFLEXD4.spi = FCOMSPI4; + SPIFLEXD4.flexcom = FLEXCOM4; + SPIFLEXD4.dmarx = NULL; + SPIFLEXD4.dmatx = NULL; + SPIFLEXD4.rxdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_PER2MEM | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF1 | + XDMAC_CC_DIF_AHB_IF0 | + XDMAC_CC_SAM_FIXED_AM | + XDMAC_CC_DAM_INCREMENTED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM4_RX); + SPIFLEXD4.txdmamode = XDMAC_CC_TYPE_PER_TRAN | + XDMAC_CC_MBSIZE_SINGLE | + XDMAC_CC_DSYNC_MEM2PER | + XDMAC_CC_PROT_SEC | + XDMAC_CC_CSIZE_CHK_1 | + XDMAC_CC_DWIDTH_BYTE | + XDMAC_CC_SIF_AHB_IF0 | + XDMAC_CC_DIF_AHB_IF1 | + XDMAC_CC_SAM_INCREMENTED_AM | + XDMAC_CC_DAM_FIXED_AM | + XDMAC_CC_PERID(PERID_FLEXCOM4_TX); +#endif /* SAMA_SPI_USE_FLEXCOM4 */ } /** @@ -220,46 +410,134 @@ void spi_lld_start(SPIDriver *spip) { /* Configures the peripheral.*/ if (spip->state == SPI_STOP) { - /* Execute a software reset of the SPI twice */ - spip->spi->SPI_CR = SPI_CR_SWRST; - spip->spi->SPI_CR = SPI_CR_SWRST; #if SAMA_SPI_USE_SPI0 if (&SPID0 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_SPI0_IRQ_PRIORITY, + spip->dmarx = dmaChannelAllocate(SAMA_SPI_SPI0_DMA_IRQ_PRIORITY, (sama_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - spip->dmatx = dmaChannelAllocate(SAMA_SPI_SPI0_IRQ_PRIORITY, + spip->dmatx = dmaChannelAllocate(SAMA_SPI_SPI0_DMA_IRQ_PRIORITY, (sama_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); /* Enable SPI0 clock */ pmcEnableSPI0(); - } #endif /* SAMA_SPI_USE_SPI0 */ #if SAMA_SPI_USE_SPI1 if (&SPID1 == spip) { - spip->dmarx = dmaChannelAllocate(SAMA_SPI_SPI1_IRQ_PRIORITY, + spip->dmarx = dmaChannelAllocate(SAMA_SPI_SPI1_DMA_IRQ_PRIORITY, (sama_dmaisr_t)spi_lld_serve_rx_interrupt, (void *)spip); - spip->dmatx = dmaChannelAllocate(SAMA_SPI_SPI1_IRQ_PRIORITY, + spip->dmatx = dmaChannelAllocate(SAMA_SPI_SPI1_DMA_IRQ_PRIORITY, (sama_dmaisr_t)spi_lld_serve_tx_interrupt, (void *)spip); /* Enable SPI1 clock */ pmcEnableSPI1(); - } #endif /* SAMA_SPI_USE_SPI1 */ +#if SAMA_SPI_USE_FLEXCOM0 + if (&SPIFLEXD0 == spip) { + spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + + spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + /* Enabling USART on FLEXCOM */ + spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; + /* Enable FLEXCOM0 clock */ + pmcEnableFLEXCOM0(); + } +#endif /* SAMA_SPI_USE_FLEXCOM0 */ +#if SAMA_SPI_USE_FLEXCOM1 + if (&SPIFLEXD1 == spip) { + spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + + spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + /* Enabling USART on FLEXCOM */ + spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; + /* Enable FLEXCOM1 clock */ + pmcEnableFLEXCOM1(); + } +#endif /* SAMA_SPI_USE_FLEXCOM1 */ +#if SAMA_SPI_USE_FLEXCOM2 + if (&SPIFLEXD2 == spip) { + spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + + spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + /* Enabling USART on FLEXCOM */ + spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; + /* Enable FLEXCOM2 clock */ + pmcEnableFLEXCOM2(); + } +#endif /* SAMA_SPI_USE_FLEXCOM2 */ +#if SAMA_SPI_USE_FLEXCOM3 + if (&SPIFLEXD3 == spip) { + spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + + spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + /* Enabling USART on FLEXCOM */ + spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; + /* Enable FLEXCOM3 clock */ + pmcEnableFLEXCOM3(); + } +#endif /* SAMA_SPI_USE_FLEXCOM3 */ +#if SAMA_SPI_USE_FLEXCOM4 + if (&SPIFLEXD4 == spip) { + spip->dmarx = dmaChannelAllocate(SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_rx_interrupt, + (void *)spip); + + spip->dmatx = dmaChannelAllocate(SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY, + (sama_dmaisr_t)spi_lld_serve_tx_interrupt, + (void *)spip); + /* Enabling USART on FLEXCOM */ + spip->flexcom->FLEX_MR = FLEX_MR_OPMODE_SPI; + /* Enable FLEXCOM4 clock */ + pmcEnableFLEXCOM4(); + } +#endif /* SAMA_SPI_USE_FLEXCOM4 */ } + /* Set mode */ + dmaChannelSetMode(spip->dmarx, spip->rxdmamode); + dmaChannelSetMode(spip->dmatx, spip->txdmamode); + /* Disable write protection */ spiDisableWP(spip->spi); + + /* Execute a software reset of the SPI twice */ + spip->spi->SPI_CR = SPI_CR_SWRST; + spip->spi->SPI_CR = SPI_CR_SWRST; + /* SPI configuration */ spip->spi->SPI_MR = spip->config->mr; + spip->spi->SPI_MR &= ~SPI_MR_PCS_Msk; + spip->spi->SPI_MR |= SPI_PCS(spip->config->npcs); spip->spi->SPI_CSR[spip->config->npcs] = spip->config->csr; + + /* if SPI_CSRx_BITS > 8, dma is set to 16 bits */ + if (((spip->spi->SPI_CSR[spip->config->npcs] >> 4) & 0xF) > 0) { + dmaChannelSetMode(spip->dmatx, spip->txdmamode | XDMAC_CC_DWIDTH_HALFWORD); + dmaChannelSetMode(spip->dmarx, spip->rxdmamode | XDMAC_CC_DWIDTH_HALFWORD); + } + /* Enable SPI */ spip->spi->SPI_CR |= SPI_CR_SPIEN; /* Enable write protection. */ @@ -285,6 +563,7 @@ void spi_lld_stop(SPIDriver *spip) { spip->spi->SPI_CR |= SPI_CR_SPIDIS; /* Enable write protection */ spiEnableWP(spip->spi); + #if SAMA_SPI_USE_SPI0 if (&SPID0 == spip) /* Disable SPI0 clock */ @@ -296,10 +575,47 @@ void spi_lld_stop(SPIDriver *spip) { /* Disable SPI1 clock */ pmcDisableSPI1(); -#endif /* SAMA_SPI_USE_SPI1 */ +#endif /* SAMA_SPI_USE_FLEXCOM0 */ + +#if SAMA_SPI_USE_FLEXCOM0 + if (&SPIFLEXD0 == spip) + /* Disable FLEXCOM0 clock */ + pmcDisableFLEXCOM0(); + +#endif /* SAMA_SPI_USE_FLEXCOM0 */ + +#if SAMA_SPI_USE_FLEXCOM1 + if (&SPIFLEXD1 == spip) + /* Disable FLEXCOM1 clock */ + pmcDisableFLEXCOM1(); + +#endif /* SAMA_SPI_USE_FLEXCOM1 */ + +#if SAMA_SPI_USE_FLEXCOM2 + if (&SPIFLEXD2 == spip) + /* Disable FLEXCOM2 clock */ + pmcDisableFLEXCOM2(); + +#endif /* SAMA_SPI_USE_FLEXCOM2 */ + +#if SAMA_SPI_USE_FLEXCOM3 + if (&SPIFLEXD3 == spip) + /* Disable FLEXCOM3 clock */ + pmcDisableFLEXCOM3(); + +#endif /* SAMA_SPI_USE_FLEXCOM3 */ + +#if SAMA_SPI_USE_FLEXCOM4 + if (&SPIFLEXD4 == spip) + /* Disable FLEXCOM4 clock */ + pmcDisableFLEXCOM4(); + +#endif /* SAMA_SPI_USE_FLEXCOM4 */ } } +#if (SPI_SELECT_MODE == (SPI_SELECT_MODE_LLD || SPI_SELECT_MODE_PAD || \ + SPI_SELECT_MODE_PORT || SPI_SELECT_MODE_LINE)) || defined(__DOXYGEN__) /** * @brief Asserts the slave select signal and prepares for transfers. * @@ -308,21 +624,7 @@ void spi_lld_stop(SPIDriver *spip) { * @notapi */ void spi_lld_select(SPIDriver *spip) { - - /** - * NOTE: This should only be called in master mode. - */ - - uint16_t pad = spip->config->npcs; - /* Disable write protection */ - spiDisableWP(spip->spi); - - spip->spi->SPI_MR &= ~SPI_MR_PCS_Msk; - spip->spi->SPI_MR |= SPI_PCS(pad); - - /* Enable write protection */ - spiEnableWP(spip->spi); - + /* No implementation on SAMA.*/ } /** @@ -334,13 +636,9 @@ void spi_lld_select(SPIDriver *spip) { * @notapi */ void spi_lld_unselect(SPIDriver *spip) { - - /** - * NOTE: This should only be called in master mode. - */ - spip->spi->SPI_CR = SPI_CR_LASTXFER; - + /* No implementation on SAMA.*/ } +#endif /** * @brief Exchanges data on the SPI bus. @@ -360,21 +658,18 @@ void spi_lld_unselect(SPIDriver *spip) { void spi_lld_exchange(SPIDriver *spip, size_t n, const void *txbuf, void *rxbuf) { - osalDbgAssert(n > XDMAC_MAX_BT_SIZE, "unsupported DMA transfer size"); /* Writing channel */ dmaChannelSetSource(spip->dmatx, txbuf); dmaChannelSetDestination(spip->dmatx, &spip->spi->SPI_TDR); dmaChannelSetTransactionSize(spip->dmatx, n); - dmaChannelSetMode(spip->dmatx, spip->txdmamode); + /* Reading channel */ dmaChannelSetSource(spip->dmarx, &spip->spi->SPI_RDR); dmaChannelSetDestination(spip->dmarx, rxbuf); dmaChannelSetTransactionSize(spip->dmarx, n); - dmaChannelSetMode(spip->dmarx, spip->rxdmamode); dmaChannelEnable(spip->dmarx); dmaChannelEnable(spip->dmatx); - } /** @@ -392,17 +687,15 @@ void spi_lld_exchange(SPIDriver *spip, size_t n, */ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { - osalDbgAssert(n > XDMAC_MAX_BT_SIZE, "unsupported DMA transfer size"); /* Writing channel */ dmaChannelSetSource(spip->dmatx, txbuf); dmaChannelSetDestination(spip->dmatx, &spip->spi->SPI_TDR); dmaChannelSetTransactionSize(spip->dmatx, n); - dmaChannelSetMode(spip->dmatx, spip->txdmamode); + /* Reading channel */ dmaChannelSetSource(spip->dmarx, &spip->spi->SPI_RDR); dmaChannelSetDestination(spip->dmarx, &dummyrx); dmaChannelSetTransactionSize(spip->dmarx, n); - dmaChannelSetMode(spip->dmarx, spip->rxdmamode); dmaChannelEnable(spip->dmarx); dmaChannelEnable(spip->dmatx); @@ -423,21 +716,18 @@ void spi_lld_send(SPIDriver *spip, size_t n, const void *txbuf) { */ void spi_lld_receive(SPIDriver *spip, size_t n, void *rxbuf) { - osalDbgAssert(n > XDMAC_MAX_BT_SIZE, "unsupported DMA transfer size"); /* Writing channel */ dmaChannelSetSource(spip->dmatx, &dummytx); dmaChannelSetDestination(spip->dmatx, &spip->spi->SPI_TDR); dmaChannelSetTransactionSize(spip->dmatx, n); - dmaChannelSetMode(spip->dmatx, spip->txdmamode); + /* Reading channel */ dmaChannelSetSource(spip->dmarx, &spip->spi->SPI_RDR); dmaChannelSetDestination(spip->dmarx, rxbuf); dmaChannelSetTransactionSize(spip->dmarx, n); - dmaChannelSetMode(spip->dmarx, spip->rxdmamode); dmaChannelEnable(spip->dmarx); dmaChannelEnable(spip->dmatx); - } #endif /* HAL_USE_SPI */ diff --git a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h b/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h index 1cf26434e..5d19b6555 100644 --- a/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h +++ b/os/hal/ports/SAMA/LLD/SPIv1/hal_spi_lld.h @@ -44,29 +44,184 @@ * @details If set to @p TRUE the support for SPI0 is included. */ #if !defined(SAMA_SPI_USE_SPI0) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_SPI0 FALSE +#define SAMA_SPI_USE_SPI0 FALSE #endif -/** @} */ + /** * @brief SPI1 driver enable switch. * @details If set to @p TRUE the support for SPI1 is included. * @note The default is @p FALSE. */ #if !defined(SAMA_SPI_USE_SPI1) || defined(__DOXYGEN__) -#define SAMA_SPI_USE_SPI1 FALSE +#define SAMA_SPI_USE_SPI1 FALSE +#endif + +/** + * @brief SPI FLEXCOM0 driver enable switch. + * @details If set to @p TRUE the support for FLEXCOM0 is included. + */ +#if !defined(SAMA_SPI_USE_FLEXCOM0) || defined(__DOXYGEN__) +#define SAMA_SPI_USE_FLEXCOM0 FALSE +#endif + +/** + * @brief SPI FLEXCOM1 driver enable switch. + * @details If set to @p TRUE the support for FLEXCOM1 is included. + */ +#if !defined(SAMA_SPI_USE_FLEXCOM1) || defined(__DOXYGEN__) +#define SAMA_SPI_USE_FLEXCOM1 FALSE +#endif + +/** + * @brief SPI FLEXCOM2 driver enable switch. + * @details If set to @p TRUE the support for FLEXCOM2 is included. + */ +#if !defined(SAMA_SPI_USE_FLEXCOM2) || defined(__DOXYGEN__) +#define SAMA_SPI_USE_FLEXCOM2 FALSE +#endif + +/** + * @brief SPI FLEXCOM3 driver enable switch. + * @details If set to @p TRUE the support for FLEXCOM3 is included. + */ +#if !defined(SAMA_SPI_USE_FLEXCOM3) || defined(__DOXYGEN__) +#define SAMA_SPI_USE_FLEXCOM3 FALSE +#endif + +/** + * @brief SPI FLEXCOM4 driver enable switch. + * @details If set to @p TRUE the support for FLEXCOM4 is included. + */ +#if !defined(SAMA_SPI_USE_FLEXCOM4) || defined(__DOXYGEN__) +#define SAMA_SPI_USE_FLEXCOM4 FALSE +#endif + +/** + * @brief SPI0 DMA interrupt priority level setting. + */ +#if !defined(SAMA_SPI_SPI0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SAMA_SPI_SPI0_DMA_IRQ_PRIORITY 4 +#endif + +/** + * @brief SPI1 DMA interrupt priority level setting. + */ +#if !defined(SAMA_SPI_SPI1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SAMA_SPI_SPI1_DMA_IRQ_PRIORITY 4 +#endif + +/** + * @brief FLEXCOM0 DMA interrupt priority level setting. + */ +#if !defined(SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SAMA_SPI_FLEXCOM0_DMA_IRQ_PRIORITY 4 +#endif + +/** + * @brief FLEXCOM1 DMA interrupt priority level setting. + */ +#if !defined(SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SAMA_SPI_FLEXCOM1_DMA_IRQ_PRIORITY 4 +#endif + +/** + * @brief FLEXCOM2 DMA interrupt priority level setting. + */ +#if !defined(SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SAMA_SPI_FLEXCOM2_DMA_IRQ_PRIORITY 4 +#endif + +/** + * @brief FLEXCOM3 DMA interrupt priority level setting. + */ +#if !defined(SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SAMA_SPI_FLEXCOM3_DMA_IRQ_PRIORITY 4 #endif +/** + * @brief FLEXCOM4 DMA interrupt priority level setting. + */ +#if !defined(SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define SAMA_SPI_FLEXCOM4_DMA_IRQ_PRIORITY 4 +#endif +/** @} */ /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ + +/** + * @brief At least an SPI unit is in use. + */ +#define SAMA_SPI_USE_SPI (SAMA_SPI_USE_SPI0 || \ + SAMA_SPI_USE_SPI1) + +/** + * @brief At least an FLEXCOM unit is in use. + */ +#define SAMA_SPI_USE_FLEXCOM (SAMA_SPI_USE_FLEXCOM0 || \ + SAMA_SPI_USE_FLEXCOM1 || \ + SAMA_SPI_USE_FLEXCOM2 || \ + SAMA_SPI_USE_FLEXCOM3 || \ + SAMA_SPI_USE_FLEXCOM4) + +#if !SAMA_SPI_USE_SPI0 && !SAMA_SPI_USE_SPI1 && \ + !SAMA_SPI_USE_FLEXCOM0 && !SAMA_SPI_USE_FLEXCOM1 && \ + !SAMA_SPI_USE_FLEXCOM2 && !SAMA_SPI_USE_FLEXCOM3 && \ + !SAMA_SPI_USE_FLEXCOM4 +#error "SPI driver activated but no SPI peripheral assigned" +#endif + +/* Checks on allocation of UARTx units.*/ +#if SAMA_SPI_USE_FLEXCOM0 +#if defined(SAMA_FLEXCOM0_IS_USED) +#error "SPIFLEXD0 requires FLEXCOM0 but the peripheral is already used" +#else +#define SAMA_FLEXCOM0_IS_USED +#endif +#endif + +#if SAMA_SPI_USE_FLEXCOM1 +#if defined(SAMA_FLEXCOM1_IS_USED) +#error "SPIFLEXD1 requires FLEXCOM1 but the peripheral is already used" +#else +#define SAMA_FLEXCOM1_IS_USED +#endif +#endif + +#if SAMA_SPI_USE_FLEXCOM2 +#if defined(SAMA_FLEXCOM2_IS_USED) +#error "SPIFLEXD2 requires FLEXCOM2 but the peripheral is already used" +#else +#define SAMA_FLEXCOM2_IS_USED +#endif +#endif + +#if SAMA_SPI_USE_FLEXCOM3 +#if defined(SAMA_FLEXCOM3_IS_USED) +#error "SPIFLEXD3 requires FLEXCOM3 but the peripheral is already used" +#else +#define SAMA_FLEXCOM3_IS_USED +#endif +#endif + +#if SAMA_SPI_USE_FLEXCOM4 +#if defined(SAMA_FLEXCOM4_IS_USED) +#error "SPIFLEXD4 requires FLEXCOM4 but the peripheral is already used" +#else +#define SAMA_FLEXCOM4_IS_USED +#endif +#endif + +#if SPI_SELECT_MODE == (SPI_SELECT_MODE_LLD || SPI_SELECT_MODE_PAD || \ + SPI_SELECT_MODE_PORT || SPI_SELECT_MODE_LINE) +#error "SPI_SELECT_MODE_NONE is supported by this driver" +#endif + #if !defined(SAMA_DMA_REQUIRED) #define SAMA_DMA_REQUIRED #endif -#if !SAMA_SPI_USE_SPI0 && !SAMA_SPI_USE_SPI1 -#error "SPI driver activated but no SPI peripheral assigned" -#endif /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -141,6 +296,12 @@ struct SPIDriver { * @brief Pointer to the SPIx registers block. */ Spi *spi; +#if SAMA_SPI_USE_FLEXCOM + /** + * @brief Pointer to the FLEXCOMx registers block. + */ + Flexcom *flexcom; +#endif /** * @brief Receive DMA stream. */ @@ -177,6 +338,26 @@ extern SPIDriver SPID0; extern SPIDriver SPID1; #endif +#if SAMA_SPI_USE_FLEXCOM0 && !defined(__DOXYGEN__) +extern SPIDriver SPIFLEXD0; +#endif + +#if SAMA_SPI_USE_FLEXCOM1 && !defined(__DOXYGEN__) +extern SPIDriver SPIFLEXD1; +#endif + +#if SAMA_SPI_USE_FLEXCOM2 && !defined(__DOXYGEN__) +extern SPIDriver SPIFLEXD2; +#endif + +#if SAMA_SPI_USE_FLEXCOM3 && !defined(__DOXYGEN__) +extern SPIDriver SPIFLEXD3; +#endif + +#if SAMA_SPI_USE_FLEXCOM4 && !defined(__DOXYGEN__) +extern SPIDriver SPIFLEXD4; +#endif + #ifdef __cplusplus extern "C" { #endif -- cgit v1.2.3