NUC200_Template/BSP/StdDriver/src/pdma.c

285 lines
9.2 KiB
C

/**************************************************************************//**
* @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. ***/