rkdeveloptool/RKComm.cpp
liuyi 081d237ad5 rkdeveloptool: v1.3
1.add LD to list devices
2.add PRM to write parameter
3.change PGPT to PPT to support print parameter and GPT

Signed-off-by: liuyi <liuyi@rock-chips.com>
2018-03-28 09:22:40 +08:00

794 lines
18 KiB
C++

/*
* (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
* Seth Liu 2017.03.01
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "RKComm.h"
#include "RKLog.h"
#include "Endian.h"
extern unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber);
CRKComm::CRKComm(CRKLog *pLog)
{
memset(&m_deviceDesc,0,sizeof(STRUCT_RKDEVICE_DESC));
m_log = pLog;
}
CRKComm::~CRKComm()
{
}
CRKUsbComm::CRKUsbComm(STRUCT_RKDEVICE_DESC devDesc, CRKLog *pLog, bool &bRet):CRKComm(pLog)
{
bRet = InitializeUsb(devDesc);
}
CRKUsbComm::~CRKUsbComm()
{
UninitializeUsb();
}
bool CRKUsbComm::InitializeUsb(STRUCT_RKDEVICE_DESC devDesc)
{
m_pUsbHandle = NULL;
m_pipeBulkIn = m_pipeBulkOut = 0;
m_interfaceNum = -1;
if (!devDesc.pUsbHandle) {
return false;
}
memcpy(&m_deviceDesc, &devDesc, sizeof(STRUCT_RKDEVICE_DESC));
int iRet;
iRet = libusb_open((libusb_device *)devDesc.pUsbHandle, (libusb_device_handle **)&m_pUsbHandle);
if (iRet!=0) {
if (m_log) {
m_log->Record("Error:InitializeUsb-->open device failed,err=%d", iRet);
}
return false;
}
struct libusb_config_descriptor *pConfigDesc=NULL;
iRet = libusb_get_active_config_descriptor((libusb_device *)devDesc.pUsbHandle, &pConfigDesc);
if (iRet!=0) {
if (m_log) {
m_log->Record("Error:InitializeUsb-->get device config descriptor failed, err=%d", iRet);
}
return false;
}
int i, j, k;
const struct libusb_interface *pInterface;
const struct libusb_endpoint_descriptor *pEndpointDesc;
const struct libusb_interface_descriptor *pInterfaceDesc;
for(i = 0; i < pConfigDesc->bNumInterfaces; i++) {
pInterface = pConfigDesc->interface + i;
for(j = 0; j < pInterface->num_altsetting; j++) {
pInterfaceDesc = pInterface->altsetting+j;
if (m_deviceDesc.emUsbType == RKUSB_MSC) {
if( (pInterfaceDesc->bInterfaceClass != 8) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 0x50))
continue;
}
else
{
if( (pInterfaceDesc->bInterfaceClass != 0xff) || (pInterfaceDesc->bInterfaceSubClass != 6) || (pInterfaceDesc->bInterfaceProtocol != 5))
continue;
}
for(k = 0; k < pInterfaceDesc->bNumEndpoints; k++) {
pEndpointDesc = pInterfaceDesc->endpoint+k;
if ((pEndpointDesc->bEndpointAddress & 0x80) == 0) {
if (m_pipeBulkOut == 0)
m_pipeBulkOut = pEndpointDesc->bEndpointAddress;
}
else {
if (m_pipeBulkIn == 0)
m_pipeBulkIn = pEndpointDesc->bEndpointAddress;
}
if ((m_pipeBulkIn != 0) && (m_pipeBulkOut != 0)) {//found it
m_interfaceNum = i;
libusb_free_config_descriptor(pConfigDesc);
iRet = libusb_claim_interface((libusb_device_handle *)m_pUsbHandle, m_interfaceNum);
if (iRet != 0) {
if (m_log) {
m_log->Record("Error:libusb_claim_interface failed,err=%d", iRet);
}
return false;
}
return true;
}
}
}
}
libusb_free_config_descriptor(pConfigDesc);
return false;
}
void CRKUsbComm::UninitializeUsb()
{
if (m_pUsbHandle) {
libusb_close((libusb_device_handle *)m_pUsbHandle);
m_pUsbHandle = NULL;
}
memset(&m_deviceDesc, 0, sizeof(STRUCT_RKDEVICE_DESC));
m_pipeBulkIn = m_pipeBulkOut = 0;
return ;
}
bool CRKUsbComm::Reset_Usb_Config(STRUCT_RKDEVICE_DESC devDesc)
{
bool bRet;
UninitializeUsb();
bRet = InitializeUsb(devDesc);
return bRet;
}
bool CRKUsbComm::Reset_Usb_Device()
{
int iRet = -1;
if (m_pUsbHandle) {
iRet=libusb_reset_device((libusb_device_handle *)m_pUsbHandle);
}
return (iRet == 0) ? true : false;
}
bool CRKUsbComm::RKU_Read(BYTE* lpBuffer, DWORD dwSize)
{
int iRet;
int nRead;
iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, CMD_TIMEOUT);
if (iRet!=0) {
if (m_log) {
m_log->Record("Error:RKU_Read failed,err=%d", iRet);
}
return false;
}
if (nRead != (int)dwSize) {
if (m_log) {
m_log->Record("Error:RKU_Read failed, size=%d, read=%d", dwSize, nRead);
}
return false;
}
return true;
}
bool CRKUsbComm::RKU_Write(BYTE* lpBuffer, DWORD dwSize)
{
int iRet;
int nWrite;
iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkOut, lpBuffer, dwSize, &nWrite, CMD_TIMEOUT);
if (iRet != 0) {
if (m_log) {
m_log->Record("Error:RKU_Write failed, err=%d", iRet);
}
return false;
}
if (nWrite != (int)dwSize) {
if (m_log) {
m_log->Record("Error:RKU_Write failed, size=%d, read=%d", dwSize, nWrite);
}
return false;
}
return true;
}
int CRKUsbComm::RandomInteger(int low, int high)
{
int k;
double d;
d = (double)rand() / ((double)RAND_MAX + 1);
k = (int)(d * (high - low + 1));
return (low + k);
}
DWORD CRKUsbComm::MakeCBWTag()
{
DWORD tag = 0;
int i = 0;
for(i=0; i<4; i++){
tag <<= 8;
tag += RandomInteger(0, 0xFF);
}
return tag;
}
void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code)
{
memset(pCBW,0, sizeof(CBW));
pCBW->dwCBWSignature = CBW_SIGN;
pCBW->dwCBWTag = MakeCBWTag();
pCBW->cbwcb.ucOperCode = code;
switch(code) {
case TEST_UNIT_READY: /* Test Unit Ready : 0 */
case READ_FLASH_ID: /* Read Flash ID : 1 */
case READ_FLASH_INFO:
case READ_CHIP_INFO:
case READ_EFUSE:
case READ_CAPABILITY:
pCBW->ucCBWFlags= DIRECTION_IN;
pCBW->ucCBWCBLength = 0x06;
break;
case DEVICE_RESET: /* Reset Device : 0xff */
case ERASE_SYSTEMDISK:
case SET_RESET_FLAG:
pCBW->ucCBWFlags = DIRECTION_OUT;
pCBW->ucCBWCBLength = 0x06;
break;
case TEST_BAD_BLOCK: /* Test Bad Block : 3 */
case READ_SECTOR: /* Read Pages : 4 */
case READ_LBA: /* Read Pages : 4 */
case READ_SDRAM: /* Write Pages : 15 */
case READ_SPI_FLASH:
case READ_NEW_EFUSE:
pCBW->ucCBWFlags = DIRECTION_IN;
pCBW->ucCBWCBLength = 0x0a;
break;
case WRITE_SECTOR: /* Write Pages : 5 */
case WRITE_LBA: /* Write Pages : 15 */
case WRITE_SDRAM: /* Write Pages : 15 */
case EXECUTE_SDRAM:
case ERASE_NORMAL: /* Erase Blocks : 6 */
case ERASE_FORCE: /* Read Spare : 11 */
case WRITE_EFUSE:
case WRITE_SPI_FLASH:
case WRITE_NEW_EFUSE:
case ERASE_LBA:
pCBW->ucCBWFlags = DIRECTION_OUT;
pCBW->ucCBWCBLength = 0x0a;
break;
default:
break;
}
}
bool CRKUsbComm::RKU_ClearBuffer(CBW& cbw, CSW& csw)
{
DWORD dwReadBytes=0;
DWORD dwTotalRead=0;
int iTryCount;
iTryCount = 3;
do {
dwReadBytes = RKU_Read_EX((BYTE*)&csw, sizeof(CSW) );
if (UFI_CHECK_SIGN(cbw,csw))
{
return true;
}
if (dwReadBytes != sizeof(CSW))
{
iTryCount--;
sleep(3);
}
dwTotalRead += dwReadBytes;
if (dwTotalRead >= MAX_CLEAR_LEN)
{
break;
}
}while ( iTryCount > 0 );
return false;
}
DWORD CRKUsbComm::RKU_Read_EX(BYTE* lpBuffer, DWORD dwSize)
{
int iRet;
int nRead;
iRet = libusb_bulk_transfer((libusb_device_handle *)m_pUsbHandle, m_pipeBulkIn, lpBuffer, dwSize, &nRead, 5000);
if (iRet != 0) {
if (m_log) {
m_log->Record("Error:RKU_Read_EX failed, err=%d", iRet);
}
return 0;
}
return nRead;
}
int CRKUsbComm::RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_EraseBlock failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
USHORT usCount;
usCount = dwCount;
if(dwCount > MAX_ERASE_BLOCKS)
return ERR_CROSS_BORDER;
InitializeCBW(&cbw, (USB_OPERATION_CODE)ucEraseType);
cbw.ucCBWLUN = ucFlashCS;
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
{
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
{
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
if(csw.ucCSWStatus == 1)
return ERR_FOUND_BAD_BLOCK;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_ReadChipInfo(BYTE* lpBuffer)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
InitializeCBW(&cbw, READ_CHIP_INFO);
cbw.dwCBWTransferLength = 16;
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
{
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read(lpBuffer, 16))
{
return ERR_DEVICE_READ_FAILED;
}
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
{
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_ReadFlashID(BYTE* lpBuffer)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_ReadChipInfo failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
InitializeCBW(&cbw, READ_FLASH_ID);
cbw.dwCBWTransferLength = 5;
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
{
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read(lpBuffer, 5))
{
return ERR_DEVICE_READ_FAILED;
}
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW)))
{
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_ReadFlashInfo failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
InitializeCBW(&cbw, READ_FLASH_INFO);
cbw.dwCBWTransferLength = 11;
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
{
return ERR_DEVICE_WRITE_FAILED;
}
DWORD dwRead;
dwRead = RKU_Read_EX(lpBuffer, 512);
if ((dwRead < 11) || (dwRead > 512))
{
return ERR_DEVICE_READ_FAILED;
}
if (puiRead)
{
*puiRead = dwRead;
}
/*
if(!RKU_Read(hDev, lpBuffer, 11))
{
return ERR_DEVICE_READ_FAILED;
}
*/
if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
{
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_ReadCapability(BYTE* lpBuffer)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_ReadCapability failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
DWORD dwRead;
InitializeCBW(&cbw, READ_CAPABILITY);
cbw.dwCBWTransferLength = 8;
if(!RKU_Write((BYTE*)&cbw, sizeof(CBW)))
{
return ERR_DEVICE_WRITE_FAILED;
}
dwRead = RKU_Read_EX((BYTE*)&csw, sizeof(CSW));
if(dwRead != 8)
{
return ERR_DEVICE_READ_FAILED;
}
memcpy(lpBuffer, (BYTE*)&csw, 8);
if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
{
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_ReadLBA failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
USHORT wSectorSize;
USHORT usSectorLen;
wSectorSize = 512;
usSectorLen=dwCount;
InitializeCBW(&cbw, READ_LBA);
cbw.dwCBWTransferLength = dwCount * wSectorSize;
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
cbw.cbwcb.usLength = EndianU16_LtoB(usSectorLen);
cbw.cbwcb.ucReserved = bySubCode;
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
{
return ERR_DEVICE_WRITE_FAILED;
}
DWORD dwTotal;
dwTotal = usSectorLen * wSectorSize;
if(!RKU_Read(lpBuffer, dwTotal))
{
return ERR_DEVICE_READ_FAILED;
}
if(!RKU_Read((BYTE*)&csw, sizeof(CSW)))
{
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
if(csw.ucCSWStatus == 1)
return ERR_FAILED;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_ResetDevice(BYTE bySubCode)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_ResetDevice failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
InitializeCBW(&cbw, DEVICE_RESET);
cbw.cbwcb.ucReserved = bySubCode;
if(!RKU_Write((BYTE *)&cbw, sizeof(CBW)))
{
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read((BYTE *)&csw, sizeof(CSW)))
{
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) ) {
bool bRet;
bRet = RKU_ClearBuffer(cbw, csw);
if (!bRet) {
return ERR_CMD_NOTMATCH;
}
}
if(csw.ucCSWStatus == 1)
return ERR_FAILED;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_TestDeviceReady(DWORD *dwTotal, DWORD *dwCurrent, BYTE bySubCode)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_TestDeviceReady failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
InitializeCBW(&cbw, TEST_UNIT_READY);
cbw.cbwcb.ucReserved = bySubCode;
if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) ) {
bool bRet;
bRet = RKU_ClearBuffer(cbw ,csw);
if (!bRet) {
return ERR_CMD_NOTMATCH;
}
}
if ((dwTotal!=NULL)&&(dwCurrent!=NULL)) {
*dwCurrent = (csw.dwCBWDataResidue >>16);
*dwTotal = (csw.dwCBWDataResidue & 0x0000FFFF);
*dwTotal = EndianU16_BtoL(*dwTotal);
*dwCurrent = EndianU16_BtoL(*dwCurrent);
}
if(csw.ucCSWStatus == 1) {
return ERR_DEVICE_UNREADY;
}
return ERR_DEVICE_READY;
}
int CRKUsbComm::RKU_WriteLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_WriteLBA failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
USHORT wSectorSize;
USHORT usCount;
wSectorSize = 512;
usCount = dwCount;
DWORD dwTotal = usCount * wSectorSize;
InitializeCBW(&cbw, WRITE_LBA);
cbw.dwCBWTransferLength = dwCount * wSectorSize;
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
cbw.cbwcb.ucReserved = bySubCode;
if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Write( lpBuffer, dwTotal)) {
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
if(csw.ucCSWStatus == 1)
return ERR_FAILED;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_EraseLBA(DWORD dwPos, DWORD dwCount)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_WriteLBA failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
USHORT usCount;
usCount = dwCount;
InitializeCBW(&cbw, ERASE_LBA);
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
if(csw.ucCSWStatus == 1)
return ERR_FAILED;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_WriteSector(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer)
{
if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) {
if (m_log) {
m_log->Record("Error:RKU_WriteSector failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
CBW cbw;
CSW csw;
USHORT wSectorSize;
USHORT usCount;
usCount=dwCount;
if(usCount > 32)
return ERR_CROSS_BORDER;
wSectorSize = 528;
InitializeCBW(&cbw, WRITE_SECTOR);
cbw.dwCBWTransferLength = dwCount * wSectorSize;
cbw.cbwcb.dwAddress = EndianU32_LtoB(dwPos);
cbw.cbwcb.usLength = EndianU16_LtoB(usCount);
if(!RKU_Write( (BYTE *)&cbw, sizeof(CBW))) {
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Write( lpBuffer, usCount * wSectorSize)) {
return ERR_DEVICE_WRITE_FAILED;
}
if(!RKU_Read( (BYTE *)&csw, sizeof(CSW))) {
return ERR_DEVICE_READ_FAILED;
}
if( !UFI_CHECK_SIGN(cbw, csw) )
return ERR_CMD_NOTMATCH;
if(csw.ucCSWStatus == 1)
return ERR_FAILED;
return ERR_SUCCESS;
}
int CRKUsbComm::RKU_DeviceRequest(DWORD dwRequest, BYTE *lpBuffer, DWORD dwDataSize)
{
if (m_deviceDesc.emUsbType != RKUSB_MASKROM) {
if (m_log) {
m_log->Record("Error:RKU_DeviceRequest failed,device not support");
}
return ERR_DEVICE_NOT_SUPPORT;
}
if ((dwRequest != 0x0471) && (dwRequest != 0x0472)) {
if (m_log) {
m_log->Record("Error:RKU_DeviceRequest failed,request not support");
}
return ERR_REQUEST_NOT_SUPPORT;
}
bool bSendPendPacket = false;
USHORT crcValue = 0xffff;
BYTE *pData = NULL;
pData = new BYTE[dwDataSize + 5];
memset(pData, 0, dwDataSize + 5);
memcpy(pData, lpBuffer, dwDataSize);
switch(dwDataSize % 4096) {
case 4095:
++dwDataSize;
break;
case 4094:
bSendPendPacket = true;
break;
case 0:
default:
break;
}
crcValue = CRC_CCITT(pData, dwDataSize);
pData[dwDataSize] = (crcValue & 0xff00) >> 8;
pData[dwDataSize+1] = crcValue & 0x00ff;
dwDataSize += 2;
UINT nSendBytes = 0;
DWORD dwTotalSended = 0;
int iRet;
while(dwTotalSended < dwDataSize) {
nSendBytes = ( (dwDataSize - dwTotalSended) > 4096) ? 4096 : (dwDataSize - dwTotalSended);
iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, pData + dwTotalSended, nSendBytes, CMD_TIMEOUT);
if (iRet != (int)nSendBytes) {
if (m_log) {
m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d",dwRequest, iRet);
}
delete []pData;
return ERR_REQUEST_FAIL;
}
dwTotalSended += nSendBytes;
}
if(bSendPendPacket) {
BYTE ucFillByte = 0;
iRet = libusb_control_transfer((libusb_device_handle *)m_pUsbHandle, 0x40, 0xC, 0, dwRequest, &ucFillByte, 1, CMD_TIMEOUT);
if (iRet != 0) {
if (m_log) {
m_log->Record("Error:RKU_DeviceRequest-->DeviceRequest vendor=0x%x failed, err=%d", dwRequest, iRet);
}
delete []pData;
return ERR_REQUEST_FAIL;
}
}
delete []pData;
return ERR_SUCCESS;
}