/*************************************************************************//**
* @file main.c
* @version V1.00
* @brief A project template for M480 MCU.
*
* @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "NuMicro.h"
#define ADC_PDMA_CH (4)
#define ADC_PDMA_OPENED_CH (1 << ADC_PDMA_CH)
#define ADC_DMA_SAMPLE_COUNT (4)
uint16_t pdmaConvertedData[ADC_DMA_SAMPLE_COUNT] = {0};
enum
{
ADC0_CH0 = 0,
ADC0_CH1,
ADC0_CH2,
ADC0_CH3,
ADC0_CH4,
ADC0_CH5,
ADC0_CH6,
ADC0_CH7,
ADC0_CH8,
ADC0_CH9,
ADC0_CH10,
ADC0_CH11,
ADC0_CH12,
ADC0_CH13,
ADC0_CH14,
ADC0_CH15,
ADC0_CH16_BAND_GAP_VOLT,
ADC0_CH17_TEMP_SENSOR,
ADC0_CH18_VBAT,
ADC_CH_DEFAULT
} ADC_CH_TypeDef;
typedef enum
{
flag_ADC_Band_GAP = 0,
flag_ADC_Data_Ready,
flag_ADC_Sensor_Ready,
flag_PDMA_Trans_Data_Ready,
flag_DEFAULT
} Flag_Index;
uint32_t BitFlag = 0;
#define BitFlag_ON(flag) (BitFlag|=flag)
#define BitFlag_OFF(flag) (BitFlag&=~flag)
#define BitFlag_READ(flag) ((BitFlag&flag)?1:0)
#define ReadBit(bit) (uint32_t)(1<<bit)
#define is_flag_set(idx) (BitFlag_READ(ReadBit(idx)))
#define set_flag(idx,en) ( (en == 1) ? (BitFlag_ON(ReadBit(idx))) : (BitFlag_OFF(ReadBit(idx))))
void ReloadPDMA(void)
{
/* transfer width is half word(16 bit) and transfer count is ADCDatalenght+1 */
PDMA_SetTransferCnt(PDMA, ADC_PDMA_CH, PDMA_WIDTH_16, ADC_DMA_SAMPLE_COUNT);
/* Select PDMA request source as ADC RX */
PDMA_SetTransferMode(PDMA, ADC_PDMA_CH, PDMA_EADC0_RX, FALSE, (uint32_t) 0);
}
void PDMA_IRQHandler(void)
{
uint32_t status = PDMA_GET_INT_STATUS(PDMA);
if (status & PDMA_INTSTS_ABTIF_Msk) /* abort */
{
#if 0
PDMA_CLR_ABORT_FLAG(PDMA, PDMA_GET_ABORT_STS(PDMA));
#else
if (PDMA_GET_ABORT_STS(PDMA) & ADC_PDMA_OPENED_CH)
{
printf("ABTSTS\r\n");
}
PDMA_CLR_ABORT_FLAG(PDMA, ADC_PDMA_OPENED_CH);
#endif
}
else if (status & PDMA_INTSTS_TDIF_Msk) /* done */
{
if(PDMA_GET_TD_STS(PDMA) & ADC_PDMA_OPENED_CH)
{
//insert process
set_flag(flag_PDMA_Trans_Data_Ready, ENABLE);
printf("TDIF\r\n");
}
/* Clear PDMA transfer done interrupt flag */
PDMA_CLR_TD_FLAG(PDMA, ADC_PDMA_OPENED_CH);
}
else if (status & (PDMA_INTSTS_REQTOF1_Msk)) /* Check the DMA time-out interrupt flag */
{
PDMA_CLR_TMOUT_FLAG(PDMA, ADC_PDMA_CH);
printf("REQTOF\r\n");
}
else
{
}
}
void PDMA_Init(void)
{
SYS_ResetModule(PDMA_RST);
/* Configure PDMA peripheral mode form ADC to memory */
/* Open PDMA Channel 1 based on ADC_PDMA_CH setting*/
// PDMA_Open(PDMA, BIT0 << ADC_PDMA_CH);
PDMA_Open(PDMA, 0);
/* transfer width is half word(16 bit) and transfer count is ADCDatalenght+1 */
PDMA_SetTransferCnt(PDMA, ADC_PDMA_CH, PDMA_WIDTH_16, ADC_DMA_SAMPLE_COUNT);
/* Set source address as ADC data register (no increment) and destination address as g_i32ConversionData array (increment) */
PDMA_SetTransferAddr(PDMA, ADC_PDMA_CH, (uint32_t) & (EADC->CURDAT), PDMA_SAR_FIX, (uint32_t)pdmaConvertedData, PDMA_DAR_INC);
/* Select PDMA request source as ADC RX */
PDMA_SetTransferMode(PDMA, ADC_PDMA_CH, PDMA_EADC0_RX, FALSE, 0);
/* Set PDMA as single request type for ADC */
PDMA_SetBurstType(PDMA, ADC_PDMA_CH, PDMA_REQ_SINGLE, PDMA_BURST_128);
PDMA_EnableInt(PDMA, ADC_PDMA_CH, PDMA_INT_TRANS_DONE);
NVIC_EnableIRQ(PDMA_IRQn);
PDMA_Trigger(PDMA, ADC_PDMA_CH);
/* ADC enable PDMA transfer */
EADC_ENABLE_PDMA(EADC);
}
void EADC00_IRQHandler(void)
{
// printf(" EADC00_IRQHandler\r\n");
EADC_CLR_INT_FLAG(EADC, EADC_STATUS2_ADIF0_Msk); /* Clear the A/D ADINT0 interrupt flag */
}
void ADC_Convert_Ext_Channel(void)
{
/* Set input mode as single-end, and Single mode*/
EADC_Open(EADC, EADC_CTL_DIFFEN_SINGLE_END);
EADC_SetExtendSampleTime(EADC, 0x0f, 0x3F);
EADC_ConfigSampleModule(EADC, 0, EADC_ADINT0_TRIGGER, 0);
EADC_ConfigSampleModule(EADC, 1, EADC_ADINT0_TRIGGER, 1);
EADC_ConfigSampleModule(EADC, 2, EADC_ADINT0_TRIGGER, 2);
EADC_ConfigSampleModule(EADC, 3, EADC_ADINT0_TRIGGER, 3);
EADC_CLR_INT_FLAG(EADC, EADC_STATUS2_ADIF0_Msk);
EADC_ENABLE_INT(EADC, (BIT0 << 0));
EADC_ENABLE_SAMPLE_MODULE_INT(EADC, 0, 0x7FF);
NVIC_EnableIRQ(EADC00_IRQn);
PDMA_Init();
EADC_START_CONV(EADC, 0x0F);
}
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);
/* Enable External XTAL (4~24 MHz) */
CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
/* Waiting for 12MHz clock ready */
CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
/* Set core clock as PLL_CLOCK from PLL */
CLK_SetCoreClock(FREQ_192MHZ);
/* Set PCLK0/PCLK1 to HCLK/2 */
CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);
/* Enable UART clock */
CLK_EnableModuleClock(UART0_MODULE);
/* Select UART clock source from HXT */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
/* Enable EADC module clock */
CLK_EnableModuleClock(EADC_MODULE);
/* EADC clock source is 96MHz, set divider to 8, EADC clock is 96/8 MHz */
CLK_SetModuleClock(EADC_MODULE, 0, CLK_CLKDIV0_EADC(8));
CLK_EnableModuleClock(PDMA_MODULE);
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
SystemCoreClockUpdate();
/* Set GPB multi-function pins for UART0 RXD and TXD */
SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk);
SYS->GPB_MFPH |= (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);
PB->MODE &= ~(GPIO_MODE_MODE0_Msk | GPIO_MODE_MODE1_Msk | GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);
SYS->GPB_MFPL &= ~(SYS_GPB_MFPL_PB0MFP_Msk | SYS_GPB_MFPL_PB1MFP_Msk | SYS_GPB_MFPL_PB2MFP_Msk | SYS_GPB_MFPL_PB3MFP_Msk);
SYS->GPB_MFPL |= (SYS_GPB_MFPL_PB0MFP_EADC0_CH0 | SYS_GPB_MFPL_PB1MFP_EADC0_CH1 | SYS_GPB_MFPL_PB2MFP_EADC0_CH2 | SYS_GPB_MFPL_PB3MFP_EADC0_CH3);
GPIO_DISABLE_DIGITAL_PATH(PB, BIT0 | BIT1 | BIT2 | BIT3);
/* Set reference voltage to external pin (3.3V) */
SYS_SetVRef(SYS_VREFCTL_VREF_PIN);
/* Lock protected registers */
SYS_LockReg();
}
/*
* This is a template project for M480 series MCU. Users could based on this project to create their
* own application without worry about the IAR/Keil project settings.
*
* This template application uses external crystal as HCLK source and configures UART0 to print out
* "Hello World", users may need to do extra system configuration based on their system design.
*/
int main()
{
SYS_Init();
/* Init UART to 115200-8n1 for print message */
UART_Open(UART0, 115200);
printf("\r\nCLK_GetCPUFreq : %8d\r\n", CLK_GetCPUFreq());
printf("CLK_GetHXTFreq : %8d\r\n", CLK_GetHXTFreq());
printf("CLK_GetLXTFreq : %8d\r\n", CLK_GetLXTFreq());
printf("CLK_GetPCLK0Freq : %8d\r\n", CLK_GetPCLK0Freq());
printf("CLK_GetPCLK1Freq : %8d\r\n", CLK_GetPCLK1Freq());
ADC_Convert_Ext_Channel();
/* Got no where to go, just loop forever */
while(1)
{
pdmaConvertedData[0] = EADC_GET_CONV_DATA(EADC, 0);
pdmaConvertedData[1] = EADC_GET_CONV_DATA(EADC, 1);
pdmaConvertedData[2] = EADC_GET_CONV_DATA(EADC, 2);
pdmaConvertedData[3] = EADC_GET_CONV_DATA(EADC, 3);
printf("%04d,%04d,%04d,%04d \r\n", pdmaConvertedData[0], pdmaConvertedData[1], pdmaConvertedData[2], pdmaConvertedData[3] );
}
}
/*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
|
|