157 lines
4.3 KiB
C
157 lines
4.3 KiB
C
#include "include.h"
|
||
|
||
#if USER_KEY_QDEC_EN
|
||
|
||
AT(.com_text.qdec)
|
||
void qdec_key_msg_enqueue(u8 msg)
|
||
{
|
||
reset_sleep_delay_all(); //复位休眠计数
|
||
msg_enqueue(msg);
|
||
}
|
||
|
||
/*
|
||
* 旋转编码器Quadrate Decode
|
||
* QDEC_MAP_G1: A -> PB0, B -> PB1
|
||
* QDEC_MAP_G2: A -> PE1, B -> PE2
|
||
* QDEC_MAP_G3: A -> PE6, B -> PE7
|
||
*/
|
||
|
||
AT(.com_text.qdec)
|
||
void qdec_isr(void)
|
||
{
|
||
u32 qdeccon = QDECCON;
|
||
if (qdeccon & BIT(1)) { //interrupt is enbale?
|
||
if (qdeccon & BIT(30)) { //forward
|
||
QDECCPND = BIT(30);
|
||
qdec_key_msg_enqueue(MSG_QDEC_FORWARD);
|
||
}
|
||
if (qdeccon & BIT(31)) { //reverse
|
||
QDECCPND = BIT(31);
|
||
qdec_key_msg_enqueue(MSG_QDEC_REVERSE);
|
||
}
|
||
}
|
||
}
|
||
|
||
void bsp_qdec_init(void)
|
||
{
|
||
CLKGAT2 |= BIT(2); //qdec clk enable
|
||
#if (USER_QDEC_MAPPING == QDEC_MAP_G1)
|
||
GPIOBDIR |= 0x03;
|
||
GPIOBDE |= 0x03;
|
||
GPIOBFEN |= 0x03;
|
||
GPIOBPU |= 0x03;
|
||
#elif (USER_QDEC_MAPPING == QDEC_MAP_G2)
|
||
GPIOEDIR |= 0x06;
|
||
GPIOEDE |= 0x06;
|
||
GPIOEFEN |= 0x06;
|
||
GPIOEPU |= 0x06;
|
||
#elif (USER_QDEC_MAPPING == QDEC_MAP_G3)
|
||
GPIOEDIR |= 0xc0;
|
||
GPIOEDE |= 0xc0;
|
||
GPIOEFEN |= 0xc0;
|
||
GPIOEPU |= 0xc0;
|
||
#endif
|
||
sys_irq_init(IRQ_QDEC_VECTOR, 0, qdec_isr);
|
||
FUNCMCON2 = USER_QDEC_MAPPING;
|
||
QDECCON = 45 << 3; //quadrate decode filter length
|
||
QDECCPND = BIT(30) | BIT(31);
|
||
QDECCON = BIT(0) | BIT(1); //qdec decode enable, interrupt enable
|
||
}
|
||
|
||
#elif USER_ADKEY_QDEC_EN
|
||
|
||
/*
|
||
* QDEC_A串接5.1K,QEC_B串接10K,接到同一IO上。IO开内部10K上拉,用ADC来采电压。
|
||
* 正旋:3.3v -- 1.113v -- 0.825v -- 1.65v -- 3.3v
|
||
* 反旋:3.3v -- 1.65v -- 0.825v -- 1.113v -- 3.3v
|
||
*/
|
||
|
||
enum {
|
||
QEC_AH_BH, //A输出高电平,B输出高电平,空闲状态
|
||
QEC_AL_BH, //A输出低电平,B输出高电平
|
||
QEC_AL_BL, //A输出低电平,B输出低电平
|
||
QEC_AH_BL, //A输出高电平,B输出低电平
|
||
};
|
||
|
||
typedef struct {
|
||
u8 status[3];
|
||
u8 cnt;
|
||
u8 pre_sta;
|
||
} qdec_cb_t;
|
||
static qdec_cb_t qdec_cb;
|
||
|
||
AT(.com_rodata.pwrkey.table)
|
||
const adkey_tbl_t qdec_adkey_table[6] = {
|
||
{0x30, QEC_AH_BH},
|
||
{0x4C, QEC_AL_BL},
|
||
{0x6A, QEC_AL_BH},
|
||
{0x8A, QEC_AH_BL},
|
||
{0xFF, QEC_AH_BH},
|
||
};
|
||
|
||
void bsp_qdec_init(void)
|
||
{
|
||
u8 io_num = get_adc_gpio_num(USER_QDEC_ADCH);
|
||
|
||
memset(&qdec_cb, 0, sizeof(qdec_cb_t));
|
||
if (io_num != IO_NONE) {
|
||
gpio_t gpio;
|
||
gpio_cfg_init(&gpio, io_num);
|
||
gpio.sfr[GPIOxDE] |= gpio.pin;
|
||
gpio.sfr[GPIOxDIR] |= gpio.pin;
|
||
gpio.sfr[GPIOxPU] |= gpio.pin;
|
||
saradc_set_channel(BIT(USER_QDEC_ADCH));
|
||
}
|
||
}
|
||
|
||
AT(.com_text.qdec)
|
||
void qdec_key_msg_enqueue(u8 msg)
|
||
{
|
||
reset_sleep_delay_all(); //复位休眠计数
|
||
msg_enqueue(msg);
|
||
}
|
||
|
||
//每毫秒ADC采样值进行处理
|
||
AT(.com_text.qdec)
|
||
void bsp_qdec_adc_process(u8 adc_val)
|
||
{
|
||
u8 num = 0;
|
||
u8 qdec_cur_sta;
|
||
|
||
while ((u8)adc_val > qdec_adkey_table[num].adc_val) {
|
||
num++;
|
||
}
|
||
qdec_cur_sta = qdec_adkey_table[num].usage_id;
|
||
if (qdec_cur_sta != qdec_cb.pre_sta) {
|
||
if (qdec_cur_sta != QEC_AH_BH) {
|
||
if (qdec_cb.pre_sta == QEC_AH_BH) {
|
||
qdec_cb.cnt = 0;
|
||
}
|
||
if (qdec_cb.cnt < 3) {
|
||
qdec_cb.status[qdec_cb.cnt++] = qdec_cur_sta;
|
||
}
|
||
}
|
||
qdec_cb.pre_sta = qdec_cur_sta;
|
||
} else {
|
||
if (qdec_cur_sta == QEC_AH_BH) { //结束
|
||
if (qdec_cb.cnt == 3 && qdec_cb.status[1] == QEC_AL_BL) {
|
||
if (qdec_cb.status[0] == QEC_AL_BH && qdec_cb.status[2] == QEC_AH_BL) {
|
||
qdec_key_msg_enqueue(MSG_QDEC_FORWARD);
|
||
//uart_putchar('F');
|
||
} else if (qdec_cb.status[2] == QEC_AL_BH && qdec_cb.status[0] == QEC_AH_BL) {
|
||
qdec_key_msg_enqueue(MSG_QDEC_REVERSE);
|
||
//uart_putchar('R');
|
||
}
|
||
}
|
||
memset(&qdec_cb, 0, sizeof(qdec_cb_t));
|
||
}
|
||
}
|
||
}
|
||
|
||
#else
|
||
void bsp_qdec_init(void)
|
||
{
|
||
|
||
}
|
||
#endif // USER_ADKEY_QDEC_EN
|