2025-02-18 15:40:42 +08:00

215 lines
5.0 KiB
C
Raw Permalink 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 "asm/includes.h"
#include "asm/irflt.h"
#include "timer.h"
#include "generic/gpio.h"
#define ir_log log_d
//红外定时器定义
#define IR_TIMER TIMER0
#define IR_IRQ_TIME_IDX IRQ_TIME0_IDX
#define IR_TIME_REG JL_TIMER0
IR_CODE ir_code; ///<红外遥控信息
u16 timer1_pad;
static const u16 timer_div[] = {
/*0000*/ 1,
/*0001*/ 4,
/*0010*/ 16,
/*0011*/ 64,
/*0100*/ 2,
/*0101*/ 8,
/*0110*/ 32,
/*0111*/ 128,
/*1000*/ 256,
/*1001*/ 4 * 256,
/*1010*/ 16 * 256,
/*1011*/ 64 * 256,
/*1100*/ 2 * 256,
/*1101*/ 8 * 256,
/*1110*/ 32 * 256,
/*1111*/ 128 * 256,
};
#define IRFLT_OUTPUT_TIMER_SEL(x) SFR(JL_IOMAP->CON0, 8, 3, x)
/*----------------------------------------------------------------------------*/
/**@brief time1红外中断服务函数
@param void
@param void
@return void
@note void timer1_ir_isr(void)
*/
/*----------------------------------------------------------------------------*/
___interrupt
void timer_ir_isr(void)
{
u16 bCap1;
u8 cap = 0;
static u8 cnt = 0;
IR_TIME_REG->CON |= BIT(14);
bCap1 = IR_TIME_REG->PRD;
IR_TIME_REG->CNT = 0;
cap = bCap1 / ir_code.timer_pad;
/* ir_log("cnt = %d, cap = 0x%x", cnt++, cap); */
if (cap <= 1) {
ir_code.wData >>= 1;
ir_code.bState++;
ir_code.boverflow = 0;
} else if (cap == 2) {
ir_code.wData >>= 1;
ir_code.bState++;
ir_code.wData |= 0x8000;
ir_code.boverflow = 0;
}
/*13ms-Sync*/
/*
else if ((cap == 13) || (cap < 8) || (cap > 110))
{
ir_code.bState = 0;
}
else
{
ir_code.boverflow = 0;
}
*/
else if ((cap == 13) && (ir_code.boverflow < 8)) {
ir_code.bState = 0;
} else if ((cap < 8) && (ir_code.boverflow < 5)) {
ir_code.bState = 0;
} else if ((cap > 110) && (ir_code.boverflow > 53)) {
ir_code.bState = 0;
} else if ((cap > 20) && (ir_code.boverflow > 53)) { //溢出情况下 12M 48M
ir_code.bState = 0;
} else {
ir_code.boverflow = 0;
}
if (ir_code.bState == 16) {
ir_code.wUserCode = ir_code.wData;
}
if (ir_code.bState == 32) {
/* printf("[0x%X]",ir_code.wData); */
}
}
/*----------------------------------------------------------------------------*/
/**@brief ir按键初始化
@param void
@param void
@return void
@note void set_ir_clk(void)
((cnt - 1)* 分频数)/lsb_clk = 1ms
*/
/*----------------------------------------------------------------------------*/
#define APP_TIMER_CLK clk_get("timer")
#define TIMER_UNIT_MS 1
#define MAX_TIME_CNT 0x07ff //分频准确范围,更具实际情况调整
#define MIN_TIME_CNT 0x0030
void set_ir_clk(void)
{
u32 clk;
u32 prd_cnt;
u8 index;
for (index = 0; index < (sizeof(timer_div) / sizeof(timer_div[0])); index++) {
prd_cnt = TIMER_UNIT_MS * (APP_TIMER_CLK / 1000) / timer_div[index];
if (prd_cnt > MIN_TIME_CNT && prd_cnt < MAX_TIME_CNT) {
break;
}
}
ir_code.timer_pad = prd_cnt;
IR_TIME_REG->CON = ((index << 4) | BIT(3) | BIT(1) | BIT(0));
}
/*----------------------------------------------------------------------------*/
/**@brief 获取ir按键值
@param void
@param void
@return void
@note void get_irkey_value(void)
*/
/*----------------------------------------------------------------------------*/
u8 get_irflt_value(void)
{
u8 tkey = 0xff;
if (ir_code.bState != 32) {
return tkey;
}
/* printf("(0x%X_%x)",ir_code.wUserCode,ir_code.wData); */
if ((((u8 *)&ir_code.wData)[0] ^ ((u8 *)&ir_code.wData)[1]) == 0xff) {
/* if (ir_code.wUserCode == 0xFF00) */
{
/* printf("<%d>",(u8)ir_code.wData); */
tkey = (u8)ir_code.wData;
}
} else {
ir_code.bState = 0;
}
return tkey;
}
void ir_input_io_sel(u8 port)
{
//选择input channel1输入
// IOMC2[13 : 8]
// 0 ~ 15: PA0 ~ PA15
//16 ~ 31: PB0 ~ PB15
//32 ~ 47: PC0 ~ PC15
//48 ~ 55: PD0 ~ PD7
gpio_irflt_in(port);
gpio_set_direction(port, 1);
gpio_set_die(port, 1);
}
void ir_output_timer_sel()
{
IRFLT_OUTPUT_TIMER_SEL(IR_TIMER);
request_irq(IR_IRQ_TIME_IDX, 0, timer_ir_isr, 0);
}
static void ir_timeout(void *priv)
{
ir_code.boverflow++;
if (ir_code.boverflow > 56) { //56*2ms ~= 112ms
ir_code.bState = 0;
}
}
void ir_timeout_set(void)
{
sys_s_hi_timer_add(NULL, ir_timeout, 2); //2ms
}
void irflt_config()
{
JL_IR->RFLT_CON = 0;
JL_IR->RFLT_CON |= BIT(7); //256 div
JL_IR->RFLT_CON |= BIT(3); //osc
JL_IR->RFLT_CON |= BIT(0); //irflt enable
set_ir_clk();
}
void log_irflt_info()
{
ir_log("IOMC0 = 0x%x", JL_IOMAP->CON0);
ir_log("IOMC2 = 0x%x", JL_IOMAP->CON2);
ir_log("RFLT_CON = 0x%x", JL_IR->RFLT_CON);
ir_log("IR_TIME_REG = 0x%x", IR_TIME_REG->CON);
}