/**
 * @file app_driver_remote.c
 * @author panda (panzd@tuya.com)
 * @brief 433遥控组件 - 驱动层（定时查询方式）
 * @version 1.0
 * @date 2022-01-14
 *
 * @copyright Copyright © HANGZHOU 2022 Tuya Inc. All rights reserved.
 *
 */
 #include "app_driver_remote.h"
 #include "tuya_cloud_types.h"
 
 #include "tal_memory.h"
 #include "tal_sw_timer.h"
 #include "tal_system.h"
 #include "tal_thread.h"
 #include "tal_semaphore.h"
 #include "tal_log.h"
 
 #include "tkl_timer.h"
 #include "tkl_gpio.h"
 
 #define QNE_LOG_TAG		"bsp_hal_rf433"
#define QNE_LOG_LEVEL	QNE_LOG_LEVEL_DBUG

#include "tuya_cloud_types.h"
#include "app_driver_remote.h"
#include "qne_log.h"
#include "bsp_driver_hal.h"

QNE_STATIC  qneU8_t  u8ReceEn = 0, u8SendEn = 0, u8RfSendPin = 0xff, u8RfRecePin = 0xff;
QNE_STATIC  qneU16_t u16Rf433Addr = 0;
QNE_STATIC  qneU8_t  u8Rf433Cmd   = 0, u8RfBuffer[20] = {0}, u8RfLenght = 0;
QNE_STATIC  qneU8_t  u8SnedSta = 0, u8SendX = 0, u8SendY = 0, u8SendBit = 0;
QNE_STATIC  qneU16_t u16SnedTick = 0;

#ifndef CFG_RF433_SEND_PREAMBLE_US           /* Rf443发送前导码时间 / us */
#define CFG_RF433_SEND_PREAMBLE_US           ( 8000 )  
#endif

#ifndef CFG_RF433_SEND_BIT_UNIT_US           /* Rf443发送一个bit 单位时间 / us */
#define CFG_RF433_SEND_BIT_UNIT_US           ( 1000 )  
#endif

 /***********************************************************
 *************************micro define***********************
 ***********************************************************/
 #define REMOTE_RECV_FLITER_TIME 300 // 遥控器接受过零时间，即在一定时间内接收到的遥控码一致需要过滤，ms
 
 #define __IS_RF_VAL_BETWEEN(time, min_time, max_time) (((time) < (max_time)) && ((time) >= (min_time)))
 
 #define RF433_MIN_PERIOD_US        200      // 433最小的时基 us
 #define HW_TIMER_FIQ_CLOSE_EXIT_US 250000UL // 退出关闭fiq的超时时间 us
 
 #define REMOTE_STAND_RECV_LEN 24 * 2 // 遥控器地址码接收标准帧长度
 
 #define HW_TIMER_PERIOD_US         50                          // 硬件定时器检测周期 us
 #define HW_TIMER_MIN_DECREASE_HEAD (1500 / HW_TIMER_PERIOD_US) // 帧头min us
 #define HW_TIMER_MAX_INCREASE_HEAD (1000 / HW_TIMER_PERIOD_US) // 帧头max us
 #define HW_TIMER_MIN_DECREASE_S    (100 / HW_TIMER_PERIOD_US)  // 短时间 min
 #define HW_TIMER_MAX_INCREASE_S    (500 / HW_TIMER_PERIOD_US)  // 短时间 maxm ， 增大遥控码兼容性
 #define HW_TIMER_MIN_DECREASE_H    (200 / HW_TIMER_PERIOD_US)  // 长时间 min
 #define HW_TIMER_MAX_INCREASE_H    (600 / HW_TIMER_PERIOD_US)  // 长时间 max
 
 STATIC THREAD_HANDLE remote_thrd_hdl = NULL;
 
 /***********************************************************
 *************************typedef define*********************
 ***********************************************************/
 // 遥控器驱动结构体
 typedef struct {
     REMOTE_DRV_S usr_cfg;  // 用户配置
     UINT_T start_time_min; // 同步帧低电平时间
     UINT_T start_time_max; // 同步帧低电平时间
     UINT_T long_time_min;  // 数据bit的多时间min值
     UINT_T long_time_max;  // 数据bit的多时间max值
     UINT_T short_time_min; // 数据bit的多时间min值
     UINT_T short_time_max; // 数据bit的多时间max值
     UCHAR_T recv_addr[3];  // 当前接收的遥控地址
 } remote_cfg_t;
 
 /***********************************************************
 *************************variable define********************
 ***********************************************************/
 // 遥控器配置结构体指针
 STATIC remote_cfg_t *p_remote_cfg = NULL;
 STATIC remote_recv_handle sg_p_recv_cb = NULL; // 接受处理回调
 
 STATIC SEM_HANDLE SemaphoreRecv; // 遥控器接受成功通知信号量
 
 // 长按过滤
 STATIC UINT_T sg_filter_time = REMOTE_RECV_FLITER_TIME; // 遥控过滤时间
 STATIC TIMER_ID sg_fliter_tm = 0;
 STATIC BOOL_T sg_is_fliter_ok = TRUE; // 长按过滤标志，默认300ms未接收到则ok
 
 /***********************************************************
 *************************function define********************
 ***********************************************************/
 
 /************************************************* 特殊处理，只针对bk平台 **********************************************************/
 //开始rf接收时调用
 VOID_T tuya_rx_rf_interrupt_preprocess(VOID_T)
 {
 
 }
 
 //退出rf接收时调用
 VOID_T tuya_rx_rf_interrupt_postprocess(VOID_T)
 {
 
 }
 
 /************************************************* 硬件处理 **********************************************************/
 
 STATIC volatile UINT_T sg_recv_idx = 0;                       // 接受字节数
 STATIC UINT_T sg_remote_arr[REMOTE_STAND_RECV_LEN + 1] = {0}; // 遥控器接收的地址码，共24字节
 
 /**
  * @brief 硬件定时器回调
  *
  * @param[in] param 硬件定时器序号
  */
 STATIC VOID_T __hw_timer_detect_cb(VOID_T *param)
 {
     STATIC BOOL_T bStatuChange = FALSE;
     STATIC BOOL_T bLastLevel = FALSE;
     STATIC UINT_T fiqCnt;       // fiq时间计数
     STATIC BOOL_T is_fiq_close; // fiq是否已关闭
 
    if ( u8SendEn ) {
        switch ( u8SnedSta ) {
            case 0:
                if ( u16SnedTick == 0 ) {
                    tkl_gpio_write(u8RfSendPin, 0);
                }
                u16SnedTick = u16SnedTick + HW_TIMER_PERIOD_US;
                if ( u16SnedTick >= CFG_RF433_SEND_PREAMBLE_US ) {
                    u8SnedSta = 1;
                    u8SendX = u8SendY = 0;
                    u16SnedTick = 0;
                }
            break;

            case 1:
                if ( ( u16SnedTick == 0 ) ) {
                    if ( u8RfBuffer[u8SendX] & ( 0X80 >> u8SendY ) ) {
                        u8SendBit = 1;
                    } else {
                        u8SendBit = 0;
                    }
                    // u8SendY = ( u8SendY + 1 ) % 8;
                    // u8SendX = ( u8SendY ) ? u8SendX : ( u8SendX + 1 );
                }
                if ( u8SendBit ) {
                    if ( u16SnedTick >= 750 ) {
                        tkl_gpio_write(u8RfSendPin, 0);
                    } else {
                        tkl_gpio_write(u8RfSendPin, 1);
                    }
                } else {
                    if ( u16SnedTick >= 250 ) {
                        tkl_gpio_write(u8RfSendPin, 0);
                    } else {
                        tkl_gpio_write(u8RfSendPin, 1);
                    }
                }
                u16SnedTick = ( u16SnedTick + HW_TIMER_PERIOD_US ) % CFG_RF433_SEND_BIT_UNIT_US;
                if ( ( u16SnedTick == 0 ) ) {
                    u8SendY = ( u8SendY + 1 ) % 8;
                    u8SendX = ( u8SendY ) ? u8SendX : ( u8SendX + 1 );
                    if ( u8SendX == u8RfLenght ) {
                        u8SnedSta = 2;
                    }
                }
            break;

            case 2:
                if ( u16SnedTick >= 250 ) {
                    tkl_gpio_write(u8RfSendPin, 0);
                } else {
                    tkl_gpio_write(u8RfSendPin, 1);
                }
                u16SnedTick = u16SnedTick + HW_TIMER_PERIOD_US ;
                if ( u16SnedTick >= 950 ) {
                    u8SendEn = 0;
                    u16SnedTick = 0;
                    tkl_gpio_write(u8RfSendPin, 1);
                }
            break;
        }
    }

    if ( u8RfRecePin != 0xff ) {
        // 如果fiq关闭后，一直没接收到有效遥控码，则等待超时后关闭
        if (is_fiq_close && ++fiqCnt > (HW_TIMER_FIQ_CLOSE_EXIT_US / HW_TIMER_PERIOD_US)) {
            is_fiq_close = FALSE;
            fiqCnt = 0;
            tuya_rx_rf_interrupt_postprocess();
        }
    
        sg_remote_arr[sg_recv_idx]++; // 计数加一
    
        UINT16_T bGpioLevel = 0;
        if ( u8RfRecePin != 0xff ) {
            tkl_gpio_read(p_remote_cfg->usr_cfg.pin, &bGpioLevel);
        }
        
        //= tuya_gpio_read(p_remote_cfg->usr_cfg.pin);
        if (bGpioLevel != bLastLevel) {
            bStatuChange = TRUE;
        }
    
        if (bStatuChange == FALSE) {
            return;
        }
        // IO发生改变
        bStatuChange = FALSE;
        bLastLevel = bGpioLevel;
    
        if (sg_recv_idx == 0) {
            // 帧头检测：需要读到高电平，且低电平时间满足需求
            if (bGpioLevel == TRUE &&
                sg_remote_arr[sg_recv_idx] > p_remote_cfg->start_time_min && sg_remote_arr[sg_recv_idx] < p_remote_cfg->start_time_max) {
                // bk_printf("s:%d\r\n", sg_remote_arr[sg_recv_idx]);
                //tkl_log_output("+");
                fiqCnt = 0;
                sg_recv_idx = 1;
                is_fiq_close = TRUE;
                tuya_rx_rf_interrupt_preprocess();
            } else {
                // bk_printf("n:%d\r\n",sg_remote_arr[sg_recv_idx]);
                //tkl_log_output("-");
                sg_remote_arr[sg_recv_idx] = 0;
            }
        } else {
            // 数据: 判断低电平时间范围，高电平时间范围
            if ((sg_remote_arr[sg_recv_idx] > p_remote_cfg->short_time_min && sg_remote_arr[sg_recv_idx] < p_remote_cfg->short_time_max) ||
                (sg_remote_arr[sg_recv_idx] > p_remote_cfg->long_time_min && sg_remote_arr[sg_recv_idx] < p_remote_cfg->long_time_max)) {
                if (++sg_recv_idx >= REMOTE_STAND_RECV_LEN + 1) {
                    // 一帧接收完成
                    fiqCnt = 0;
                    sg_recv_idx = 0;
                    is_fiq_close = FALSE;
                    tuya_rx_rf_interrupt_postprocess();
    
                    // int i;
                    // for (i = 0; i < REMOTE_STAND_RECV_LEN + 1; i++) {
                    //     bk_printf("%d ", sg_remote_arr[i]);
                    // }
                    // bk_printf("\r\nrecv OK\r\n");
    
                    // 接受成功，post 二值信号量
                    tal_semaphore_post(SemaphoreRecv);
                }
            } else {
                sg_recv_idx = 0;
                memset(sg_remote_arr, 0, sizeof(sg_remote_arr));
                // int i;
                // for (i = 0; i < REMOTE_STAND_RECV_LEN + 1; i++) {
                //     sg_remote_arr[i] = 0;
                // }
    
                // 再次帧头检测，这次不用关闭fiq
                if (bGpioLevel == TRUE &&
                    sg_remote_arr[sg_recv_idx] > p_remote_cfg->start_time_min && sg_remote_arr[sg_recv_idx] < p_remote_cfg->start_time_max) {
                    // bk_printf("s:%d\r\n", sg_remote_arr[sg_recv_idx]);
                    sg_recv_idx = 1;
                    fiqCnt = 0;
                }
            }
        }
    }
 }
 /*********************************************** basic func ************************************************************/
 
 /**
  * @brief 将8个1字节的byte[0,1]转换为一个hex字节
  *        采用小端，即首bit为最高位bit
  * @param bit_data 1字节的byte[0,1]，构成每一个地址码的bit
  * @return UCHAR_T 16进制的地址码
  */
 STATIC INLINE UCHAR_T __convert_bit_data_to_hex_data(IN UCHAR_T *bit_data)
 {
     UCHAR_T val = 0;
     UCHAR_T i;
     UCHAR_T temp;
 
     for (i = 8; i > 0; i--) {
         temp = (bit_data[8 - i] > 0) ? 1 : 0;
         val |= ((1 << (i - 1)) * temp);
     }
 
     return val;
 }
 
 /**
  * @brief 用于清空长按过滤标志位
  *
  * @param[in] timerID
  * @param[in] pTimerArg
  */
 STATIC VOID_T __recv_continue_fliter_timer_cb(TIMER_ID timerID, void *arg)
 {
     TAL_PR_NOTICE("433 continue check filter ok!");
     sg_is_fliter_ok = TRUE;
 }
 
 /**
  * @brief 更新接收到的遥控码地址
  */
 STATIC VOID_T __update_recv_remote_addr(VOID_T)
 {
     UCHAR_T arr_remote[24] = {0};
     UCHAR_T index = 0;
     int i = 1;
     for (; i < REMOTE_STAND_RECV_LEN + 1;) {
         // bk_printf("%d-%d ", sg_remote_arr[i], sg_remote_arr[i + 1]);
         if (sg_remote_arr[i] < sg_remote_arr[i + 1]) {
             arr_remote[index] = 0;
         } else {
             arr_remote[index] = 1;
         }
         i += 2;
         index++;
     }
     p_remote_cfg->recv_addr[0] = __convert_bit_data_to_hex_data(&arr_remote[0]);
     p_remote_cfg->recv_addr[1] = __convert_bit_data_to_hex_data(&arr_remote[8]);
     p_remote_cfg->recv_addr[2] = __convert_bit_data_to_hex_data(&arr_remote[16]);
     // TAL_PR_NOTICE("update recv remote [%02x %02x %02x]", p_remote_cfg->recv_addr[0], p_remote_cfg->recv_addr[1], p_remote_cfg->recv_addr[2]);
 }
 
 /**
  * @brief 判断能否被控制，遥控码需要经过时间过滤
  *        当遥控长按时，会一直接收到遥控码，如果300ms内一直接收为同一遥控码，则被过滤，返回false
  * @return false - 不能控制，被过滤； true - 能控制，说明遥控码改变或者未接收时间超过300ms
  */
 STATIC BOOL_T __is_ctrl_by_continue_recv(VOID_T)
 {
     BOOL_T is_ctrl = FALSE;
     if (TRUE == sg_is_fliter_ok) {
         sg_is_fliter_ok = FALSE;
         is_ctrl = TRUE;
     }
 
     if (sg_fliter_tm) {
         tal_sw_timer_start(sg_fliter_tm, sg_filter_time, TAL_TIMER_ONCE);
     }
     return is_ctrl;
 }
 
 /**
  * @brief 处理遥控器任务
  *
  * @param[in] pArg 此处无用
  */
 STATIC VOID_T __remote_task(PVOID_T pArg)
 {
     // 初始化默认会post一个信号量出来，需要先处理一次
     tal_semaphore_wait(SemaphoreRecv, SEM_WAIT_FOREVER);
     TAL_PR_DEBUG_RAW("remote task init success\r\n");
 
     while (1) {
         tal_semaphore_wait(SemaphoreRecv, SEM_WAIT_FOREVER);
         __update_recv_remote_addr();
 
         UINT_T remote_addr = ((UINT_T)p_remote_cfg->recv_addr[0]) | ((UINT_T)p_remote_cfg->recv_addr[1] << 8) | ((UINT_T)p_remote_cfg->recv_addr[2] << 16);
         if (remote_addr == 0xffffff) {
             continue;
         }
 
         if (__is_ctrl_by_continue_recv() && sg_p_recv_cb) {
             sg_p_recv_cb(remote_addr);
         }
     }
 }
 /********************************************** interface *************************************************************/
 
 /**
  * @brief rf433遥控器驱动初始化
  *
  * @param[in] p_remote 遥控器配置结构体指针
  * @return { OPRT_OK 代表成功。如果是其他错误码，请参考 tuya_error_code.h }
  */
 OPERATE_RET tuya_remote_driver_init(IN REMOTE_DRV_S *p_remote, IN remote_recv_handle func)
 {
     OPERATE_RET rt = OPRT_OK;
 
     TUYA_TIMER_BASE_CFG_T timer_cfg = {0};
     if (p_remote == NULL) {
         TAL_PR_ERR("rf433 not enable");
         return OPRT_INVALID_PARM;
     }
 
     STATIC BOOL_T is_433_init = FALSE;
     if (is_433_init) {
         TAL_PR_NOTICE("rf433 init already");
         return OPRT_OK;
     }
 
     // 申请内存
     remote_cfg_t *p_cfg = (remote_cfg_t *)tal_malloc(SIZEOF(remote_cfg_t));
     if (NULL == p_cfg) {
         TAL_PR_ERR("rf433 malloc fail");
         return OPRT_MALLOC_FAILED;
     }
     memset(p_cfg, 0, SIZEOF(remote_cfg_t));
     p_remote_cfg = p_cfg;
     // 拷贝应用层的配置
     memmove(&p_remote_cfg->usr_cfg, p_remote, SIZEOF(REMOTE_DRV_S));
 
     if (p_remote_cfg->usr_cfg.freq_min >= RF433_MIN_PERIOD_US) {
         p_remote_cfg->start_time_min = p_remote_cfg->usr_cfg.freq_min * 31 / HW_TIMER_PERIOD_US - HW_TIMER_MIN_DECREASE_HEAD; // 帧头最小时间 us
         p_remote_cfg->start_time_max = p_remote_cfg->usr_cfg.freq_min * 31 / HW_TIMER_PERIOD_US + HW_TIMER_MAX_INCREASE_HEAD;
         p_remote_cfg->short_time_min = p_remote_cfg->usr_cfg.freq_min * 0.9 / HW_TIMER_PERIOD_US - HW_TIMER_MIN_DECREASE_S; // 只允许差一个检测单位
         p_remote_cfg->short_time_max = p_remote_cfg->usr_cfg.freq_min * 1.1 / HW_TIMER_PERIOD_US + HW_TIMER_MAX_INCREASE_S;
         p_remote_cfg->long_time_min = p_remote_cfg->usr_cfg.freq_min * 0.9 * 3 / HW_TIMER_PERIOD_US - HW_TIMER_MIN_DECREASE_H;
         p_remote_cfg->long_time_max = p_remote_cfg->usr_cfg.freq_min * 1.1 * 3 / HW_TIMER_PERIOD_US + HW_TIMER_MAX_INCREASE_H;
     } else {
         TAL_PR_ERR("input 433 time too small:%d", p_remote_cfg->usr_cfg.freq_min);
         tal_free(p_cfg);
         p_remote_cfg = NULL;
         return OPRT_COM_ERROR;
     }
     TAL_PR_NOTICE("[433]-start_us:[%d:%d], short:[%d:%d], long:[%d:%d]", p_remote_cfg->start_time_min, p_remote_cfg->start_time_max, p_remote_cfg->short_time_min, p_remote_cfg->short_time_max, p_remote_cfg->long_time_min, p_remote_cfg->long_time_max);
 
     if (func) {
         sg_p_recv_cb = func;
     }
 
     // 二值信号量和线程创建
     TUYA_CALL_ERR_LOG(tal_semaphore_create_init(&SemaphoreRecv, 0, 1));
 
     const THREAD_CFG_T thread_cfg = {
         .thrdname = "remote_task_0",
         .stackDepth = 4*1024,
         .priority = THREAD_PRIO_0,
     };
     TUYA_CALL_ERR_LOG(tal_thread_create_and_start(&remote_thrd_hdl, NULL, NULL, __remote_task, NULL, &thread_cfg));
     
 
     // 软件定时器
     OPERATE_RET op_ret = OPRT_OK;
     op_ret = tal_sw_timer_create(__recv_continue_fliter_timer_cb, NULL, &sg_fliter_tm);
     if (OPRT_OK != op_ret) {
         TAL_PR_ERR("add sys time err:%d", op_ret);
         return OPRT_COM_ERROR;
     }
 
     // tuya_gpio_inout_set(p_remote_cfg->usr_cfg.pin, TRUE);
     if ( p_remote_cfg->usr_cfg.pin != 0xff ) {
        TUYA_GPIO_BASE_CFG_T gpio_cfg = {
            .mode = TUYA_GPIO_PULLUP,
            .direct = TUYA_GPIO_INPUT
        };
        tkl_gpio_init(p_remote_cfg->usr_cfg.pin, &gpio_cfg);
     }
     TAL_PR_NOTICE("*** driver remote io:%d, hard timer:%d ***", p_remote_cfg->usr_cfg.pin, p_remote_cfg->usr_cfg.hw_timer_id);
     // 硬件定时器配置
     // bk_timer_initialize_us(p_remote_cfg->usr_cfg.hw_timer_id, HW_TIMER_PERIOD_US, __hw_timer_detect_cb);
     timer_cfg.mode = TUYA_TIMER_MODE_PERIOD;
     timer_cfg.cb = __hw_timer_detect_cb;
     timer_cfg.args = NULL;
     TUYA_CALL_ERR_LOG(tkl_timer_init(p_remote_cfg->usr_cfg.hw_timer_id, &timer_cfg));
     TUYA_CALL_ERR_LOG(tkl_timer_start(p_remote_cfg->usr_cfg.hw_timer_id, HW_TIMER_PERIOD_US));
 
     is_433_init = TRUE;
 
     TAL_PR_NOTICE("tuya driver remote init success");
 
     return OPRT_OK;
 }
 
 /**
  * @brief 设置过滤时间，即接收的遥控码不变，则不触发回调，需要这段时间不接收
  *        或者接收到其他遥控码才能再次执行回调
  * @param[in] filter_time 过滤时间 ms，0代表接收到即触发回调；默认为300ms
  */
 VOID_T tuya_remote_driver_set_filter_time(IN UINT_T filter_time)
 {
     sg_filter_time = filter_time;
 }



 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



STATIC VOID __remote_drv_recv_handle(OUT UINT_T remote_addr)
{
    // QNE_LOGE("recv 433 addr[%02x-%02x-%02x] \n", remote_addr & 0xFF, (remote_addr >> 8) & 0xFF, (remote_addr >> 16) & 0xFF);
    u8ReceEn = 1;
    u16Rf433Addr = ( remote_addr & 0xFF ) << 8 | ( ( remote_addr >> 8 ) & 0xFF );
    u8Rf433Cmd   = ( remote_addr >> 16 ) & 0xFF;
}

qneU16_t u16BspHal_Rf433AddrGet(qneVOID_t)
{
    return u16Rf433Addr;
}

qneU8_t u8BspHal_Rf433CmdGet(qneVOID_t)
{
    return u8Rf433Cmd;
}

qneU8_t u8BspHal_Rf433ReceEnGet(qneVOID_t)
{
    return u8ReceEn;
}

qneU8_t u8BspHal_Rf433SendEnGet(qneVOID_t)
{
    return u8SendEn;
}

qneVOID_t vBspHal_Rf433DataClean(qneVOID_t)
{
    u8Rf433Cmd   = 0;
    u16Rf433Addr = 0;
}

qneVOID_t vBspHal_Rf433ReceEnClean(qneVOID_t)
{
    u8ReceEn = 0;
}

qneVOID_t vBspHal_Rf433SendEnClean(qneVOID_t)
{
    u8SendEn = 0;
}

qneVOID_t vBspHal_Rf433Send(qneU8_t *u8Buffer, qneU8_t u8Lenght)
{
    if ( ( u8Lenght > 20 ) || ( u8SendEn ) ) {
        return;
    }
    u8SendEn = 1;
    u8SnedSta = 0;
    u8RfLenght = u8Lenght;
    qneMemcpy(u8RfBuffer, u8Buffer, u8Lenght);
}

qneOpRet_t opBspHal_Rf433Init(qneU8_t u8RecePin, qneU8_t u8SendPin, qneU16_t u16Freq)
{
    qneOpRet_t opRet = QNE_OP_OK;
    REMOTE_DRV_S remote_cfg = {
        .pin = u8RecePin,
        .freq_min = u16Freq,
        .hw_timer_id = TUYA_TIMER_NUM_0,
    };
    u8RfRecePin = u8RecePin;
    tuya_remote_driver_set_filter_time(10);
    OPERATE_RET op_ret = tuya_remote_driver_init(&remote_cfg, __remote_drv_recv_handle);
    if ( u8SendPin != 0xff ) {
        u8RfSendPin = u8SendPin;
        opBspHal_GpioInit(u8SendPin, HAL_GPIO_OUTPUT, HAL_GPIO_PULLHIGH, QNE_NULL);
        tkl_gpio_write(u8RfSendPin, 1);
    }
    if (OPRT_OK != op_ret) {
        QNE_LOGE("remote init hardware fail:%d", op_ret);
        opRet = QNE_OP_ERR;
    }
    return opRet;
}