MAX_CARLINK_A270S/MXC_A27-PCB4.5-270T/ArkmicroFiles/libcpu-amt630hv100/source/pwm_cap.c

207 lines
4.9 KiB
C

#include "FreeRTOS.h"
#include "board.h"
#ifdef PWM_CAP_SUPPORT
#include "chip.h"
#include "pwm_cap.h"
#define PWM_CAP_INT_CLEAR (0x10*4)
#define PWM_CAP_INT_EN (0x20*4)
#define PWM_CAP_INT_STA (0x21*4)
#define PWM_CAP_SYS_FRQ (0x00)
#define PWM_CAP_SETTING (0x04)
#define PWM_CAP_CYCLE_CAP (0x08)
#define PWM_FRE_CAP (0x0c)
#define PWM_CAP_CLK 198000000
#define PWM_CAP_REG(x) (REGS_PWM_BASE + 0x100 + 0x10 * (x))
void pwm_cap_Int_Handler(void *para);
static void pwm_cap_clk_config(UINT8 id,UINT32 clk)
{
writel(clk,PWM_CAP_REG(id) + PWM_CAP_SYS_FRQ);
}
static void pwm_cap_en(UINT8 id,UINT8 enable)
{
unsigned int reg;
reg = readl(PWM_CAP_REG(id) + PWM_CAP_SETTING);
if(enable)
reg |= (1UL<<31);
else
reg &= ~(1UL<<31);
writel(reg, PWM_CAP_REG(id) + PWM_CAP_SETTING);
}
static void pwm_cap_int_method(UINT8 id,UINT8 int_method)
{
unsigned int reg;
reg = readl(PWM_CAP_REG(id) + PWM_CAP_SETTING);
reg &= ~(0x3<<28);
reg |= (int_method<<28);
writel(reg,PWM_CAP_REG(id) + PWM_CAP_SETTING);
}
static void pwm_cap_set_glitch(UINT8 id,UINT8 glitch)
{
unsigned int reg;
reg = readl(PWM_CAP_REG(id) + PWM_CAP_SETTING);
reg &= ~(0xF<<24);
reg |= (glitch<<24);
writel(reg,PWM_CAP_REG(id) + PWM_CAP_SETTING);
}
static void pwm_cap_method(UINT8 id,UINT8 cap_method)
{
unsigned int reg;
reg = readl(PWM_CAP_REG(id) + PWM_CAP_SETTING);
reg &= ~(0x1<<30);
reg |= (cap_method<<30);
writel(reg,PWM_CAP_REG(id) + PWM_CAP_SETTING);
}
static void pwm_cap_times(UINT8 id,UINT8 cat_times)
{
unsigned int reg;
reg = readl(PWM_CAP_REG(id) + PWM_CAP_SETTING);
reg &= ~(0xFF<<16);
reg |= (cat_times<<16);
writel(reg,PWM_CAP_REG(id) + PWM_CAP_SETTING);
}
static void pwm_cap_based_unit(UINT8 id,UINT8 cap_based_unit)
{
unsigned int reg;
reg = readl(PWM_CAP_REG(id) + PWM_CAP_SETTING);
reg &= ~(0x7<<12);
reg |= (cap_based_unit<<12);
writel(reg,PWM_CAP_REG(id) + PWM_CAP_SETTING);
}
static void pwm_cap_interval(UINT8 id,UINT8 cap_interval)
{
unsigned int reg;
reg = readl(PWM_CAP_REG(id) + PWM_CAP_SETTING);
reg &= ~(0xFF<<0);
reg |= (cap_interval<<0);
writel(reg,PWM_CAP_REG(id) + PWM_CAP_SETTING);
}
void pwm_Initial_Cap(UINT8 id)
{
pwm_cap_clk_config(id,PWM_CAP_CLK);
pwm_cap_int_method(id,PWM_CAP_ONCE_FINISH_INT);
pwm_cap_set_glitch(id,PWM_CAP_GLITCH);
pwm_cap_method(id,PWM_CAP_NUM);
pwm_cap_times(id,PWM_CAP_TIMES);
pwm_cap_based_unit(id,PWM_CAP_UINT_100MS);
pwm_cap_interval(id,PWM_CAP_INTERVAL);
request_irq(RCRT_IRQn, 0, pwm_cap_Int_Handler, NULL);
}
void pwm_cap_Int_Handler(void *para)
{
unsigned int val;
unsigned int Regval;
val = readl(PWM_CAP_REG(0) + PWM_CAP_INT_STA);
printf( "capture interrupt is valid\r\n") ;
if(val&1)
{
Regval = readl(PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
Regval |= (1<<0);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
printf("capture 0 interrupt is valid\r\n");
pwm_getCapVal(PWM_CAP_CH0);
Regval &=~(1<<0);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
writel(readl(PWM_CAP_REG(PWM_CAP_CH0) + PWM_CAP_SETTING)|(1UL<<31),PWM_CAP_REG(PWM_CAP_CH0) +PWM_CAP_SETTING);
}
if(val&(1<<1))
{
Regval = readl(PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
Regval |= (1<<1);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
printf( " capture 1 interrupt is valid\r\n");
pwm_getCapVal(1);
Regval &= ~(1<<1);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
}
if(val&(1<<2))
{
Regval = readl(PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
Regval |= (1<<2);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
printf( " capture 2 interrupt is valid\r\n");
pwm_getCapVal(2);
Regval &= ~(1<<2);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
}
if(val&(1<<3))
{
printf( " capture 3 interrupt is valid\r\n");
Regval = readl(PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
Regval |= (1<<3);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
pwm_getCapVal(3);
Regval &=~ (1<<3);
writel(Regval,PWM_CAP_REG(0) +PWM_CAP_INT_CLEAR);
}
}
double pwm_getCapVal(UINT8 id)
{
UINT32 reg,num;
double fre;
reg=readl(PWM_CAP_REG(id)+PWM_CAP_CYCLE_CAP);
writel(readl(PWM_CAP_REG(id)+PWM_CAP_SETTING)|(1UL<<31),PWM_CAP_REG(id)+PWM_CAP_SETTING);
num = reg>>8;
fre = ((reg&0xf0)>>4)/16.0+(reg&0xf)/256.0;
fre += num;
reg = readl(PWM_CAP_REG(id)+PWM_CAP_SETTING);
if(((reg >>12)&0x7)==4)
fre*=1;
else if(((reg >>12)&0x7)==2)
fre*=10;
else if(((reg >>12)&0x7)==1)
fre*=100;
else
fre*=1000;
printf("pwm cap value %lf\n",(fre+0.9));
return (fre + 0.9);
}
void pwm_enableCapIRQ(UINT8 id,unsigned char en)
{
unsigned int reg = 0;
reg = readl(PWM_CAP_REG(0)+ PWM_CAP_INT_EN);
reg &=~(1<<id);
if(en)
{
reg |=(1<<id);
writel(reg,PWM_CAP_REG(0)+ PWM_CAP_INT_EN);
}
else
writel(reg,PWM_CAP_REG(0)+ PWM_CAP_INT_EN);
}
void pwm_cap_init(UINT8 id)
{
// unsigned int irq_enable = 1;
pwm_Initial_Cap(id);
pwm_enableCapIRQ(id,1);
pwm_cap_en(id,PWM_CAP_ENABLE);
}
#endif