mcu_ab568x/userboot240328/app/platform/bsp/bsp_qdec.c
2025-05-30 18:03:10 +08:00

157 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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.1KQEC_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