xref: /rkdeveloptool/RKDevice.cpp (revision 76af099afcbcafd97801028de2ba3421d3c12865)
1*76af099aSliuyi /*
2*76af099aSliuyi  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
3*76af099aSliuyi  * Seth Liu 2017.03.01
4*76af099aSliuyi  *
5*76af099aSliuyi  * SPDX-License-Identifier:	GPL-2.0+
6*76af099aSliuyi  */
7*76af099aSliuyi 
8*76af099aSliuyi #include "RKDevice.h"
9*76af099aSliuyi 
10*76af099aSliuyi const char* szManufName[] =
11*76af099aSliuyi {
12*76af099aSliuyi 	"SAMSUNG",
13*76af099aSliuyi 	"TOSHIBA",
14*76af099aSliuyi 	"HYNIX",
15*76af099aSliuyi 	"INFINEON",
16*76af099aSliuyi 	"MICRON",
17*76af099aSliuyi 	"RENESAS",
18*76af099aSliuyi 	"ST",
19*76af099aSliuyi 	"INTEL"
20*76af099aSliuyi };
21*76af099aSliuyi 
22*76af099aSliuyi void CRKDevice::SetVendorID(USHORT value)
23*76af099aSliuyi {
24*76af099aSliuyi 	m_vid = value;
25*76af099aSliuyi }
26*76af099aSliuyi void CRKDevice::SetProductID(USHORT value)
27*76af099aSliuyi {
28*76af099aSliuyi 	m_pid = value;
29*76af099aSliuyi }
30*76af099aSliuyi void CRKDevice::SetDeviceType(ENUM_RKDEVICE_TYPE value)
31*76af099aSliuyi {
32*76af099aSliuyi 	m_device = value;
33*76af099aSliuyi }
34*76af099aSliuyi void CRKDevice::SetOsType(ENUM_OS_TYPE value)
35*76af099aSliuyi {
36*76af099aSliuyi 	m_os = value;
37*76af099aSliuyi }
38*76af099aSliuyi 
39*76af099aSliuyi void CRKDevice::SetUsbType(ENUM_RKUSB_TYPE value)
40*76af099aSliuyi {
41*76af099aSliuyi 	m_usb = value;
42*76af099aSliuyi }
43*76af099aSliuyi void CRKDevice::SetBcdUsb(USHORT value)
44*76af099aSliuyi {
45*76af099aSliuyi 	m_bcdUsb = value;
46*76af099aSliuyi }
47*76af099aSliuyi void CRKDevice::SetLayerName(char *value)
48*76af099aSliuyi {
49*76af099aSliuyi 	strcpy(m_layerName,value);
50*76af099aSliuyi }
51*76af099aSliuyi void CRKDevice::SetLocationID(DWORD value)
52*76af099aSliuyi {
53*76af099aSliuyi 	m_locationID = value;
54*76af099aSliuyi }
55*76af099aSliuyi 
56*76af099aSliuyi void CRKDevice::SetCallBackPointer(ProgressPromptCB value)
57*76af099aSliuyi {
58*76af099aSliuyi 	if (value)
59*76af099aSliuyi 	{
60*76af099aSliuyi 		m_callBackProc = value;
61*76af099aSliuyi 	}
62*76af099aSliuyi }
63*76af099aSliuyi CRKLog* CRKDevice::GetLogObjectPointer()
64*76af099aSliuyi {
65*76af099aSliuyi 	return m_pLog;
66*76af099aSliuyi }
67*76af099aSliuyi 
68*76af099aSliuyi CRKComm* CRKDevice::GetCommObjectPointer()
69*76af099aSliuyi {
70*76af099aSliuyi 	return m_pComm;
71*76af099aSliuyi }
72*76af099aSliuyi 
73*76af099aSliuyi USHORT CRKDevice::GetVendorID()
74*76af099aSliuyi {
75*76af099aSliuyi 	return m_vid;
76*76af099aSliuyi }
77*76af099aSliuyi USHORT CRKDevice::GetProductID()
78*76af099aSliuyi {
79*76af099aSliuyi 	return m_pid;
80*76af099aSliuyi }
81*76af099aSliuyi ENUM_RKDEVICE_TYPE CRKDevice::GetDeviceType()
82*76af099aSliuyi {
83*76af099aSliuyi 	return m_device;
84*76af099aSliuyi }
85*76af099aSliuyi ENUM_OS_TYPE CRKDevice::GetOsType()
86*76af099aSliuyi {
87*76af099aSliuyi 	return m_os;
88*76af099aSliuyi }
89*76af099aSliuyi 
90*76af099aSliuyi ENUM_RKUSB_TYPE CRKDevice::GetUsbType()
91*76af099aSliuyi {
92*76af099aSliuyi 	return m_usb;
93*76af099aSliuyi }
94*76af099aSliuyi 
95*76af099aSliuyi USHORT CRKDevice::GetBcdUsb()
96*76af099aSliuyi {
97*76af099aSliuyi 	return m_bcdUsb;
98*76af099aSliuyi }
99*76af099aSliuyi DWORD CRKDevice::GetLocationID()
100*76af099aSliuyi {
101*76af099aSliuyi 	return m_locationID;
102*76af099aSliuyi }
103*76af099aSliuyi char* CRKDevice::GetLayerName()
104*76af099aSliuyi {
105*76af099aSliuyi 	return m_layerName;
106*76af099aSliuyi }
107*76af099aSliuyi 
108*76af099aSliuyi string CRKDevice::GetLayerString(DWORD dwLocationID)
109*76af099aSliuyi {
110*76af099aSliuyi 	char szLocation[32] = "\0";
111*76af099aSliuyi 	sprintf(szLocation, "%d-%d", dwLocationID >> 8, dwLocationID & 0xff);
112*76af099aSliuyi 	return szLocation;
113*76af099aSliuyi }
114*76af099aSliuyi 
115*76af099aSliuyi CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device)
116*76af099aSliuyi {
117*76af099aSliuyi 	VendorID.setContainer(this);
118*76af099aSliuyi     	VendorID.getter(&CRKDevice::GetVendorID);
119*76af099aSliuyi  	VendorID.setter(&CRKDevice::SetVendorID);
120*76af099aSliuyi 
121*76af099aSliuyi 	ProductID.setContainer(this);
122*76af099aSliuyi     	ProductID.getter(&CRKDevice::GetProductID);
123*76af099aSliuyi  	ProductID.setter(&CRKDevice::SetProductID);
124*76af099aSliuyi 
125*76af099aSliuyi 	DeviceType.setContainer(this);
126*76af099aSliuyi     	DeviceType.getter(&CRKDevice::GetDeviceType);
127*76af099aSliuyi  	DeviceType.setter(&CRKDevice::SetDeviceType);
128*76af099aSliuyi 
129*76af099aSliuyi 	UsbType.setContainer(this);
130*76af099aSliuyi     	UsbType.getter(&CRKDevice::GetUsbType);
131*76af099aSliuyi  	UsbType.setter(&CRKDevice::SetUsbType);
132*76af099aSliuyi 
133*76af099aSliuyi 	LayerName.setContainer(this);
134*76af099aSliuyi     	LayerName.getter(&CRKDevice::GetLayerName);
135*76af099aSliuyi  	LayerName.setter(&CRKDevice::SetLayerName);
136*76af099aSliuyi 
137*76af099aSliuyi 	BcdUsb.setContainer(this);
138*76af099aSliuyi     	BcdUsb.getter(&CRKDevice::GetBcdUsb);
139*76af099aSliuyi  	BcdUsb.setter(&CRKDevice::SetBcdUsb);
140*76af099aSliuyi 
141*76af099aSliuyi 	LocationID.setContainer(this);
142*76af099aSliuyi     	LocationID.getter(&CRKDevice::GetLocationID);
143*76af099aSliuyi 	LocationID.setter(&CRKDevice::SetLocationID);
144*76af099aSliuyi 
145*76af099aSliuyi 	OsType.setContainer(this);
146*76af099aSliuyi     	OsType.getter(&CRKDevice::GetOsType);
147*76af099aSliuyi  	OsType.setter(&CRKDevice::SetOsType);
148*76af099aSliuyi 
149*76af099aSliuyi 	LogObjectPointer.setContainer(this);
150*76af099aSliuyi     	LogObjectPointer.getter(&CRKDevice::GetLogObjectPointer);
151*76af099aSliuyi 
152*76af099aSliuyi 	CommObjectPointer.setContainer(this);
153*76af099aSliuyi     	CommObjectPointer.getter(&CRKDevice::GetCommObjectPointer);
154*76af099aSliuyi 
155*76af099aSliuyi 	CallBackPointer.setContainer(this);
156*76af099aSliuyi  	CallBackPointer.setter(&CRKDevice::SetCallBackPointer);
157*76af099aSliuyi 
158*76af099aSliuyi 	m_vid = device.usVid;
159*76af099aSliuyi 	m_pid = device.usPid;
160*76af099aSliuyi 	m_usb = device.emUsbType;
161*76af099aSliuyi 	m_device = device.emDeviceType;
162*76af099aSliuyi 	m_bcdUsb = device.usbcdUsb;
163*76af099aSliuyi 	m_locationID = device.uiLocationID;
164*76af099aSliuyi 	strcpy(m_layerName, GetLayerString(m_locationID).c_str());
165*76af099aSliuyi 
166*76af099aSliuyi 	memset(m_flashInfo.blockState, 0, IDBLOCK_TOP);
167*76af099aSliuyi 	m_flashInfo.usPhyBlokcPerIDB = 1;
168*76af099aSliuyi 	m_flashInfo.uiSecNumPerIDB = 0;
169*76af099aSliuyi 	m_callBackProc = NULL;
170*76af099aSliuyi 	m_chipData = NULL;
171*76af099aSliuyi 	m_pImage = NULL;
172*76af099aSliuyi 	m_pLog = NULL;
173*76af099aSliuyi 	m_pComm = NULL;
174*76af099aSliuyi 	m_pFlashInfoData = NULL;
175*76af099aSliuyi 	m_usFlashInfoDataLen = 0;
176*76af099aSliuyi 	m_usFlashInfoDataOffset = 0;
177*76af099aSliuyi 	m_bEmmc = false;
178*76af099aSliuyi }
179*76af099aSliuyi CRKDevice::~CRKDevice()
180*76af099aSliuyi {
181*76af099aSliuyi 	if (m_pComm) {
182*76af099aSliuyi 		delete m_pComm;
183*76af099aSliuyi 		m_pComm = NULL;
184*76af099aSliuyi 	}
185*76af099aSliuyi 	if (m_chipData) {
186*76af099aSliuyi 		delete []m_chipData;
187*76af099aSliuyi 		m_chipData = NULL;
188*76af099aSliuyi 	}
189*76af099aSliuyi 
190*76af099aSliuyi 	if (m_pFlashInfoData) {
191*76af099aSliuyi 		delete []m_pFlashInfoData;
192*76af099aSliuyi 		m_pFlashInfoData = NULL;
193*76af099aSliuyi 	}
194*76af099aSliuyi }
195*76af099aSliuyi bool CRKDevice::SetObject(CRKImage *pImage, CRKComm *pComm, CRKLog *pLog)
196*76af099aSliuyi {
197*76af099aSliuyi 	if (!pComm) {
198*76af099aSliuyi 		return false;
199*76af099aSliuyi 	}
200*76af099aSliuyi 	m_pImage = pImage;
201*76af099aSliuyi 	m_pComm = pComm;
202*76af099aSliuyi 	m_pLog = pLog;
203*76af099aSliuyi 	if (m_pImage) {
204*76af099aSliuyi 		m_os = m_pImage->OsType;
205*76af099aSliuyi 	} else
206*76af099aSliuyi 		m_os = RK_OS;
207*76af099aSliuyi 	return true;
208*76af099aSliuyi }
209*76af099aSliuyi int CRKDevice::EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount)
210*76af099aSliuyi {
211*76af099aSliuyi 	int sectorOffset,nWrittenBlcok,iRet;
212*76af099aSliuyi 	BYTE emptyData[4 * (SECTOR_SIZE+SPARE_SIZE)];
213*76af099aSliuyi 	memset(emptyData, 0xff, 4 * (SECTOR_SIZE + SPARE_SIZE));
214*76af099aSliuyi 	nWrittenBlcok = 0;
215*76af099aSliuyi 	while (dwCount > 0) {
216*76af099aSliuyi  		sectorOffset = (ucFlashCS * m_flashInfo.uiBlockNum + dwPos + nWrittenBlcok) * m_flashInfo.uiSectorPerBlock;
217*76af099aSliuyi 		iRet = m_pComm->RKU_WriteSector(sectorOffset, 4, emptyData);
218*76af099aSliuyi 		if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
219*76af099aSliuyi 			if (m_pLog) {
220*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmcBlock-->RKU_WriteSector failed, RetCode(%d)", m_layerName, iRet);
221*76af099aSliuyi 			}
222*76af099aSliuyi 			return iRet;
223*76af099aSliuyi 		}
224*76af099aSliuyi 		dwCount--;
225*76af099aSliuyi 		nWrittenBlcok++;
226*76af099aSliuyi 	}
227*76af099aSliuyi 	return ERR_SUCCESS;
228*76af099aSliuyi }
229*76af099aSliuyi int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount)
230*76af099aSliuyi {
231*76af099aSliuyi 	int nWritten,iRet;
232*76af099aSliuyi 	BYTE emptyData[32 * SECTOR_SIZE];
233*76af099aSliuyi 	memset(emptyData, 0xff, 32 * SECTOR_SIZE);
234*76af099aSliuyi 
235*76af099aSliuyi 	while (dwCount > 0) {
236*76af099aSliuyi 		nWritten = (dwCount < 32) ? dwCount : 32;
237*76af099aSliuyi 		iRet = m_pComm->RKU_WriteLBA(dwSectorPos, nWritten, emptyData);
238*76af099aSliuyi 		if (iRet != ERR_SUCCESS) {
239*76af099aSliuyi 			if (m_pLog) {
240*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmcByWriteLBA-->RKU_WriteLBA failed, RetCode(%d)", m_layerName, iRet);
241*76af099aSliuyi 			}
242*76af099aSliuyi 			return iRet;
243*76af099aSliuyi 		}
244*76af099aSliuyi 		dwCount -= nWritten;
245*76af099aSliuyi 		dwSectorPos += nWritten;
246*76af099aSliuyi 	}
247*76af099aSliuyi 	return ERR_SUCCESS;
248*76af099aSliuyi }
249*76af099aSliuyi bool CRKDevice::EraseEmmc()
250*76af099aSliuyi {
251*76af099aSliuyi 	UINT uiCount, uiEraseCount, uiSectorOffset;
252*76af099aSliuyi 	int iRet = ERR_SUCCESS, iLoopTimes = 0;
253*76af099aSliuyi 	uiCount = m_flashInfo.uiFlashSize;
254*76af099aSliuyi 
255*76af099aSliuyi 	DWORD dwLayerID;
256*76af099aSliuyi 	dwLayerID = m_locationID;
257*76af099aSliuyi 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
258*76af099aSliuyi 	uiEraseCount = 4;
259*76af099aSliuyi 	while (uiEraseCount < uiCount) {
260*76af099aSliuyi 		uiSectorOffset = uiEraseCount * 2048;
261*76af099aSliuyi 		if (uiEraseCount>8) {
262*76af099aSliuyi 			iRet = EraseEmmcByWriteLBA(uiSectorOffset, 32);
263*76af099aSliuyi 		} else
264*76af099aSliuyi 			iRet = EraseEmmcByWriteLBA(uiSectorOffset, 2048);
265*76af099aSliuyi 		if (iRet != ERR_SUCCESS) {
266*76af099aSliuyi 			if (m_pLog) {
267*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:EraseEmmc-->EraseEmmcByWriteLBA failed, RetCode(%d)", m_layerName, iRet);
268*76af099aSliuyi 			}
269*76af099aSliuyi 			return false;
270*76af099aSliuyi 		}
271*76af099aSliuyi 		uiEraseCount++;
272*76af099aSliuyi 		iLoopTimes++;
273*76af099aSliuyi 		if (iLoopTimes%8 == 0) {
274*76af099aSliuyi 			if (m_callBackProc) {
275*76af099aSliuyi 				m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiEraseCount, emCallStep);
276*76af099aSliuyi 				emCallStep = CALL_MIDDLE;
277*76af099aSliuyi 			}
278*76af099aSliuyi 		}
279*76af099aSliuyi 	}
280*76af099aSliuyi 	if (m_callBackProc) {
281*76af099aSliuyi 		emCallStep = CALL_LAST;
282*76af099aSliuyi 		m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiCount, emCallStep);
283*76af099aSliuyi 	}
284*76af099aSliuyi 	return true;
285*76af099aSliuyi }
286*76af099aSliuyi bool CRKDevice::GetFlashInfo()
287*76af099aSliuyi {
288*76af099aSliuyi 	STRUCT_FLASHINFO_CMD info;
289*76af099aSliuyi 	BYTE flashID[5];
290*76af099aSliuyi 	int iRet;
291*76af099aSliuyi 	UINT uiRead;
292*76af099aSliuyi 	iRet = m_pComm->RKU_ReadFlashInfo((PBYTE)&info, &uiRead);
293*76af099aSliuyi 	if( ERR_SUCCESS == iRet ) {
294*76af099aSliuyi 		if ((info.usBlockSize == 0) || (info.bPageSize == 0)) {
295*76af099aSliuyi 			if (m_pLog) {
296*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed,pagesize or blocksize is zero", m_layerName);
297*76af099aSliuyi 			}
298*76af099aSliuyi 			return false;
299*76af099aSliuyi 		}
300*76af099aSliuyi 		if (info.bManufCode <= 7) {
301*76af099aSliuyi 			strcpy(m_flashInfo.szManufacturerName, szManufName[info.bManufCode]);
302*76af099aSliuyi 		} else {
303*76af099aSliuyi 			strcpy(m_flashInfo.szManufacturerName, "UNKNOWN");
304*76af099aSliuyi 		}
305*76af099aSliuyi 		m_flashInfo.uiFlashSize = info.uiFlashSize / 2 / 1024;
306*76af099aSliuyi 		m_flashInfo.uiPageSize = info.bPageSize / 2;
307*76af099aSliuyi 		m_flashInfo.usBlockSize = info.usBlockSize / 2;
308*76af099aSliuyi 		m_flashInfo.bECCBits = info.bECCBits;
309*76af099aSliuyi 		m_flashInfo.bAccessTime = info.bAccessTime;
310*76af099aSliuyi 		m_flashInfo.uiBlockNum = m_flashInfo.uiFlashSize * 1024 / m_flashInfo.usBlockSize;
311*76af099aSliuyi 		m_flashInfo.uiSectorPerBlock = info.usBlockSize;
312*76af099aSliuyi 		m_flashInfo.bFlashCS = info.bFlashCS;
313*76af099aSliuyi 		m_flashInfo.usValidSecPerBlock = (info.usBlockSize / info.bPageSize) * 4;
314*76af099aSliuyi 		if (m_pFlashInfoData) {
315*76af099aSliuyi 			delete []m_pFlashInfoData;
316*76af099aSliuyi 			m_pFlashInfoData = NULL;
317*76af099aSliuyi 		}
318*76af099aSliuyi 		m_usFlashInfoDataLen = BYTE2SECTOR(uiRead);
319*76af099aSliuyi 		m_pFlashInfoData = new BYTE[SECTOR_SIZE * m_usFlashInfoDataLen];
320*76af099aSliuyi 		memset(m_pFlashInfoData, 0, SECTOR_SIZE * m_usFlashInfoDataLen);
321*76af099aSliuyi 		memcpy(m_pFlashInfoData, (PBYTE)&info, uiRead);
322*76af099aSliuyi 		if (m_pLog) {
323*76af099aSliuyi 			string strFlashInfo;
324*76af099aSliuyi 			m_pLog->PrintBuffer(strFlashInfo, m_pFlashInfoData, 11);
325*76af099aSliuyi 			m_pLog->Record("<LAYER %s> INFO:FlashInfo:%s", m_layerName, strFlashInfo.c_str());
326*76af099aSliuyi 		}
327*76af099aSliuyi 	} else {
328*76af099aSliuyi 		if (m_pLog) {
329*76af099aSliuyi 			m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashInfo failed, RetCode(%d)", m_layerName, iRet);
330*76af099aSliuyi 		}
331*76af099aSliuyi 		return false;
332*76af099aSliuyi 	}
333*76af099aSliuyi 	iRet = m_pComm->RKU_ReadFlashID(flashID);
334*76af099aSliuyi 	if( ERR_SUCCESS == iRet ) {
335*76af099aSliuyi 		DWORD *pID = (DWORD *)flashID;
336*76af099aSliuyi 		if (*pID==0x434d4d45)/*emmc*/ {
337*76af099aSliuyi 			m_bEmmc = true;
338*76af099aSliuyi 		} else
339*76af099aSliuyi 			m_bEmmc = false;
340*76af099aSliuyi 	} else {
341*76af099aSliuyi 		if (m_pLog) {
342*76af099aSliuyi 			m_pLog->Record("<LAYER %s> ERROR:GetFlashInfo-->RKU_ReadFlashID failed, RetCode(%d)", m_layerName, iRet);
343*76af099aSliuyi 		}
344*76af099aSliuyi 		return false;
345*76af099aSliuyi 	}
346*76af099aSliuyi 	return true;
347*76af099aSliuyi }
348*76af099aSliuyi bool CRKDevice::TestDevice()
349*76af099aSliuyi {
350*76af099aSliuyi 	int iResult, iTryCount;
351*76af099aSliuyi 	DWORD dwTotal, dwCurrent, dwLayerID;
352*76af099aSliuyi 	dwLayerID = m_locationID;
353*76af099aSliuyi 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
354*76af099aSliuyi 	do {
355*76af099aSliuyi 		iTryCount = 3;
356*76af099aSliuyi 		while (iTryCount > 0) {
357*76af099aSliuyi 			iResult = m_pComm->RKU_TestDeviceReady(&dwTotal, &dwCurrent);
358*76af099aSliuyi 			if ((iResult == ERR_SUCCESS) || (iResult == ERR_DEVICE_UNREADY)) {
359*76af099aSliuyi 				break;
360*76af099aSliuyi 			}
361*76af099aSliuyi 			if (m_pLog) {
362*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, RetCode(%d)", m_layerName, iResult);
363*76af099aSliuyi 			}
364*76af099aSliuyi 			iTryCount--;
365*76af099aSliuyi 			sleep(1);
366*76af099aSliuyi 		}
367*76af099aSliuyi 		if (iTryCount <= 0) {
368*76af099aSliuyi 			return false;
369*76af099aSliuyi 		}
370*76af099aSliuyi 
371*76af099aSliuyi 		if (iResult == ERR_SUCCESS) {
372*76af099aSliuyi 			if (emCallStep == CALL_MIDDLE) {
373*76af099aSliuyi 				if (m_callBackProc) {
374*76af099aSliuyi 					dwCurrent = dwTotal;
375*76af099aSliuyi 					emCallStep = CALL_LAST;
376*76af099aSliuyi 					m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
377*76af099aSliuyi 				}
378*76af099aSliuyi 			}
379*76af099aSliuyi 			break;
380*76af099aSliuyi 		}
381*76af099aSliuyi 		if (dwCurrent>dwTotal) {
382*76af099aSliuyi 			if (m_pLog) {
383*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed,Total=%d, Current=%d", m_layerName, dwTotal, dwCurrent);
384*76af099aSliuyi 			}
385*76af099aSliuyi 			return false;
386*76af099aSliuyi 		}
387*76af099aSliuyi 		if (UsbType == RKUSB_LOADER) {
388*76af099aSliuyi 			if (dwTotal == 0) {
389*76af099aSliuyi 				if (m_pLog)
390*76af099aSliuyi 				{
391*76af099aSliuyi 					m_pLog->Record("<LAYER %s> ERROR:TestDevice-->RKU_TestDeviceReady failed, Total is zero", m_layerName);
392*76af099aSliuyi 				}
393*76af099aSliuyi 				return false;
394*76af099aSliuyi 			}
395*76af099aSliuyi 		}
396*76af099aSliuyi 		if (m_callBackProc)
397*76af099aSliuyi 		{
398*76af099aSliuyi 			m_callBackProc(dwLayerID, TESTDEVICE_PROGRESS, dwTotal, dwCurrent, emCallStep);
399*76af099aSliuyi 			emCallStep = CALL_MIDDLE;
400*76af099aSliuyi 		}
401*76af099aSliuyi 		sleep(1);
402*76af099aSliuyi 	}while(iResult == ERR_DEVICE_UNREADY);
403*76af099aSliuyi 	return true;
404*76af099aSliuyi }
405*76af099aSliuyi bool CRKDevice::ResetDevice()
406*76af099aSliuyi {
407*76af099aSliuyi 	int iRet;
408*76af099aSliuyi 	iRet = m_pComm->RKU_ResetDevice();
409*76af099aSliuyi 	if (iRet == ERR_SUCCESS) {
410*76af099aSliuyi 		return true;
411*76af099aSliuyi 	} else {
412*76af099aSliuyi 		bool bRet = false;
413*76af099aSliuyi 		if ((iRet == -2) || (iRet == -4)) {
414*76af099aSliuyi 			bRet = true;
415*76af099aSliuyi 		}
416*76af099aSliuyi 		if (m_pLog) {
417*76af099aSliuyi 			m_pLog->Record("<LAYER %s> ERROR:ResetDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
418*76af099aSliuyi 		}
419*76af099aSliuyi 		return bRet;
420*76af099aSliuyi 	}
421*76af099aSliuyi }
422*76af099aSliuyi 
423*76af099aSliuyi bool CRKDevice::PowerOffDevice()
424*76af099aSliuyi {
425*76af099aSliuyi 	int iRet;
426*76af099aSliuyi 	iRet = m_pComm->RKU_ResetDevice(RST_POWEROFF_SUBCODE);
427*76af099aSliuyi 	if (iRet == ERR_SUCCESS) {
428*76af099aSliuyi 		return true;
429*76af099aSliuyi 	} else {
430*76af099aSliuyi 		if (m_pLog) {
431*76af099aSliuyi 			m_pLog->Record("<LAYER %s> ERROR:PowerOffDevice-->RKU_ResetDevice failed, RetCode(%d)", m_layerName, iRet);
432*76af099aSliuyi 		}
433*76af099aSliuyi 		return false;
434*76af099aSliuyi 	}
435*76af099aSliuyi }
436*76af099aSliuyi bool CRKDevice::CheckChip()
437*76af099aSliuyi {
438*76af099aSliuyi 	int iRet;
439*76af099aSliuyi 	BYTE bChipInfo[CHIPINFO_LEN];
440*76af099aSliuyi 	ENUM_RKDEVICE_TYPE curDeviceType = RKNONE_DEVICE;
441*76af099aSliuyi 	memset(bChipInfo, 0, CHIPINFO_LEN);
442*76af099aSliuyi 	iRet = m_pComm->RKU_ReadChipInfo(bChipInfo);
443*76af099aSliuyi 	if (iRet == ERR_SUCCESS) {
444*76af099aSliuyi 		if (!m_chipData) {
445*76af099aSliuyi 			m_chipData = new BYTE[CHIPINFO_LEN];
446*76af099aSliuyi 		}
447*76af099aSliuyi 		memset(m_chipData, 0, CHIPINFO_LEN);
448*76af099aSliuyi 		memcpy(m_chipData, bChipInfo, CHIPINFO_LEN);
449*76af099aSliuyi 		DWORD *pValue;
450*76af099aSliuyi 		pValue = (DWORD *)(&bChipInfo[0]);
451*76af099aSliuyi 
452*76af099aSliuyi 		if ((ENUM_RKDEVICE_TYPE)(*pValue) == m_device) {
453*76af099aSliuyi 			return true;
454*76af099aSliuyi 		}
455*76af099aSliuyi 		if (*pValue == 0x524B3237) {
456*76af099aSliuyi 			curDeviceType = RK27_DEVICE;
457*76af099aSliuyi 		} else if (*pValue == 0x32373341) {
458*76af099aSliuyi 			curDeviceType = RKCAYMAN_DEVICE;
459*76af099aSliuyi 		} else if (*pValue == 0x524B3238) {
460*76af099aSliuyi 			curDeviceType = RK28_DEVICE;
461*76af099aSliuyi 		} else if (*pValue == 0x32383158) {
462*76af099aSliuyi 			curDeviceType = RK281X_DEVICE;
463*76af099aSliuyi 		} else if (*pValue == 0x32383242) {
464*76af099aSliuyi 			curDeviceType = RKPANDA_DEVICE;
465*76af099aSliuyi 		} else if (*pValue == 0x32393058) {
466*76af099aSliuyi 			curDeviceType = RK29_DEVICE;
467*76af099aSliuyi 		} else if (*pValue == 0x32393258) {
468*76af099aSliuyi 			curDeviceType = RK292X_DEVICE;
469*76af099aSliuyi 		} else if (*pValue == 0x33303041) {
470*76af099aSliuyi 			curDeviceType = RK30_DEVICE;
471*76af099aSliuyi 		} else if (*pValue == 0x33313041) {
472*76af099aSliuyi 			curDeviceType = RK30B_DEVICE;
473*76af099aSliuyi 		} else if (*pValue == 0x33313042) {
474*76af099aSliuyi 			curDeviceType = RK31_DEVICE;
475*76af099aSliuyi 		} else if (*pValue == 0x33323041) {
476*76af099aSliuyi 			curDeviceType = RK32_DEVICE;
477*76af099aSliuyi 		} else if (*pValue == 0x32363243) {
478*76af099aSliuyi 			curDeviceType = RKSMART_DEVICE;
479*76af099aSliuyi 		} else if (*pValue == 0x6E616E6F) {
480*76af099aSliuyi 			curDeviceType = RKNANO_DEVICE;
481*76af099aSliuyi 		} else if (*pValue == 0x4E4F5243) {
482*76af099aSliuyi 			curDeviceType = RKCROWN_DEVICE;
483*76af099aSliuyi 		}
484*76af099aSliuyi 
485*76af099aSliuyi 		if (curDeviceType == m_device){
486*76af099aSliuyi 			return true;
487*76af099aSliuyi 		} else {
488*76af099aSliuyi 			if (m_pLog) {
489*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:CheckChip-->Chip is not match, firmware(0x%x), device(0x%x)", m_layerName, m_device, *pValue);
490*76af099aSliuyi 			}
491*76af099aSliuyi 			return false;
492*76af099aSliuyi 		}
493*76af099aSliuyi 	}
494*76af099aSliuyi 	else {
495*76af099aSliuyi 		if (m_pLog) {
496*76af099aSliuyi 			m_pLog->Record("<LAYER %s> ERROR:CheckChip-->RKU_ReadChipInfo failed,RetCode(%d)", m_layerName, iRet);
497*76af099aSliuyi 		}
498*76af099aSliuyi 		return false;
499*76af099aSliuyi 	}
500*76af099aSliuyi }
501*76af099aSliuyi 
502*76af099aSliuyi int CRKDevice::DownloadBoot()
503*76af099aSliuyi {
504*76af099aSliuyi 	UCHAR i;
505*76af099aSliuyi 	DWORD dwSize, dwDelay;
506*76af099aSliuyi 	PBYTE pBuffer = NULL;
507*76af099aSliuyi 	for ( i = 0; i < m_pImage->m_bootObject->Entry471Count; i++ ) {
508*76af099aSliuyi 		if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY471, i, dwSize, dwDelay) ) {
509*76af099aSliuyi 			if (m_pLog) {
510*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Property failed,index(%d)", m_layerName, i);
511*76af099aSliuyi 			}
512*76af099aSliuyi 			return -2;
513*76af099aSliuyi 		}
514*76af099aSliuyi 		if (dwSize>0) {
515*76af099aSliuyi 			pBuffer = new BYTE[dwSize];
516*76af099aSliuyi 			if ( !m_pImage->m_bootObject->GetEntryData(ENTRY471, i, pBuffer) ) {
517*76af099aSliuyi 				if (m_pLog) {
518*76af099aSliuyi 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry471Data failed,index(%d)", m_layerName, i);
519*76af099aSliuyi 				}
520*76af099aSliuyi 				delete []pBuffer;
521*76af099aSliuyi 				return -3;
522*76af099aSliuyi 			}
523*76af099aSliuyi 			if ( !Boot_VendorRequest(0x0471,pBuffer,dwSize) ) {
524*76af099aSliuyi 				if (m_pLog) {
525*76af099aSliuyi 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest471 failed,index(%d)", m_layerName, i);
526*76af099aSliuyi 				}
527*76af099aSliuyi 				delete []pBuffer;
528*76af099aSliuyi 				return -4;
529*76af099aSliuyi 			}
530*76af099aSliuyi 			delete []pBuffer;
531*76af099aSliuyi 			pBuffer = NULL;
532*76af099aSliuyi 			if (dwDelay>0) {
533*76af099aSliuyi 				usleep(dwDelay * 1000);
534*76af099aSliuyi 			}
535*76af099aSliuyi 
536*76af099aSliuyi 		}
537*76af099aSliuyi 	}
538*76af099aSliuyi 
539*76af099aSliuyi 	for ( i=0; i < m_pImage->m_bootObject->Entry472Count; i++ ) {
540*76af099aSliuyi 		if ( !m_pImage->m_bootObject->GetEntryProperty(ENTRY472, i, dwSize, dwDelay) ) {
541*76af099aSliuyi 			if (m_pLog) {
542*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Property failed,index(%d)", m_layerName, i);
543*76af099aSliuyi 			}
544*76af099aSliuyi 			return -2;
545*76af099aSliuyi 		}
546*76af099aSliuyi 		if (dwSize > 0) {
547*76af099aSliuyi 			pBuffer = new BYTE[dwSize];
548*76af099aSliuyi 			if ( !m_pImage->m_bootObject->GetEntryData(ENTRY472, i, pBuffer) ) {
549*76af099aSliuyi 				if (m_pLog) {
550*76af099aSliuyi 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->GetEntry472Data failed,index(%d)", m_layerName, i);
551*76af099aSliuyi 				}
552*76af099aSliuyi 				delete []pBuffer;
553*76af099aSliuyi 				return -3;
554*76af099aSliuyi 			}
555*76af099aSliuyi 			if ( !Boot_VendorRequest(0x0472, pBuffer, dwSize) ) {
556*76af099aSliuyi 				if (m_pLog) {
557*76af099aSliuyi 					m_pLog->Record("<LAYER %s> ERROR:DownloadBoot-->Boot_VendorRequest472 failed,index(%d)", m_layerName, i);
558*76af099aSliuyi 				}
559*76af099aSliuyi 				delete []pBuffer;
560*76af099aSliuyi 				return -4;
561*76af099aSliuyi 			}
562*76af099aSliuyi 			delete []pBuffer;
563*76af099aSliuyi 			pBuffer = NULL;
564*76af099aSliuyi 			if (dwDelay > 0) {
565*76af099aSliuyi 				usleep(dwDelay * 1000);
566*76af099aSliuyi 			}
567*76af099aSliuyi 		}
568*76af099aSliuyi 	}
569*76af099aSliuyi 	sleep(1);
570*76af099aSliuyi 	return 0;
571*76af099aSliuyi 
572*76af099aSliuyi }
573*76af099aSliuyi bool CRKDevice::Boot_VendorRequest( DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize)
574*76af099aSliuyi {
575*76af099aSliuyi 	int iRet;
576*76af099aSliuyi 	iRet = m_pComm->RKU_DeviceRequest(requestCode, pBuffer, dwDataSize);
577*76af099aSliuyi 	return (iRet == ERR_SUCCESS) ? true : false;
578*76af099aSliuyi }
579*76af099aSliuyi int CRKDevice::EraseAllBlocks()
580*76af099aSliuyi {
581*76af099aSliuyi 	int i;
582*76af099aSliuyi 	UINT uiBlockCount;
583*76af099aSliuyi 	int iRet = ERR_SUCCESS, iErasePos = 0, iEraseBlockNum = 0, iEraseTimes = 0, iCSIndex = 0;
584*76af099aSliuyi 	BYTE bCSCount = 0;
585*76af099aSliuyi 	for (i = 0; i < 8; i++) {
586*76af099aSliuyi 		if ( m_flashInfo.bFlashCS & (1 << i) ) {
587*76af099aSliuyi 			bCSCount++;
588*76af099aSliuyi 		}
589*76af099aSliuyi 	}
590*76af099aSliuyi 	DWORD dwLayerID;
591*76af099aSliuyi 	dwLayerID = LocationID;
592*76af099aSliuyi 	ENUM_CALL_STEP emCallStep = CALL_FIRST;
593*76af099aSliuyi 	if (m_bEmmc) {
594*76af099aSliuyi 		iRet = EraseEmmcBlock(0, 0, IDBLOCK_TOP);
595*76af099aSliuyi 		if (iRet != ERR_SUCCESS) {
596*76af099aSliuyi 			if (m_pLog) {
597*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmcBlock failed,RetCode(%d)", m_layerName, iRet);
598*76af099aSliuyi 			}
599*76af099aSliuyi 			return -1;
600*76af099aSliuyi 		}
601*76af099aSliuyi 		if (!EraseEmmc()) {
602*76af099aSliuyi 			if (m_pLog) {
603*76af099aSliuyi 				m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName);
604*76af099aSliuyi 			}
605*76af099aSliuyi 			return -1;
606*76af099aSliuyi 		}
607*76af099aSliuyi 		return 0;
608*76af099aSliuyi 	}
609*76af099aSliuyi 	for (i = 0; i < 8; i++) {
610*76af099aSliuyi 		if ( m_flashInfo.bFlashCS & (1 << i) ) {
611*76af099aSliuyi 			uiBlockCount = m_flashInfo.uiBlockNum;
612*76af099aSliuyi 			iErasePos = 0;
613*76af099aSliuyi 			iEraseTimes = 0;
614*76af099aSliuyi 			while (uiBlockCount > 0) {
615*76af099aSliuyi 				iEraseBlockNum = (uiBlockCount < MAX_ERASE_BLOCKS) ? uiBlockCount : MAX_ERASE_BLOCKS;
616*76af099aSliuyi 				iRet = m_pComm->RKU_EraseBlock(i, iErasePos, iEraseBlockNum, ERASE_FORCE);
617*76af099aSliuyi 				if ((iRet != ERR_SUCCESS) && (iRet != ERR_FOUND_BAD_BLOCK)) {
618*76af099aSliuyi 					if (m_pLog) {
619*76af099aSliuyi 						m_pLog->Record("<LAYER %s> ERROR:EraseAllBlocks-->RKU_EraseBlock failed,RetCode(%d)", m_layerName, iRet);
620*76af099aSliuyi 					}
621*76af099aSliuyi 					return -1;
622*76af099aSliuyi 				}
623*76af099aSliuyi 				iErasePos += iEraseBlockNum;
624*76af099aSliuyi 				uiBlockCount -= iEraseBlockNum;
625*76af099aSliuyi 				iEraseTimes++;
626*76af099aSliuyi 				if (iEraseTimes % 8 == 0) {
627*76af099aSliuyi 					if (m_callBackProc) {
628*76af099aSliuyi 						m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum + iErasePos, emCallStep);
629*76af099aSliuyi 						emCallStep = CALL_MIDDLE;
630*76af099aSliuyi 					}
631*76af099aSliuyi 				}
632*76af099aSliuyi 			}
633*76af099aSliuyi 			iCSIndex++;
634*76af099aSliuyi 		}
635*76af099aSliuyi 	}
636*76af099aSliuyi 
637*76af099aSliuyi 	if (m_callBackProc) {
638*76af099aSliuyi 		emCallStep = CALL_LAST;
639*76af099aSliuyi 		m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, m_flashInfo.uiBlockNum * bCSCount, iCSIndex * m_flashInfo.uiBlockNum, emCallStep);
640*76af099aSliuyi 	}
641*76af099aSliuyi 	return 0;
642*76af099aSliuyi }
643*76af099aSliuyi 
644