移植HPW423评分版433解码器
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "timer.h"
|
||||
#include "light_transition.h"
|
||||
#include "pwm.h"
|
||||
#include "rf433_decoder.h"
|
||||
union rf433_flag rf_flag = {0};
|
||||
unsigned char high_level_time;
|
||||
unsigned char low_level_time;
|
||||
@@ -98,6 +99,8 @@ static uint8_t pair_command_replay;
|
||||
#define PAIR_HOLD_FRAME_COUNT 4U
|
||||
#define PAIR_FRAME_SILENCE_TICKS 100U
|
||||
#define PAIRING_WINDOW_TICKS 50000UL
|
||||
#define RF433_RELEASE_TIMEOUT_TICKS 1500U
|
||||
#define RF433_MS_TO_SAMPLE_TICKS(ms) ((uint16_t)((ms) * (1000U / RF433_DECODER_SAMPLE_US)))
|
||||
uint8_t long_flag_s=0;
|
||||
|
||||
void _433_fun(void);
|
||||
@@ -339,7 +342,22 @@ static void Encoder_key_NoCode(){
|
||||
}
|
||||
|
||||
|
||||
static void Rf433_Decoder_Frame_Poll(void)
|
||||
{
|
||||
Rf433DecoderFrame_t frame;
|
||||
|
||||
if(!rf433_decoder_get_frame(&frame)) return;
|
||||
|
||||
receive_data = frame.code;
|
||||
receive_temp = frame.code;
|
||||
res_data = frame.key;
|
||||
rf_frame_sequence++;
|
||||
rf_flag.rf_receive_flag.receive_finish = 1U;
|
||||
long_time = RF433_RELEASE_TIMEOUT_TICKS;
|
||||
}
|
||||
|
||||
void Encoder_key(){
|
||||
Rf433_Decoder_Frame_Poll();
|
||||
Encoder_key_NoCode(); //一对一
|
||||
Pairing_Feedback_Task();
|
||||
}
|
||||
@@ -364,106 +382,41 @@ static void set_click(){
|
||||
}
|
||||
}
|
||||
|
||||
void rf433_receive(void)//rf433接收,查询周期100us
|
||||
void rf433_receive(void)//RF433 sample, called every 100 us
|
||||
{
|
||||
rf433_decoder_sample((RF_DATA == HIGH_LEVEL) ? 1U : 0U);
|
||||
|
||||
if (RF_DATA == LOW_LEVEL)
|
||||
if(long_time > 0U)
|
||||
{
|
||||
low_level_time++;//记录低电平时间
|
||||
rf_flag.rf_receive_flag.current_level = 0; //当前电平状态
|
||||
}
|
||||
else if (RF_DATA == HIGH_LEVEL)
|
||||
{
|
||||
high_level_time++;//记录高电平时间
|
||||
|
||||
if (!rf_flag.rf_receive_flag.current_level)//每个上升沿检测,0→1,一个完整的周期检测
|
||||
long_time--;
|
||||
long_flag_s = 0U;
|
||||
if(KEY_STATE_re == 1U)
|
||||
{
|
||||
// if ((high_level_time > 1 && high_level_time < 7) && (low_level_time > 115 && low_level_time < 125)) //判同步码,时间间隔12ms
|
||||
//if ((high_level_time > 4 && high_level_time < 9) && ((low_level_time > 17 && low_level_time < 23))) //判同步码,时间间隔12ms
|
||||
if ((high_level_time > 1 && high_level_time < 7) && (low_level_time > 115 && low_level_time < 130)) //判同步码,时间间隔12ms
|
||||
{
|
||||
//进来这里需要13ms
|
||||
rf_flag.rf_receive_flag.sync_code = 1;//同步码接收成功标志
|
||||
receive_data_cnt = 0;
|
||||
receive_temp = 0;
|
||||
long_time=frames_time;
|
||||
|
||||
}
|
||||
else if (rf_flag.rf_receive_flag.sync_code)//开始接收数据包
|
||||
if(time_300ms == 0U)
|
||||
{
|
||||
//if ((high_level_time > 1 && high_level_time < 9) && (low_level_time > 8 && low_level_time < 18)) //数据低电平
|
||||
if ((high_level_time >= 1 && high_level_time <= 7) && (low_level_time >= 7 && low_level_time <= 16)) //数据低电平
|
||||
{
|
||||
receive_data_cnt++;//接收24位位数
|
||||
receive_temp = receive_temp << 1;
|
||||
if (receive_data_cnt == 24)//24位数据接收完成
|
||||
{
|
||||
rf_frame_sequence++;
|
||||
//进来这个if需要40ms
|
||||
rf_flag.rf_receive_flag.receive_finish = 1;//24位数据接收完成标志
|
||||
rf_flag.rf_receive_flag.sync_code = 0;
|
||||
receive_data = receive_temp;//将接收到的编码复制到解码寄存器中
|
||||
res_data=receive_temp;
|
||||
}
|
||||
}
|
||||
//else if ((high_level_time > 7 && high_level_time < 18) && (low_level_time > 2 && low_level_time < 9)) //数据高电平
|
||||
else if ((high_level_time >= 7 && high_level_time <= 16) && (low_level_time >= 2 && low_level_time<= 7)) //数据高电平
|
||||
{
|
||||
receive_temp = receive_temp << 1;
|
||||
receive_temp |= 1;
|
||||
receive_data_cnt++;
|
||||
if (receive_data_cnt == 24)
|
||||
{
|
||||
rf_frame_sequence++;
|
||||
//进来这个if需要40ms3748f3
|
||||
rf_flag.rf_receive_flag.receive_finish = 1;//24位数据接收完成标志
|
||||
rf_flag.rf_receive_flag.sync_code = 0;
|
||||
receive_data = receive_temp;//将接收到的编码复制到解码寄存器中
|
||||
res_data=receive_temp;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
rf_flag.rf_receive_flag.sync_code = 0;//接收失败
|
||||
}
|
||||
long_time=frames_time;//该值一定要大与68,68是指68ms通过逻辑分析仪测量一帧的时间
|
||||
//
|
||||
//
|
||||
}
|
||||
if(long_time>0){ //一直按着会进入该if
|
||||
//P05=0; //433LED灯
|
||||
long_time--;
|
||||
long_flag_s=0;
|
||||
if( KEY_STATE_re==1){
|
||||
if(time_300ms==0){
|
||||
time_300ms=Short_time;
|
||||
long_flag_s=1;
|
||||
KEY_STATE_re=0;
|
||||
}
|
||||
else if(time_300ms>0) time_300ms--;
|
||||
}
|
||||
}
|
||||
else { //松手
|
||||
time_300ms=LongPress_time;
|
||||
long_time=0;
|
||||
long_flag_s=0;
|
||||
Key_TypeDef.KEY_STATE_Click=0;
|
||||
KEY_STATE_re=0;
|
||||
}
|
||||
|
||||
low_level_time = 0;//清零低电平时间
|
||||
high_level_time = 1;//高电平时间开始计数
|
||||
|
||||
time_300ms = RF433_MS_TO_SAMPLE_TICKS(Short_time);
|
||||
long_flag_s = 1U;
|
||||
KEY_STATE_re = 0U;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_300ms--;
|
||||
}
|
||||
}
|
||||
rf_flag.rf_receive_flag.current_level = 1;//当前电平状态
|
||||
}
|
||||
//
|
||||
if(time_5s<=PAIRING_WINDOW_TICKS){
|
||||
time_5s++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
time_300ms = RF433_MS_TO_SAMPLE_TICKS(LongPress_time);
|
||||
long_flag_s = 0U;
|
||||
Key_TypeDef.KEY_STATE_Click = 0U;
|
||||
KEY_STATE_re = 0U;
|
||||
}
|
||||
|
||||
if(time_5s <= PAIRING_WINDOW_TICKS)
|
||||
{
|
||||
time_5s++;
|
||||
}
|
||||
}
|
||||
uint16_t spee_dealy_time=0; //速度缓慢变换
|
||||
|
||||
#define REMOTE_MODE_MIN 0U
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include "pwm.h"
|
||||
#include "mode.h"
|
||||
#include "RF433.h"
|
||||
#include "rf433_decoder.h"
|
||||
#include "rgblight.h"
|
||||
#include "timer.h"
|
||||
#include "fmc_spi.h"
|
||||
@@ -239,6 +240,7 @@ void board_init()
|
||||
clock_init();
|
||||
// app_uart_init();
|
||||
rf433_gpio_init();
|
||||
rf433_decoder_init();
|
||||
#if (_DEBUG_ == 1)
|
||||
app_uart_init();
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,787 @@
|
||||
#include "rf433_decoder.h"
|
||||
#include "rf433_decoder_port.h"
|
||||
|
||||
#define RF433_FIFO_SIZE 256u
|
||||
|
||||
#define RF433_GLITCH_DYNAMIC_MIN 2u
|
||||
#define RF433_GLITCH_DYNAMIC_MAX 4u
|
||||
|
||||
#define RF433_SYNC_LOW_MIN 35u //45改35
|
||||
#define RF433_SYNC_LOW_MAX 200u //180改200
|
||||
#define RF433_SYNC_HIGH_MIN 1u
|
||||
#define RF433_SYNC_HIGH_MAX 15u //12改15
|
||||
|
||||
#define RF433_BIT_LEN 24u
|
||||
#define RF433_REPEAT_CONFIRM 1u //2改1
|
||||
|
||||
#define RF433_LEVEL_TIMEOUT 300u //300
|
||||
|
||||
#define RF433_BIT_TOTAL_MIN 3u //4改3
|
||||
#define RF433_BIT_TOTAL_MAX 40u //35改40
|
||||
|
||||
#define RF433_PROCESS_MAX_ONCE 32u
|
||||
|
||||
#define RF433_FRAME_SCORE_MIN 50u //70改50
|
||||
#define RF433_BIT_SCORE_GOOD 4u
|
||||
#define RF433_BIT_SCORE_NORMAL 3u
|
||||
#define RF433_BIT_SCORE_POOR 1u
|
||||
|
||||
#define RF433_WINDOW_TIGHT 0u
|
||||
#define RF433_WINDOW_NORMAL 1u
|
||||
#define RF433_WINDOW_LOOSE 2u
|
||||
|
||||
|
||||
// 新增:连发屏蔽间隔(单位:100us采样tick,200=20ms内相同码只输出一次)
|
||||
#define RF433_ANTI_REPEAT_TICK 200u
|
||||
|
||||
|
||||
#if RF433_DECODER_DEBUG_PULSE
|
||||
#define RF433_PULSE_LOG(fmt, ...) RF433_DECODER_LOG(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define RF433_PULSE_LOG(fmt, ...)
|
||||
#endif
|
||||
|
||||
#if RF433_DECODER_DEBUG_DETAIL
|
||||
#define RF433_DETAIL_LOG(fmt, ...) RF433_DECODER_LOG(fmt, ##__VA_ARGS__)
|
||||
#else
|
||||
#define RF433_DETAIL_LOG(fmt, ...)
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RF433_STATE_IDLE = 0,
|
||||
RF433_STATE_DATA,
|
||||
} Rf433State_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t level;
|
||||
uint16_t width;
|
||||
} Rf433Pulse_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
volatile Rf433Pulse_t fifo[RF433_FIFO_SIZE];
|
||||
volatile uint16_t w;
|
||||
volatile uint16_t r;
|
||||
volatile uint16_t lost;
|
||||
uint8_t last_level;
|
||||
uint16_t width;
|
||||
uint8_t inited;
|
||||
} Rf433Fifo_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rf433State_t state;
|
||||
uint16_t last_high;
|
||||
uint16_t last_low;
|
||||
uint16_t t;
|
||||
uint16_t short_min;
|
||||
uint16_t short_max;
|
||||
uint16_t long_min;
|
||||
uint16_t long_max;
|
||||
uint32_t data;
|
||||
uint8_t bit_cnt;
|
||||
uint8_t bit_score_sum;
|
||||
uint8_t frame_score;
|
||||
uint8_t ppl_locked;
|
||||
uint8_t window_mode;
|
||||
uint32_t last_code;
|
||||
uint8_t same_cnt;
|
||||
Rf433DecoderFrame_t frame;
|
||||
bool frame_ready;
|
||||
|
||||
|
||||
} Rf433Decode_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Rf433Pulse_t p0;
|
||||
Rf433Pulse_t p1;
|
||||
Rf433Pulse_t p2;
|
||||
uint8_t cnt;
|
||||
} Rf433Repair_t;
|
||||
|
||||
static Rf433Fifo_t s_fifo;
|
||||
static Rf433Decode_t s_dec;
|
||||
static Rf433Repair_t s_repair;
|
||||
|
||||
static uint16_t rf433_limit_t(uint16_t t)
|
||||
{
|
||||
if (t < 2u)
|
||||
{
|
||||
t = 2u;
|
||||
}
|
||||
|
||||
if (t > 12u)
|
||||
{
|
||||
t = 12u;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static void rf433_update_range_by_t(uint16_t t)
|
||||
{
|
||||
t = rf433_limit_t(t);
|
||||
s_dec.t = t;
|
||||
|
||||
if (s_dec.window_mode == RF433_WINDOW_TIGHT)
|
||||
{
|
||||
s_dec.short_min = 1u;
|
||||
s_dec.short_max = (uint16_t)(t + t / 2u + 2u);
|
||||
s_dec.long_min = (uint16_t)(t * 2u);
|
||||
s_dec.long_max = (uint16_t)(t * 4u + 2u);
|
||||
}
|
||||
else if (s_dec.window_mode == RF433_WINDOW_LOOSE)
|
||||
{
|
||||
s_dec.short_min = 1u;
|
||||
s_dec.short_max = (uint16_t)(t * 2u + 4u);
|
||||
s_dec.long_min = (uint16_t)(t + t / 2u);
|
||||
if (s_dec.long_min < 3u)
|
||||
{
|
||||
s_dec.long_min = 3u;
|
||||
}
|
||||
s_dec.long_max = (uint16_t)(t * 7u + 4u);
|
||||
}
|
||||
else
|
||||
{
|
||||
s_dec.short_min = 1u;
|
||||
s_dec.short_max = (uint16_t)(t * 2u + 3u);
|
||||
s_dec.long_min = (uint16_t)(t + t / 2u);
|
||||
if (s_dec.long_min < 3u)
|
||||
{
|
||||
s_dec.long_min = 3u;
|
||||
}
|
||||
s_dec.long_max = (uint16_t)(t * 7u + 3u);
|
||||
}
|
||||
}
|
||||
|
||||
static void rf433_decode_reset(void)
|
||||
{
|
||||
s_dec.state = RF433_STATE_IDLE;
|
||||
s_dec.last_high = 0;
|
||||
s_dec.last_low = 0;
|
||||
s_dec.data = 0;
|
||||
s_dec.bit_cnt = 0;
|
||||
s_dec.bit_score_sum = 0;
|
||||
s_dec.frame_score = 0;
|
||||
s_dec.window_mode = RF433_WINDOW_NORMAL;
|
||||
rf433_update_range_by_t(4u);
|
||||
}
|
||||
|
||||
static void rf433_repair_reset(void)
|
||||
{
|
||||
s_repair.cnt = 0;
|
||||
s_repair.p0.level = 0;
|
||||
s_repair.p0.width = 0;
|
||||
s_repair.p1.level = 0;
|
||||
s_repair.p1.width = 0;
|
||||
s_repair.p2.level = 0;
|
||||
s_repair.p2.width = 0;
|
||||
}
|
||||
|
||||
static void rf433_debug_reset(const char *reason, uint16_t high, uint16_t low)
|
||||
{
|
||||
RF433_DETAIL_LOG("[RF433 RESET] %s bits=%d high=%d low=%d data=0x%06X T=%d win=%d lost=%d\r\n",
|
||||
reason,
|
||||
s_dec.bit_cnt,
|
||||
high,
|
||||
low,
|
||||
(unsigned int)s_dec.data,
|
||||
s_dec.t,
|
||||
s_dec.window_mode,
|
||||
s_fifo.lost);
|
||||
}
|
||||
|
||||
void rf433_decoder_init(void)
|
||||
{
|
||||
s_fifo.w = 0;
|
||||
s_fifo.r = 0;
|
||||
s_fifo.lost = 0;
|
||||
s_fifo.last_level = 0;
|
||||
s_fifo.width = 0;
|
||||
s_fifo.inited = 0;
|
||||
|
||||
s_dec.last_code = 0;
|
||||
s_dec.same_cnt = 0;
|
||||
s_dec.frame_ready = false;
|
||||
s_dec.ppl_locked = 0;
|
||||
s_dec.window_mode = RF433_WINDOW_NORMAL;
|
||||
|
||||
|
||||
rf433_decode_reset();
|
||||
rf433_repair_reset();
|
||||
}
|
||||
|
||||
void rf433_decoder_sample(uint8_t level)
|
||||
{
|
||||
uint16_t next;
|
||||
Rf433Pulse_t pulse;
|
||||
|
||||
level = level ? 1u : 0u;
|
||||
|
||||
if (!s_fifo.inited)
|
||||
{
|
||||
s_fifo.last_level = level;
|
||||
s_fifo.width = 1;
|
||||
s_fifo.inited = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (level == s_fifo.last_level)
|
||||
{
|
||||
if (s_fifo.width < 0xFFFFu)
|
||||
{
|
||||
s_fifo.width++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
pulse.level = s_fifo.last_level;
|
||||
pulse.width = s_fifo.width;
|
||||
s_fifo.last_level = level;
|
||||
s_fifo.width = 1;
|
||||
|
||||
next = (uint16_t)((s_fifo.w + 1u) % RF433_FIFO_SIZE);
|
||||
if (next != s_fifo.r)
|
||||
{
|
||||
s_fifo.fifo[s_fifo.w] = pulse;
|
||||
s_fifo.w = next;
|
||||
}
|
||||
else if (s_fifo.lost < 0xFFFFu)
|
||||
{
|
||||
s_fifo.lost++;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rf433_fifo_pop(Rf433Pulse_t *pulse)
|
||||
{
|
||||
if (pulse == 0 || s_fifo.r == s_fifo.w)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*pulse = s_fifo.fifo[s_fifo.r];
|
||||
s_fifo.r = (uint16_t)((s_fifo.r + 1u) % RF433_FIFO_SIZE);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool rf433_is_sync(uint16_t high, uint16_t low)
|
||||
{
|
||||
if (high == 0u || low == 0u)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (high < RF433_SYNC_HIGH_MIN || high > RF433_SYNC_HIGH_MAX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (low < RF433_SYNC_LOW_MIN || low > RF433_SYNC_LOW_MAX)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (low < (uint16_t)(high * 10u)) //12
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rf433_ppl_update_by_sync(uint16_t sync_low)
|
||||
{
|
||||
uint16_t t_new = rf433_limit_t((uint16_t)(sync_low / 31u));
|
||||
uint16_t t_filter;
|
||||
|
||||
if (s_dec.ppl_locked)
|
||||
{
|
||||
t_filter = (uint16_t)((s_dec.t * 7u + t_new) / 8u);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_filter = (uint16_t)((s_dec.t * 3u + t_new) / 4u);
|
||||
}
|
||||
|
||||
rf433_update_range_by_t(t_filter);
|
||||
}
|
||||
|
||||
static void rf433_update_t_by_bit(uint16_t high, uint16_t low, uint8_t bit)
|
||||
{
|
||||
uint16_t t_new;
|
||||
uint16_t t_filter;
|
||||
|
||||
if (bit == 0u)
|
||||
{
|
||||
t_new = (uint16_t)((high + low / 3u) / 2u);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_new = (uint16_t)((high / 3u + low) / 2u);
|
||||
}
|
||||
|
||||
t_new = rf433_limit_t(t_new);
|
||||
|
||||
if (s_dec.ppl_locked)
|
||||
{
|
||||
t_filter = (uint16_t)((s_dec.t * 7u + t_new) / 8u);
|
||||
}
|
||||
else
|
||||
{
|
||||
t_filter = (uint16_t)((s_dec.t * 3u + t_new) / 4u);
|
||||
}
|
||||
|
||||
rf433_update_range_by_t(t_filter);
|
||||
}
|
||||
|
||||
static uint16_t rf433_get_glitch_max(void)
|
||||
{
|
||||
uint16_t v = s_dec.t / 2u;
|
||||
|
||||
if (v < RF433_GLITCH_DYNAMIC_MIN)
|
||||
{
|
||||
v = RF433_GLITCH_DYNAMIC_MIN;
|
||||
}
|
||||
|
||||
if (v > RF433_GLITCH_DYNAMIC_MAX)
|
||||
{
|
||||
v = RF433_GLITCH_DYNAMIC_MAX;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static bool rf433_is_short(uint16_t width)
|
||||
{
|
||||
return ((width >= s_dec.short_min) && (width <= s_dec.short_max));
|
||||
}
|
||||
|
||||
static bool rf433_is_long(uint16_t width)
|
||||
{
|
||||
return ((width >= s_dec.long_min) && (width <= s_dec.long_max));
|
||||
}
|
||||
|
||||
static bool rf433_total_valid(uint16_t high, uint16_t low)
|
||||
{
|
||||
uint16_t total = (uint16_t)(high + low);
|
||||
return ((total >= RF433_BIT_TOTAL_MIN) && (total <= RF433_BIT_TOTAL_MAX));
|
||||
}
|
||||
|
||||
static bool rf433_decode_bit(uint16_t high, uint16_t low, uint8_t *bit)
|
||||
{
|
||||
if (bit == 0 || !rf433_total_valid(high, low))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rf433_is_short(high) && rf433_is_long(low))
|
||||
{
|
||||
*bit = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (rf433_is_long(high) && rf433_is_short(low))
|
||||
{
|
||||
*bit = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#if RF433_DECODER_DEBUG_DETAIL
|
||||
static const char *rf433_bit_fail_reason(uint16_t high, uint16_t low)
|
||||
{
|
||||
if (!rf433_total_valid(high, low))
|
||||
{
|
||||
return "total";
|
||||
}
|
||||
|
||||
if (!rf433_is_short(high) && !rf433_is_long(high))
|
||||
{
|
||||
return "high";
|
||||
}
|
||||
|
||||
if (!rf433_is_short(low) && !rf433_is_long(low))
|
||||
{
|
||||
return "low";
|
||||
}
|
||||
|
||||
return "pair";
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint16_t rf433_abs_diff_u16(uint16_t a, uint16_t b)
|
||||
{
|
||||
return (a > b) ? (uint16_t)(a - b) : (uint16_t)(b - a);
|
||||
}
|
||||
|
||||
static uint8_t rf433_score_bit(uint16_t high, uint16_t low, uint8_t bit)
|
||||
{
|
||||
uint16_t ideal_high;
|
||||
uint16_t ideal_low;
|
||||
uint16_t err;
|
||||
|
||||
if (bit == 0u)
|
||||
{
|
||||
ideal_high = s_dec.t;
|
||||
ideal_low = (uint16_t)(s_dec.t * 3u);
|
||||
}
|
||||
else
|
||||
{
|
||||
ideal_high = (uint16_t)(s_dec.t * 3u);
|
||||
ideal_low = s_dec.t;
|
||||
}
|
||||
|
||||
err = (uint16_t)(rf433_abs_diff_u16(high, ideal_high) +
|
||||
rf433_abs_diff_u16(low, ideal_low));
|
||||
|
||||
if (err <= 2u)
|
||||
{
|
||||
return RF433_BIT_SCORE_GOOD;
|
||||
}
|
||||
|
||||
if (err <= 5u)
|
||||
{
|
||||
return RF433_BIT_SCORE_NORMAL;
|
||||
}
|
||||
|
||||
return RF433_BIT_SCORE_POOR;
|
||||
}
|
||||
|
||||
static uint8_t rf433_calc_frame_score(void)
|
||||
{
|
||||
uint16_t score;
|
||||
|
||||
if (s_dec.bit_cnt == 0u)
|
||||
{
|
||||
return 0u;
|
||||
}
|
||||
|
||||
score = (uint16_t)s_dec.bit_score_sum * 100u;
|
||||
score = score / (uint16_t)(RF433_BIT_LEN * RF433_BIT_SCORE_GOOD);
|
||||
return (score > 100u) ? 100u : (uint8_t)score;
|
||||
}
|
||||
|
||||
static void rf433_update_window_by_score(uint8_t score)
|
||||
{
|
||||
if (score >= 90u)
|
||||
{
|
||||
s_dec.window_mode = RF433_WINDOW_TIGHT;
|
||||
s_dec.ppl_locked = 1u;
|
||||
}
|
||||
else if (score >= 60u)
|
||||
{
|
||||
s_dec.window_mode = RF433_WINDOW_NORMAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_dec.window_mode = RF433_WINDOW_LOOSE;
|
||||
s_dec.ppl_locked = 0u;
|
||||
}
|
||||
|
||||
rf433_update_range_by_t(s_dec.t);
|
||||
}
|
||||
|
||||
static void rf433_output_code(uint32_t code)
|
||||
{
|
||||
if (code == s_dec.last_code)
|
||||
{
|
||||
if (s_dec.same_cnt < 255u)
|
||||
{
|
||||
s_dec.same_cnt++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s_dec.last_code = code;
|
||||
s_dec.same_cnt = 1;
|
||||
|
||||
|
||||
}
|
||||
|
||||
RF433_DETAIL_LOG("[RF433 REPEAT] code=0x%06X same=%d/%d\r\n",
|
||||
(unsigned int)code,
|
||||
s_dec.same_cnt,
|
||||
RF433_REPEAT_CONFIRM);
|
||||
|
||||
if (s_dec.same_cnt >= RF433_REPEAT_CONFIRM)
|
||||
{
|
||||
s_dec.frame.code = code;
|
||||
s_dec.frame.bit_len = RF433_BIT_LEN;
|
||||
s_dec.frame.addr_h = (uint8_t)((code >> 16) & 0xFFu);
|
||||
s_dec.frame.addr_l = (uint8_t)((code >> 8) & 0xFFu);
|
||||
s_dec.frame.key = (uint8_t)(code & 0xFFu);
|
||||
s_dec.frame.score = s_dec.frame_score;
|
||||
s_dec.frame_ready = true;
|
||||
|
||||
|
||||
|
||||
s_dec.same_cnt = 0;
|
||||
|
||||
RF433_DECODER_LOG("[RF433 OK] code=0x%06X addr_h=0x%02X addr_l=0x%02X key=0x%02X score=%d\r\n",
|
||||
(unsigned int)s_dec.frame.code,
|
||||
s_dec.frame.addr_h,
|
||||
s_dec.frame.addr_l,
|
||||
s_dec.frame.key,
|
||||
s_dec.frame.score);
|
||||
}
|
||||
}
|
||||
|
||||
static void rf433_process_clean_pulse(Rf433Pulse_t pulse)
|
||||
{
|
||||
uint8_t bit;
|
||||
uint8_t bit_score;
|
||||
|
||||
if (pulse.width == 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pulse.width > RF433_LEVEL_TIMEOUT)
|
||||
{
|
||||
rf433_debug_reset("timeout", s_dec.last_high, pulse.width);
|
||||
rf433_decode_reset();
|
||||
rf433_repair_reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (pulse.level)
|
||||
{
|
||||
s_dec.last_high = pulse.width;
|
||||
return;
|
||||
}
|
||||
|
||||
s_dec.last_low = pulse.width;
|
||||
|
||||
if (rf433_is_sync(s_dec.last_high, s_dec.last_low))
|
||||
{
|
||||
s_dec.window_mode = s_dec.ppl_locked ? RF433_WINDOW_TIGHT : RF433_WINDOW_NORMAL;
|
||||
rf433_ppl_update_by_sync(s_dec.last_low);
|
||||
|
||||
RF433_DETAIL_LOG("[RF433 SYNC] high=%d low=%d T=%d short=%d-%d long=%d-%d win=%d lock=%d\r\n",
|
||||
s_dec.last_high,
|
||||
s_dec.last_low,
|
||||
s_dec.t,
|
||||
s_dec.short_min,
|
||||
s_dec.short_max,
|
||||
s_dec.long_min,
|
||||
s_dec.long_max,
|
||||
s_dec.window_mode,
|
||||
s_dec.ppl_locked);
|
||||
|
||||
s_dec.state = RF433_STATE_DATA;
|
||||
s_dec.data = 0;
|
||||
s_dec.bit_cnt = 0;
|
||||
s_dec.bit_score_sum = 0;
|
||||
s_dec.frame_score = 0;
|
||||
s_dec.last_high = 0;
|
||||
s_dec.last_low = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_dec.state != RF433_STATE_DATA ||
|
||||
s_dec.last_high == 0u ||
|
||||
s_dec.last_low == 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (rf433_decode_bit(s_dec.last_high, s_dec.last_low, &bit))
|
||||
{
|
||||
bit_score = rf433_score_bit(s_dec.last_high, s_dec.last_low, bit);
|
||||
if (s_dec.bit_score_sum <= (uint8_t)(255u - bit_score))
|
||||
{
|
||||
s_dec.bit_score_sum += bit_score;
|
||||
}
|
||||
|
||||
rf433_update_t_by_bit(s_dec.last_high, s_dec.last_low, bit);
|
||||
s_dec.data <<= 1;
|
||||
if (bit)
|
||||
{
|
||||
s_dec.data |= 1u;
|
||||
}
|
||||
s_dec.bit_cnt++;
|
||||
|
||||
RF433_DETAIL_LOG("[RF433 BIT] idx=%02d bit=%d high=%d low=%d score=%d T=%d data=0x%06X\r\n",
|
||||
s_dec.bit_cnt,
|
||||
bit,
|
||||
s_dec.last_high,
|
||||
s_dec.last_low,
|
||||
bit_score,
|
||||
s_dec.t,
|
||||
(unsigned int)s_dec.data);
|
||||
|
||||
if (s_dec.bit_cnt >= RF433_BIT_LEN)
|
||||
{
|
||||
s_dec.frame_score = rf433_calc_frame_score();
|
||||
rf433_update_window_by_score(s_dec.frame_score);
|
||||
|
||||
RF433_DECODER_LOG("[RF433 FRAME] score=%3d T=%2d win=%d lock=%d bits=%2d code=0x%06X addr_h=0x%02X addr_l=0x%02X key=0x%02X\r\n",
|
||||
s_dec.frame_score,
|
||||
s_dec.t,
|
||||
s_dec.window_mode,
|
||||
s_dec.ppl_locked,
|
||||
s_dec.bit_cnt,
|
||||
(unsigned int)s_dec.data,
|
||||
(unsigned int)((s_dec.data >> 16) & 0xFFu),
|
||||
(unsigned int)((s_dec.data >> 8) & 0xFFu),
|
||||
(unsigned int)(s_dec.data & 0xFFu));
|
||||
|
||||
if (s_dec.frame_score >= RF433_FRAME_SCORE_MIN)
|
||||
{
|
||||
rf433_output_code(s_dec.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
RF433_DECODER_LOG("[RF433 BAD] score=%d code=0x%06X\r\n",
|
||||
s_dec.frame_score,
|
||||
(unsigned int)s_dec.data);
|
||||
}
|
||||
|
||||
rf433_decode_reset();
|
||||
rf433_repair_reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if RF433_DECODER_DEBUG_DETAIL
|
||||
RF433_DETAIL_LOG("[RF433 BIT_ERR] reason=%s idx=%02d high=%d low=%d total=%d T=%d short=%d-%d long=%d-%d data=0x%06X\r\n",
|
||||
rf433_bit_fail_reason(s_dec.last_high, s_dec.last_low),
|
||||
(uint8_t)(s_dec.bit_cnt + 1u),
|
||||
s_dec.last_high,
|
||||
s_dec.last_low,
|
||||
(uint16_t)(s_dec.last_high + s_dec.last_low),
|
||||
s_dec.t,
|
||||
s_dec.short_min,
|
||||
s_dec.short_max,
|
||||
s_dec.long_min,
|
||||
s_dec.long_max,
|
||||
(unsigned int)s_dec.data);
|
||||
#endif
|
||||
rf433_debug_reset("bit", s_dec.last_high, s_dec.last_low);
|
||||
rf433_decode_reset();
|
||||
rf433_repair_reset();
|
||||
}
|
||||
}
|
||||
|
||||
static bool rf433_can_merge_glitch(Rf433Pulse_t a, Rf433Pulse_t b, Rf433Pulse_t c)
|
||||
{
|
||||
if (a.level != c.level)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (b.width > rf433_get_glitch_max())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a.width == 0u || c.width == 0u)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rf433_repair_input_pulse(Rf433Pulse_t pulse)
|
||||
{
|
||||
Rf433Pulse_t merged;
|
||||
Rf433Pulse_t out;
|
||||
|
||||
RF433_PULSE_LOG("[RF433 RAW] L=%d W=%d\r\n", pulse.level, pulse.width);
|
||||
|
||||
if (pulse.width == 0u)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pulse.width > RF433_LEVEL_TIMEOUT)
|
||||
{
|
||||
rf433_debug_reset("timeout", s_dec.last_high, pulse.width);
|
||||
rf433_decode_reset();
|
||||
rf433_repair_reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_repair.cnt == 0u)
|
||||
{
|
||||
s_repair.p0 = pulse;
|
||||
s_repair.cnt = 1u;
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_repair.cnt == 1u)
|
||||
{
|
||||
s_repair.p1 = pulse;
|
||||
s_repair.cnt = 2u;
|
||||
return;
|
||||
}
|
||||
|
||||
s_repair.p2 = pulse;
|
||||
if (rf433_can_merge_glitch(s_repair.p0, s_repair.p1, s_repair.p2))
|
||||
{
|
||||
merged.level = s_repair.p0.level;
|
||||
merged.width = (uint16_t)(s_repair.p0.width +
|
||||
s_repair.p1.width +
|
||||
s_repair.p2.width);
|
||||
|
||||
RF433_PULSE_LOG("[RF433 MERGE] %d:%d + %d:%d + %d:%d => %d:%d\r\n",
|
||||
s_repair.p0.level,
|
||||
s_repair.p0.width,
|
||||
s_repair.p1.level,
|
||||
s_repair.p1.width,
|
||||
s_repair.p2.level,
|
||||
s_repair.p2.width,
|
||||
merged.level,
|
||||
merged.width);
|
||||
|
||||
s_repair.p0 = merged;
|
||||
s_repair.cnt = 1u;
|
||||
return;
|
||||
}
|
||||
|
||||
out = s_repair.p0;
|
||||
RF433_PULSE_LOG("[RF433 CLEAN] L=%d W=%d\r\n", out.level, out.width);
|
||||
rf433_process_clean_pulse(out);
|
||||
|
||||
s_repair.p0 = s_repair.p1;
|
||||
s_repair.p1 = s_repair.p2;
|
||||
s_repair.cnt = 2u;
|
||||
}
|
||||
|
||||
void rf433_decoder_process(void)
|
||||
{
|
||||
Rf433Pulse_t pulse;
|
||||
uint8_t cnt = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
while ((cnt < RF433_PROCESS_MAX_ONCE) && rf433_fifo_pop(&pulse))
|
||||
{
|
||||
rf433_repair_input_pulse(pulse);
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
bool rf433_decoder_get_frame(Rf433DecoderFrame_t *frame)
|
||||
{
|
||||
if (frame == 0 || !s_dec.frame_ready)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*frame = s_dec.frame;
|
||||
s_dec.frame_ready = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t rf433_decoder_get_lost_count(void)
|
||||
{
|
||||
return s_fifo.lost;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef __RF433_DECODER_H__
|
||||
#define __RF433_DECODER_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define RF433_DECODER_SAMPLE_US 100u
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t code;
|
||||
uint8_t bit_len;
|
||||
uint8_t addr_h;
|
||||
uint8_t addr_l;
|
||||
uint8_t key;
|
||||
uint8_t score;
|
||||
} Rf433DecoderFrame_t;
|
||||
|
||||
void rf433_decoder_init(void);
|
||||
void rf433_decoder_sample(uint8_t level);
|
||||
void rf433_decoder_process(void);
|
||||
bool rf433_decoder_get_frame(Rf433DecoderFrame_t *frame);
|
||||
uint16_t rf433_decoder_get_lost_count(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef __RF433_DECODER_PORT_H__
|
||||
#define __RF433_DECODER_PORT_H__
|
||||
|
||||
#ifndef RF433_DECODER_LOG
|
||||
#define RF433_DECODER_LOG(fmt, ...) ((void)0)
|
||||
#endif
|
||||
|
||||
#ifndef RF433_DECODER_DEBUG_DETAIL
|
||||
#define RF433_DECODER_DEBUG_DETAIL 0
|
||||
#endif
|
||||
|
||||
#ifndef RF433_DECODER_DEBUG_PULSE
|
||||
#define RF433_DECODER_DEBUG_PULSE 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "timer.h"
|
||||
#include "mode.h"
|
||||
#include "RF433.h"
|
||||
#include "rf433_decoder.h"
|
||||
#include "ota_flash_interface.h"
|
||||
#include "ota_protocol.h"
|
||||
#include "pwm.h"
|
||||
@@ -31,6 +32,7 @@ TASK_COMPONENTS TaskComps[] =
|
||||
{0,50,50,ble_state_sync_poll},
|
||||
{0, 311, 1, app_op_flash}, //用户数据持久化 fmc_spi_read9
|
||||
{0, 311, 1, xc_ota_schedule}, //保存flash数据任务 8 //最后调用的
|
||||
{0, 1, 1, rf433_decoder_process},
|
||||
};
|
||||
|
||||
/**************************************************************************************
|
||||
|
||||
@@ -719,6 +719,21 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\app\src\Rf433.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rf433_decoder.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\app\src\rf433_decoder.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rf433_decoder.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\app\src\rf433_decoder.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rf433_decoder_port.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\app\src\rf433_decoder_port.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>PWM.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -1507,6 +1522,21 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\app\src\Rf433.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rf433_decoder.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\app\src\rf433_decoder.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rf433_decoder.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\app\src\rf433_decoder.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>rf433_decoder_port.h</FileName>
|
||||
<FileType>5</FileType>
|
||||
<FilePath>..\app\src\rf433_decoder_port.h</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>PWM.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
|
||||
Reference in New Issue
Block a user