杰理AC695创建GPIO中断的方法
官方SDK里没有单独GPIO中断的demo,需要自己写一个,此例程支持上升沿、下降沿或者双边缘触发
int iocap_init(u32 port)
{
log_info("%s[port:0x%x]", __func__, port);
iocap_input_io_sel(port);
iocap_config();
iocap_timeout_set();
return 0;
}
初始化GPIO
static void iocap_input_io_sel(u8 port)
{
log_info("%s[port:0x%x]", __func__, port);
INPUT_CHANNEL1_SRC_SEL(port);
/* INPUT_CHANNEL2_SRC_SEL(port); */
/* gpio_irflt_in(port); */
gpio_set_direction(port, 1);
gpio_set_die(port, 1);
#if IO_CAP_DEFAULT_LEVEL
gpio_set_pull_up(port, 1);
gpio_set_pull_down(port, 0);
#else
gpio_set_pull_up(port, 0);
gpio_set_pull_down(port, 1);
#endif
}
创建中断
static void iocap_config()
{
JL_IR->RFLT_CON = 0;
JL_IR->RFLT_CON |= BIT(6) | BIT(5); //64 div
/* JL_IR->RFLT_CON |= BIT(7); //256 div */
/* JL_IR->RFLT_CON |= BIT(7) | BIT(4); //512 div */
/* JL_IR->RFLT_CON |= BIT(3); //osc 24m */
JL_IR->RFLT_CON |= BIT(3) | BIT(2); //PLL_48m(兼容省晶振)
// 1/(48M / 64 ) * 3 = 4us , 小于4us的抖动都会过滤掉
// 1/(48M / 256) * 3 = 16us , 小于16us的抖动都会过滤掉
// 1/(48M / 512) * 3 = 32us , 小于32us的抖动都会过滤掉
JL_IR->RFLT_CON |= BIT(0); //irflt enable
IRFLT_OUTPUT_TIMER_SEL(IO_CAP_IRFLT);
set_timer_clk();
}
//需要按照协议一个bit的周期来调整,最好是一个bit频率的100倍
static void set_timer_clk(void)
{
u32 clk = 24 * 1000000L; //clk_get("lsb")
log_info("%s[CLK:%d]", __func__, clk);
memset(IO_CAP_TIMER, 0x00, sizeof(JL_TIMER_TypeDef));
IO_CAP_TIMER->CON = BIT(14);
request_irq(IO_CAP_IRQ_TIMER_IDX, IO_CAP_IRQ_TIMER_PRIO, timer_iocap_isr, 0);
IO_CAP_TIMER->CON |= (2 << 2);//OSC_24M
IO_CAP_TIMER->CON |= (1 << 4);// 4分频
iocap.clock_us = clk / 4 / 1000 / 1000;
log_info("%s[clock_us:%d]", __func__, iocap.clock_us);
IO_CAP_TIMER->CON &= ~(0b11);//关闭
//默认为高电平,下降沿捕获,可以自己修改
中断回调
___interrupt
AT_VOLATILE_RAM_CODE
static void timer_iocap_isr(void)
{
IO_CAP_TIMER->CON |= BIT(14);
IO_CAP_TIMER->CNT = 0;
/* putchar('/'); */
if(cap_io_level){
cap_io_level = 0;
gpio_set_pull_up(cap_io, 0);
gpio_set_pull_down(cap_io, 1);
IO_CAP_TIMER->CON &= ~(0b11);//关闭
IO_CAP_TIMER->CON |= 0b10;//上升沿捕获
}else{
cap_io_level = 1;
gpio_set_pull_up(cap_io, 1);
gpio_set_pull_down(cap_io, 0);
IO_CAP_TIMER->CON &= ~(0b11);//关闭
IO_CAP_TIMER->CON |= 0b11;//下降沿捕获
}
/* put_u32hex(cap); */
/* put_u32hex(us); */
}
要用到的宏和变量
#define IO_CAP_IRFLT TIMER2
#define IO_CAP_TIMER JL_TIMER2
#define IO_CAP_IRQ_TIMER_IDX IRQ_TIME2_IDX
#define IO_CAP_IRQ_TIMER_PRIO 6
#define IO_CAP_DEFAULT_LEVEL 1//1:默认高电平,对应下降沿捕抓开始
static u8 cap_io_level = 0;