TIMER1_CNT read 1 but not 0 after reset
Closed this issue · 14 comments
after power up or one-shot reset, TIMER1_CNT value is always 1, why isn't 0?
and in very rare circumstances, the counter stops counting in one-shot mode, the CTL is 0x42000015, INTSTS is 0x00000001 but CNT is always 0x00000001, the issue is found when there is power switching but there is no voltage drop (> 3V always) for the MCU in the process. any tips?
the simplied code logic like this:
....initial module clock....
uint32_t val = 0;
while (1) {
if (TIMER_IS_ACTIVE(TIMER1)) {
val= TIMER_GetCounter(TIMER1);
} else {
TIMER1->CTL |= TIMER_CTL_RSTCNT_Msk;
TIMER_ClearIntFlag(TIMER1);
TIMER_Start(TIMER1);
val= 0;
}
}
It's a known issue. There exists some synchronization problem between timer register and internal circut.
Once the timer start conuting, counter register keeps 1 for 2 clocks, and all subsequent counting takes 1 clock.
is there any register setting error that will lead to timer's CTL is 0x42000015, CMP is 0x00FFFFFF, but CNT is always 0x00000001 ?
the PLL and the related clocks are correct, set RSTCNT to 1 in CTL will fix the failure.
有没有可能register设定错误会导致CTL是0x42000015但是CNT却不计数一直返回0x00000001?
PLL以及相关clock的enable设置都没有问题, RSTCNT设为1就可以恢复正常.
can you provide your code?
can you provide your code?
it's on the second post this topic, with the initial setting :
CLK_EnableModuleClock(TMR1_MODULE);
TIMER1->CTL = TIMER_ONESHOT_MODE;
TIMER_SET_PRESCALE_VALUE(TIMER1, 21);
TIMER_SET_CMP_VALUE(TIMER1, 0xFFFFFF);
Above image is captured from ICE window after program run completed.
It's not 0x00000015, not 0x42000015.
/************************************************************************//
- @file main.c
- @Version V1.00
$Revision: 3 $ $Date: 15/05/28 10:37a $ - @brief Demonstrate the usage of TIMER_Delay() API to generate a 1
-
second delay.
- @note
- Copyright (C) 2015 Nuvoton Technology Corp. All rights reserved.
*****************************************************************************/
#include <stdio.h>
#include "Mini58Series.h"
void SYS_Init(void)
{
/---------------------------------------------------------------------------------------------------------/
/* Init System Clock /
/---------------------------------------------------------------------------------------------------------*/
/* Unlock protected registers */
SYS_UnlockReg();
/* Set P5 multi-function pins for XTAL1 and XTAL2 */
SYS->P5_MFP &= ~(SYS_MFP_P50_Msk | SYS_MFP_P51_Msk);
SYS->P5_MFP |= (SYS_MFP_P50_XT1_IN | SYS_MFP_P51_XT1_OUT);
/* Enable external 12MHz XTAL (UART), and HIRC */
CLK->PWRCTL = CLK_PWRCTL_XTL12M | CLK_PWRCTL_HIRCEN_Msk;
/* Waiting for clock ready */
CLK_WaitClockReady(CLK_STATUS_XTLSTB_Msk | CLK_STATUS_HIRCSTB_Msk);
/* Enable UART and Timer 0 clock */
CLK->APBCLK = CLK_APBCLK_UART0CKEN_Msk | CLK_APBCLK_TMR0CKEN_Msk;
/* Enable UART and Timer 1 clock */
CLK->APBCLK = CLK_APBCLK_TMR1CKEN_Msk;
/* Select UART clock source from external crystal*/
CLK->CLKSEL1 = (CLK->CLKSEL1 & ~CLK_CLKSEL1_UARTSEL_Msk) | CLK_CLKSEL1_UARTSEL_XTAL;
/* Update System Core Clock */
/* User can use SystemCoreClockUpdate() to calculate SystemCoreClock and CycylesPerUs automatically. */
SystemCoreClockUpdate();
/*---------------------------------------------------------------------------------------------------------*/
/* Init I/O Multi-function */
/*---------------------------------------------------------------------------------------------------------*/
/* Set P1 multi-function pins for UART RXD, TXD */
SYS->P1_MFP = SYS_MFP_P12_UART0_RXD | SYS_MFP_P13_UART0_TXD;
/* Lock protected registers */
SYS_LockReg();
}
int main(void)
{
uint32_t val = 0;
/* Init System, IP clock and multi-function I/O
In the end of SYS_Init() will issue SYS_LockReg()
to lock protected register. If user want to write
protected register, please issue SYS_UnlockReg()
to unlock protected register if necessary */
SYS_Init();
/* Init UART to 115200-8n1 for print message */
UART_Open(UART0, 115200);
TIMER1->CTL = TIMER_ONESHOT_MODE;
TIMER_SET_PRESCALE_VALUE(TIMER1, 21);
TIMER_SET_CMP_VALUE(TIMER1, 0xFFFFFF);
while (1);
}
yes, in most case when the counter stops, CTL is 0x00000015. it just happens in very rary circumstances in thousands of power on/off switching with a battery as a backup power. when it happens, all other functions like uart/i2c/gpio irq still work normally, and when the fault encountered, it's always timer1 failure.
please change the code in while (1) to:
while (1) {
if (TIMER_IS_ACTIVE(TIMER1)) {
uint32_t i;
uint32_t val = TIMER_GetCounter(TIMER1);
for (i = 0; i < 1000; i++) {
if (val != TIMER_GetCounter(TIMER1))
break;
}
if (i == 1000)
printf("ERROR ....");
} else {
TIMER1->CTL |= TIMER_CTL_RSTCNT_Msk;
TIMER_ClearIntFlag(TIMER1);
TIMER_Start(TIMER1);
}
}
The "ERROR..." might never be printed in normal state without power noise, but with power noise, it might be printed unexpectedly.
So, what's the problem?
Sorry, I cannot catch your point.
The program seems run as expected. Timer1 is counting and ERROR is not printed.
So, what's the problem? Sorry, I cannot catch your point. The program seems run as expected. Timer1 is counting and ERROR is not printed.
but sometimes ERROR is printed as unexpected with noise on power, and the noise doesn't impact any other functions except timer1.
Power noise or EMI issues are not expected to be solved here.
Suggest to contact with Nuvoton FAE.
Power noise or EMI issues are not expected to be solved here. Suggest to contact with Nuvoton FAE.
OK, thanks for the replies