void TcbdUpdateStatus(I08U *_rawData, TcbdDiagnosis_t *_diagInfo)
{
    TcbdStatusInfo_t *oldStatus, *currStatus;
    TcbdDiagnosis_t *diagInfo;// = (_diagInfo) ? _diagInfo: &Diagnosis.diagInfo;

    if(!_rawData && !_diagInfo) return;

    if(_rawData == NULL) 
    {
        TcpalMemoryCopy(_diagInfo, &Diagnosis.diagInfo, sizeof(TcbdDiagnosis_t));
        return;
    }

    diagInfo   = (_diagInfo) ? _diagInfo: &Diagnosis.diagInfo;
    oldStatus  = &Diagnosis.oldStatus;
    currStatus = &Diagnosis.currStatus;
    TcpalMemoryCopy(oldStatus, currStatus, sizeof(TcbdStatusInfo_t));

    currStatus->rfLoopGain = _rawData[OFFSET_RF_LOOP_GAIN];
    currStatus->bbLoopGain = _rawData[OFFSET_BB_LOOP_GAIN];

    currStatus->prsSnr    = *((I32U*)(_rawData+OFFSET_PRS_SNR));
    currStatus->pcber     = *((I32U*)(_rawData+OFFSET_PCBER));

    currStatus->rsPktCnt  = *((I32U*)(_rawData+OFFSET_RS_PKT_CNT));
    currStatus->rsOverCnt = *((I32U*)(_rawData+OFFSET_RS_OVER_CNT));
    currStatus->rsErrCnt  = *((I64U*)(_rawData+OFFSET_RS_ERR_CNT_LO));
    currStatus->rsErrCnt |=(*((I64U*)(_rawData+OFFSET_RS_ERR_CNT_HI))) <<32;

    //TcbdDebug(1, "RFGain:%d, BBGain:%d pcber:%d\n", 
    //    currStatus->rfLoopGain, currStatus->bbLoopGain, currStatus->pcber);

    if(currStatus->rsPktCnt != oldStatus->rsPktCnt)
    {
        Diagnosis.resynced = 0;
        if(currStatus->rsPktCnt == 0 && oldStatus->rsPktCnt)
        {
            Diagnosis.resynced = 1;
        }
    }
    else if(currStatus->rsPktCnt < oldStatus->rsPktCnt)
    {
        if(oldStatus->rsPktCnt < 0x80000000)
        {
            Diagnosis.resynced = 1;
        }
    }

    TcbdCalcSnr(diagInfo);
    TcbdCalcPcber(diagInfo);
    TcbdCalcViterbiber(diagInfo);
    TcbdCalcTsper(diagInfo);
    TcbdCalcRssi(diagInfo);
    
    diagInfo->lock = *((I08U*)_rawData);
    if(Diagnosis.resynced)
        TcpalMemorySet(MovingAvg, 0, sizeof(MovingAvg));
}
static I32S TcbdParseBootBin(I08U* _data, I32U _size, TcbdBootBin_t *_bootBin)
{
    I32U idx = 0;
    I32U length;
    I32S tableIdx = 0;

    //coldboot      0x00000001
    //dagu          0x00000002
    //dint          0x00000003
    //rand          0x00000004
    //col_order: 0x00000005

    //sizebyte      4byte
    //data          nbyte

    TcpalMemorySet(_bootBin, 0, sizeof(TcbdBootBin_t)*MAX_BOOT_TABLE);

    // cold boot
    if (_data[idx + 3] != 0x01)
    {
        TcbdDebug(DEBUG_ERROR, "# Coldboot_preset_Error\n");
        return 0;
    }
    idx += 4;
    length = (_data[idx] << 24) + (_data[idx + 1] << 16) + (_data[idx + 2] << 8) + (_data[idx + 3]);
    idx += 4;
    _bootBin[tableIdx].addr = CODE_MEM_BASE;
    _bootBin[tableIdx].data = _data + idx;
    _bootBin[tableIdx].crc = *((I32U*)(_data+idx + length-4));
    _bootBin[tableIdx++].size = length - 4;
    idx += length;
    _size -= (length + 8);

    // dagu
    if (_data[idx + 3] != 0x02)
    {
        TcbdDebug(DEBUG_ERROR, "# Coldboot_preset_Error\n");
        return 0;
    }
    idx += 4;
    length = (_data[idx] << 24) + (_data[idx + 1] << 16) + (_data[idx + 2] << 8) + (_data[idx + 3]);
    idx += 4;
    _bootBin[tableIdx].addr = CODE_TABLEBASE_DAGU;
    _bootBin[tableIdx].data = _data + idx;
    _bootBin[tableIdx++].size = length;
    idx += length;
    _size -= (length + 8);

    // dint
    if (_data[idx + 3] != 0x03)
    {
        TcbdDebug(DEBUG_ERROR, "# Coldboot_preset_Error\n");
        return 0;
    }
    idx += 4;
    length = (_data[idx] << 24) + (_data[idx + 1] << 16) + (_data[idx + 2] << 8) + (_data[idx + 3]);
    idx += 4;
    _bootBin[tableIdx].addr = CODE_TABLEBASE_DINT;
    _bootBin[tableIdx].data = _data + idx;
    _bootBin[tableIdx++].size = length;
    idx += length;
    _size -= (length + 8);

    // rand
    if (_data[idx + 3] != 0x04)
    {
        TcbdDebug(DEBUG_ERROR, "# Coldboot_preset_Error\n");
        return 0;
    }

    idx += 4;
    length = (_data[idx] << 24) + (_data[idx + 1] << 16) + (_data[idx + 2] << 8) + (_data[idx + 3]);
    idx += 4;
    _bootBin[tableIdx].addr = CODE_TABLEBASE_RAND;
    _bootBin[tableIdx].data = _data + idx;
    _bootBin[tableIdx++].size = length;
    idx += length;
    _size -= (length + 8);

    if (_size >= 8) /* cmmb */
    {
        // col_order
        if (_data[idx + 3] != 0x05)
        {
            TcbdDebug(DEBUG_ERROR, "# Coldboot_preset_Error\n");
            return 0;
        }
        idx += 4;
        length = (_data[idx] << 24) + (_data[idx + 1] << 16) + (_data[idx + 2] << 8) + (_data[idx + 3]);
        idx += 4;

        _bootBin[tableIdx].addr = CODE_TABLEBASE_COL_ORDER;
        _bootBin[tableIdx].data = _data + idx;
        _bootBin[tableIdx++].size = length;
        idx += length;
        _size -= (length + 8);
    }

    //TcbdDebug(DEBUG_API_COMMON, " # remain size :%d \n", _size);

    return tableIdx;
}
void TcbdInitDiagnosis(void)
{
    TcpalMemorySet(&Diagnosis, 0, sizeof(Diagnosis));
    TcpalMemorySet(MovingAvg, 0, sizeof(MovingAvg));
}