更新时间:2022-11-24 09:20:27下载pdf
由于涂鸦模组 SDK 只提供红外相关系统 DP 回调的数据接口,如果您想要实现红外功能,必须重新从驱动层开始实现红外发送与红外学习功能,大大增加了开发难度与开发周期。
红外应用组件的出现大大改变了现状,您无需关心红外相关数据链路的实现,只需要注册符合硬件的红外发送、接收引脚与红外发送接收状态回调即可完成红外相关功能开发。SDK 的整体结构如下所示:
.
├── Doc
│ ├── Readme.md
│ ├── tuya_ir_drv_bk7231n.c
│ ├── tuya_ir_drv_bk7231n.h
│ ├── tuya_ir_drv_rtl8710bn.c
│ ├── tuya_ir_drv_rtl8710bn.h
│ ├── tuya_ir_drv_rtl8720cf.c
│ ├── tuya_ir_drv_rtl8720cf.h
│ ├── tuya_ir_drv_rtl8720cs.c
│ ├── tuya_ir_drv_rtl8720cs.h
│ ├── tuya_ir_proc.c
│ └── tuya_ir_proc.h
├── include
│ ├── tuya_ir_app.h
│ ├── tuya_ir_ctrl.h
│ ├── tuya_ir_data_handle.h
│ ├── tuya_ir_drv_struct.h
│ └── tuya_ir_user_api.h
├── local.mk
├── README.md
├── src
│ ├── tuya_ir_app.c
│ ├── tuya_ir_app.o
│ ├── tuya_ir_ctrl.c
│ ├── tuya_ir_ctrl.o
│ ├── tuya_ir_data_handle.c
│ └── tuya_ir_data_handle.o
└── svc_ir_module.yaml
文件 | 说明 | 您是否需要关注 |
---|---|---|
tuya_ir_app.c |
红外应用组件应用逻辑处理 | 否 |
tuya_ir_ctrl.c |
红外应用组件应用具体逻辑实现 | 否 |
tuya_ir_data_handle.c |
红外学习码滤波处理函数 | 否 |
tuya_ir_user_api.h |
API 声明 | 是 |
tuya_ir_drv_struct.h |
红外驱动结构体声明 | 是 |
Doc |
已适配的平台驱动及红外应用组件 SDK 介绍 | 是 |
您需要用到的驱动数据结构在tuya_ir_drv_struct.h
头文件中已声明,其中驱动接口说明如下:
typedef enum
{
TIM_COUNT_UP_MODE = 0,
TIM_COUNT_DOWN_MODE = 1,
TIM_INVALID_MODE = 2,
}TIM_COUNT_MODE_E;
typedef struct
{
FLOAT_T timer_mhz;
TIM_COUNT_MODE_E count_mode; //0:Counting-up 1:Counting-down
}TUYA_IR_TIM_INFO,*P_TUYA_IR_TIM_INFO;
//ir_ops
typedef struct
{
VOID_T (*tuya_ir_drv_timer_init)(VOID_T);
VOID_T (*tuya_ir_drv_timer_start)(IN UINT_T tim_us);
VOID_T (*tuya_ir_drv_timer_stop)(VOID_T);
UINT_T (*tuya_ir_drv_timer_getcount)(VOID_T);
VOID_T (*tuya_ir_drv_timer_getinfo)(INOUT TUYA_IR_TIM_INFO *tim_info);
VOID_T (*tuya_ir_drv_pwm_init)(IN UCHAR_T ir_txpin,IN UINT_T freq);
VOID_T (*tuya_ir_drv_pwm_setfreq)(IN UINT_T freq);
VOID_T (*tuya_ir_drv_pwm_send)(VOID_T);
VOID_T (*tuya_ir_drv_pwm_stop)(VOID_T);
VOID_T (*tuya_ir_drv_gpioirq_init)(IN UCHAR_T ir_rxpin);
VOID_T (*tuya_ir_drv_gpioirq_en)(IN UCHAR_T is_enable);
VOID_T (*tuya_ir_drv_plat_related_init)(VOID_T);
VOID_T (*tuya_ir_drv_irtx_start_cb)(VOID_T);
VOID_T (*tuya_ir_drv_irtx_finish_cb)(VOID_T);
VOID_T (*tuya_ir_drv_irrx_start_cb)(VOID_T);
VOID_T (*tuya_ir_drv_irrx_finish_cb)(VOID_T);
}TUYA_IR_DRV_OPTS,*P_TUYA_IR_DRV_OPTS;
typedef struct { FLOAT_T timer_mhz; TIM_COUNT_MODE_E count_mode; //0:Counting-up 1:Counting-down }TUYA_IR_TIM_INFO,*P_TUYA_IR_TIM_INFO; |
timer_mhz:硬件定数器频率 count_mode:硬件定时器计数模式 |
---|---|
VOID_T (*tuya_ir_drv_timer_init)(VOID_T); | 硬件定时器初始化 |
VOID_T (*tuya_ir_drv_timer_start)(IN UINT_T tim_us); | 硬件定时器定时开启 |
VOID_T (*tuya_ir_drv_timer_stop)(VOID_T); | 硬件定时器定时关闭 |
UINT_T (*tuya_ir_drv_timer_getcount)(VOID_T); | 获取硬件定时器计数值 |
VOID_T (*tuya_ir_drv_timer_getinfo)(INOUT TUYA_IR_TIM_INFO *tim_info); | 获取硬件定时器相关属性 |
VOID_T (*tuya_ir_drv_pwm_init)(IN UCHAR_T ir_txpin,IN UINT_T freq); | pwm初始化 |
VOID_T (*tuya_ir_drv_pwm_setfreq)(IN UINT_T freq); | pwm设置频率 |
VOID_T (*tuya_ir_drv_pwm_send)(VOID_T); | pwm开启 |
VOID_T (*tuya_ir_drv_pwm_stop)(VOID_T); | pwm关闭 |
VOID_T (*tuya_ir_drv_gpioirq_init)(IN UCHAR_T ir_rxpin); | 外部中断初始化 |
VOID_T (*tuya_ir_drv_gpioirq_en)(IN UCHAR_T is_enable); | 外部中断使能/失能 |
VOID_T (*tuya_ir_drv_plat_related_init)(VOID_T); | 模组平台初始化(不同模组有所差异、不用则赋NULL) |
VOID_T (*tuya_ir_drv_irtx_start_cb)(VOID_T); | 红外发送开始驱动回调(不同模组有所差异,需要再发送设置某些参数,不用则赋NULL) |
VOID_T (*tuya_ir_drv_irtx_finish_cb)(VOID_T); | 红外发送结束驱动回调(不同模组有所差异,需要再发送设置某些参数,不用则赋NULL) |
VOID_T (*tuya_ir_drv_irrx_start_cb)(VOID_T); | 红外学习开始驱动回调(不同模组有所差异,需要再发送设置某些参数,不用则赋NULL) |
VOID_T (*tuya_ir_drv_irrx_finish_cb)(VOID_T); | 红外学习结束驱动回调(不同模组有所差异,需要再发送设置某些参数,不用则赋NULL) |
您红外初始化需要了解的数据结构说明如下:
typedef struct
{
SHORT_T carr_compensation_val;
SHORT_T lowlevel_compensation_val;
}TUYA_IRAPP_TX_CFG_S;
typedef struct
{
UCHAR_T txpin;
UCHAR_T rxpin;
TUYA_IR_STAT_CB ir_stat_cb;
TUYA_IRAPP_TX_CFG_S ir_tx_cfg;
} TUYA_IRAPP_CFG_S,*P_TUYA_IRAPP_CFG_S;
参数 | 说明 |
---|---|
txpin | 红外发送引脚 |
rxpin | 红外接收引脚 |
TUYA_IR_STAT_CB | 红外发送接收状态回调 |
TUYA_IRAPP_TX_CFG_S | 红外发送补偿值设置(不同平台硬件定时器定时误差有大有小,通过此变量设置) |
OPERATE_RET tuya_irapp_module_init(IN TUYA_IRAPP_CFG_S *p_ir_cfg,IN TUYA_IR_DRV_OPTS* p_ir_opts);
VOID_T tuya_irapp_irdata_send(IN TY_IR_CODE_S *ir_code, IN UCHAR_T code_num);
VOID_T tuya_irapp_irstudy_ctrl(IN TY_IR_STUDY_CTL_E irstudy_mode);
VOID_T tuya_irapp_set_irdata_recv_cb(IN TUYA_IR_DATARECV_CB cb);
CHAR_T tuya_irapp_is_irsend_stat(VOID_T);
VOID_T tuya_irctrl_set_carrorlow(CHAR_T enable);
VOID_T tuya_irctrl_timeout_irq(VOID_T);
VOID_T tuya_irctrl_recv_irq(VOID_T);
OPERATE_RET tuya_irapp_module_init(IN TUYA_IRAPP_CFG_S p_ir_cfg,IN TUYA_IR_DRV_OPTS p_ir_opts); | /** * @brief: tuya_irapp_module_init * @desc: tuya Infrared function initialization * * @param[in] TUYA_IRAPP_CFG_S: p_ir_cfg * @param[in] TUYA_IR_DRV_OPTS: p_ir_opts * * @return OPERATE_RET * * @note none */ |
---|---|
VOID_T tuya_irapp_irdata_send(IN TY_IR_CODE_S *ir_code, IN UCHAR_T code_num); | /** * @brief: tuya_irapp_irdata_send * @desc: tuya Infrared data transmission * * @param[in] ir_code: infrared data * @param[in] code_num: num of ir_code * * @return VOID_T * * @note none */ |
VOID_T tuya_irapp_irstudy_ctrl(IN TY_IR_STUDY_CTL_E irstudy_mode); | /** * @brief: tuya_irapp_irstudy_ctrl * @desc: tuya Infrared learning state control * * @param[in] irstudy_mode: Infrared learning state * * @return VOID_T * * @note none */ |
VOID_T tuya_irapp_set_irdata_recv_cb(IN TUYA_IR_DATARECV_CB cb); | /** * @brief: tuya_irapp_set_irdata_recv_cb * @desc: tuya Infrared learning data callback * * @param[in] TUYA_IR_DATARECV_CB: Infrared learning data callback function pointer * * @return VOID_T * * @note none */ |
CHAR_T tuya_irapp_is_irsend_stat(VOID_T); | /** * @brief: tuya_irapp_is_irsend_stat * @desc: Gets the infrared transmission status * * @return True OR False * * @note none */ |
VOID_T tuya_irctrl_set_carrorlow(CHAR_T enable); | /** * @brief: tuya_irctrl_set_carrorlow * @desc: Set the infrared transmitting carrier or low level * * @return True OR False * * @note none */ |
VOID_T tuya_irctrl_timeout_irq(VOID_T); | /** * @brief: tuya_irctrl_timeout_irq * @desc: Infrared timer interrupt handler function * * @return none * * @note Called by the developer in the timer interrupt callback function */ |
VOID_T tuya_irctrl_recv_irq(VOID_T); | /** * @brief: tuya_irctrl_recv_irq * @desc: Infrared external interrupt handler function * * @return none * * @note Called by developer in external interrupt function callback */ |
驱动接口实现Demo:
#include"tuya_ir_drv_rtl8710bn.h"
STATIC TY_IR_DRV_S ty_irhw ={0};
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_irq_handle(VOID_T *param);
STATIC VOID_T tuya_rtl8710bn_ir_drv_gpioirq_handle(UINT_T param, gpio_irq_event event);
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_init(VOID_T);
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_start(IN UINT_T tim_us);
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_stop(VOID_T);
STATIC UINT_T tuya_rtl8710bn_ir_drv_timer_getcount(VOID_T);
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_getinfo(INOUT TUYA_IR_TIM_INFO *tim_info);
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_init(IN CHAR_T ir_txpin,IN UINT_T freq);
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_setfreq(IN UINT_T freq);
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_send(VOID_T);
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_stop(VOID_T);
STATIC VOID_T tuya_rtl8710bn_ir_drv_gpioirq_init(IN UCHAR_T ir_rxpin);
STATIC VOID_T tuya_rtl8710bn_ir_drv_gpioirq_en(IN UCHAR_T is_enable);
OPERATE_RET tuya_rtl8710bn_get_ir_drv_ops(INOUT TUYA_IR_DRV_OPTS *p_irops)
{
if (NULL == p_irops)
{
return OPRT_INVALID_PARM;
}
p_irops->tuya_ir_drv_timer_init = tuya_rtl8710bn_ir_drv_timer_init;
p_irops->tuya_ir_drv_timer_start = tuya_rtl8710bn_ir_drv_timer_start;
p_irops->tuya_ir_drv_timer_stop = tuya_rtl8710bn_ir_drv_timer_stop;
p_irops->tuya_ir_drv_timer_getcount = tuya_rtl8710bn_ir_drv_timer_getcount;
p_irops->tuya_ir_drv_timer_getinfo = tuya_rtl8710bn_ir_drv_timer_getinfo;
p_irops->tuya_ir_drv_pwm_init = tuya_rtl8710bn_ir_drv_pwm_init;
p_irops->tuya_ir_drv_pwm_setfreq = tuya_rtl8710bn_ir_drv_pwm_setfreq;
p_irops->tuya_ir_drv_pwm_send = tuya_rtl8710bn_ir_drv_pwm_send;
p_irops->tuya_ir_drv_pwm_stop = tuya_rtl8710bn_ir_drv_pwm_stop;
p_irops->tuya_ir_drv_gpioirq_init = tuya_rtl8710bn_ir_drv_gpioirq_init;
p_irops->tuya_ir_drv_gpioirq_en = tuya_rtl8710bn_ir_drv_gpioirq_en;
p_irops->tuya_ir_drv_plat_related_init = NULL;
p_irops->tuya_ir_drv_irtx_start_cb = NULL;
p_irops->tuya_ir_drv_irtx_finish_cb = NULL;
p_irops->tuya_ir_drv_irrx_start_cb = NULL;
p_irops->tuya_ir_drv_irrx_finish_cb = NULL;
return OPRT_OK;
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_irq_handle(VOID_T *param)
{
TY_IR_DRV_S *p_ty_irhw = (TY_IR_DRV_S*)param;
RTIM_INTClear(TIMx[p_ty_irhw->timerid]);
//call tuya ir send irq function
tuya_irctrl_timeout_irq();
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_gpioirq_handle(UINT_T param, gpio_irq_event event)
{
TY_IR_DRV_S *p_ty_irhw = (TY_IR_DRV_S *)param;
if (IRQ_RISE == event)
{
gpio_irq_set_event(&(p_ty_irhw->irq), IRQ_FALL);
}
else if (IRQ_FALL == event)
{
gpio_irq_set_event(&(p_ty_irhw->irq), IRQ_RISE);
}
tuya_irctrl_recv_irq();
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_init(VOID_T)
{
RTIM_TimeBaseInitTypeDef TIM_InitStruct;
ty_irhw.timerid = TY_IR_TIMER_ID;
RTIM_TimeBaseStructInit(&TIM_InitStruct);
TIM_InitStruct.TIM_Idx = ty_irhw.timerid;
TIM_InitStruct.TIM_Prescaler = 39; // prescaler = (TIM_Prescaler+1)
TIM_InitStruct.TIM_UpdateEvent = TRUE; // UEV enable
TIM_InitStruct.TIM_UpdateSource = TIM_UpdateSource_Overflow;
TIM_InitStruct.TIM_ARRProtection = TRUE;
RTIM_TimeBaseInit(TIMx[ty_irhw.timerid], &TIM_InitStruct, TIMx_irq[ty_irhw.timerid], (IRQ_FUN)tuya_rtl8710bn_ir_drv_timer_irq_handle, (UINT_T)&ty_irhw);
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_start(IN UINT_T tim_us)
{
RTIM_TypeDef *RTIM = TIMx[ty_irhw.timerid];
UINT_T period;
RTIM->PSC = 39;
period = (UINT_T)((FLOAT_T)tim_us * 40 / ((RTIM->PSC & 0xFF) + 1));
period = (period > 0xFFFF) ? 0xFFFF : period;
RTIM_ChangePeriod(RTIM, period);
RTIM_INTConfig(RTIM, TIM_IT_Update, TRUE);
RTIM_Cmd(RTIM, TRUE);
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_stop(VOID_T)
{
RTIM_Cmd(TIMx[ty_irhw.timerid], FALSE);
}
STATIC UINT_T tuya_rtl8710bn_ir_drv_timer_getcount(VOID_T)
{
RTIM_TypeDef *RTIM = TIMx[ty_irhw.timerid];
return RTIM_GetCount(RTIM);
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_timer_getinfo(INOUT TUYA_IR_TIM_INFO *tim_info)
{
tim_info->timer_mhz = 1; //1MHZ
tim_info->count_mode = TIM_COUNT_UP_MODE;
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_init(IN CHAR_T ir_txpin,IN UINT_T freq)
{
ty_irhw.txpin = ir_txpin;
pwmout_init(&(ty_irhw.pwm), ty_irhw.txpin);
pwmout_stop(&(ty_irhw.pwm));
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_setfreq(IN UINT_T freq)
{
pwmout_period_us(&(ty_irhw.pwm), (UINT_T)(1000000 / freq));
pwmout_pulsewidth_us(&(ty_irhw.pwm), (UINT_T)(1000000 / freq) >> 1);
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_send(VOID_T)
{
pwmout_start(&(ty_irhw.pwm));
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_pwm_stop(VOID_T)
{
pwmout_stop(&(ty_irhw.pwm));
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_gpioirq_init(IN UCHAR_T ir_rxpin)
{
ty_irhw.rxpin = ir_rxpin;
gpio_irq_init(&(ty_irhw.irq), ty_irhw.rxpin, (gpio_irq_handler)tuya_rtl8710bn_ir_drv_gpioirq_handle, (UINT_T)&ty_irhw);
gpio_irq_pull_ctrl(&(ty_irhw.irq), PullUp);
gpio_irq_set(&(ty_irhw.irq), IRQ_FALL, FALSE);
gpio_irq_disable(&(ty_irhw.irq));
}
STATIC VOID_T tuya_rtl8710bn_ir_drv_gpioirq_en(IN UCHAR_T is_enable)
{
if (is_enable)
{
gpio_irq_set(&(ty_irhw.irq), IRQ_FALL, TRUE);
gpio_irq_enable(&(ty_irhw.irq));
}
else
{
gpio_irq_set(&(ty_irhw.irq), IRQ_FALL, FALSE);
gpio_irq_disable(&(ty_irhw.irq));
}
}
#ifndef __TUYA_IR_DRV_RTL8710BN_H__
#define __TUYA_IR_DRV_RTL8710BN_H__
#include "gpio_irq_api.h"
#include "pwmout_api.h"
#include "timer_api.h"
#include "tuya_gpio.h"
#include "tuya_cloud_types.h"
#include "tuya_ir_drv_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TY_IR_TIMER_ID 4
#define TY_IR_TX_IO_ARRAY {TY_GPIOA_5,TY_GPIOA_12,TY_GPIOA_14,TY_GPIOA_15,TY_GPIOA_22}
#define TY_IR_RX_IO_ARRAY {TY_GPIOA_5,TY_GPIOA_12,TY_GPIOA_14,TY_GPIOA_15,TY_GPIOA_19,TY_GPIOA_22}
#define TY_IR_TX_CARR_COMPENSATION_VAL (0)
#define TY_IR_TX_LOWLEVEL_COMPENSATION_VAL (-10)
typedef struct
{
gpio_irq_t irq;
pwmout_t pwm;
UCHAR_T timerid;
UCHAR_T txpin;
UCHAR_T rxpin;
} TY_IR_DRV_S,*P_TY_IR_DRV_S;
OPERATE_RET tuya_rtl8710bn_get_ir_drv_ops(INOUT TUYA_IR_DRV_OPTS *p_irops);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
应用Demo:
HW_IRSET_S * ir_config = get_ir_config();
TUYA_IRAPP_CFG_S ir_cfg = {0};
ir_cfg.txpin = ir_config->ir_io_set.ir_send;
ir_cfg.rxpin = ir_config->ir_io_set.ir_recv;
ir_cfg.ir_stat_cb = irapp_stat_cb;
ir_cfg.ir_tx_cfg.carr_compensation_val = TY_IR_TX_CARR_COMPENSATION_VAL;
ir_cfg.ir_tx_cfg.lowlevel_compensation_val = TY_IR_TX_LOWLEVEL_COMPENSATION_VAL;
TUYA_IR_DRV_OPTS ir_opts = {0};
tuya_rtl8710bn_get_ir_drv_ops(&ir_opts);
op_ret = tuya_irapp_module_init(&ir_cfg,&ir_opts);
if (op_ret != OPRT_OK)
{
PR_ERR("tuya_irbox_init err:%d!",op_ret);
return op_ret;
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