// 同步模块
// 杭州秒寻科技有限公司
// 周涛
// 2023-11-09

#include "includes.h"

// 模块全局变量
static SYNC_MANAGE_T gSync_stManage = {0};
const uint8 gSync_abySyncWord[6][8] = {{0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8}, {0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8}, {0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98}, {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58}, {0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x59, 0x58}, {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8}};

// 声明两个全局变量
extern const uint8_t g_cmt2310a_page0[CMT2310A_PAGE0_SIZE];
extern const uint8_t g_cmt2310a_page1[CMT2310A_PAGE1_SIZE];

// 模块初始化
uint8 sync_init()
{
    uint8 byFlag = 0;
    uint32 dwChipId = 0;

    // 初始化模块变量
    SYS_MEMSET(&gSync_stManage, 0, sizeof(SYNC_MANAGE_T));

    // 芯片软复位，芯片进入IDLE状态
    sync_soft_reset();

    // 配置page0寄存器
    sync_rewrite_reg_page(0, (uint8 *)g_cmt2310a_page0, CMT2310A_PAGE0_SIZE);

    // 配置page1寄存器
    sync_rewrite_reg_page(1, (uint8 *)g_cmt2310a_page1, CMT2310A_PAGE1_SIZE);

    // 配置TCXO
    sync_config_tcxo();

    // 芯片上电，并进入sleep状态
    sync_power_up();

    // 判断芯片ID是否正确
    dwChipId = sync_read_chip_id();
    if (dwChipId != SYNC_CHIP_ID)
    {
        return 0;
    }

    // 配置32兆晶振稳定时间
    byFlag = sync_config_oscillator_wait_time(0x40);
    if (!byFlag)
    {
        return 0;
    }

    // 配置芯片复位端口
    byFlag = sync_config_gpio5_rest();
    if (!byFlag)
    {
        return 0;
    }

    // IR校准
    byFlag = sync_ir_calibration();
    if (!byFlag)
    {
        return 0;
    }

    // 配置手动跳频模式
    byFlag = sync_manual_jump_freq_mode();
    if (!byFlag)
    {
        return 0;
    }

    byFlag = sync_config_rx_dout(); // 配置数据输出端口
    if (!byFlag)
    {
        return 0;
    }

    byFlag = sync_config_rx_int(); // 配置接收中断
    if (!byFlag)
    {
        return 0;
    }

    byFlag = sync_update_rssi_select(); // 收到SYNC_OK时更新rssi
    if (!byFlag)
    {
        return 0;
    }

    byFlag = sync_rx_exit_status(); // 接收完成后自动转入rfs状态
    if (!byFlag)
    {
        return 0;
    }

    byFlag = sync_rxtx_ready_receive_signal(); // 开启数据接收
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 选择寄存器页，支持page0,page1和page2
// byPage:寄存器页，取值0，1和2
void sync_select_reg_page(uint8 byPage)
{
    uint8 byData = 0;

    switch (byPage)
    {
    case 2:
        sync_wirte_reg(0x7E, 0x80);
        break;
    case 1:
        sync_wirte_reg(0x7E, 0x40);
        break;
    case 0:
    default:
        sync_wirte_reg(0x7E, 0x00);
        break;
    }

    return;
}

// 读寄存器
void sync_read_reg(uint8 byAddress, uint8 *pbyValue)
{
    driverapp_sync_read_byte(byAddress, pbyValue); // 读取寄存器原值
}

// 配置寄存器
//  byAddress:寄存器地址
//  byValue:新值
uint8 sync_wirte_reg(uint8 byAddress, uint8 byValue)
{
    // uint8 byOutValue = 0;
    driverapp_sync_write_byte(byAddress, byValue);

    // 检查数据是否写正确
    //  driver_delay_nxus(5);
    //  driverapp_sync_read_byte(byAddress, &byOutValue);
    //  if (byOutValue != byValue)
    //  {
    //  	return 0;
    //  }

    return 1;
}

// 重新配置寄存器值(需要先读出寄存器原值)
// byAddress:寄存器地址
// byValue:新值
// byMask:掩码
uint8 sync_rewrite_reg(uint8 byAddress, uint8 byValue, uint8 byMask)
{
    uint8 byRegValue = 0;
    uint8 byFlag = 0;

    sync_read_reg(byAddress, &byRegValue); // 读取寄存器原值
    byRegValue &= (~byMask);               // 保护本次不配置的位
    byRegValue |= byValue;                 // 重新组织新值

    byFlag = sync_wirte_reg(byAddress, byRegValue); // 写寄存器值
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 查询芯片工作状态
// byStatus:待查询的芯片状态
uint8 sync_get_work_status(uint8 byStatus)
{
    uint8 byChipStatus = 0;

    // 芯片切换状态最长不超过2毫秒
    for (uint16 i = 0; i < 1000; i++)
    {
        driver_delay_nxus(2);
        sync_read_reg(0x0A, &byChipStatus);
        if (byStatus == byChipStatus)
        {
            return 1; // 正确准状态
        }
    }

    return 0; // 错误状态
}

// 切换芯片工作状态
// byGoStatus:转换状态，包括SYNC_STATUS_GO_SLEEP,SYNC_STATUS_GO_READY,SYNC_STATUS_GO_TX,SYNC_STATUS_GO_RX,SYNC_STATUS_GO_TFS,SYNC_STATUS_GO_RFS
// byGetStatus:工作状态，包括SYNC_STATUS_IDLE,SYNC_STATUS_SLEEP,SYNC_STATUS_READY,SYNC_STATUS_RFS,SYNC_STATUS_TFS,SYNC_STATUS_RX,SYNC_STATUS_TX
// 返回值：0错误，1正确
uint8 sync_switch_work_status(uint8 byGoStatus, uint8 byGetStatus)
{
    uint8 byFlag = 0;

    // 对命令进行容错
    if (byGoStatus != SYNC_STATUS_GO_SLEEP && byGoStatus != SYNC_STATUS_GO_READY && byGoStatus != SYNC_STATUS_GO_TX && byGoStatus != SYNC_STATUS_GO_RX && byGoStatus != SYNC_STATUS_GO_TFS && byGoStatus != SYNC_STATUS_GO_RFS)
    {
        return 0;
    }

    // 对状态进行容错处理
    if (byGetStatus != SYNC_STATUS_IDLE && byGetStatus != SYNC_STATUS_SLEEP && byGetStatus != SYNC_STATUS_READY && byGetStatus != SYNC_STATUS_RFS && byGetStatus != SYNC_STATUS_TFS && byGetStatus != SYNC_STATUS_RX && byGetStatus != SYNC_STATUS_TX)
    {
        return 0;
    }

    sync_wirte_reg(0x01, byGoStatus);           // 切换状态命令,该寄存器只可写
    byFlag = sync_get_work_status(byGetStatus); // 查询芯片状态
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 配置API命令，提高RF抗干扰能力
// byApiCommand:命令
uint8 sync_config_api_command(uint8 byApiCommand)
{
    uint8 byData = 0;

    sync_wirte_reg(0x08, byApiCommand); // 执行API命令
    byApiCommand |= 0x80;

    // 延时1.5秒等待命令执行成功
    for (uint16 i = 0; i < 750; i++)
    {
        driver_delay_nxms(2); // 延时2毫秒
        sync_read_reg(0x09, &byData);
        if (byData == byApiCommand)
        {
            return 1;
        }
    }

    return 0;
}

// 配置电容值以校准中心频率
uint8 sync_config_cap_load(uint8 byCapValue)
{
    uint8 byFlag = 0;

    // 参数容错处理
    if (byCapValue < 0 || byCapValue > 31)
    {
        return 0;
    }

    sync_select_reg_page(1);
    byFlag = sync_rewrite_reg(0x06, byCapValue, 0x1F);
    if (!byFlag)
    {
        sync_select_reg_page(0);
        return 0;
    }

    sync_select_reg_page(0);

    return 1;
}

// 芯片软复位（复位之后，要延时20毫秒，等待芯片进入稳定状态）
void sync_soft_reset()
{
    sync_wirte_reg(0x7F, 0xFF); // 该寄存器可写不可读
    driver_delay_nxms(20);      // 延时20毫秒
}

// 配置一页寄存器
// byRegPage:寄存器页，取值0，1或2
// pbyData:数据指针
// wLen:数据长度
void sync_rewrite_reg_page(uint8 byRegPage, uint8 *pbyData, uint16 wLen)
{
    sync_select_reg_page(byRegPage);
    driverapp_sync_write_bytes(SYNC_BURST_WRITE_REG, pbyData, wLen);
    sync_select_reg_page(0);
}

// 读取芯片ID，以验证SPI接口
uint32 sync_read_chip_id()
{
    uint32 dwChipId = 0;
    uint8 byData = 0;

    sync_select_reg_page(2); // 选择寄存器page2

    // 高8位
    sync_read_reg(0x40, &byData);
    dwChipId = byData;
    dwChipId = dwChipId << 8;

    // 中间8位
    sync_read_reg(0x41, &byData);
    dwChipId = dwChipId | byData;
    dwChipId = dwChipId << 8;

    // 低8位
    sync_read_reg(0x42, &byData);
    dwChipId = dwChipId | byData;

    sync_select_reg_page(0); // 选择寄存器page0

    return dwChipId;
}

// 将GPIO端口配置为芯片复位端口
uint8 sync_config_gpio5_rest()
{
    // 将GPIO5配置为芯片复位端口
    uint8 byMask = 7 << 3;                       // 中间3位(3-5)
    return sync_rewrite_reg(0x06, 0x00, byMask); // 配置GPIO端口功能
}

// 配置32M晶振稳定时间(搞不懂设的是什么值)
uint8 sync_config_oscillator_wait_time(uint8 byValue)
{
    uint8 byMask = 3 << 6;
    return sync_rewrite_reg(0x07, byValue, byMask);
}

// 芯片上电，进入sleep状态
void sync_power_up(void)
{
    sync_wirte_reg(0x00, 0x03);
    driver_delay_nxms(10); // 延时10毫秒，以便芯片进入稳定状态
}

// 配置tcxo晶振
void sync_config_tcxo()
{
    uint8 byMask = 0x07 << 0;

    // 选择NIRQ的功能为tcxo
    sync_rewrite_reg(0x07, 0x04, byMask);

    // 配置tcxo驱动电流
    sync_select_reg_page(1);
    byMask = 0x03 << 6;
    sync_rewrite_reg(0x05, 0x00, byMask);
    sync_select_reg_page(0);

    return;
}

// IR校准，提升抗干扰能力
uint8 sync_ir_calibration()
{
    uint8 byFlag = 0;

    // 切换至ready状态
    byFlag = sync_switch_work_status(SYNC_STATUS_GO_READY, SYNC_STATUS_READY); // 切换至ready状态
    if (!byFlag)
    {
        return 0;
    }
    driver_delay_nxms(2); // 延时2毫秒
    byFlag = sync_config_api_command(0x02);
    if (!byFlag)
    {
        return 0;
    }
    driver_delay_nxms(10); // 延时
    byFlag = sync_config_api_command(0x01);
    if (!byFlag)
    {
        return 0;
    }

    // 校准中心频率
    byFlag = sync_config_cap_load(0x02);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 配置手动跳频模式
uint8 sync_manual_jump_freq_mode()
{
    uint8 byMask = 3 << 6;
    return sync_rewrite_reg(0x16, 0xC0, byMask);
}

// 配置接收输出端口
uint8 sync_config_rx_dout()
{
    uint8 byFlag = 0;

    // GPIO1选择DOUT功能
    uint8 byMask = 7 << 3;
    byFlag = sync_rewrite_reg(0x04, 0x18, byMask);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 配置接收中断
uint8 sync_config_rx_int()
{
    uint8 byFlag = 0;

    // GPIO0选择INT1功能
    uint8 byMask = 7 << 0;
    byFlag = sync_rewrite_reg(0x04, 0x01, byMask);
    if (!byFlag)
    {
        return 0;
    }

    // 配置INT1中断源
    byFlag = sync_wirte_reg(0x10, 0x04); // SYNC_PASS
    // byFlag = sync_wirte_reg(0x10, 0x08); // update by zt 2024-10-16(pkt_done)
    if (!byFlag)
    {
        return 0;
    }

    // 使能中断
    byFlag = sync_wirte_reg(0x12, 0x08); // SYNC_PASS中断
    // byFlag = sync_wirte_reg(0x12, 0x01); // pkt_done中断 update by zt 2024-10-16(pkt_done)
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 配置发送中断
uint8 sync_config_tx_int()
{
    uint8 byFlag = 0;

    // 将INT2映射到GPIO1
    uint8 byMask = 7 << 3;                         // 中间3位(3-5)
    byFlag = sync_rewrite_reg(0x04, 0x10, byMask); // 配置中断使用的GPIO端口
    if (!byFlag)
    {
        return 0;
    }

    // 配置int2的触发源为TX_DONE(发送完成)
    byFlag = sync_wirte_reg(0x11, 0x10);
    if (!byFlag)
    {
        return 0;
    }

    // 使能int2的TX_DONE中断
    byFlag = sync_wirte_reg(0x12, 0x20);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 实时更新RSSI，以便实时监测RSSI
uint8 sync_update_rssi_select()
{
    uint8 byFlag = 0;
    uint8 byMask = 0x02 << 2;

    sync_select_reg_page(1);
    byFlag = sync_rewrite_reg(0x62, 0x08, byMask); // 收到SYNC_PASS时更新RSSI
    if (!byFlag)
    {
        sync_select_reg_page(0);
        return 0;
    }
    sync_select_reg_page(0);

    return 1;
}

// 接收完成后自动切换至rfs状态
uint8 sync_rx_exit_status()
{
    uint8 byMask = 7 << 4;
    return sync_rewrite_reg(0x61, 0x50, byMask);
}

// 发送完成后自动切换至tfs状态
uint8 sync_tx_exit_status()
{
    uint8 byMask = 7 << 4;
    return sync_rewrite_reg(0x60, 0x30, byMask);
}

// 发送数据前-预处理
uint8 sync_pre_send_data()
{
    uint8 byFlag = 0;

    // go sleep
    byFlag = sync_switch_work_status(SYNC_STATUS_GO_SLEEP, SYNC_STATUS_SLEEP);
    if (!byFlag)
    {
        return 0;
    }

    // go ready
    byFlag = sync_switch_work_status(SYNC_STATUS_GO_READY, SYNC_STATUS_READY);
    if (!byFlag)
    {
        return 0;
    }

    // go tfs
    byFlag = sync_switch_work_status(SYNC_STATUS_GO_TFS, SYNC_STATUS_TFS);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

// 查询接收电平值
// 注意：如果读出来的值高位不为1，则读出来的数据即为电平值，否则减去256后才是电平值
void sync_read_rssi()
{
    int16 wRssiValue = 0;
    uint8 byRegValue = 0; // 寄存器原始值
    int16 wAverageRssi = 0;

    // 读取RSSI值
    sync_read_reg(0x22, &byRegValue);
    if ((byRegValue & 0x80) > 0)
    {
        wRssiValue = byRegValue - 256;
    }
    else
    {
        wRssiValue = byRegValue;
    }

    // 统计三次rssi的均值
    gSync_stManage.awRssiValue[gSync_stManage.byCounter] = wRssiValue;
    gSync_stManage.byCounter++;
    if (gSync_stManage.byCounter >= SYNC_RSSI_COUNT_TIMES)
    {
        gSync_stManage.byCounter = 0;
        for (uint8 i = 0; i < SYNC_RSSI_COUNT_TIMES; i++)
        {
            wAverageRssi += gSync_stManage.awRssiValue[i];
        }

        wAverageRssi /= SYNC_RSSI_COUNT_TIMES;
        gSync_stManage.wRssiValue = wAverageRssi;
    }

    return;
}

// 查询rssi电平值
int16 sync_query_rssi()
{
    return gSync_stManage.wRssiValue;
}

// 配置同步字
// pbyData:同步字，8字节
uint8 sync_set_rx_sync_word(uint8 byData)
{
    uint8 byFlag = 0;
    uint8 bySyncRegAddress = 0x34; //
    uint8 byIndex = 0;
    uint8 *pbySyncWordList = NULL;

    // 默认值
    if (byData == 0xFF || byData > SYS_SYNC_WORD_MAX_ID)
    {
        byData = 1;
    }

    // 容错处理
    if (byData < 1 || byData > SYS_SYNC_WORD_MAX_ID)
    {
        return 0;
    }
    byIndex = byData - 1;
    pbySyncWordList = gSync_abySyncWord[byIndex];

    // go sleep
    byFlag = sync_switch_work_status(SYNC_STATUS_GO_SLEEP, SYNC_STATUS_SLEEP);
    if (!byFlag)
    {
        return 0;
    }

    // go ready
    byFlag = sync_switch_work_status(SYNC_STATUS_GO_READY, SYNC_STATUS_READY);
    if (!byFlag)
    {
        return 0;
    }

    // 从低位到高位配置同步字即存在
    for (uint8 i = 0; i < 8; i++)
    {
        sync_wirte_reg(bySyncRegAddress, pbySyncWordList[i]);
        bySyncRegAddress--;
    }

    return 1;
}

// 配置同步接收模块参数
// byCarrierId:频点ID，0-250
// byFreqSpace:频点间隔，单位khz，，最小值50K，最大250，默认间隔选250kHz
// byRxSyncWordIndex:接收同步字
uint8 sync_set_rx_init_param(uint8 byCarrierId, uint8 byFreqSpace, uint8 byRxSyncWordIndex)
{
    uint8 byFlag = 0;

    // 配置接收频率
    byFlag = sync_freq_config_carrier_freq(byCarrierId, byFreqSpace);
    if (!byFlag)
    {
        return byFlag;
    }

    // 配置接收同步字
    byFlag = sync_set_rx_sync_word(byRxSyncWordIndex);
    if (!byFlag)
    {
        return byFlag;
    }

    return 1;
}