📄 dvb_upd.c
字号:
/*************************************************************************
(C)Copyright Cheertek Inc. 2002-2004,
D700, all right reserved.
Product : STB Firmware
*************************************************************************/
/*
* The purpose of this program is to transfer the UPD file with Xmodem/Xmodem 1K protocol to client STB.
* UPD file format, |Header|Length|Data|MPEG_CRC32|
* Header 8 characters This string must be match with original software in STB.
* Length 4 bytes This is start from "Data" to MPEG CRC32.
* Data N bytes The software program. The extension file name is ".BIN".
* MPEG CRC32 4 bytes This is calculated from "Header" to "Data".
*
*/
#include <stdio.h>
#include <string.h>
#include "malloc.h"
#include "ct_irq.h"
#include "ct_type.h"
#include "ct_sys.h"
#include "ct_uart.h"
#include "ct_drammap.h"
#include "db_api.h"
#include "dvb_av.h"
#include "dvb_flash.h"
#include "dvb_fp.h"
#include "dvb_sys.h"
#include "dvb_upd.h"
#include "xmodem.h"
#include "mpegcrc32.h"
#include "ap_defs.h"
#if 1
#define DVBUPD_MSG(p)
#else
#define DVBUPD_MSG(p) printf p
#endif
#if 1
#define DVBUPD_DBG(p)
#else
#define DVBUPD_DBG(p) printf p
#endif
/************************************************************************
* Definitions.
************************************************************************/
//#define UPD_DEBUG
#define UPD_TOTAL_READ_BANK 17
#define UPD_TOTAL_FLASH_BANK 30
#define HEAD_INFO_LEN (HEADER_LEN + 4) /* bytes of Header + Length */
#define TAIL_INFO_LEN (4) /* bytes of MPEG CRC32 */
#define BOX_INFO_LEN (16) /* bytes of STB version info */
/************************************************************************
* Globle Var.
************************************************************************/
static u8 *m_pu8FlashAddr = NULL;
static u8 m_au8Header[HEAD_INFO_LEN];
bool8 b8Update2PC = FALSE; //TRUE: update to PC, FALSE: update to STB
EN_UPDATE_DATA_TYPE_T enUpdateType = EN_UPDATE_CODE_ONLY; //EN_UPDATE_CODE_ONLY;
//Added by Atony 2007.8.7 , suit for releasing obj only
#ifdef UPD_CODE_BANK_TOTALITY
static u8 u8CodeBankTotality = UPD_CODE_BANK_TOTALITY ;
#else
static u8 u8CodeBankTotality = UPD_TOTAL_READ_BANK ;
#endif
#ifdef CODE_SEGMENT_START_BANK
static u8 u8CodeStartBankNum = CODE_SEGMENT_START_BANK ;
#else
static u8 u8CodeStartBankNum = 1 ;
#endif
u8 DVB_UpdSetCodeBankTotality(u8 banks)
{
return u8CodeBankTotality=banks ;
}
u8 DVB_UpdGetCodeBankTotality(void)
{
return u8CodeBankTotality ;
}
u8 DVB_UpdSetCodeStartBank(u8 startBank)
{
return u8CodeStartBankNum=startBank ;
}
u8 DVB_UpdGetCodeStartBank(void)
{
return u8CodeStartBankNum ;
}
/************************************************************************
* Set current update type.
************************************************************************/
void DVB_UpdSetUpdateType(EN_UPDATE_DATA_TYPE_T enUpdType)
{
enUpdateType = enUpdType;
} /* end DVB_UpdSetUpdateType */
/************************************************************************
* Get current update type.
************************************************************************/
EN_UPDATE_DATA_TYPE_T DVB_UpdGetUpdateType(void)
{
return (enUpdateType);
} /* end DVB_UpdGetUpdateType */
/************************************************************************
* Set server updating to PC or STB.
************************************************************************/
void DVB_UpdSetServer2PC(bool8 b8Enable)
{
/*
* TRUE: update to PC, check CRC16 or checksum for each packet,
* FALSE: update to STB, doesn't check packet.
*/
b8Update2PC = b8Enable;
} /* end DVB_UpdSetServer2PC */
/************************************************************************
* Get current state which is updating to STB or PC.
************************************************************************/
bool8 DVB_UpdGetServer2PCState(void)
{
return (b8Update2PC);
} /* end DVB_UpdGetServer2PCState */
/************************************************************************
* Upload Bin Image. (Marlin 20060523 modify)
************************************************************************/
static void upload_getdata(u8 *pu8buffer, u32 offset, u32 u32Length, u32 u32TotalLen)
{
u32 u32Crc;
bool8 b8LastPacket = FALSE;
#ifdef UPD_DEBUG
// For testing - start
u8 msg[20];
DVB_OSDRectangle(10, 10, 500, 30, 219);
sprintf(msg, "Offset=%ld, Length=%ld", offset, u32Length);
AP_OSDTextUniCodeByu8String(0, 10, 10, msg);
// For testing - end
#endif
if(offset + u32Length >= u32TotalLen) // Last Packet.
{
u32Length -= (TAIL_INFO_LEN + BOX_INFO_LEN);
b8LastPacket = TRUE;
}
if(offset == 0) // First Packet.
{
CRC_MPEG32_Start();
memcpy(pu8buffer, m_au8Header, HEAD_INFO_LEN);
DVB_FlashReadData((u32)m_pu8FlashAddr, &pu8buffer[HEAD_INFO_LEN], u32Length - HEAD_INFO_LEN);
CRC_MPEG32_AddData(pu8buffer, u32Length);
}
else
{
DVB_FlashReadData((u32)m_pu8FlashAddr + offset - HEAD_INFO_LEN, pu8buffer, u32Length);
CRC_MPEG32_AddData(pu8buffer, u32Length);
}
if(b8LastPacket == TRUE)
{
u32Crc = CRC_MPEG32_GetCRC();
pu8buffer[u32Length+0] = (u8)((u32Crc & 0xFF000000) >> 24);
pu8buffer[u32Length+1] = (u8)((u32Crc & 0x00FF0000) >> 16);
pu8buffer[u32Length+2] = (u8)((u32Crc & 0x0000FF00) >> 8);
pu8buffer[u32Length+3] = (u8)((u32Crc & 0x000000FF) );
XModemGetBoxInfo(&pu8buffer[u32Length+4]);
}
}
static u32 upload_progress(u32 sentbytes, u32 totalbytes)
{
#ifdef UPD_DEBUG
// For testing - start
u8 msg[20];
sprintf(msg, "sent=%ld, total=%ld", sentbytes, totalbytes);
DVB_OSDRectangle(10, 40, 500, 30, 219);
AP_OSDTextUniCodeByu8String(0, 10, 40, msg);
// For testing - end
#endif
DVB_UpdateProgress_Callback(sentbytes * 100 / totalbytes, EN_DVB_UPDATE_TRANSMIT_CALLBACK);
return 0;
}
/************************************************************************
* Transmit update data to slave STB.
************************************************************************/
EN_DVB_UPDATE_ERROR_TYPE DVB_UpdateSlaveSTB(void)
{
EN_DVB_UPDATE_ERROR_TYPE enUpdRetErr = EN_DVB_UPDATE_NO_ERROR;
u32 u32TotalLength, u32temp;
u8 u8StartBank, u8BankNum;
u16 u16cmd, u16Percent;
memset(m_au8Header, 0x00, HEAD_INFO_LEN);
//==========================================
// HEADER: 8 Bytes
//==========================================
switch(enUpdateType)
{
case EN_UPDATE_DATABASE_ONLY:
u8BankNum = DVB_DBGetBankNum();
u8StartBank = DVB_DBGetStartBank();
u32temp = DVB_DBGetDigest();
memcpy(m_au8Header, "d__B", 4);
m_au8Header[4] = (u32temp & 0xFF000000) >> 24;
m_au8Header[5] = (u32temp & 0x00FF0000) >> 16;
m_au8Header[6] = (u32temp & 0x0000FF00) >> 8;
m_au8Header[7] = (u32temp & 0x000000FF) ;
break;
case EN_UPDATE_CODE_ONLY:
u8BankNum = DVB_UpdGetCodeBankTotality();
u8StartBank = DVB_UpdGetCodeStartBank();
memcpy(m_au8Header, DVB_GetImageHeader(), HEADER_LEN);
break;
case EN_UPDATE_CODE_DATABASE:
#ifdef USER_DB_START_BANK
u8BankNum = DVB_DBGetBankNum()+DVB_UpdGetCodeBankTotality();
#else
u8BankNum = UPD_TOTAL_FLASH_BANK;
#endif
u8StartBank = DVB_UpdGetCodeStartBank();
memcpy(m_au8Header, "CTMODE", 6);
m_au8Header[6] = 0x30 + 1;
m_au8Header[7] = 0x30 + (10 - 1);
break;
default:
return EN_XMODEM_ERR_ABORT;
}
u32TotalLength = FLASHSRV_BYTE_MODE_BANK_SIZE * u8BankNum + TAIL_INFO_LEN;
//==========================================
// LENGTH: 4 Bytes
//==========================================
m_au8Header[HEADER_LEN ] = (u32TotalLength & 0xFF000000) >> 24;
m_au8Header[HEADER_LEN + 1] = (u32TotalLength & 0x00FF0000) >> 16;
m_au8Header[HEADER_LEN + 2] = (u32TotalLength & 0x0000FF00) >> 8;
m_au8Header[HEADER_LEN + 3] = (u32TotalLength & 0x000000FF) ;
/* Get the flash address */
m_pu8FlashAddr = (u8*)DVB_FlashGetBankAddress(u8StartBank);
/* Send data to serial port by 1K XModem protocol */
switch(XModemSendPacket(TRUE, u32TotalLength + HEAD_INFO_LEN + BOX_INFO_LEN, upload_getdata, upload_progress))
{
case EN_XMODEM_NO_ERROR:
enUpdRetErr = EN_DVB_UPDATE_NO_ERROR;
DVB_UpdateProgress_Callback(100, EN_DVB_UPDATE_TRANSMIT_CALLBACK);
DVBUPD_DBG(("Xomdem transfer completed\r\n"));
break;
case EN_XMODEM_ERR_ABORT:
enUpdRetErr = EN_DVB_UPDATE_ERR_ABORT;
break;
case EN_XMODEM_ERR_TIMEOUT:
enUpdRetErr = EN_DVB_UPDATE_ERR_TIMEOUT;
break;
default:
enUpdRetErr = EN_DVB_UPDATE_ERR;
break;
}
DVB_7SegShow((u8)enUpdRetErr);
if(enUpdRetErr != EN_DVB_UPDATE_NO_ERROR) return (enUpdRetErr);
/*
* When update to PC, it needn't draw burnning percent, so return.
*/
if(b8Update2PC == TRUE) return (enUpdRetErr);
while(1)
{
u16cmd = readbyte(5000);
if(u16cmd == TIMEOUT)
{
enUpdRetErr = EN_DVB_UPDATE_ERR_BURN;
break;
}
else if(u16cmd == 0xA0)
{
/* Slave STB burning success. */
DVB_UpdateProgress_Callback(100, EN_DVB_UPDATE_BURN_CALLBACK);
enUpdRetErr = EN_DVB_UPDATE_NO_ERROR;
break;
}
else if(u16cmd == 0xA1)
{
/* Slave STB burning fail */
enUpdRetErr = EN_DVB_UPDATE_ERR_BURN;
break;
}
else if((u16cmd >= 0x20) && (u16cmd < u8BankNum + 0x20))
{
/* Slave STB send completed bank to this STB */
u16Percent = (u16cmd - 0x1F) * 100 / u8BankNum;
if(u16Percent > 100) u16Percent = 100;
DVB_UpdateProgress_Callback((u8)u16Percent, EN_DVB_UPDATE_BURN_CALLBACK);
}
}
DVB_7SegShow((u8)enUpdRetErr);
return (enUpdRetErr);
} /* end DVB_UpdateSlaveSTB */
/************************************************************************
* Initialize master STB to update.
************************************************************************/
bool8 DVB_UpdateInit(void)
{
/* Init signal */
DVB_7SegShow(1234);
DVB_AVDemuxDisable();
DVB_AudioVideoStop();
CT_UART_Enable_Interrupts(FALSE);
DVB_7SegShow(0);
return (TRUE);
} /* end DVB_UpdateInit */
/************************************************************************
* Close update setting.
************************************************************************/
void DVB_UpdateClose(void)
{
CT_UART_Enable_Interrupts(TRUE);
} /* end DVB_UpdateClose */
/************************************************************************
* Receive update data from slave STB.
************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -