2017-03-07 16:12:52 +08:00
|
|
|
/*
|
|
|
|
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
|
|
|
|
* Seth Liu 2017.03.01
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "RKDevice.h"
|
|
|
|
|
|
|
|
const char* szManufName[] =
|
|
|
|
{
|
|
|
|
"SAMSUNG",
|
|
|
|
"TOSHIBA",
|
|
|
|
"HYNIX",
|
|
|
|
"INFINEON",
|
|
|
|
"MICRON",
|
|
|
|
"RENESAS",
|
|
|
|
"ST",
|
|
|
|
"INTEL"
|
|
|
|
};
|
|
|
|
|
|
|
|
void CRKDevice::SetVendorID(USHORT value)
|
|
|
|
{
|
|
|
|
m_vid = value;
|
|
|
|
}
|
|
|
|
void CRKDevice::SetProductID(USHORT value)
|
|
|
|
{
|
|
|
|
m_pid = value;
|
|
|
|
}
|
|
|
|
void CRKDevice::SetDeviceType(ENUM_RKDEVICE_TYPE value)
|
|
|
|
{
|
|
|
|
m_device = value;
|
|
|
|
}
|
|
|
|
void CRKDevice::SetOsType(ENUM_OS_TYPE value)
|
|
|
|
{
|
|
|
|
m_os = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRKDevice::SetUsbType(ENUM_RKUSB_TYPE value)
|
|
|
|
{
|
|
|
|
m_usb = value;
|
|
|
|
}
|
|
|
|
void CRKDevice::SetBcdUsb(USHORT value)
|
|
|
|
{
|
|
|
|
m_bcdUsb = value;
|
|
|
|
}
|
|
|
|
void CRKDevice::SetLayerName(char *value)
|
|
|
|
{
|
|
|
|
strcpy(m_layerName,value);
|
|
|
|
}
|
|
|
|
void CRKDevice::SetLocationID(DWORD value)
|
|
|
|
{
|
|
|
|
m_locationID = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CRKDevice::SetCallBackPointer(ProgressPromptCB value)
|
|
|
|
{
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
m_callBackProc = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CRKLog* CRKDevice::GetLogObjectPointer()
|
|
|
|
{
|
|
|
|
return m_pLog;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRKComm* CRKDevice::GetCommObjectPointer()
|
|
|
|
{
|
|
|
|
return m_pComm;
|
|
|
|
}
|
|
|
|
|
|
|
|
USHORT CRKDevice::GetVendorID()
|
|
|
|
{
|
|
|
|
return m_vid;
|
|
|
|
}
|
|
|
|
USHORT CRKDevice::GetProductID()
|
|
|
|
{
|
|
|
|
return m_pid;
|
|
|
|
}
|
|
|
|
ENUM_RKDEVICE_TYPE CRKDevice::GetDeviceType()
|
|
|
|
{
|
|
|
|
return m_device;
|
|
|
|
}
|
|
|
|
ENUM_OS_TYPE CRKDevice::GetOsType()
|
|
|
|
{
|
|
|
|
return m_os;
|
|
|
|
}
|
|
|
|
|
|
|
|
ENUM_RKUSB_TYPE CRKDevice::GetUsbType()
|
|
|
|
{
|
|
|
|
return m_usb;
|
|
|
|
}
|
|
|
|
|
|
|
|
USHORT CRKDevice::GetBcdUsb()
|
|
|
|
{
|
|
|
|
return m_bcdUsb;
|
|
|
|
}
|
|
|
|
DWORD CRKDevice::GetLocationID()
|
|
|
|
{
|
|
|
|
return m_locationID;
|
|
|
|
}
|
|
|
|
char* CRKDevice::GetLayerName()
|
|
|
|
{
|
|
|
|
return m_layerName;
|
|
|
|
}
|
|
|
|
|
|
|
|
string CRKDevice::GetLayerString(DWORD dwLocationID)
|
|
|
|
{
|
|
|
|
char szLocation[32] = "\0";
|
|
|
|
sprintf(szLocation, "%d-%d", dwLocationID >> 8, dwLocationID & 0xff);
|
|
|
|
return szLocation;
|
|
|
|
}
|
|
|
|
|
|
|
|
CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device)
|
|
|
|
{
|
|
|
|
VendorID.setContainer(this);
|
|
|
|
VendorID.getter(&CRKDevice::GetVendorID);
|
|
|
|
VendorID.setter(&CRKDevice::SetVendorID);
|
|
|
|
|
|
|
|
ProductID.setContainer(this);
|
|
|
|
ProductID.getter(&CRKDevice::GetProductID);
|
|
|
|
ProductID.setter(&CRKDevice::SetProductID);
|
|
|
|
|
|
|
|
DeviceType.setContainer(this);
|
|
|
|
DeviceType.getter(&CRKDevice::GetDeviceType);
|
|
|
|
DeviceType.setter(&CRKDevice::SetDeviceType);
|
|
|
|
|
|
|
|
UsbType.setContainer(this);
|
|
|
|
UsbType.getter(&CRKDevice::GetUsbType);
|
|
|
|
UsbType.setter(&CRKDevice::SetUsbType);
|
|
|
|
|
|
|
|
LayerName.setContainer(this);
|
|
|
|
LayerName.getter(&CRKDevice::GetLayerName);
|
|
|
|
LayerName.setter(&CRKDevice::SetLayerName);
|
|
|
|
|
|
|
|
BcdUsb.setContainer(this);
|
|
|
|
BcdUsb.getter(&CRKDevice::GetBcdUsb);
|
|
|
|
BcdUsb.setter(&CRKDevice::SetBcdUsb);
|
|
|
|
|
|
|
|
LocationID.setContainer(this);
|
|
|
|
LocationID.getter(&CRKDevice::GetLocationID);
|
|
|
|
LocationID.setter(&CRKDevice::SetLocationID);
|
|
|
|
|
|
|
|
OsType.setContainer(this);
|
|
|
|
OsType.getter(&CRKDevice::GetOsType);
|
|
|
|
OsType.setter(&CRKDevice::SetOsType);
|
|
|
|
|
|
|
|
LogObjectPointer.setContainer(this);
|
|
|
|
LogObjectPointer.getter(&CRKDevice::GetLogObjectPointer);
|
|
|
|
|
|
|
|
CommObjectPointer.setContainer(this);
|
|
|
|
CommObjectPointer.getter(&CRKDevice::GetCommObjectPointer);
|
|
|
|
|
|
|
|
CallBackPointer.setContainer(this);
|
|
|
|
CallBackPointer.setter(&CRKDevice::SetCallBackPointer);
|
|
|
|
|
|
|
|
m_vid = device.usVid;
|
|
|
|
m_pid = device.usPid;
|
|
|
|
m_usb = device.emUsbType;
|
|
|
|
m_device = device.emDeviceType;
|
|
|
|
m_bcdUsb = device.usbcdUsb;
|
|
|
|
m_locationID = device.uiLocationID;
|
|
|
|
strcpy(m_layerName, GetLayerString(m_locationID).c_str());
|
|
|
|
|
|
|
|
memset(m_flashInfo.blockState, 0, IDBLOCK_TOP);
|
|
|
|
m_flashInfo.usPhyBlokcPerIDB = 1;
|
|
|
|
m_flashInfo.uiSecNumPerIDB = 0;
|
|
|
|
m_callBackProc = NULL;
|
|
|
|
m_chipData = NULL;
|
|
|
|
m_pImage = NULL;
|
|
|
|
m_pLog = NULL;
|
|
|
|
m_pComm = NULL;
|
|
|
|
m_pFlashInfoData = NULL;
|
|
|
|
m_usFlashInfoDataLen = 0;
|
|
|
|
m_usFlashInfoDataOffset = 0;
|
|
|
|
m_bEmmc = false;
|
2018-03-28 09:22:40 +08:00
|
|
|
m_bDirectLba = false;
|
|
|
|
m_bFirst4mAccess = false;
|
2017-03-07 16:12:52 +08:00
|
|
|
}
|
|
|
|
CRKDevice::~CRKDevice()
|
|
|
|
{
|
|
|
|
if (m_pComm) {
|
|
|
|
delete m_pComm;
|
|
|
|
m_pComm = NULL;
|
|
|
|
}
|
|
|
|
if (m_chipData) {
|
|
|
|
delete []m_chipData;
|
|
|
|
m_chipData = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_pFlashInfoData) {
|
|
|
|
delete []m_pFlashInfoData;
|
|
|
|
m_pFlashInfoData = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog)
|
|
|
|
{
|
|
|
|
if (!pComm) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
m_pImage = pImage;
|
|
|
|
m_pComm = pComm;
|
|
|
|
m_pLog = pLog;
|
|
|
|
if (m_pImage) {
|
|
|
|
m_os = m_pImage->OsType;
|
|
|
|
} else
|
|
|
|
m_os = RK_OS;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount)
|
|
|
|
{
|
|
|
|
int sectorOffset,nWrittenBlcok,iRet;
|
|
|
|
BYTE emptyData[4 * (SECTOR_SIZE+SPARE_SIZE)];
|
|
|
|
memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE));
|
|
|
|
nWrittenBlcok = 0;
|
|
|
|
while (dwCount > 0) {
|
|
|
|
sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock;
|
|
|
|
iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData);
|
|
|
|
if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:EraseEmmcBlock-->RKU_WriteSector failed, RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return iRet;
|
|
|
|
}
|
|
|
|
dwCount--;
|
|
|
|
nWrittenBlcok++;
|
|
|
|
}
|
|
|
|
return ERR_SUCCESS;
|
|
|
|
}
|
|
|
|
int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount)
|
|
|
|
{
|
|
|
|
int nWritten,iRet;
|
|
|
|
BYTE emptyData[32 * SECTOR_SIZE];
|
|
|
|
memset(emptyData, 0xff, 32 * SECTOR_SIZE);
|
|
|
|
|
|
|
|
while (dwCount > 0) {
|
|
|
|
nWritten = (dwCount < 32) ? dwCount : 32;
|
|
|
|
iRet = m_pComm->RKU_WriteLBA(dwSectorPos, nWritten, emptyData);
|
|
|
|
if (iRet != ERR_SUCCESS) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:EraseEmmcByWriteLBA-->RKU_WriteLBA failed, RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return iRet;
|
|
|
|
}
|
|
|
|
dwCount -= nWritten;
|
|
|
|
dwSectorPos += nWritten;
|
|
|
|
}
|
|
|
|
return ERR_SUCCESS;
|
|
|
|
}
|
|
|
|
bool CRKDevice::EraseEmmc()
|
|
|
|
{
|
2018-03-28 09:22:40 +08:00
|
|
|
UINT uiCount,uiEraseCount,uiSectorOffset,uiTotalCount;
|
|
|
|
UINT uiErase=1024*32;
|
|
|
|
int iRet=ERR_SUCCESS,iLoopTimes=0;
|
|
|
|
uiTotalCount = uiCount = m_flashInfo.uiFlashSize*2*1024;
|
|
|
|
uiSectorOffset = 0;
|
2017-03-07 16:12:52 +08:00
|
|
|
DWORD dwLayerID;
|
|
|
|
dwLayerID = m_locationID;
|
|
|
|
ENUM_CALL_STEP emCallStep = CALL_FIRST;
|
2018-03-28 09:22:40 +08:00
|
|
|
|
|
|
|
while (uiCount)
|
|
|
|
{
|
|
|
|
if (uiCount >= uiErase)
|
|
|
|
{
|
|
|
|
uiEraseCount = uiErase;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
uiEraseCount = uiCount;
|
|
|
|
iRet = m_pComm->RKU_EraseLBA(uiSectorOffset, uiEraseCount);
|
|
|
|
|
2017-03-07 16:12:52 +08:00
|
|
|
if (iRet != ERR_SUCCESS) {
|
|
|
|
if (m_pLog) {
|
2018-03-28 09:22:40 +08:00
|
|
|
m_pLog->Record("ERROR:EraseEmmc-->RKU_EraseLBA failed,RetCode(%d),offset=0x%x,count=0x%x",iRet, uiSectorOffset, uiEraseCount);
|
2017-03-07 16:12:52 +08:00
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
2018-03-28 09:22:40 +08:00
|
|
|
uiCount -= uiEraseCount;
|
|
|
|
uiSectorOffset += uiEraseCount;
|
2017-03-07 16:12:52 +08:00
|
|
|
iLoopTimes++;
|
2018-03-28 09:22:40 +08:00
|
|
|
if (iLoopTimes % 8 == 0) {
|
2017-03-07 16:12:52 +08:00
|
|
|
if (m_callBackProc) {
|
2018-03-28 09:22:40 +08:00
|
|
|
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiSectorOffset, emCallStep);
|
2017-03-07 16:12:52 +08:00
|
|
|
emCallStep = CALL_MIDDLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m_callBackProc) {
|
|
|
|
emCallStep = CALL_LAST;
|
2018-03-28 09:22:40 +08:00
|
|
|
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiTotalCount, emCallStep);
|
2017-03-07 16:12:52 +08:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool CRKDevice::GetFlashInfo()
|
|
|
|
{
|
|
|
|
STRUCT_FLASHINFO_CMD info;
|
|
|
|
BYTE flashID[5];
|
|
|
|
int iRet;
|
|
|
|
UINT uiRead;
|
|
|
|
iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead);
|
|
|
|
if( ERR_SUCCESS == iRet ) {
|
|
|
|
if ((info.usBlockSize == 0) || (info.bPageSize == 0)) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero", m_layerName);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (info.bManufCode <= 7) {
|
|
|
|
strcpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]);
|
|
|
|
} else {
|
|
|
|
strcpy(m_flashInfo.szManufacturerName, "UNKNOWN");
|
|
|
|
}
|
|
|
|
m_flashInfo.uiFlashSize = info.uiFlashSize / 2 / 1024;
|
|
|
|
m_flashInfo.uiPageSize = info.bPageSize / 2;
|
|
|
|
m_flashInfo.usBlockSize = info.usBlockSize / 2;
|
|
|
|
m_flashInfo.bECCBits = info.bECCBits;
|
|
|
|
m_flashInfo.bAccessTime = info.bAccessTime;
|
|
|
|
m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize;
|
|
|
|
m_flashInfo.uiSectorPerBlock = info.usBlockSize;
|
|
|
|
m_flashInfo.bFlashCS = info.bFlashCS;
|
|
|
|
m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4;
|
|
|
|
if (m_pFlashInfoData) {
|
|
|
|
delete []m_pFlashInfoData;
|
|
|
|
m_pFlashInfoData = NULL;
|
|
|
|
}
|
|
|
|
m_usFlashInfoDataLen = BYTE2SECTOR(uiRead);
|
|
|
|
m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen];
|
|
|
|
memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen);
|
|
|
|
memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead);
|
|
|
|
if (m_pLog) {
|
|
|
|
string strFlashInfo;
|
|
|
|
m_pLog->PrintBuffer(strFlashInfo, m_pFlashInfoData, 11);
|
|
|
|
m_pLog->Record("<LAYER %s> INFO:FlashInfo:%s", m_layerName, strFlashInfo.c_str());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed, RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
iRet = m_pComm->RKU_ReadFlashID(flashID);
|
|
|
|
if( ERR_SUCCESS == iRet ) {
|
|
|
|
DWORD *pID = (DWORD *)flashID;
|
|
|
|
if (*pID==0x434d4d45)/*emmc*/ {
|
|
|
|
m_bEmmc = true;
|
|
|
|
} else
|
|
|
|
m_bEmmc = false;
|
|
|
|
} else {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashID failed, RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool CRKDevice::TestDevice()
|
|
|
|
{
|
|
|
|
int iResult, iTryCount;
|
|
|
|
DWORD dwTotal, dwCurrent, dwLayerID;
|
|
|
|
dwLayerID = m_locationID;
|
|
|
|
ENUM_CALL_STEP emCallStep = CALL_FIRST;
|
|
|
|
do {
|
|
|
|
iTryCount = 3;
|
|
|
|
while (iTryCount > 0) {
|
|
|
|
iResult = m_pComm->RKU_TestDeviceReady(&dwTotal, &dwCurrent);
|
|
|
|
if ((iResult == ERR_SUCCESS) || (iResult == ERR_DEVICE_UNREADY)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, RetCode(%d)", m_layerName, iResult);
|
|
|
|
}
|
|
|
|
iTryCount--;
|
|
|
|
sleep(1);
|
|
|
|
}
|
|
|
|
if (iTryCount <= 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (iResult == ERR_SUCCESS) {
|
|
|
|
if (emCallStep == CALL_MIDDLE) {
|
|
|
|
if (m_callBackProc) {
|
|
|
|
dwCurrent = dwTotal;
|
|
|
|
emCallStep = CALL_LAST;
|
|
|
|
m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (dwCurrent>dwTotal) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed,Total=%d, Current=%d", m_layerName, dwTotal, dwCurrent);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (UsbType == RKUSB_LOADER) {
|
|
|
|
if (dwTotal == 0) {
|
|
|
|
if (m_pLog)
|
|
|
|
{
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, Total is zero", m_layerName);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (m_callBackProc)
|
|
|
|
{
|
|
|
|
m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
|
|
|
|
emCallStep = CALL_MIDDLE;
|
|
|
|
}
|
|
|
|
sleep(1);
|
|
|
|
}while(iResult == ERR_DEVICE_UNREADY);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
bool CRKDevice::ResetDevice()
|
|
|
|
{
|
|
|
|
int iRet;
|
|
|
|
iRet = m_pComm->RKU_ResetDevice();
|
|
|
|
if (iRet == ERR_SUCCESS) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
bool bRet = false;
|
|
|
|
if ((iRet == -2) || (iRet == -4)) {
|
|
|
|
bRet = true;
|
|
|
|
}
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:ResetDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CRKDevice::PowerOffDevice()
|
|
|
|
{
|
|
|
|
int iRet;
|
|
|
|
iRet = m_pComm->RKU_ResetDevice(RST_POWEROFF_SUBCODE);
|
|
|
|
if (iRet == ERR_SUCCESS) {
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:PowerOffDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bool CRKDevice::CheckChip()
|
|
|
|
{
|
|
|
|
int iRet;
|
|
|
|
BYTE bChipInfo[CHIPINFO_LEN];
|
|
|
|
ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE;
|
|
|
|
memset(bChipInfo, 0, CHIPINFO_LEN);
|
|
|
|
iRet = m_pComm->RKU_ReadChipInfo(bChipInfo);
|
|
|
|
if (iRet == ERR_SUCCESS) {
|
|
|
|
if (!m_chipData) {
|
|
|
|
m_chipData = new BYTE[CHIPINFO_LEN];
|
|
|
|
}
|
|
|
|
memset(m_chipData, 0, CHIPINFO_LEN);
|
|
|
|
memcpy(m_chipData, bChipInfo, CHIPINFO_LEN);
|
|
|
|
DWORD *pValue;
|
|
|
|
pValue = (DWORD *)(&bChipInfo[0]);
|
|
|
|
|
|
|
|
if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (*pValue == 0x524B3237) {
|
|
|
|
curDeviceType = RK27_DEVICE;
|
|
|
|
} else if (*pValue == 0x32373341) {
|
|
|
|
curDeviceType = RKCAYMAN_DEVICE;
|
|
|
|
} else if (*pValue == 0x524B3238) {
|
|
|
|
curDeviceType = RK28_DEVICE;
|
|
|
|
} else if (*pValue == 0x32383158) {
|
|
|
|
curDeviceType = RK281X_DEVICE;
|
|
|
|
} else if (*pValue == 0x32383242) {
|
|
|
|
curDeviceType = RKPANDA_DEVICE;
|
|
|
|
} else if (*pValue == 0x32393058) {
|
|
|
|
curDeviceType = RK29_DEVICE;
|
|
|
|
} else if (*pValue == 0x32393258) {
|
|
|
|
curDeviceType = RK292X_DEVICE;
|
|
|
|
} else if (*pValue == 0x33303041) {
|
|
|
|
curDeviceType = RK30_DEVICE;
|
|
|
|
} else if (*pValue == 0x33313041) {
|
|
|
|
curDeviceType = RK30B_DEVICE;
|
|
|
|
} else if (*pValue == 0x33313042) {
|
|
|
|
curDeviceType = RK31_DEVICE;
|
|
|
|
} else if (*pValue == 0x33323041) {
|
|
|
|
curDeviceType = RK32_DEVICE;
|
|
|
|
} else if (*pValue == 0x32363243) {
|
|
|
|
curDeviceType = RKSMART_DEVICE;
|
|
|
|
} else if (*pValue == 0x6E616E6F) {
|
|
|
|
curDeviceType = RKNANO_DEVICE;
|
|
|
|
} else if (*pValue == 0x4E4F5243) {
|
|
|
|
curDeviceType = RKCROWN_DEVICE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (curDeviceType == m_device){
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:CheckChip-->Chip is not match, firmware(0x%x), device(0x%x)", m_layerName, m_device, *pValue);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int CRKDevice::DownloadBoot()
|
|
|
|
{
|
|
|
|
UCHAR i;
|
|
|
|
DWORD dwSize, dwDelay;
|
|
|
|
PBYTE pBuffer = NULL;
|
|
|
|
for ( i = 0; i < m_pImage->m_bootObject->Entry471Count; i++ ) {
|
|
|
|
if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY471, i, dwSize, dwDelay) ) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Property failed,index(%d)", m_layerName, i);
|
|
|
|
}
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
if (dwSize>0) {
|
|
|
|
pBuffer = new BYTE[dwSize];
|
|
|
|
if ( !m_pImage->m_bootObject->GetEntryData(ENTRY471, i, pBuffer) ) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Data failed,index(%d)", m_layerName, i);
|
|
|
|
}
|
|
|
|
delete []pBuffer;
|
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
if ( !Boot_VendorRequest(0x0471,pBuffer,dwSize) ) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest471 failed,index(%d)", m_layerName, i);
|
|
|
|
}
|
|
|
|
delete []pBuffer;
|
|
|
|
return -4;
|
|
|
|
}
|
|
|
|
delete []pBuffer;
|
|
|
|
pBuffer = NULL;
|
|
|
|
if (dwDelay>0) {
|
|
|
|
usleep(dwDelay * 1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i=0; i < m_pImage->m_bootObject->Entry472Count; i++ ) {
|
|
|
|
if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY472, i, dwSize, dwDelay) ) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Property failed,index(%d)", m_layerName, i);
|
|
|
|
}
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
if (dwSize > 0) {
|
|
|
|
pBuffer = new BYTE[dwSize];
|
|
|
|
if ( !m_pImage->m_bootObject->GetEntryData(ENTRY472, i, pBuffer) ) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Data failed,index(%d)", m_layerName, i);
|
|
|
|
}
|
|
|
|
delete []pBuffer;
|
|
|
|
return -3;
|
|
|
|
}
|
|
|
|
if ( !Boot_VendorRequest(0x0472, pBuffer, dwSize) ) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest472 failed,index(%d)", m_layerName, i);
|
|
|
|
}
|
|
|
|
delete []pBuffer;
|
|
|
|
return -4;
|
|
|
|
}
|
|
|
|
delete []pBuffer;
|
|
|
|
pBuffer = NULL;
|
|
|
|
if (dwDelay > 0) {
|
|
|
|
usleep(dwDelay * 1000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sleep(1);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
bool CRKDevice::Boot_VendorRequest( DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize)
|
|
|
|
{
|
|
|
|
int iRet;
|
|
|
|
iRet = m_pComm->RKU_DeviceRequest(requestCode, pBuffer, dwDataSize);
|
|
|
|
return (iRet == ERR_SUCCESS) ? true : false;
|
|
|
|
}
|
2021-01-22 14:26:24 +08:00
|
|
|
int CRKDevice::EraseAllBlocks(bool force_block_erase)
|
2017-03-07 16:12:52 +08:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
UINT uiBlockCount;
|
|
|
|
int iRet = ERR_SUCCESS, iErasePos = 0, iEraseBlockNum = 0, iEraseTimes = 0, iCSIndex = 0;
|
|
|
|
BYTE bCSCount = 0;
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
if ( m_flashInfo.bFlashCS & (1 << i) ) {
|
|
|
|
bCSCount++;
|
|
|
|
}
|
|
|
|
}
|
2018-03-28 09:22:40 +08:00
|
|
|
ReadCapability();
|
2017-03-07 16:12:52 +08:00
|
|
|
DWORD dwLayerID;
|
|
|
|
dwLayerID = LocationID;
|
|
|
|
ENUM_CALL_STEP emCallStep = CALL_FIRST;
|
2021-01-22 14:26:24 +08:00
|
|
|
if (!force_block_erase) {
|
|
|
|
if ((m_bEmmc)||(m_bDirectLba)) {
|
|
|
|
if (!EraseEmmc()) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName);
|
|
|
|
}
|
|
|
|
return -1;
|
2017-03-07 16:12:52 +08:00
|
|
|
}
|
2021-01-22 14:26:24 +08:00
|
|
|
return 0;
|
2017-03-07 16:12:52 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
|
|
if ( m_flashInfo.bFlashCS & (1 << i) ) {
|
|
|
|
uiBlockCount = m_flashInfo.uiBlockNum;
|
|
|
|
iErasePos = 0;
|
|
|
|
iEraseTimes = 0;
|
|
|
|
while (uiBlockCount > 0) {
|
|
|
|
iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS;
|
|
|
|
iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE);
|
|
|
|
if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
|
|
|
|
if (m_pLog) {
|
|
|
|
m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet);
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
iErasePos += iEraseBlockNum;
|
|
|
|
uiBlockCount -= iEraseBlockNum;
|
|
|
|
iEraseTimes++;
|
|
|
|
if (iEraseTimes % 8 == 0) {
|
|
|
|
if (m_callBackProc) {
|
|
|
|
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep);
|
|
|
|
emCallStep = CALL_MIDDLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
iCSIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_callBackProc) {
|
|
|
|
emCallStep = CALL_LAST;
|
|
|
|
m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2018-03-28 09:22:40 +08:00
|
|
|
bool CRKDevice::ReadCapability()
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
BYTE data[8];
|
|
|
|
ret = m_pComm->RKU_ReadCapability(data);
|
|
|
|
if (ret != ERR_SUCCESS)
|
|
|
|
{
|
|
|
|
if (m_pLog)
|
|
|
|
{
|
|
|
|
m_pLog->Record("ERROR:ReadCapability-->RKU_ReadCapability failed,err(%d)", ret);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (data[0] & 0x1)
|
|
|
|
{
|
|
|
|
m_bDirectLba = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_bDirectLba = false;
|
|
|
|
if (data[0] & 0x4)
|
|
|
|
{
|
|
|
|
m_bFirst4mAccess = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
m_bFirst4mAccess = false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-03-07 16:12:52 +08:00
|
|
|
|