diff --git a/project/example/ble/ble_peripheral/app/src/Rf433.c b/project/example/ble/ble_peripheral/app/src/Rf433.c index 519c009..6902477 100644 --- a/project/example/ble/ble_peripheral/app/src/Rf433.c +++ b/project/example/ble/ble_peripheral/app/src/Rf433.c @@ -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 { - - if (RF_DATA == LOW_LEVEL) - { - 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,一个完整的周期检测 - { - // 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 ((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;//高电平时间开始计数 - - } - rf_flag.rf_receive_flag.current_level = 1;//当前电平状态 - } -// - if(time_5s<=PAIRING_WINDOW_TICKS){ - time_5s++; - } -} + rf433_decoder_sample((RF_DATA == HIGH_LEVEL) ? 1U : 0U); + if(long_time > 0U) + { + long_time--; + long_flag_s = 0U; + if(KEY_STATE_re == 1U) + { + if(time_300ms == 0U) + { + time_300ms = RF433_MS_TO_SAMPLE_TICKS(Short_time); + long_flag_s = 1U; + KEY_STATE_re = 0U; + } + else + { + time_300ms--; + } + } + } + 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 diff --git a/project/example/ble/ble_peripheral/app/src/arch_main.c b/project/example/ble/ble_peripheral/app/src/arch_main.c index c9f7446..31a2a7a 100644 --- a/project/example/ble/ble_peripheral/app/src/arch_main.c +++ b/project/example/ble/ble_peripheral/app/src/arch_main.c @@ -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 diff --git a/project/example/ble/ble_peripheral/app/src/rf433_decoder.c b/project/example/ble/ble_peripheral/app/src/rf433_decoder.c new file mode 100644 index 0000000..9973aa1 --- /dev/null +++ b/project/example/ble/ble_peripheral/app/src/rf433_decoder.c @@ -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; +} diff --git a/project/example/ble/ble_peripheral/app/src/rf433_decoder.h b/project/example/ble/ble_peripheral/app/src/rf433_decoder.h new file mode 100644 index 0000000..377e4c2 --- /dev/null +++ b/project/example/ble/ble_peripheral/app/src/rf433_decoder.h @@ -0,0 +1,25 @@ +#ifndef __RF433_DECODER_H__ +#define __RF433_DECODER_H__ + +#include +#include + +#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 diff --git a/project/example/ble/ble_peripheral/app/src/rf433_decoder_port.h b/project/example/ble/ble_peripheral/app/src/rf433_decoder_port.h new file mode 100644 index 0000000..0012ddd --- /dev/null +++ b/project/example/ble/ble_peripheral/app/src/rf433_decoder_port.h @@ -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 diff --git a/project/example/ble/ble_peripheral/app/src/timeslice.c b/project/example/ble/ble_peripheral/app/src/timeslice.c index 90ffc9d..8404a4d 100644 --- a/project/example/ble/ble_peripheral/app/src/timeslice.c +++ b/project/example/ble/ble_peripheral/app/src/timeslice.c @@ -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}, }; /************************************************************************************** diff --git a/project/example/ble/ble_peripheral/mdk/ble_peripheral.uvprojx b/project/example/ble/ble_peripheral/mdk/ble_peripheral.uvprojx index a0082be..011f4f2 100644 --- a/project/example/ble/ble_peripheral/mdk/ble_peripheral.uvprojx +++ b/project/example/ble/ble_peripheral/mdk/ble_peripheral.uvprojx @@ -719,6 +719,21 @@ 1 ..\app\src\Rf433.c + + rf433_decoder.c + 1 + ..\app\src\rf433_decoder.c + + + rf433_decoder.h + 5 + ..\app\src\rf433_decoder.h + + + rf433_decoder_port.h + 5 + ..\app\src\rf433_decoder_port.h + PWM.c 1 @@ -1507,6 +1522,21 @@ 1 ..\app\src\Rf433.c + + rf433_decoder.c + 1 + ..\app\src\rf433_decoder.c + + + rf433_decoder.h + 5 + ..\app\src\rf433_decoder.h + + + rf433_decoder_port.h + 5 + ..\app\src\rf433_decoder_port.h + PWM.c 1