#include "cycle_task.h"
#include "riu_common.h"
#include <stdio.h>
#include <string.h>

// ڲ״̬
static unsigned int s_last_heartbeat = 0;       // һЧֵ
static unsigned char s_timeout_cnt = 0;         // ʱ
static unsigned char s_timeout_flag = 0;        // ʱ״̬־
static unsigned short s_last_valid_volt = 0;    // һЧѹ
static unsigned char s_last_valid_cmd = 0;      // һЧָ

// ȡӦλϢID
static void GetMsgID(unsigned int *cmd_id, unsigned int *data1_id)
{
    switch(g_riu_pos_no)
    {
        case 1: *cmd_id = 0x0125; *data1_id = 0x1400; break;
        case 2: *cmd_id = 0x4125; *data1_id = 0x5400; break;
        case 3: *cmd_id = 0x8125; *data1_id = 0x9400; break;
        case 4: *cmd_id = 0x4126; *data1_id = 0x5480; break;
        default: *cmd_id = 0; *data1_id = 0; break;
    }
}

// 1394߳ʼ
void Bus_Init(void)
{
    unsigned int ret = 0;
//    printf("ʼ1394߳ʼ...\r\n");

    while(1)
    {
        // RIU ID
        setRIUID(g_bus_set_val);
        // ʼ
        ret = init2KRN(0, 0x1C0000, 1);

        if(ret == 0)
        {
//            printf("1394߳ʼ\r\n");
            break;
        }
        else
        {
//            printf("1394߳ʼʧܣ...\r\n");
        }
    }

    // ʼݰ
    memset(g_cmd_buf, 0, sizeof(g_cmd_buf));
    memset(g_data1_buf, 0, sizeof(g_data1_buf));
    s_last_heartbeat = 0;
    s_timeout_cnt = 0;
    s_timeout_flag = 0;
    g_analog_output_volt = 0.0f;
}

// ģɼ
static void AnalogCollect(void)
{
    unsigned short raw1, raw2;
    float volt1, volt2;

#if SIMULATOR_MODE
    raw1 = sim_adc_ch1;
    raw2 = sim_adc_ch2;
#else
    // ʵӲַָȡֵ
    raw1 = *(unsigned short *)0x145301;
    raw2 = *(unsigned short *)0x145311;
#endif

    // ʽʵʵѹ
    volt1 = raw1 * 20.0f / 65535.0f / 0.8f;
    volt2 = raw2 * 20.0f / 65535.0f / 0.8f;

    // DATA116λͨ116λͨ2ѹ100ϱ
    g_data1_buf[77] = ((unsigned short)(volt1 * 100) << 16) | (unsigned short)(volt2 * 100);
}

// ģ
static void AnalogOutput(void)
{
    unsigned LONG cmd_word = g_cmd_buf[10];
    unsigned char cmd_valid = (cmd_word >> 31) & 0x01;
    unsigned char cmd_out = (cmd_word >> 30) & 0x01;
    unsigned short cmd_volt = cmd_word & 0xFFFF;

    // 6ִ߼
    if(cmd_valid == 1)
    {
        if(cmd_out == 1)
        {
            // ָѹ10V޷
            g_analog_output_volt = (cmd_volt > 10) ? 10.0f : (float)cmd_volt;
        }
        else
        {
            // 0V
            g_analog_output_volt = 0.0f;
        }
        // һЧָ
        s_last_valid_volt = cmd_volt;
        s_last_valid_cmd = cmd_out;
    }
    // ָЧ򱣳ԭ
}

// 
static unsigned char HeartbeatCheck(void)
{
    unsigned int cur_heartbeat = g_cmd_buf[8];

    // и
    if(cur_heartbeat != s_last_heartbeat)
    {
        // ӳʱ״ָ̬
        if(s_timeout_flag == 1)
        {
//            printf("CMDָͨ\r\n");
            s_timeout_flag = 0;
        }
        s_last_heartbeat = cur_heartbeat;
        s_timeout_cnt = 0;
        return 1; // Ч
    }
    // ޸
    else
    {
        s_timeout_cnt++;
        // ﵽ180msʱֵ
        if(s_timeout_cnt >= HEARTBEAT_TIMEOUT && s_timeout_flag == 0)
        {
//            printf("棺CMDʱѳ180msδ\r\n");
            s_timeout_flag = 1;
        }
        return 0; // Ч
    }
}

// װDATA1ݰ
static void Data1PackAndSend(void)
{
    unsigned int cmd_id, data1_id;
    GetMsgID(&cmd_id, &data1_id);

    // 
    g_data1_buf[8]++;

    // BITԽ
    g_data1_buf[22] = 0;
    if(g_cpu_bit_result) g_data1_buf[22] |= (1 << 28);
    if(g_ram_bit_result) g_data1_buf[22] |= (1 << 29);

    // ݰ
    sendAsyStream(0, data1_id, g_data1_buf);
}

// 
void CycleTask_Run(void)
{
    unsigned int cmd_id, data1_id;
    unsigned int ret;

    GetMsgID(&cmd_id, &data1_id);

    // 1. CMDݰ
    ret = receiveAsyStream(0, cmd_id, g_cmd_buf);
    if(ret != 0)
    {
//        printf("CMDݰʧ\r\n");
        return;
    }

    // 2. ⣬ЧݲӦָ
    if(HeartbeatCheck() == 0)
    {
        // ޸£ִָ
    }
    else
    {
        // 3. Чָִģ
        AnalogOutput();
    }

    // 4. ģɼ
    AnalogCollect();

    // 5. ϱDATA1
    Data1PackAndSend();
}
