/******************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url] main.c
* [url=home.php?mod=space&uid=895143]@version[/url] V1.00
* $Revision: 2 $
* $Date: 20/06/01 1:35p $
* [url=home.php?mod=space&uid=247401]@brief[/url] Use PDMA channel 1 to transfer data from memory to memory.
* @note
* SPDX-License-Identifier: Apache-2.0
* Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NuMicro.h"
#define PDMA_CH 1
/*---------------------------------------------------------------------------------------------------------*/
/* Global variables */
/*---------------------------------------------------------------------------------------------------------*/
uint32_t PDMA_TEST_LENGTH = 64;
uint8_t au8SrcArray[256];
uint8_t au8DestArray[256];
uint32_t volatile g_u32IsTestOver = 0;
/**
* @brief DMA IRQ
*
* @param None
*
* [url=home.php?mod=space&uid=266161]@return[/url] None
*
* [url=home.php?mod=space&uid=1543424]@Details[/url] The DMA default IRQ, declared in startup_M0A21.s.
*/
void PDMA_IRQHandler(void)
{
uint32_t status = PDMA_GET_INT_STATUS(PDMA);
if (status & PDMA_INTSTS_ABTIF_Msk) /* abort */
{
/* Check if channel 1 has abort error */
if (PDMA_GET_ABORT_STS(PDMA) & PDMA_ABTSTS_ABTIF1_Msk)
g_u32IsTestOver = 2;
/* Clear abort flag of channel 1 */
PDMA_CLR_ABORT_FLAG(PDMA, PDMA_ABTSTS_ABTIF1_Msk);
}
else if (status & PDMA_INTSTS_TDIF_Msk) /* done */
{
/* Check transmission of channel 1 has been transfer done */
if (PDMA_GET_TD_STS(PDMA) & PDMA_TDSTS_TDIF1_Msk)
g_u32IsTestOver = 1;
/* Clear transfer done flag of channel 1 */
PDMA_CLR_TD_FLAG(PDMA, PDMA_TDSTS_TDIF1_Msk);
}
else
printf("unknown interrupt !!\n");
}
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Enable HIRC clock (Internal RC 48MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
/* Wait for HIRC clock ready */
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
/* Select HCLK clock source as HIRC and HCLK source divider as 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
/* Enable UART0 clock */
CLK_EnableModuleClock(UART0_MODULE);
/* Switch UART0 clock source to HIRC */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));
/* Enable PDMA clock */
CLK_EnableModuleClock(PDMA_MODULE);
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock and cyclesPerUs automatically. */
SystemCoreClockUpdate();
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set PB multi-function pins for UART0 RXD=PB.6 and TXD=PB.4 */
SYS->GPB_MFP1 = (SYS->GPB_MFP1 & ~(SYS_GPB_MFP1_PB4MFP_Msk | SYS_GPB_MFP1_PB6MFP_Msk)) |
(SYS_GPB_MFP1_PB4MFP_UART0_TXD | SYS_GPB_MFP1_PB6MFP_UART0_RXD);
}
int main()
{
/* Unlock protected registers */
SYS_UnlockReg();
SYS_Init();
/* Lock protected registers */
SYS_LockReg();
/* Init UART0 to 115200-8n1 for print message */
UART_Open(UART0, 115200);
printf("+------------------------------------------------------+ \n");
printf("| PDMA Memory to Memory Driver Sample Code | \n");
printf("+------------------------------------------------------+ \n");
/*------------------------------------------------------------------------------------------------------
au8SrcArray au8DestArray
--------------------------- --> ---------------------------
/| [0] | [1] | [2] | [3] | | [0] | [1] | [2] | [3] |\
| | | | | | | | | |
PDMA_TEST_LENGTH | ... | | ... | PDMA_TEST_LENGTH
| | | | | | | | | |
\| [60] | [61] | [62] | [63] | | [60] | [61] | [62] | [63] |/
--------------------------- ---------------------------
\ / \ /
32bits(one word) 32bits(one word)
PDMA transfer configuration:
Channel = 1
Operation mode = basic mode
Request source = PDMA_MEM(memory to memory)
transfer done and table empty interrupt = enable
Transfer count = PDMA_TEST_LENGTH
Transfer width = 32 bits(one word)
Source address = au8SrcArray
Source address increment size = 32 bits(one word)
Destination address = au8DestArray
Destination address increment size = 32 bits(one word)
Transfer type = burst transfer
Total transfer length = PDMA_TEST_LENGTH * 32 bits
------------------------------------------------------------------------------------------------------*/
/* Open Channel 1 */
PDMA_Open(PDMA, 1 << PDMA_CH);
/* Transfer count is PDMA_TEST_LENGTH, transfer width is 32 bits(one word) */
PDMA_SetTransferCnt(PDMA, PDMA_CH, PDMA_WIDTH_32, PDMA_TEST_LENGTH);
/* Set source address is au8SrcArray, destination address is au8DestArray, Source/Destination increment size is 32 bits(one word) */
PDMA_SetTransferAddr(PDMA, PDMA_CH, (uint32_t)au8SrcArray, PDMA_SAR_INC, (uint32_t)au8DestArray, PDMA_DAR_INC);
/* Request source is memory to memory */
PDMA_SetTransferMode(PDMA, PDMA_CH, PDMA_MEM, FALSE, 0);
/* Transfer type is burst transfer and burst size is 4 */
PDMA_SetBurstType(PDMA, PDMA_CH, PDMA_REQ_BURST, PDMA_BURST_4);
/* Enable interrupt */
PDMA_EnableInt(PDMA, PDMA_CH, PDMA_INT_TRANS_DONE);
/* Enable NVIC for PDMA */
NVIC_EnableIRQ(PDMA_IRQn);
g_u32IsTestOver = 0;
/* Generate a software request to trigger transfer with PDMA channel 1 */
PDMA_Trigger(PDMA, PDMA_CH);
/* Waiting for transfer done */
while (g_u32IsTestOver == 0);
/* Check transfer result */
if (g_u32IsTestOver == 1)
printf("test done...\n");
else if (g_u32IsTestOver == 2)
printf("target abort...\n");
/* Close channel 1 */
PDMA_Close(PDMA);
while (1);
}
/*** (C) COPYRIGHT 2020 Nuvoton Technology Corp. ***/
|