示例代码,实现了在进入关机模式之前测试系统状态的功能。如果系统在断电模式下比预期消耗更多的电量,则可以使用此功能检查是否存在可能导致电源泄漏的系统设置。
/******************************************************************************
* [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: 15/12/29 2:56p $
* [url=home.php?mod=space&uid=247401]@brief[/url] Sample code which implements a function to test system state before
* entering power-down mode. If a system consumes more power than
* expected in power-down mode, this function can be used to check if
* there is any system setting that may cause power leakage.
*
* @note
* Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "Nano103.h"
#include "sys.h"
#ifdef __DEBUG_MSG
#define DEBUG_MSG printf
#else
#define DEBUG_MSG(...)
#endif
/* External functions */
/* Global variables */
__IO int32_t _Wakeup_Flag = 0; /* 1 indicates system wake up from power down mode */
__IO uint32_t _Pin_Setting[11]; /* store Px_H_MFP and Px_L_MFP */
__IO uint32_t _PullUp_Setting[6]; /* store GPIOx_PUEN */
/**
* @brief Store original setting of multi-function pin selection.
* @param None.
* [url=home.php?mod=space&uid=266161]@return[/url] None.
*/
void SavePinSetting()
{
/* Save Pin selection setting */
_Pin_Setting[0] = SYS->GPA_MFPL;
_Pin_Setting[1] = SYS->GPA_MFPH;
_Pin_Setting[2] = SYS->GPB_MFPL;
_Pin_Setting[3] = SYS->GPB_MFPH;
_Pin_Setting[4] = SYS->GPC_MFPL;
_Pin_Setting[5] = SYS->GPC_MFPH;
_Pin_Setting[6] = SYS->GPD_MFPL;
_Pin_Setting[7] = SYS->GPD_MFPH;
_Pin_Setting[8] = SYS->GPE_MFPL;
_Pin_Setting[9] = SYS->GPF_MFPL;
/* Save Pull-up setting */
_PullUp_Setting[0] = PA->PUEN;
_PullUp_Setting[1] = PB->PUEN;
_PullUp_Setting[2] = PC->PUEN;
_PullUp_Setting[3] = PD->PUEN;
_PullUp_Setting[4] = PE->PUEN;
_PullUp_Setting[5] = PF->PUEN;
}
/**
* @brief Save multi-function pin setting and then go to power down.
* @param None.
* @return None.
*/
void Enter_PowerDown()
{
SavePinSetting(); /* Back up original setting */
/* Set function pin to GPIO mode */
SYS->GPA_MFPL = 0;
SYS->GPA_MFPH = 0;
SYS->GPB_MFPL = (SYS_GPB_MFPL_PB0MFP_UART0_RXD | SYS_GPB_MFPL_PB1MFP_UART0_TXD); // exclude debug port;
SYS->GPB_MFPH = 0;
SYS->GPC_MFPL = 0;
SYS->GPC_MFPH = 0;
SYS->GPD_MFPL = 0;
SYS->GPD_MFPH = 0;
SYS->GPE_MFPL = 0;
//SYS->GPE_MFPH = 0;
//SYS->GPF_MFPL = 0x0000FF00; // exclude GPF3:HXT_OUT, GPF2:HXT_IN
SYS->GPF_MFPL = 0x00FFFF00; // exclude GPF5:ICE_DAT, GPF4:ICE_CLK, GPF3:HXT_OUT, GPF2:HXT_IN
/* Enable GPIO pull up */
PA->PUEN = 0xFFFF;
PB->PUEN = 0xFFFF;
PC->PUEN = 0xFFFF;
PD->PUEN = 0xFFFF;
PE->PUEN = 0xFFFF;
//PF->PUEN = 0x0033; /* exclude GPF3 and GPF2 which are HXT OUT/IN */
PF->PUEN = 0x0003; /* exclude GPF5:ICE_DAT, GPF4:ICE_CLK, GPF3:HXT_OUT, GPF2:HXT_IN */
//CLK->PWRCTL |= CLK_PWRCTL_PDWKIEN_Msk; /* Enable wake up interrupt source */
//NVIC_EnableIRQ(PDWU_IRQn); /* Enable IRQ request for PDWU interrupt */
SYS_UnlockReg(); /* Unlock protected registers */
SCB->SCR = SCB_SCR_SLEEPDEEP_Msk; /* Set Deep sleep */
CLK->PWRCTL |= (CLK_PWRCTL_PDEN_Msk | CLK_PWRCTL_PDWKDLY_Msk ); /* Enable Power down and wake up */
//__WFI(); /* system really enter power down here ! */
}
/**
* @brief Power Down check function.
* @param None.
* @return None.
*/
void PowerDown_Check()
{
uint32_t i,j;
volatile uint32_t Tmp_NVIC_ISER;
uint32_t gpio_error_count = 0;
char *symbo_gpio[6] = {"A", "B", "C", "D", "E", "F"};
GPIO_T *tGPIO;
uint32_t SYS_MFP = 0xffffffff;
printf("\n/***** PowerDown Check *****/");
printf("\n/***** GPIO Check: *****/");
Tmp_NVIC_ISER = NVIC->ISER[0]; //save NVIC setting
NVIC->ICER[0] = 0xFFFFFFFF; //disables a device-specific interrupt in the NVIC interrupt controller
for(j = 0; j < 11; j++) { /* Check MFP is set GPIO mode or not */
SYS_MFP = *((volatile unsigned int *)(SYS_BASE + 0x30 + (j *4)));
for(i = 0; i < 8; i++) {
if(SYS_MFP & (0x7 << (i*4))) {
gpio_error_count++;
printf("\nGP%s Pin %d not set GPIO !!", symbo_gpio[(j/2)], (i+(8*(j%2))) );
}
}
}
if( (SYS->GPF_MFPL & SYS_GPF_MFPL_PF3MFP_XT1_IN) != SYS_GPF_MFPL_PF3MFP_XT1_IN) { /* Check HXT_OUT pin */
printf("\nGPF Pin 2 not set HXT_OUT !!!");
printf("\nPlease Check GPF Pin 2 not connect crystal !!!");
}
if( (SYS->GPF_MFPL & SYS_GPF_MFPL_PF2MFP_XT1_OUT) != SYS_GPF_MFPL_PF2MFP_XT1_OUT) { /* Check HXT_IN pin */
printf("\nGPF Pin 3 not set HXT_IN !!!");
printf("\nPlease Check GPF Pin 3 not connect crystal !!!");
}
for(j = 0; j < 6; j++) {
tGPIO =(GPIO_T*)((uint32_t)PA + (j * (0x40)));
for(i = 0; i < 16; i++) {
if((j == 4) & (i > 9)) // GPE
break;
if((j == 5) & (i > 5)) // GPF
break;
if(!(tGPIO->PIN & (1 << i))) { /* Check Pin status */
gpio_error_count++;
printf("\nGP%s Pin %d can not pull high!!", symbo_gpio[j], i);
}
}
}
if(gpio_error_count)
printf("\nGPIO Check fail !!");
else
printf("\nGPIO Check pass");
printf("\n");
printf("\n/***** Clock Check: *****/");
if(CLK->PWRCTL & CLK_PWRCTL_HXT_EN) /* Check HXT_EN */
printf("\nHXT Enable");
else
printf("\nHXT Disable");
if(CLK->PWRCTL & CLK_PWRCTL_LXT_EN) /* Check LXT_EN */
printf("\nLXT Enable");
else
printf("\nLXT Disable");
if(CLK->PWRCTL & CLK_PWRCTL_HIRC0_EN) /* Check HIRCO_EN */
printf("\nHIRC Enable");
else
printf("\nHIRC Disable");
if(CLK->PWRCTL & CLK_PWRCTL_LIRC_EN) /* Check LICR_EN */
printf("\nLIRC Enable");
else
printf("\nLIRC Disable");
printf("\n");
printf("\n/***** Power Down setting check: *****/");
if(CLK->PWRCTL & CLK_PWRCTL_PWRDOWN_EN) /* Check Power Down Enable */
printf("\nChip Power-down mode Enable ");
else
printf("\nChip Power-down mode Disable !!!");
if(SCB->SCR & 0x04) /* Check SCB configuration */
printf("\nSCB->SCR set (0x%x) : ok", SCB->SCR);
else
printf("\nSCB->SCR set (0x%x) : error", SCB->SCR);
//Restore NVIC->ISER setting
NVIC->ISER[0] = Tmp_NVIC_ISER;
printf("\n");
printf("\n/***** Wake-up setting check: *****/");
if(CLK->PWRCTL & CLK_PWRCTL_DELY_EN) /* Check Wake up delay */
printf("\nWake-up Delay Counter Enable");
else
printf("\nWake-up Delay Counter Disable");
if(CLK->PWRCTL & CLK_PWRCTL_WAKEINT_EN) /* Check Wake up interrupt */
printf("\nPower-down Mode Wake-up Interrupt Enable");
else
printf("\nPower-down Mode Wake-up Interrupt Disable");
if( NVIC->ISER[0] & (1 << ((uint32_t)(PDWU_IRQn) & 0x1F)) ) /* Check NVIC IRQ */
printf("\nEnable PDWU_IRQn request for PDWU interrupt");
else
printf("\nDisable PDWU_IRQn request for PDWU interrupt");
printf("\n");
printf("\n/***** ISR check: *****/");
if(NVIC_GetPendingIRQ(PDWU_IRQn)) /* Check Wake up interrupt pending */
printf("\nPowerDown WakeUp Interrupt status is pending. (check fail)");
else
printf("\nPowerDown WakeUp Interrupt status is not pending. (check ok)");
if(CLK->WKINTSTS & 0x1) /* Check Wake up status */
printf("\nWake-up Interrupt Status is set. (check fail)");
else
printf("\nWake-up Interrupt Status is not set. (check ok)");
printf("\n");
printf("\n/***** PowerDown Check End *****/");
}
/**
* @brief Init system clock and I/O multi function .
* @param None
* @return None
*/
void SYS_Init(void)
{
/*---------------------------------------------------------------------------------------------------------*/
/* Init System Clock */
/*---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Enable IP clock */
CLK->APBCLK |= CLK_APBCLK_UART0_EN; // UART0 Clock Enable
/* Select IP clock source */
CLK->CLKSEL1 &= ~CLK_CLKSEL1_UART0SEL_Msk;
CLK->CLKSEL1 |= CLK_CLKSEL1_UART0SEL_HIRC;// Clock source from HIRC
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
SystemCoreClockUpdate();
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set PB multi-function pins for UART0 RXD and TXD */
SYS->GPB_MFPL &= ~(SYS_GPB_MFPL_PB0MFP_Msk|SYS_GPB_MFPL_PB1MFP_Msk);
SYS->GPB_MFPL |= (SYS_GPB_MFPL_PB0MFP_UART0_RXD|SYS_GPB_MFPL_PB1MFP_UART0_TXD);
/* Lock protected registers */
SYS_LockReg();
}
/**
* @brief Config UART0.
* @param None
* @return None
*/
void UART0_Init()
{
UART_Open(UART0, 115200); /* set UART baudrate is 115200 */
}
/**
* @brief Main routine.
* @param None.
* @return None.
*/
int32_t main(void)
{
/* Init System, IP clock and multi-function I/O */
SYS_Init();
/* Init UART0 for printf */
UART0_Init();
/* Prepare to enter power down mode, to demo the usage of PowerDown_Check(),
this function does not actually put this system to power down mode */
Enter_PowerDown();
/* Check system state before enter power down mode */
PowerDown_Check();
while(1);
}
/*** (C) COPYRIGHT 2015 Nuvoton Technology Corp. ***/
|