/****************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url] main.c
* [url=home.php?mod=space&uid=895143]@version[/url] V3.00
* [url=home.php?mod=space&uid=247401]@brief[/url] Show how to wake up system form Power-down mode by UART interrupt.
*
* [url=home.php?mod=space&uid=17282]@CopyRight[/url] (C) 2019 Nuvoton Technology Corp. All rights reserved.
*
******************************************************************************/
#include <stdio.h>
#include "NuMicro.h"
#define PLL_CLOCK 64000000
#define RS485_ADDRESS 0xC0
/*---------------------------------------------------------------------------------------------------------*/
/* Define functions prototype */
/*---------------------------------------------------------------------------------------------------------*/
void UART_DataWakeUp(void);
void UART_CTSWakeUp(void);
void UART_RxThresholdWakeUp(void);
void UART_RS485WakeUp(void);
void UART_PowerDown_TestItem(void);
void UART_PowerDownWakeUpTest(void);
/*---------------------------------------------------------------------------------------------------------*/
/* Function for System Entry to Power Down Mode */
/*---------------------------------------------------------------------------------------------------------*/
void PowerDownFunction(void)
{
/* Check if all the debug messages are finished */
UART_WAIT_TX_EMPTY(DEBUG_PORT);
/* Enter to Power-down mode */
CLK_PowerDown();
}
void SYS_Init(void)
{
/* Set PF multi-function pins for XT1_OUT(PF.2) and XT1_IN(PF.3) */
SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF2MFP_Msk)) | SYS_GPF_MFPL_PF2MFP_XT1_OUT;
SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF3MFP_Msk)) | SYS_GPF_MFPL_PF3MFP_XT1_IN;
/* Set PF multi-function pins for X32_OUT(PF.4) and X32_IN(PF.5) */
SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF4MFP_Msk)) | SYS_GPF_MFPL_PF4MFP_X32_OUT;
SYS->GPF_MFPL = (SYS->GPF_MFPL & (~SYS_GPF_MFPL_PF5MFP_Msk)) | SYS_GPF_MFPL_PF5MFP_X32_IN;
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Enable HIRC, HXT and LXT clock */
CLK_EnableXtalRC(CLK_PWRCTL_HIRCEN_Msk);
CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);
CLK_EnableXtalRC(CLK_PWRCTL_LXTEN_Msk);
/* Wait for HIRC, HXT and LXT clock ready */
CLK_WaitClockReady(CLK_STATUS_HIRCSTB_Msk);
CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);
CLK_WaitClockReady(CLK_STATUS_LXTSTB_Msk);
/* Enable PLL */
CLK->PLLCTL = CLK_PLLCTL_128MHz_HIRC;
/* Waiting for PLL stable */
CLK_WaitClockReady(CLK_STATUS_PLLSTB_Msk);
/* Select HCLK clock source as PLL and HCLK source divider as 2 */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_PLL, CLK_CLKDIV0_HCLK(2));
/* Enable UART module clock */
CLK_EnableModuleClock(UART0_MODULE);
CLK_EnableModuleClock(UART1_MODULE);
/* Select UART module clock source as HIRC and UART module clock divider as 1 */
CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HIRC, CLK_CLKDIV0_UART0(1));
CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_HIRC, CLK_CLKDIV0_UART1(1));
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set multi-function pins for UART0 RXD and TXD */
SYS->GPB_MFPH = (SYS->GPB_MFPH & (~(UART0_RXD_PB12_Msk | UART0_TXD_PB13_Msk))) | UART0_RXD_PB12 | UART0_TXD_PB13;
/* Set PB multi-function pins for UART1 RXD(PB.6), TXD(PB.7) and nCTS(PB.9) */
SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB6MFP_Msk)) | SYS_GPB_MFPL_PB6MFP_UART1_RXD;
SYS->GPB_MFPL = (SYS->GPB_MFPL & (~SYS_GPB_MFPL_PB7MFP_Msk)) | SYS_GPB_MFPL_PB7MFP_UART1_TXD;
SYS->GPB_MFPH = (SYS->GPB_MFPH & (~SYS_GPB_MFPH_PB9MFP_Msk)) | SYS_GPB_MFPH_PB9MFP_UART1_nCTS;
}
void UART0_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init UART */
/*---------------------------------------------------------------------------------------------------------*/
/* Reset UART0 */
SYS_ResetModule(UART0_RST);
/* Configure UART0 and set UART0 baud rate */
UART_Open(UART0, 115200);
}
void UART1_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init UART */
/*---------------------------------------------------------------------------------------------------------*/
/* Reset UART1 */
SYS_ResetModule(UART1_RST);
/* Configure UART1 and set UART1 Baudrate */
UART_Open(UART1, 9600);
}
/*---------------------------------------------------------------------------------------------------------*/
/* Main Function */
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
/* Unlock protected registers */
SYS_UnlockReg();
/* Init System, peripheral clock and multi-function I/O */
SYS_Init();
/* Lock protected registers */
SYS_LockReg();
/* Init UART0 for printf */
UART0_Init();
/* Init UART1 for test */
UART1_Init();
/*---------------------------------------------------------------------------------------------------------*/
/* SAMPLE CODE */
/*---------------------------------------------------------------------------------------------------------*/
printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %dHz\n", SystemCoreClock);
printf("UART Sample Program\n\n");
/* UART Power-down and Wake-up sample function */
UART_PowerDownWakeUpTest();
printf("\nUART Sample Program End\n");
while(1);
}
/*---------------------------------------------------------------------------------------------------------*/
/* ISR to handle UART Channel 1 interrupt event */
/*---------------------------------------------------------------------------------------------------------*/
void UART1_IRQHandler(void)
{
uint32_t u32Data;
if(UART_GET_INT_FLAG(UART1, UART_INTSTS_WKINT_Msk)) /* UART wake-up interrupt flag */
{
UART_ClearIntFlag(UART1, UART_INTSTS_WKINT_Msk);
printf("UART wake-up.\n");
UART_WAIT_TX_EMPTY(DEBUG_PORT);
}
else if(UART_GET_INT_FLAG(UART1, UART_INTSTS_RDAINT_Msk | UART_INTSTS_RXTOINT_Msk)) /* UART receive data available flag */
{
while(UART_GET_RX_EMPTY(UART1) == 0)
{
u32Data = UART_READ(UART1);
if(u32Data & UART_DAT_PARITY_Msk)
printf("Address: 0x%X\n", (u32Data & 0xFF));
else
printf("Data: 0x%X\n", u32Data);
}
}
}
/*---------------------------------------------------------------------------------------------------------*/
/* UART nCTS Wake-up Function */
/*---------------------------------------------------------------------------------------------------------*/
void UART_CTSWakeUp(void)
{
/* Enable UART nCTS wake-up function */
UART1->WKCTL |= UART_WKCTL_WKCTSEN_Msk;
printf("System enter to Power-down mode.\n");
printf("Toggle UART1 nCTS to wake-up system.\n\n");
}
/*---------------------------------------------------------------------------------------------------------*/
/* UART Data Wake-up Function */
/*---------------------------------------------------------------------------------------------------------*/
void UART_DataWakeUp(void)
{
/* Enable UART data wake-up function */
UART1->WKCTL |= UART_WKCTL_WKDATEN_Msk;
/* Set UART data wake-up start bit compensation value.
It indicates how many clock cycle selected by UART_CLK does the UART controller can get the first bit (start bit)
when the device is wake-up from power-down mode.
If UART_CLK is selected as HIRC(12MHz) and the HIRC stable time is about 8.602us,
the data wake-up start bit compensation value can be set as 104. */
UART1->DWKCOMP = 104;
printf("System enter to Power-down mode.\n");
printf("Send data with baud rate 9600bps to UART1 to wake-up system.\n\n");
}
/*---------------------------------------------------------------------------------------------------------*/
/* UART Rx threshold and time-out Function */
/*---------------------------------------------------------------------------------------------------------*/
void UART_RxThresholdWakeUp(void)
{
/* Select UART clock source as LXT */
CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_LXT, CLK_CLKDIV0_UART1(1));
/* Set UART baud rate and baud rate compensation */
UART_Open(UART1, 9600);
UART1->BRCOMP = 0xA5;
/* Enable UART Rx Threshold and Rx time-out wake-up function */
UART1->WKCTL |= UART_WKCTL_WKRFRTEN_Msk | UART_WKCTL_WKTOUTEN_Msk;
/* Set Rx FIFO interrupt trigger level */
UART1->FIFO = (UART1->FIFO & (~UART_FIFO_RFITL_Msk)) | UART_FIFO_RFITL_4BYTES;
/* Enable UART Rx time-out function */
UART_SetTimeoutCnt(UART1, 40);
printf("System enter to Power-down mode.\n");
printf("Send data with baud rate 9600bps to UART1 to wake-up system.\n\n");
}
/*---------------------------------------------------------------------------------------------------------*/
/* UART RS485 address match (AAD mode) function */
/*---------------------------------------------------------------------------------------------------------*/
void UART_RS485WakeUp(void)
{
/* Select UART clock source as LXT */
CLK_SetModuleClock(UART1_MODULE, CLK_CLKSEL1_UART1SEL_LXT, CLK_CLKDIV0_UART1(1));
/* Set UART baud rate and baud rate compensation */
UART_Open(UART1, 9600);
UART1->BRCOMP = 0xA5;
/* RS485 address match (AAD mode) setting */
UART_SelectRS485Mode(UART1, UART_ALTCTL_RS485AAD_Msk, RS485_ADDRESS);
/* Enable parity source selection function */
UART1->LINE |= (UART_LINE_PSS_Msk | UART_LINE_PBE_Msk);
/* Enable UART RS485 address match, Rx Threshold and Rx time-out wake-up function */
UART1->WKCTL |= UART_WKCTL_WKRFRTEN_Msk | UART_WKCTL_WKRS485EN_Msk | UART_WKCTL_WKTOUTEN_Msk;
/* Enable UART Rx time-out function */
UART_SetTimeoutCnt(UART1, 40);
printf("System enter to Power-down mode.\n");
printf("Send RS485 address byte 0x%X with baud rate 9600bps to UART1 to wake-up system.\n\n", RS485_ADDRESS);
}
/*---------------------------------------------------------------------------------------------------------*/
/* UART Power-down and Wake-up Menu */
/*---------------------------------------------------------------------------------------------------------*/
void UART_PowerDown_TestItem(void)
{
printf("+-----------------------------------------------------------+\n");
printf("| UART Power-down and wake-up test |\n");
printf("+-----------------------------------------------------------+\n");
printf("| [1] nCTS wake-up test |\n");
printf("| [2] Data wake-up test |\n");
printf("| [3] Rx threshold and time-out wake-up test |\n");
printf("| [4] RS485 wake-up test |\n");
printf("+-----------------------------------------------------------+\n");
printf("| Quit - [Others] |\n");
printf("+-----------------------------------------------------------+\n");
printf("Please Select key (1~4): ");
}
/*---------------------------------------------------------------------------------------------------------*/
/* UART Power-down and Wake-up Test Function */
/*---------------------------------------------------------------------------------------------------------*/
void UART_PowerDownWakeUpTest(void)
{
uint32_t u32Item;
printf("Due to PLL clock stable too slow.\n");
printf("Before demo UART wake-up, this demo code will switch HCLK from PLL to HIRC.\n");
/* Unlock protected registers */
SYS_UnlockReg();
/* Select HCLK clock source as HIRC and HCLK clock divider as 1 */
CLK_SetHCLK(CLK_CLKSEL0_HCLKSEL_HIRC, CLK_CLKDIV0_HCLK(1));
/* Lock protected registers */
SYS_LockReg();
printf("\nCPU @ %dHz\n", SystemCoreClock);
/* Enable UART wake-up and receive data available interrupt */
UART_EnableInt(UART1, UART_INTEN_WKIEN_Msk | UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
UART_PowerDown_TestItem();
u32Item = getchar();
printf("%c\n\n", u32Item);
switch(u32Item)
{
case '1':
UART_CTSWakeUp();
break;
case '2':
UART_DataWakeUp();
break;
case '3':
UART_RxThresholdWakeUp();
break;
case '4':
UART_RS485WakeUp();
break;
default:
return;
}
/* Unlock protected registers before entering Power-down mode */
SYS_UnlockReg();
/* Enter to Power-down mode */
PowerDownFunction();
/* Lock protected registers after entering Power-down mode */
SYS_LockReg();
printf("Enter any key to end test.\n\n");
getchar();
/* Disable UART wake-up function */
UART1->WKCTL = 0;
/* Disable UART Interrupt */
UART_DisableInt(UART1, UART_INTEN_WKIEN_Msk | UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk);
/* Unlock protected registers */
SYS_UnlockReg();
/* Set core clock as PLL_CLOCK from PLL */
CLK_SetCoreClock(PLL_CLOCK);
/* Lock protected registers */
SYS_LockReg();
}
/*** (C) COPYRIGHT 2019 Nuvoton Technology Corp. ***/
|