红外发送参考ir_send_soft
📎 原始文档:https://www.kdocs.cn/l/ctauENHCYCFy 红外发送参考ir_send_soft
#include "asm/includes.h"
#include "timer.h"
#include "generic/gpio.h"
#include "system/init.h"
#include "timer.h"
#include "app_config.h"
#undef _DEBUG_H_
#define LOG_TAG_CONST IR_SEND_SOFT
#define LOG_TAG "[IR_SEND_SOFT]"
#include "debug.h"
#define LOG_v(t) log_tag_const_v_ ## t
#define LOG_i(t) log_tag_const_i_ ## t
#define LOG_d(t) log_tag_const_d_ ## t
#define LOG_w(t) log_tag_const_w_ ## t
#define LOG_e(t) log_tag_const_e_ ## t
#define LOG_c(t) log_tag_const_c_ ## t
#define LOG_tag(tag, n) n(tag)
const char LOG_tag(LOG_TAG_CONST,LOG_v) AT(.LOG_TAG_CONST) = 0;
const char LOG_tag(LOG_TAG_CONST,LOG_i) AT(.LOG_TAG_CONST) = 1;
const char LOG_tag(LOG_TAG_CONST,LOG_d) AT(.LOG_TAG_CONST) = 0; //log_debug
const char LOG_tag(LOG_TAG_CONST,LOG_w) AT(.LOG_TAG_CONST) = 1;
const char LOG_tag(LOG_TAG_CONST,LOG_e) AT(.LOG_TAG_CONST) = 1;
const char LOG_tag(LOG_TAG_CONST,LOG_c) AT(.LOG_TAG_CONST) = 0; //log_char
/* 软件发送 ir 波形
****************************************************
* 通过delay的方式实现,占用系统资源
***************************************************
*/
#define SOFT_IR_IO IO_PORTA_00 //红外IO口
#define LOW_LEVEL_DURATION (889) //低电平持续时间
#define THEORY_HALF_CARRIER_PERIOD (14) //例如36K的半个载波周期为 1/36000/2 = 14
#define COMPENSATION_VALUE (2) //实际上的周期会比理论上的周期要长一点,这里要加个补偿值
#define HALF_CARRIER_PERIOD (THEORY_HALF_CARRIER_PERIOD - COMPENSATION_VALUE)
#define CARRIER_NUM (32) //一个逻辑搞电平输出载波周期的个数
#define DOUBLE_CARRIER_NUM (CARRIER_NUM * 2)
AT_VOLATILE_RAM_CODE
__attribute__((always_inline_when_const_args))
static void udelay(u32 usec)
{
JL_TIMER0->CON = BIT(14);
JL_TIMER0->CNT = 0;
JL_TIMER0->PRD = clk_get("lsb")/2/ 1000000L * usec;
JL_TIMER0->CON = BIT(6) | BIT(0); //lsb clk
while ((JL_TIMER0->CON & BIT(15)) == 0);
JL_TIMER0->CON = BIT(14);
}
#define SOFT_IR_OUT_0() {gpio_direction_output(SOFT_IR_IO, 0);}
#define SOFT_IR_OUT_1() {gpio_direction_output(SOFT_IR_IO, 1);}
#define IR_OUT_LOGICAL_HIGH() \
do { \
SOFT_IR_OUT_0(); \
udelay(LOW_LEVEL_DURATION); \
for(int i=0;i<DOUBLE_CARRIER_NUM;i++){ \
if(0==(i%2)){ \
SOFT_IR_OUT_1(); \
}else{ \
SOFT_IR_OUT_0(); \
} \
udelay(HALF_CARRIER_PERIOD); \
}\
}while(0)
#define IR_OUT_LOGICAL_LOW() \
do { \
for(int i=0;i<DOUBLE_CARRIER_NUM;i++){ \
if(0==(i%2)){ \
SOFT_IR_OUT_1(); \
}else{ \
SOFT_IR_OUT_0(); \
} \
udelay(HALF_CARRIER_PERIOD); \
} \
SOFT_IR_OUT_0(); \
udelay(LOW_LEVEL_DURATION); \
}while(0)
#define IR_OUT_LOGICAL(logic) \
do { \
if(logic){ \
IR_OUT_LOGICAL_HIGH(); \
}else{ \
IR_OUT_LOGICAL_LOW(); \
} \
}while(0)
int soft_ir_init(void)
{
log_info("%s\n",__func__);
gpio_set_pull_down(SOFT_IR_IO, 0);
gpio_set_pull_up(SOFT_IR_IO, 0);
gpio_direction_output(SOFT_IR_IO, 0);
}
//---------------------------test----------------------//
AT_VOLATILE_RAM_CODE
static void soft_ir_loop(void *priv)
{
log_info("%s\n",__func__);
OS_ENTER_CRITICAL();
IR_OUT_LOGICAL(0);
IR_OUT_LOGICAL(1);
IR_OUT_LOGICAL(0);
IR_OUT_LOGICAL(1);
IR_OUT_LOGICAL(0);
IR_OUT_LOGICAL(1);
IR_OUT_LOGICAL(0);
IR_OUT_LOGICAL(1);
IR_OUT_LOGICAL(0);
IR_OUT_LOGICAL(1);
OS_EXIT_CRITICAL();
}
int soft_ir_test(void)
{
log_info("%s", __func__);
soft_ir_init();
sys_timer_add(NULL, soft_ir_loop, 500);
}