硬件环境:Cypress公司的EZ-USB2.0芯片CY7C68013-128AC.
主要程序:
#include "stdafx.h"
#include "ConfigSensor.h"
#include <iostream.h>
int iMaxOpsPending = 3; //max count of pending
char strBlkBuf[MAX_FILE_SIZE]; //the data to be written
int iDataLen; //the len of the data
int iDataOffset; //the offset of the data
int iAutoHoldRun = 1; //allow auto hold or run
int bHoldOrRun;
HANDLE ghDevice;
int LoadFile(CString strDldFile)
{
unsigned char* pbuf = (unsigned char *) strBlkBuf;
// unsigned char* pVenbuf = (unsigned char *)((CEzMrFrame*)GetParentFrame())->VenBuf;
// strDldFile.MakeLower(); // case insensitive compare
if(strDldFile.Find(".hex") != -1) //intel hex format
{
FILE *fp = fopen(strDldFile, "rb");
if(fp)
{
char endianConversion = 0; // Mask for endian conversion
DWORD offset = 0; // Offset -- set to -1 to get offset from srec or hex file
TMemCache mMemCache;
TMemImg mMemImg;
mMemCache.pImg = &mMemImg;
int result = intel_in(fp, &mMemCache, offset, endianConversion, FALSE);
fclose(fp);
/* for(int k=0; k<mMemCache.nSeg; k++)
{ //check for high mem first; load loader first if necessary
if(mMemCache.pSeg[k].TAddr >= 0x2000)
{
if((!theApp.m_nUseUserDefinedLoader) && (!theApp.m_nUseNoLoader))
{
if(theApp.m_nTarg)
{ // if Fx2
TRACE("loading Fx2 loader/n");
Ezusb_DownloadIntelHex(Vend_Ax_Fx2);
break;
}
else
{ // if Ezusb
TRACE("loading Ezusb loader/n");
Ezusb_DownloadIntelHex(Vend_Ax);
break;
}
}
}
}
for(int i=0; i<theApp.m_MemCache.nSeg; i++)
{ //load all high mem first
if(theApp.m_MemCache.pSeg[i].TAddr >= 0x2000)
{
char text[80];
memcpy(pVenbuf, theApp.m_MemCache.pSeg[i].pData, theApp.m_MemCache.pSeg[i].Size);
SendOp(OP_VEND_REQST);
}
if( ( m_nOpsPending ) >= theApp.m_nMaxOpsPending)
break;
}*/
if(result == -1)
return result; //error
if(iAutoHoldRun)
On_8051_HOLD();
for(int j=0; j < mMemCache.nSeg; j++)
{ //load all low mem last
if(mMemCache.pSeg[j].TAddr < 0x2000)
{
memcpy(pbuf, mMemCache.pSeg[j].pData, mMemCache.pSeg[j].Size);
iDataLen = mMemCache.pSeg[j].Size;
iDataOffset = mMemCache.pSeg[j].TAddr;
SendOp(OP_ANCHOR_DLD);
}
}
if(iAutoHoldRun)
On_8051_RUN();
return result;
}
else
{
AfxMessageBox("Error opening Input file.");
return -1;
}
}
else
return -1;
}
void SendOp(int OpNum)
{
OperationProc(OpNum);
}
void OperationProc(int OpNum)
{
BOOLEAN bResult = FALSE;
int nBytes = 0;
HANDLE hDevice;
char pcDriverName[] = "EZUSB-0";
switch(OpNum)
{
case OP_ANCHOR_DLD:
{
int numread = 0;
char temp[64] = "";
ANCHOR_DOWNLOAD_CONTROL downloadControl;
unsigned char* buffer;
downloadControl.Offset = (USHORT) iDataOffset;
buffer = (unsigned char*) strBlkBuf;
numread = iDataLen;
wsprintf (temp, "Anchor Download %d bytes: addr=%x",numread, downloadControl.Offset);
cout<<temp<<endl;
// Open the driver
if (bOpenDriver (&hDevice, pcDriverName) != TRUE)
{
cout<<"Failed to Open Driver"<<endl;
hDevice = NULL;
}
if (hDevice != NULL)
{
if(iDataOffset < 0x2000)
{
bResult = DeviceIoControl (hDevice,
IOCTL_EZUSB_ANCHOR_DOWNLOAD,
&downloadControl,
sizeof(ANCHOR_DOWNLOAD_CONTROL),
buffer,
numread,
(unsigned long *)&nBytes,
NULL);
if(!bResult)
cout<<"Download error!"<<endl;
}
else
{
VENDOR_OR_CLASS_REQUEST_CONTROL myRequest;
myRequest.request = (BYTE) 0xA3;
myRequest.value = (WORD) iDataOffset;
myRequest.index = (WORD) 0x00;
myRequest.direction = 0;
myRequest.requestType = 2;
myRequest.recepient = 0;
bResult = DeviceIoControl (hDevice,
IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,
&myRequest,
sizeof(VENDOR_OR_CLASS_REQUEST_CONTROL),
buffer,
numread,
(unsigned long *)&nBytes,
NULL);
if (bResult==TRUE)
{
/*if(theApp.m_nVerbose)
DumpBuffer(buffer,nBytes,hOutputBox);*/
}
else
{
cout<<"Vendor Request failed"<<endl;
}
}
}/* if valid driver handle */
if (bResult==TRUE)
{
// do nothin
}
else
{
cout<<"Anchor Download failed"<<endl;
}
CloseHandle (hDevice); // Close the handle
}
break;
case OP_8051__HOLD:
case OP_8051___RUN:
{
VENDOR_REQUEST_IN myRequest;
cout<<"Toggle 8051 Reset"<<endl;
bool bFX2 = true; //use fx2
// Open the driver
if (bOpenDriver (&hDevice, pcDriverName) != TRUE)
{
cout<<"Failed to Open Driver"<<endl;
hDevice = NULL;
}
myRequest.bRequest = 0xA0;
if(bFX2)
myRequest.wValue = 0xE600; // using CPUCS.0 in FX2
else
myRequest.wValue = 0x7F92;
myRequest.wIndex = 0x00;
myRequest.wLength = 0x01;
myRequest.bData = (bHoldOrRun == OP_8051__HOLD) ? 1 : 0;
myRequest.direction = 0x00;
if (hDevice != NULL)
{// Perform the Get-Descriptor IOCTL
bResult = DeviceIoControl (hDevice,
IOCTL_Ezusb_VENDOR_REQUEST,
&myRequest,
sizeof(VENDOR_REQUEST_IN),
NULL,
0,
(unsigned long *)&nBytes,
NULL);
}/* if valid driver handle */
if (bResult==TRUE)
{
// do nothin
}
else
{
cout<<"Reset Failed"<<endl;
}
// Close the handle
CloseHandle (hDevice);
}
break;
}// end of switch
}
void On_8051_HOLD()
{ //TPMDo: Add m_wndTBarVen manually
bHoldOrRun = OP_8051__HOLD;
SendOp(OP_8051__HOLD);
}
void On_8051_RUN()
{ //TPMDo: Add m_wndTBarVen manually
bHoldOrRun = OP_8051___RUN;
SendOp(OP_8051___RUN);
}
#define MAXSTR 256 // Maximum length of Intel Hex file string
int intel_in(FILE *fpIn, TMemCache* pMemCache, DWORD &ioOffset,
char endianFlags, BOOLEAN spaces)
{
int i;
char str[MAXSTR];
unsigned byte;
int curSeg = 0; // current seg record
int recType;
unsigned addr;
int cnt;
unsigned int totalRead = 0;
int CNTFIELD ;
int ADDRFIELD;
int RECFIELD ;
int DATAFIELD;
// offsets of fields within record -- may change later due to "spaces" setting
CNTFIELD = 1;
ADDRFIELD = 3;
RECFIELD = 7;
DATAFIELD = 9;
if (!fpIn)
return(0);
addr = 0;
pMemCache->nSeg = 0;
while(fgets(str,MAXSTR,fpIn))
{
TRACE("dldhex:%s", str);
if(str[0]!=':')
{
return(-1);
}
/* get the record type */
if (spaces || str[1] == ' ')
{
CNTFIELD = 1 + 1;
ADDRFIELD = 3 + 2;
RECFIELD = 7 + 3;
DATAFIELD = 9 + 4;
}
sscanf(str+RECFIELD,"%2x",&recType);
PCHAR ptr = pMemCache->pImg->data;
switch(recType)
{
case 2: /*seg record*/
sscanf(str+DATAFIELD,"%4x",&curSeg);
curSeg *= 0x10;
break;
case 0: /*data record*/
sscanf(str+CNTFIELD,"%2x",&cnt);
sscanf(str+ADDRFIELD,"%4x",&addr);
if(addr >= TGT_IMG_SIZE)
{
cout<<"Error loading file: address out of range/n";
return(totalRead);
}
ptr += addr; // get pointer to location in image
if(pMemCache->nSeg &&
(pMemCache->pSeg[pMemCache->nSeg-1].TAddr ==
addr - pMemCache->pSeg[pMemCache->nSeg-1].Size) &&
(pMemCache->pSeg[pMemCache->nSeg-1].Size + cnt <= MAX_EP0_XFER_SIZE) )
{ // if the segment is contiguous to the last segment, and it's not too big yet
pMemCache->pSeg[pMemCache->nSeg-1].Size += cnt; // append to previous segment
}
else
{ // start a new segment
pMemCache->pSeg[pMemCache->nSeg].TAddr = addr;
pMemCache->pSeg[pMemCache->nSeg].Size = cnt;
pMemCache->pSeg[pMemCache->nSeg].pData = ptr;
pMemCache->nSeg++;
}
for(i=0; i<cnt; i++)
{
sscanf(str+DATAFIELD+i*2,"%2x",&byte);
*(ptr + i) = byte;
totalRead++;
}
break;
case 1: /*end record*/
return(totalRead);
break;
default:
break;
}
}
return(-1); // missing end record
}
void Ezusb_DownloadIntelHex(PINTEL_HEX_RECORD pHexRecord)
{
PINTEL_HEX_RECORD ptr = pHexRecord;
unsigned char* pbuf = (unsigned char *)strBlkBuf;
unsigned char* ptmp = NULL;
ptr = pHexRecord;
On_8051_HOLD();
while (ptr->Type == 0)
{ //load low mem
if((ptmp != NULL) &&
(iDataOffset+iDataLen == ptr->Address) &&
((iDataLen+ptr->Length) <= MAX_EP0_XFER_SIZE) )
{ // continue a segment
memcpy(ptmp, ptr->Data, ptr->Length);
iDataLen += ptr->Length;
ptmp += ptr->Length;
}
else
{ // start a new segment
if(ptmp != NULL)
{ // send prev segment first
SendOp(OP_ANCHOR_DLD);
}
ptmp = pbuf;
memcpy(ptmp, ptr->Data, ptr->Length);
iDataLen = ptr->Length;
iDataOffset = ptr->Address;
ptmp += ptr->Length;
}
ptr++;
}
if(ptmp != NULL)
{ // send final segment
SendOp(OP_ANCHOR_DLD);
}
On_8051_RUN();
}
BOOLEAN bOpenDriver(HANDLE * phDeviceHandle, PCHAR devname)
{
char completeDeviceName[64] = "";
char pcMsg[64] = "";
strcat (completeDeviceName,
"////.//"
);
strcat (completeDeviceName,
devname
);
*phDeviceHandle = CreateFile( completeDeviceName,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
if (*phDeviceHandle == INVALID_HANDLE_VALUE)
{
return (FALSE);
}
else
{
return (TRUE);
} /*else*/
}//OpenDevice
BOOLEAN ConnectDevice()
{
HANDLE hDevice = NULL;
char DeviceName[MAX_DRIVER_NAME] = "EZUSB-0";
if (bOpenDriver (&hDevice, DeviceName) != TRUE)
{
cout<<"Failed to Open Device/n";
return false;
}
// ghDevice = hDevice;
CloseHandle(hDevice);
return true;
}//ConnectDevice