#include "SIF.h"
#include "common.h"


#define DATA_REV_PIN    gpio_get(SIF_REV_PIN)

#ifdef _SIF_DEBUG_
    char log_str[128] = { 0 };
#endif

typedef enum {
    INITIAL_STATE = 0,          // 初始状态,等待接收同步信号
    SYNC_L_STATE = 1,           // 接收同步低电平信号状态
    SYNC_H_STATE = 2,           // 接收同步高电平信号状态
    DATA_REV_STATE = 3,         // 读取数据码电平状态
    END_SIGNAL_STATE = 4,       // 接收结束电平信号状态
    RESTART_REV_STATE = 5       // 接收过程出错重新接收状态
} REV_STATE_e;                  // 接收数据状态枚举

unsigned char receive_state = 0;    // 接收数据状态
unsigned char receive_bit_num = 0;  // 接收的bit位个数
unsigned char receive_data_num = 0; // 接收的数据个数

unsigned char sif_receive_data_buf[REV_DATA_NUM] = { 0 };   // 接收数据缓存数组如果一帧数据有多个数据打开注释
unsigned char sif_receive_data[REV_DATA_NUM] = { 0 };
unsigned int H_L_Level_time_cnt = 0;                        // 高低电平时间计数

unsigned int Tosc = TOSC;   // 波形时基单元，一般带波特率自适应的，不会说明高低电平的时间，会用一个Tosc时基描述

uint8_t start_H_L_Level_timming_flag = 0;   // 开始高低电平计时标记
uint8_t has_read_bit = 0;                   // 1-已经读取一个bit位
uint8_t read_success = 0;                   // 一帧数据是否读取成功，0-不成功，1-成功 
uint8_t is_end_bit = 0;                     // 结束帧判定 0-未结束,1-结束标志


void GPIO_SIF_Init(void) {
    // 初始化 GPIO
    gpio_init(SIF_REV_PIN);
    
    // 将 GPIO 设置为输入模式
    gpio_set_dir(SIF_REV_PIN, GPIO_IN);
    
    // 启用下拉模式
    gpio_pull_down(SIF_REV_PIN);
}


void TIMER_SIF_IRQHandler(void)
{
    if (start_H_L_Level_timming_flag == 1) {
        H_L_Level_time_cnt++;   // 高低电平维持时间计数变量
    }

    Receive_SIF_Data_Handle();  // 接收数据处理，波特率自适应

}

