📄 counter.c
字号:
#include "db.h"
#include "mcu.h"
#define BIT(x) (1 << (x))
#define GPT_CTL_RST BIT(15) // reset=1
#define GPT_CTL_FRR BIT(8) // free-run=1, restart=0
#define GPT_CTL_CAPT (BIT(7)|BIT(6)) // disable=00,rising=01,falling=10,both=11
#define GPT_CTL_OMODE BIT(5) // 0=pulse output, 1=toggle output
#define GPT_CTL_IRQEN BIT(4) // 0=disable compare irq, 1=enable
#define GPT_CTL_CLKSRC (BIT(3)|BIT(2)|BIT(1)) // 000=stop,001=PERCLK1,010=PERCLK1/16,011=TIN,1xx=32kHz
#define GPT_CTL_TEN BIT(0) // 0=timer disabled(counter=0), 1=timer is enabled
#define GPT_STATUS_CAPT BIT(1) // 1= capture event occurred
#define GPT_STATUS_COMP BIT(0) // 1= compare event occurred
#define GPT_CLKSRC_NONE 0
#define GPT_CLKSRC_PERCLK BIT(1)
#define GPT_CLKSRC_PERCLK16 BIT(2)
#define GPT_CLKSRC_32KHZ BIT(3)
#define MPCTL0_OFS 0x1B004
#define MPCTL1_OFS 0x1B008
#define SPCTL0_OFS 0x1B00C
#define SPCTL1_OFS 0x1B010
#define PDCR_OFS 0x1B020
#define MX1_REG(x) (*(unsigned long volatile *)(__mxL_base + (x)))
#define MPCTL0 MX1_REG(MPCTL0_OFS)
#define MPCTL1 MX1_REG(MPCTL1_OFS)
#define SPCTL0 MX1_REG(SPCTL0_OFS)
#define SPCTL1 MX1_REG(SPCTL1_OFS)
#define PDCR MX1_REG(PDCR_OFS)
#define MFN(x) ((x) & 0x03FFUL)
#define MFI(x) (((x) >> 10) & 0x000FUL)
#define MFD(x) (((x) >> 16) & 0x03FFUL)
#define PD(x) (((x) >> 26) & 0x000FUL)
#define PERCLKDIV1(x) ((x) & 0x000FUL)
#define PERCLKDIV2(x) (((x) >> 4) & 0x000FUL)
#define PERCLKDIV3(x) (((x) >> 16) & 0x007FUL)
typedef volatile struct tagGPT_T {
unsigned long ctl;
unsigned long prescaler; // 8-bit prescaler, div by 1..256
unsigned long compare; // 32-bit compare
unsigned long capture; // 32-bit capture
unsigned long counter; // 32-bit count
unsigned long status; // capture and compare event status
} GPT_T;
#define GPT0_OFFSET 0x002000
#define GPT1_OFFSET 0x003000
#define GPT_OFFSET GPT1_OFFSET
#define GPT_ADDR(x) ((GPT_T *) ((x) + GPT_OFFSET))
#define FREF 16384 /* kHz */
#define SPLL 96
static GPT_T *gpt = 0;
static unsigned long __mxL_base = 0;
int counter_init (unsigned long base)
{
int i = 0;
__mxL_base = base;
gpt = GPT_ADDR(base);
// select free-running mode,
// disable compare and capture events and irq
gpt->ctl = GPT_CTL_RST; // TEN is cleared to reset the counter
while (gpt->ctl & GPT_CTL_RST) {
if (i++ == 10000)
break;
}
if (gpt->ctl & GPT_CTL_RST) {
db ("GPT SWR bit is not self-clearing\n");
gpt->ctl &= ~GPT_CTL_RST;
} else {
db ("GPT SWR is self-clearing\n");
}
// this value is hardcoded to the PLL Clock to achieve a 1MHz clock.
// Fpll = 2*Fref*(MFI + MFN/(MFD+1))/(PD+1);
db ("SPCTL0=0x%08lx, MPCTL0=0x%08lx\n", SPCTL0, MPCTL0);
//syspll = (2*FREF*(MFI(SPCTL0) + MFN(SPCTL0)/(MFD(SPCTL0)+1))/(PD(SPCTL0)+1))/1000;
//mcupll = (2*FREF*(MFI(MPCTL0) + MFN(MPCTL0)/(MFD(MPCTL0)+1))/(PD(MPCTL0)+1))/1000;
gpt->prescaler = (SPLL/ (PERCLKDIV1(PDCR) + 1)) - 1;
gpt->ctl |= (GPT_CTL_FRR | GPT_CLKSRC_PERCLK); // turn on free-run mode
db ("PERCLKDIV1=%lu, prescaler=%lu\n", PERCLKDIV1(PDCR), gpt->prescaler);
return 0;
}
int inline counter_start (void)
{
if (gpt) {
gpt->ctl |= GPT_CTL_TEN;
return 0;
}
return -1;
}
int inline counter_reset (void)
{
if (gpt) {
gpt->ctl &= ~GPT_CTL_TEN;
return 0;
}
return -1;
}
int inline counter_stop (void)
{
// clear the clk source
if (gpt) {
gpt->ctl &= ~GPT_CTL_CLKSRC;
return 0;
}
return -1;
}
unsigned long inline counter_read (void)
{
return (gpt ? gpt->counter:0xdeadbeef);
}
/* end */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -