/**************************************************************************//** * @file pdma.c * @version V3.00 * $Revision: 9 $ * $Date: 15/05/04 3:59p $ * @brief PDMA driver source file * * @note * SPDX-License-Identifier: Apache-2.0 * Copyright (C) 2014 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #include "NUC200Series.h" /** @addtogroup Standard_Driver Standard Driver @{ */ /** @addtogroup PDMA_Driver PDMA Driver @{ */ /** @addtogroup PDMA_EXPORTED_FUNCTIONS PDMA Exported Functions @{ */ /** * @brief PDMA Open * * @param[in] u32Mask Channel enable bits. * * @return None * * @details This function enable the PDMA channels. */ void PDMA_Open(uint32_t u32Mask) { PDMA_GCR->GCRCSR |= (u32Mask << 8); } /** * @brief PDMA Close * * @param None * * @return None * * @details This function disable all PDMA channels. */ void PDMA_Close(void) { PDMA_GCR->GCRCSR = 0; } /** * @brief Set PDMA Transfer Count * * @param[in] u32Ch The selected channel * @param[in] u32Width Data width. Valid values are * - \ref PDMA_WIDTH_8 * - \ref PDMA_WIDTH_16 * - \ref PDMA_WIDTH_32 * @param[in] u32TransCount Transfer count * * @return None * * @details This function set the selected channel data width and transfer count. */ void PDMA_SetTransferCnt(uint32_t u32Ch, uint32_t u32Width, uint32_t u32TransCount) { PDMA_T *pdma; pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch)); pdma->CSR = (pdma->CSR & ~PDMA_CSR_APB_TWS_Msk) | u32Width; switch(u32Width) { case PDMA_WIDTH_32: pdma->BCR = (u32TransCount << 2); break; case PDMA_WIDTH_8: pdma->BCR = u32TransCount; break; case PDMA_WIDTH_16: pdma->BCR = (u32TransCount << 1); break; default: ; } } /** * @brief Set PDMA Transfer Address * * @param[in] u32Ch The selected channel * @param[in] u32SrcAddr Source address * @param[in] u32SrcCtrl Source control attribute. Valid values are * - \ref PDMA_SAR_INC * - \ref PDMA_SAR_FIX * @param[in] u32DstAddr destination address * @param[in] u32DstCtrl destination control attribute. Valid values are * - \ref PDMA_DAR_INC * - \ref PDMA_DAR_FIX * * @return None * * @details This function set the selected channel source/destination address and attribute. */ void PDMA_SetTransferAddr(uint32_t u32Ch, uint32_t u32SrcAddr, uint32_t u32SrcCtrl, uint32_t u32DstAddr, uint32_t u32DstCtrl) { PDMA_T *pdma; pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch)); pdma->SAR = u32SrcAddr; pdma->DAR = u32DstAddr; pdma->CSR = (pdma->CSR & ~(PDMA_CSR_SAD_SEL_Msk | PDMA_CSR_DAD_SEL_Msk)) | (u32SrcCtrl | u32DstCtrl); } /** * @brief Set PDMA Transfer Mode * * @param[in] u32Ch The selected channel * @param[in] u32Peripheral The selected peripheral. Valid values are * - \ref PDMA_SPI0_TX * - \ref PDMA_SPI1_TX * - \ref PDMA_SPI2_TX * - \ref PDMA_SPI3_TX * - \ref PDMA_UART0_TX * - \ref PDMA_UART1_TX * - \ref PDMA_I2S_TX * - \ref PDMA_SPI0_RX * - \ref PDMA_SPI1_RX * - \ref PDMA_SPI2_RX * - \ref PDMA_SPI3_RX * - \ref PDMA_UART0_RX * - \ref PDMA_UART1_RX * - \ref PDMA_I2S_RX * - \ref PDMA_ADC * - \ref PDMA_MEM * @param[in] u32ScatterEn Scatter-gather mode enable * @param[in] u32DescAddr Scatter-gather descriptor address * * @return None * * @details This function set the selected channel transfer mode. Include peripheral setting. */ void PDMA_SetTransferMode(uint32_t u32Ch, uint32_t u32Peripheral, uint32_t u32ScatterEn, uint32_t u32DescAddr) { uint32_t u32Index = 0; PDMA_T *pdma; pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch)); if(u32Peripheral > PDMA_ADC) /* Memory-to-Memory */ pdma->CSR = (pdma->CSR & ~(PDMA_CSR_MODE_SEL_Msk)); else if(u32Peripheral > PDMA_I2S_TX) /* Peripheral-to-Memory */ pdma->CSR = ((pdma->CSR & ~(PDMA_CSR_MODE_SEL_Msk)) | (0x1 << PDMA_CSR_MODE_SEL_Pos)); else /* Memory-to-Peripheral */ pdma->CSR = ((pdma->CSR & ~(PDMA_CSR_MODE_SEL_Msk)) | (0x2 << PDMA_CSR_MODE_SEL_Pos)); switch(u32Peripheral) { case 0: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI0_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI0_TXSEL_Pos); break; case 1: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI1_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI1_TXSEL_Pos); break; case 2: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI2_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI2_TXSEL_Pos); break; case 3: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI3_TXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI3_TXSEL_Pos); break; case 4: PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART0_TXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART0_TXSEL_Pos); break; case 5: PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART1_TXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART1_TXSEL_Pos); break; case 6: PDMA_GCR->PDSSR2 = (PDMA_GCR->PDSSR2 & ~PDMA_PDSSR2_I2S_TXSEL_Msk) | (u32Ch << PDMA_PDSSR2_I2S_TXSEL_Pos); break; case 7: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI0_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI0_RXSEL_Pos); break; case 8: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI1_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI1_RXSEL_Pos); break; case 9: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI2_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI2_RXSEL_Pos); break; case 10: PDMA_GCR->PDSSR0 = (PDMA_GCR->PDSSR0 & ~PDMA_PDSSR0_SPI3_RXSEL_Msk) | (u32Ch << PDMA_PDSSR0_SPI3_RXSEL_Pos); break; case 11: PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART0_RXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART0_RXSEL_Pos); break; case 12: PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_UART1_RXSEL_Msk) | (u32Ch << PDMA_PDSSR1_UART1_RXSEL_Pos); break; case 13: PDMA_GCR->PDSSR2 = (PDMA_GCR->PDSSR2 & ~PDMA_PDSSR2_I2S_RXSEL_Msk) | (u32Ch << PDMA_PDSSR2_I2S_RXSEL_Pos); break; case 14: PDMA_GCR->PDSSR1 = (PDMA_GCR->PDSSR1 & ~PDMA_PDSSR1_ADC_RXSEL_Msk) | (u32Ch << PDMA_PDSSR1_ADC_RXSEL_Pos); break; default:/* select PDMA channel as memory to memory */ for(u32Index = 0; u32Index < 8; u32Index++) { if((PDMA_GCR->PDSSR0 & (0xF << (u32Index * 4))) == (u32Ch << (u32Index * 4))) PDMA_GCR->PDSSR0 |= 0xF << (u32Index * 4); if((PDMA_GCR->PDSSR1 & (0xF << (u32Index * 4))) == (u32Ch << (u32Index * 4))) PDMA_GCR->PDSSR1 |= 0xF << (u32Index * 4); if((PDMA_GCR->PDSSR2 & (0xF << (u32Index * 4))) == (u32Ch << (u32Index * 4))) PDMA_GCR->PDSSR2 |= 0xF << (u32Index * 4); } } } /** * @brief Trigger PDMA * * @param[in] u32Ch The selected channel * * @return None * * @details This function trigger the selected channel. */ void PDMA_Trigger(uint32_t u32Ch) { PDMA_T *pdma; pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch)); pdma->CSR |= (PDMA_CSR_TRIG_EN_Msk | PDMA_CSR_PDMACEN_Msk); } /** * @brief Enable Interrupt * * @param[in] u32Ch The selected channel * @param[in] u32Mask The Interrupt Type * * @return None * * @details This function enable the selected channel interrupt. */ void PDMA_EnableInt(uint32_t u32Ch, uint32_t u32Mask) { PDMA_T *pdma; pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch)); pdma->IER |= u32Mask; } /** * @brief Disable Interrupt * * @param[in] u32Ch The selected channel * @param[in] u32Mask The Interrupt Type * * @return None * * @details This function disable the selected channel interrupt. */ void PDMA_DisableInt(uint32_t u32Ch, uint32_t u32Mask) { PDMA_T *pdma; pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * u32Ch)); pdma->IER &= ~u32Mask; } /*@}*/ /* end of group PDMA_EXPORTED_FUNCTIONS */ /*@}*/ /* end of group PDMA_Driver */ /*@}*/ /* end of group Device_Driver */ /*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/