/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define TIMER_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "Timer.h"
#include "XLED.h"
#include "XVarBank.h"
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
#if defined(AT91SAM9260)
#define SYS_TIMER_DIV 32UL
#define CLEAR_TIMER_STATUS
#elif defined(SH7040)
#define SYS_TIMER_DIV 8UL
#define CLEAR_TIMER_STATUS (CMT0.CMCSR.BIT.CMF = 0)
#elif defined(N3290)
#define CLEAR_TIMER_STATUS
#if defined(CPU_144MHZ_MODE)
#define SYS_TIMER_DIV 144UL
#else
#define SYS_TIMER_DIV 192UL
#endif
#endif
#define TIMER_PERIOD (PERIPHERAL_CLOCK / SYS_TIMER_DIV / 1000UL * PERIOD_TIMES)
#define DELAY_TIME_TOTAL 20//16 // ch_20220421 : changed to 20 from 16 cause of finding FlashBlueRedLEDFast cannot be canceled.
#define PERIOD_FUNC_TOTAL 20//16 // ch_20220421 : changed to 20 from 16 cause of finding FlashBlueRedLEDFast cannot be canceled.
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
STATIC INT DelayTimer[DELAY_TIME_TOTAL];
STATIC PERIODFUNC PeriodFunc[PERIOD_FUNC_TOTAL];
/******************************************************************************
*
* Function:
*
*
* Description:
*
*
* Input:
* None
*
* Output:
* None.
*
******************************************************************************/
VOID InitialSysTimer(VOID)
{
INT i;
UINT dummy;
#if 1
PWM_TIME_DATA_T sPt;
PFN_PWM_CALLBACK *pfnOldcallback;
PWM_Open();
outp32(PCR, (inp32(PCR) & ~(1 << ((((PWM_TIMER2 & 0x07)) << 3) + 2) )) |1 << (((PWM_TIMER2 & 0x07) << 3) + 2));
outp32(PCR, (inp32(PCR) & ~(1 <<(((PWM_TIMER2 & 0x07) << 3) + 3))) | ( 1 <<(((PWM_TIMER2 & 0x07) << 3) + 3)));
#if defined(CPU_144MHZ_MODE)
outp32(PPR, (inp32(PPR) & ~CP1) | (((9 - 1) & 0xFF) << 8));// prescale 72M/9 = 8MHz
// 8MHz/8 = 1MHz
outp32(PWM_CSR, (inp32(PWM_CSR) & ~(0x7 << ((PWM_TIMER2 & 0x07)<<2) )) | ((2 & 0x7) << ((PWM_TIMER2 & 0x07)<<2)));
#else
outp32(PPR, (inp32(PPR) & ~CP1) | (((12 - 1) & 0xFF) << 8));// prescale 96M/12 = 8MHz
// 8MHz/8 = 1MHz
outp32(PWM_CSR, (inp32(PWM_CSR) & ~(0x7 << ((PWM_TIMER2 & 0x07)<<2) )) | ((2 & 0x7) << ((PWM_TIMER2 & 0x07)<<2))); //100 000 001 010 011 1 2 4 8 16
#endif
outp32(CNR0 + (PWM_TIMER2 & 0x07) * 12, (3000*PERIOD_TIMES - 1)); //8MHz/8 = 1MHz 10000 ticks = 10ms
outp32(CMR0 + (PWM_TIMER2 & 0x07) * 12, (1500*PERIOD_TIMES - 1));
outp32(PIER, inp32(PIER) | (1<<PWM_TIMER2));
PWM_InstallCallBack(PWM_TIMER2, SysTimerHandler, pfnOldcallback);
outp32(PCR, (inp32(PCR)& ~(1 << ((PWM_TIMER2 & 0x07) << 3) )) | (1 << ((PWM_TIMER2 & 0x07) << 3) ) );
#elif 0
PWM_TIME_DATA_T sPt;
PFN_PWM_CALLBACK *pfnOldcallback;
PWM_Open();
/* PWM Timer property */
sPt.u8Mode = PWM_TOGGLE_MODE;
sPt.fFrequency = 50;
sPt.u8HighPulseRatio = 50; /* High Pulse peroid : Total Pulse peroid = 1 : 100 */
sPt.bInverter = FALSE;
//sPt.u8ClockSelector = PWM_CLOCK_DIV_8;
/* Set PWM Timer 0 Configuration */
PWM_SetTimerClk(PWM_TIMER2,&sPt);
/* Enable Output for PWM Timer 0 */
//PWM_SetTimerIO(PWM_TIMER2,TRUE);
/* Enable Interrupt Sources of PWM Timer 0 */
PWM_EnableInt(PWM_TIMER2,1);
/* Install Callback function */
PWM_InstallCallBack(PWM_TIMER2, SysTimerHandler, pfnOldcallback);
/* Enable the PWM Timer 0 */
PWM_Enable(PWM_TIMER2,TRUE);
#endif
for (i = 0; i < DELAY_TIME_TOTAL; i++)
DelayTimer[i] = DELAY_TIME_NULL;
for (i = 0; i < PERIOD_FUNC_TOTAL; i++)
PeriodFunc[i] = _NULL;
}
INT SetDelayTime(INT time)
{
INT num;
for (num = 0; num < DELAY_TIME_TOTAL; num++)
{
if (DelayTimer[num] == DELAY_TIME_NULL)
{
DelayTimer[num] = time / PERIOD_TIMES;
break;
}
}
if (num == DELAY_TIME_TOTAL)
return DELAY_TIME_NULL;
return num;
}
VOID ClrDelayTime(INT num)
{
if (num == DELAY_TIME_NULL)
return;
if (num < DELAY_TIME_TOTAL)
DelayTimer[num] = DELAY_TIME_NULL;
}
BOOL CheckDelayTimer(INT num)
{
if (num == DELAY_TIME_NULL)
return FALSE;
if (DelayTimer[num] == DELAY_TIME_NULL)
return FALSE;
if (DelayTimer[num] > 0)
return TRUE;
return FALSE;
}
VOID delay_msec(INT time)
{
INT num = SetDelayTime(time);
while(CheckDelayTimer(num)){}
ClrDelayTime(num);
}
VOID DelayTime(ULONG t)
{
#if defined(AT91SAM9260) && defined(DCACHE)
t += 1; // Because the D-Cache is enabled
#endif
/*
* AT91SAM9260 : 1 msec, t = 35000
* SH7040 : 1 msec, t = 7100
*/
while (t--){}
}
BOOL StartPeriodFunc(PERIODFUNC Func)
{
INT i;
for (i = 0; i < PERIOD_FUNC_TOTAL; i++)
{
if (PeriodFunc[i] == Func || PeriodFunc[i] == _NULL)
{
PeriodFunc[i] = Func;
return TRUE;
}
}
return FALSE;
}
VOID StopPeriodFunc(PERIODFUNC Func)
{
INT i;
for (i = 0; i < PERIOD_FUNC_TOTAL; i++)
{
if (PeriodFunc[i] == Func)
{
PeriodFunc[i] = _NULL;
}
}
}
BOOL CancelPeriodFunc(PERIODFUNC Func)
{
INT i;
BOOL ret;
ret = FALSE;
for (i = 0; i < PERIOD_FUNC_TOTAL; i++)
{
if (PeriodFunc[i] == Func)
{
PeriodFunc[i] = _NULL;
ret = TRUE;
}
}
return ret;
}
STATIC VOID ScanDelayTimer(VOID)
{
INT num;
INT imask;
imask = DisableInterrupt(INTERRUPT_MASK);
for (num = 0; num < DELAY_TIME_TOTAL; num++)
{
if (DelayTimer[num] > 0 && DelayTimer[num] != DELAY_TIME_NULL)
DelayTimer[num] -= 1;
}
EnableInterrupt(imask);
}
STATIC VOID ScanPeriodFunc(VOID)
{
INT i;
for (i = 0; i < PERIOD_FUNC_TOTAL; i++)
{
if (PeriodFunc[i])
PeriodFunc[i]();
}
}
/*********************************************************
10ms定时
**********************************************************/
#if 1
void dbug(void)
{
static volatile int a=1;
if(a)
outpw(REG_GPIOC_DOUT, inpw(REG_GPIOC_DOUT)&(~BIT10));
else
outpw(REG_GPIOC_DOUT, inpw(REG_GPIOC_DOUT)|BIT10);
a++;
a%=2;
}
#endif
VOID SysTimerHandler(VOID)
{
#if defined(AT91SAM9260)
UINT status = AT91C_BASE_TC4->TC_SR;
UINT mask = AT91C_BASE_TC4->TC_IMR;
UINT interrupt = status & mask;
if (interrupt & AT91C_TC_CPCS)
SysTimerISR();
#elif defined(N3290)
//TestGpio();
SysTimerISR();
#endif
}
VOID SysTimerISR(VOID)
{
CLEAR_TIMER_STATUS;
CLOSE_WATCH_DOG;
ScanDelayTimer();
ScanPeriodFunc();
START_WATCH_DOG(0, 7);
}
Timer.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef TIMER_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define TIMER_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
#define PERIOD_TIMES 10
#define DELAY_TIME_NULL -1
#if defined(AT91SAM9260)
#define DELAY_MILLISECOND 35000
#elif defined(SH7040)
#define DELAY_MILLISECOND 7100
#elif defined(N3290)
#define DELAY_MILLISECOND 35000
#endif
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
typedef VOID (*PERIODFUNC)(VOID);
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
VOID InitialSysTimer(VOID);
INT SetDelayTime(INT);
VOID ClrDelayTime(INT);
BOOL CheckDelayTimer(INT);
VOID delay_msec(INT);
VOID DelayTime(ULONG);
BOOL StartPeriodFunc(PERIODFUNC);
VOID StopPeriodFunc(PERIODFUNC Func); // ch_20211217
BOOL CancelPeriodFunc(PERIODFUNC);
VOID SysTimerHandler(VOID);
VOID SysTimerISR(VOID);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif