蓝牙开发杰理开发AC7006定时器的使用
MTAC7006定时器的使用
1.TWS对耳没有配对一段时间后(一分钟)关机
1 2 3 4 5 6 7 8
|
#define TCFG_PAIR_AUTO_SHUT_DOWN_TIME 60
void sys_pair_auto_shut_down_enable(void) void sys_pair_auto_shut_down_disable(void)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| static u16 pair_timer = 0; static void sys_pair_auto_shut_down_deal(void *priv) { printf("%s\n", __func__); #if TCFG_USER_TWS_ENABLE if (get_bt_tws_connect_status() == 0) { if(get_bt_connect_status() == BT_STATUS_WAITINT_CONN) { printf("----------not pair and not connect ---------- enter power off !!! "); extern void sys_enter_soft_poweroff(void *priv); sys_enter_soft_poweroff(0); } } #endif }
|
1 2 3 4 5 6 7 8 9
| void sys_pair_auto_shut_down_enable(void) { #if TCFG_PAIR_AUTO_SHUT_DOWN_TIME printf("%s\n", __func__); if (pair_timer == 0) { pair_timer = sys_timeout_add(NULL, sys_pair_auto_shut_down_deal, (TCFG_PAIR_AUTO_SHUT_DOWN_TIME* 1000)); } #endif }
|
1 2 3 4 5 6 7 8 9 10
| void sys_pair_auto_shut_down_disable(void) { #if TCFG_PAIR_AUTO_SHUT_DOWN_TIME printf("%s\n", __func__); if (pair_timer) { sys_timeout_del(pair_timer); pair_timer = 0; } #endif }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #if TCFG_PAIR_AUTO_SHUT_DOWN_TIME sys_pair_auto_shut_down_disable(); #endif
#if TCFG_PAIR_AUTO_SHUT_DOWN_TIME sys_pair_auto_shut_down_enable(); #endif
|
2.定时器相关(AC69NX )
功能说明
每个芯片系列的硬件定时器timer个数,是不一样的。
- AC695X => timer0-3 总共4个(timer1用作系统定时器,禁止修改使用),16位定时器
- AC696X => timer0-5 总共6个(timer1用作系统定时器,禁止修改使用),16位定时器
- AC632X => timer0-3 总共4个(timer1用作系统定时器,禁止修改使用),32位定时器
所有蓝牙芯片的SDK,都默认使用了timer1,初始化成1ms的定时中断功能,作为整个系统的滴答时钟。所以timer1是禁用的。
部分代码驱动需要us级的精度延时需求时,可能会有 偶尔使用timer0做延时功能 。详见函数: static void udelay(u32 usec)
硬件定时器有3种使用模式,对应不同的功能,互斥使用:
- 定时中断/延时 => 一般可实现100us以上的定时中断频率(小于100us会有动态误差出现),或者4us以上的延时需求。
- PWM输出 => 可输出1MHz到几Hz,也能输出高于1MHz,甚至几十MHz,但需要修改其他功能来辅助。
- 边沿捕获 => 上升沿或下降沿捕获,无法同时,但可在中断函数里做动态切换,一般能捕获到10kHz以下的方波或过零点判断。
时钟选择(虽然有4种时钟源,但一般只使用2种):
- LSB时钟:低速总线时钟,用于MCU方案,板子不带晶振的情况。 切记不可修改系统时钟。 需要从开机开始全程跑固定系统频率。
- 24M晶振时钟:带晶振的板子,建议选此晶振,系统可以动态修改系统频率,而不会影响到外设。
接口说明
SDK没有现成的固定接口,只有一些demo参考,需要视需求,二次修改寄存器。
定时中断可参考 app_timer.c
PWM可参考 timer_pwm_init()
边沿捕获可参考红外功能 irflt.c
寄存器说明
1 2 3 4 5 6 7
| typedef struct { __RW __u32 CON; __RW __u32 CNT; __RW __u32 PRD; __RW __u32 PWM; } JL_TIMER_TypeDef;
|
timer设置范例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| JL_TIMER_TypeDef *TIMER = JL_TIMER0; if(TIMER->CON != 0){ printf("TIMER:0x%x already used", TIMER); return -1; } TIMER->CON = 0; TIMER->CON |= BIT(14);
TIMER->CON |= (0b10 << 2); TIMER->CON |= (0b0001 << 10);
TIMER->CON |= (0b0001 << 4);
TIMER->PRD = OSC_Hz / 4 / fre; TIMER->PRD = clk_get("timer") / 4 * usec / 1000000L;
TIMER->CNT = 0; TIMER->CNT = TIMER->PRD;
TIMER->PWM = (TIMER->PRD * duty) / 100;
TIMER->CON |= BIT(8);
TIMER->CON |= (0b01 << 0);
|
监控timer使用状态
1 2 3
| JL_TIMER_TypeDef *TIMER = JL_TIMER0; printf("timer:CON-0x%08x,PRD-0x%08x,PWM-0x%08x\n", TIMER->CON, TIMER->PRD, TIMER->PWM);
|
定时中断范例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
|
___interrupt AT_VOLATILE_RAM_CODE static void timer3_isr() { JL_TIMER3->CON |= BIT(14); static u8 flag = 0; if(flag){ flag = 0; JL_PORTA->OUT &= ~BIT(8); }else{ flag = 1; JL_PORTA->OUT |= BIT(8); } cnt_100us++; } void timer3_100us(void) { log_info("%s[%d]", __func__, clk_get("lsb")); u32 prd_cnt; prd_cnt = clk_get("lsb") / 1000 / 4 / 10 * 1; log_info("%s[0x%08x]", __func__, prd_cnt);
request_irq(IRQ_TIME3_IDX, 3, timer3_isr, 0); JL_TIMER3->CNT = 0; JL_TIMER3->PRD = prd_cnt; JL_TIMER3->CON = (1 << 4) | (1 << 0);
gpio_set_pull_up(IO_PORTA_08, 0); gpio_set_pull_down(IO_PORTA_08, 0); gpio_set_die(IO_PORTA_08, 1); gpio_set_direction(IO_PORTA_08, 0); }
|