/****************************************************************************** * [url=home.php?mod=space&uid=288409]@file[/url] main.c * [url=home.php?mod=space&uid=895143]@version[/url] V1.00 * $Revision: 4 $ * $Date: 18/07/13 4:20p $ * [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) 2018 Nuvoton Technology Corp. All rights reserved. *****************************************************************************/ #include <stdio.h> #include "NuMicro.h" #define PDMA_CH 1 /*---------------------------------------------------------------------------------------------------------*/ /* Global variables */ /*---------------------------------------------------------------------------------------------------------*/ uint32_t PDMA_TEST_LENGTH = 64; #ifdef __ICCARM__ #pragma data_alignment=4 uint8_t au8SrcArray[256]; uint8_t au8DestArray[256]; #else __attribute__((aligned(4))) uint8_t au8SrcArray[256]; __attribute__((aligned(4))) uint8_t au8DestArray[256]; #endif 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_M031Series.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 */ /*---------------------------------------------------------------------------------------------------------*/ /* Unlock protected registers */ SYS_UnlockReg(); /* Enable HIRC clock (Internal RC 48MHz) */ CLK->PWRCTL |= CLK_PWRCTL_HIRCEN_Msk; /* Wait for HIRC clock ready */ while((CLK->STATUS & CLK_STATUS_HIRCSTB_Msk) != CLK_STATUS_HIRCSTB_Msk); /* Select HCLK clock source as HIRC and HCLK source divider as 1 */ CLK->CLKSEL0 = (CLK->CLKSEL0 & (~CLK_CLKSEL0_HCLKSEL_Msk)) | CLK_CLKSEL0_HCLKSEL_HIRC; CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_HCLKDIV_Msk)) | CLK_CLKDIV0_HCLK(1); /* Enable UART0 clock */ CLK->APBCLK0 |= CLK_APBCLK0_UART0CKEN_Msk; /* PDMA Clock Enable */ CLK->AHBCLK |= CLK_AHBCLK_PDMACKEN_Msk; /* Switch UART0 clock source to HIRC and UART0 clock divider as 1 */ CLK->CLKSEL1 = (CLK->CLKSEL1 & (~CLK_CLKSEL1_UART0SEL_Msk)) | CLK_CLKSEL1_UART0SEL_HIRC; CLK->CLKDIV0 = (CLK->CLKDIV0 & (~CLK_CLKDIV0_UART0DIV_Msk)) | CLK_CLKDIV0_UART0(1); /* 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.12 and TXD=PB.13 */ SYS->GPB_MFPH = (SYS->GPB_MFPH & ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk)) | (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD); /* Lock protected registers */ SYS_LockReg(); } void UART0_Init(void) { /*---------------------------------------------------------------------------------------------------------*/ /* Init UART */ /*---------------------------------------------------------------------------------------------------------*/ /* Reset UART IP */ SYS->IPRST1 |= SYS_IPRST1_UART0RST_Msk; SYS->IPRST1 &= ~SYS_IPRST1_UART0RST_Msk; /* Configure UART0 and set UART0 Baudrate */ UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(__HIRC, 115200); UART0->LINE = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1; } int main() { SYS_Init(); /* Init UART0 to 115200-8n1 for print message */ UART0_Init(); printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock); 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->CHCTL |= (1 << PDMA_CH); /* Transfer configuration of Channel 1 */ PDMA->DSCT[PDMA_CH].CTL = ((PDMA_TEST_LENGTH - 1) << PDMA_DSCT_CTL_TXCNT_Pos) | /* Transfer count is PDMA_TEST_LENGTH */ \ PDMA_WIDTH_32 | /* Transfer width is 32 bits(one word) */ \ PDMA_SAR_INC | /* Source increment size is 32 bits(one word) */ \ PDMA_DAR_INC | /* Destination increment size is 32 bits(one word) */ \ PDMA_REQ_BURST | /* Transfer type is burst transfer type */ \ PDMA_BURST_4 | /* Burst size is 4. No effect in single transfer type */ \ PDMA_OP_BASIC; /* Operation mode is basic mode */ /* Configure source address */ PDMA->DSCT[PDMA_CH].SA = (uint32_t)au8SrcArray; /* Configure destination address */ PDMA->DSCT[PDMA_CH].DA = (uint32_t)au8DestArray; /* Configure PDMA channel 1 as memory to memory transfer */ PDMA->REQSEL0_3 = (PDMA->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC1_Msk) | (PDMA_MEM << PDMA_REQSEL0_3_REQSRC1_Pos); /* Enable interrupt */ PDMA->INTEN |= (1 << PDMA_CH); /* Enable NVIC for PDMA */ NVIC_EnableIRQ(PDMA_IRQn); g_u32IsTestOver = 0; /* Generate a software request to trigger transfer with PDMA channel 1 */ PDMA->SWREQ = (1 << 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->CHCTL = 0; while (1); } /*** (C) COPYRIGHT 2018 Nuvoton Technology Corp. ***/
收藏0 举报
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
183
2331
3
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号