void Receive_SIF_Data_Handle(void)
{
    switch (receive_state)          // 检测当前接收数据状态
    {
    case INITIAL_STATE:             // 初始状态，未接收到同步信息，进行同步判断
        if (DATA_REV_PIN == LOW)    // 判断接收引脚的电平状态,当读到低电平时,开始计时
        {
            receive_bit_num = REV_BIT_NUM;      // 重置bit位计数器
            receive_data_num = 0;               // 重置接收数据个数
            H_L_Level_time_cnt = 0;             // 高低电平计时变量清0
            read_success = 0;                   // 结束位置低电平判定清零
            start_H_L_Level_timming_flag = 1;   // 开始高低电平计时
            is_end_bit = 0;
            receive_state = SYNC_L_STATE;       // 进入读取同步低电平信号状态  
            memset(sif_receive_data_buf, 0, 16);
        }
        break;

    case SYNC_L_STATE:                                  // 在读取同步低电平信号期间
        if (H_L_Level_time_cnt > SYNC_TIME_NUM * Tosc)  // 如果低电平时间 > SYNC_TIME_NUM*Tosc=992*3*5us
        {                                               // 同步状态空闲时间大于15ms
            if (DATA_REV_PIN == HIGH)                   // 判断接收引脚的电平状态，当读到高电平时
            {
                H_L_Level_time_cnt = 0;                 // 高低电平计时变量清0
                receive_state = SYNC_H_STATE;           // 进入读取同步信号高电平状态
            }
        } else {
            if (DATA_REV_PIN == HIGH)                   // 同步信号低电平检测期间读到高电平重新计时
            {
                receive_state = RESTART_REV_STATE;      // 进入重新接收状态
            }
        }
        break;

    case SYNC_H_STATE:                                      // 在读取同步高电平信号期间 
        if (H_L_Level_time_cnt >= LOGIC_CYCLE_NUM * Tosc)   // 如果高电平时间超过了（32+64=96）个Tosc，则认为超时
        {
            receive_state = RESTART_REV_STATE;              // 进入重新接收状态
        } else {
            if (DATA_REV_PIN == LOW)                        // 同步信号高电平检测期间读到低电平
            {
                Tosc = H_L_Level_time_cnt / SHORT_TIME_NUM;     // 调整 Tosc 的值
                H_L_Level_time_cnt = 0;                         // 高低电平计时变量清0
                receive_state = DATA_REV_STATE;                 // 进入读取数据码低电平状态 
            }
        }
        break;

    case DATA_REV_STATE:       // 在读取数据码电平期间  
        if ((has_read_bit == 0) && (H_L_Level_time_cnt >= (HALF_LOGIC_CYCLE * Tosc))) {
            sif_receive_data_buf[receive_data_num] |= DATA_REV_PIN;
            has_read_bit = 1;
        }
        // 如果已经读取一个bit位，且时间计数已经>=96Tosc，说明一个逻辑周期过去了  
        if ((has_read_bit == 1) && (H_L_Level_time_cnt >= (LOGIC_CYCLE_NUM * Tosc))) {
            H_L_Level_time_cnt = 0; // 高低电平计时变量清0  
            has_read_bit = 0;   // 清0，读取下一个bit位
            receive_bit_num--;  // 接收的bit数-- 
            if (receive_bit_num == 0) // 如果一个字节8个bit位接收完成
            {
                receive_data_num++; // 接收的数据个数++
                receive_bit_num = REV_BIT_NUM; // 重置接收bit位个数 

                if (receive_data_num >= REV_DATA_NUM) // 如果数据采集完毕 超出了最大值
                {
                    start_H_L_Level_timming_flag = 0; // 停止高低电平计时
                    H_L_Level_time_cnt = 0; // 定时器计数值清0
                    receive_state = INITIAL_STATE; // 接收状态清0   
                }
            } else              // 如果一个字节8个bit位还没有接收完成
            {
                // 将接收数据缓存左移一位，数据从高bit位开始接收
                sif_receive_data_buf[receive_data_num] = sif_receive_data_buf[receive_data_num] << 1;

            }
        }
        // 记录 结束标志
        if (H_L_Level_time_cnt == (END_SIGNAL_FLAG_NUM * Tosc) && (DATA_REV_PIN == LOW)) {
            is_end_bit = 1;
            has_read_bit = 0;
            read_success = 1;   // 一帧数据读取成功  
#ifdef _SIF_DEBUG_
            sprintf(log_str, "rn:%d,%s.", receive_data_num, sif_receive_data_buf);
#endif
            Check_Sum_Handle();
            start_H_L_Level_timming_flag = 0; // 停止高低电平计时
            H_L_Level_time_cnt = 0; // 定时器计数值清0  
            receive_state = INITIAL_STATE; // 接收状态清0      
        }

        break;

    case END_SIGNAL_STATE:     // 在接收结束信号低电平期间 
        if (DATA_REV_PIN == LOW) {
            if (H_L_Level_time_cnt >= END_SIGNAL_TIME_NUM * Tosc) // 如果读到低电平时间>=5ms
            {
                read_success = 1; // 一帧数据读取成功 
                Check_Sum_Handle();
                start_H_L_Level_timming_flag = 0; // 停止高低电平计时
                H_L_Level_time_cnt = 0; // 定时器计数值清0
                receive_state = INITIAL_STATE; // 接收状态清0  
            }
        } else                  // 结束信号低电平检测期间一直为低
        {
            //if (H_L_Level_time_cnt >= SYNC_L_TIME_NUM)  // 如果读到低电平时间>=10ms，认为超时
            {                   // 一帧数据发送完成后需要间隔50ms才发送第二帧数据，期间肯定会被拉高
                receive_state = RESTART_REV_STATE; // 进入重新接收状态
            }
        }
        break;
    case RESTART_REV_STATE:    // 重新接收数据状态
        start_H_L_Level_timming_flag = 0; // 停止高低电平计时
        H_L_Level_time_cnt = 0; // 定时器计数值清0
        is_end_bit = 0;
        receive_state = INITIAL_STATE; // 接收状态清0        
        break;
    }
}

unsigned char *pGetSIFData(void) // 获取SIF数据
{
    return sif_receive_data;
}

#ifdef _SIF_DEBUG_
char *pGetLogStr(void)          // 获取SIF数据
{
    return log_str;
}
#endif

void Check_Sum_Handle()
{
    if (read_success == 1)      // 如果成功读取一帧数据
    {
        // 一帧数据接收成功后先根据协议要求进行校验和，验证数据的正确性 
        // 如果数据正确，根据接收的数据进行分析获取需要的内容 
        //if (check_OK)
        {
            memset(sif_receive_data, 0, REV_DATA_NUM);
            memcpy(sif_receive_data, sif_receive_data_buf, REV_DATA_NUM);
            memset(sif_receive_data_buf, 0, REV_DATA_NUM);
        }

        read_success = 0;       // 读取一帧数据清0 
    }
}


void SIF(void *p)
{
    (void)p;
    
    GPIO_SIF_Init();
    while (1)
    {
        char *SIF_DATA = (char *)pGetSIFData();
        
        printf("%s", SIF_DATA);
        vTaskDelay(pdMS_TO_TICKS(3000)); // 非阻塞延时
    }
    
    return ; 
}
