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

#include "includes.h"

// 声明两个全局变量
extern const uint8_t g_cmt2310a_page0[CMT2310A_PAGE0_SIZE];
extern const uint8_t g_cmt2310a_page1[CMT2310A_PAGE1_SIZE];
extern const uint8 gSync_abySyncWord[4][8]; // 同步字
extern uint8 gSynctx_abySendData[2];

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

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

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

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

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

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

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

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

    // 配置TCXO
    synctx_config_tcxo();

    // IR校准
    driver_delay_nxms(200);
    byFlag = synctx_ir_calibration();
    if (!byFlag)
    {
        return 0;
    }

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

    // 配置发送中断
    byFlag = synctx_config_tx_int();
    if (!byFlag)
    {
        return 0;
    }

    // 发送完成自动转入tfs状态
    byFlag = synctx_tx_exit_status();
    if (!byFlag)
    {
        return 0;
    }

    // // 预发送数据，将状态切换至tfs状态
    // byFlag = synctx_pre_send_data();
    // if (!byFlag)
    // {
    //     return 0;
    // }

    // 收发模块初化
    synctx_rxtx_init();

    return 1;
}

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

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

    return;
}

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

// 配置寄存器
//  byAddress:寄存器地址
//  byValue:新值
uint8 synctx_wirte_reg(uint8 byAddress, uint8 byValue)
{
    driverapp_synctx_write_byte(byAddress, byValue);

    return 1;
}

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

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

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

    return 1;
}

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

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

    return byFlag; // 状态
}

// 切换芯片工作状态
// 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 synctx_switch_work_status(uint8 byGoStatus, uint8 byGetStatus)
{
    uint8 byFlag = 0;

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

    return 1;
}

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

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

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

    return 0;
}

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

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

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

    synctx_select_reg_page(0);

    return 1;
}

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

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

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

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

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

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

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

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

    return dwChipId;
}

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

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

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

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

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

    return;
}

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

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

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

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

    return 1;
}

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

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

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

    return 1;
}

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

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

    // 配置INT1中断源为SYNC_PASS
    byFlag = synctx_wirte_reg(0x10, 0x04);
    if (!byFlag)
    {
        return 0;
    }

    // 使能SYNC_PASS中断
    byFlag = synctx_wirte_reg(0x12, 0x08);
    if (!byFlag)
    {
        return 0;
    }

    return 1;
}

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

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

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

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

    return 1;
}

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

    synctx_select_reg_page(1);
    byFlag = synctx_rewrite_reg(0x62, 0x0C, byMask); // 收到PKT_DONE时更新RSSI
    if (!byFlag)
    {
        synctx_select_reg_page(0);
        return 0;
    }
    synctx_select_reg_page(0);

    return 1;
}

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

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

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

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

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

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

    // 清空tx fifo
    synctx_rxtx_clear_tx_fifo();

    // 将数据写入tx fifo
    driverapp_synctx_write_bytes(SYNC_BURST_WRITE_FIFO, (uint8 *)gSynctx_abySendData, 0x02);

    return 1;
}

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

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

    return wRssiValue;
}

// 配置同步字
// pbyData:同步字编号
uint8 synctx_set_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 = synctx_switch_work_status(SYNC_STATUS_GO_SLEEP, SYNC_STATUS_SLEEP);
    if (!byFlag)
    {
        return 0;
    }

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

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

    return 1;
}

// 初始化阶段配置发射参数
// byCarrierId:频点ID，0-250
// byFreqSpace:频点间隔，单位khz，，最小值50K，最大250，默认间隔选250kHz
// biTxSyncWordId:同步字编号
// byTxPower:发射功率
uint8 synctx_set_tx_init_param(uint8 byCarrierId, uint8 byFreqSpace, uint8 biTxSyncWordId, int8 byTxPower)
{
    uint8 byFlag = 0;

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

    // 配置发射同步字
    byFlag = synctx_set_sync_word(biTxSyncWordId);
    if (!byFlag)
    {
        return byFlag;
    }

    // 配置发射功率
    synctx_power_config_tx_power(byTxPower);

    return 1;
}
