Tech Support > Computer Hardware > Microprocessors > How to opena handle to "Cypress EZ-USB FX2 (68613) - EEPROM missing" and download a program to RAM
How to opena handle to "Cypress EZ-USB FX2 (68613) - EEPROM missing" and download a program to RAM
Posted by Bill Davy on June 7th, 2007


But NOT using EZ-USB which I suspect is messing my programme up. Perhaps it
does not allow for the extra memory in the FX2LP. I have written code to
download a program (in hex or iic format) to RAM or EEPROM, but that was
when the FX2 was running vend-ax (or our software, which is derived from
it). I just need to get a file handle and then use some library functionto
send 0xA0 commands to fill memory (bracketed by setting and clearing Reset
bit in CPUCS).

Or has someone already written this :-)

I tried using
SetupDiGetClassDevs() with various GUID:

static GUID GUID_0xe0317cca = {0xe0317cca, 0xbb7c, 0x4e2a, 0x9f, 0x28, 0xa6,
0x98, 0xe6, 0x0e, 0xde, 0x99};

static GUID GUID_0x36FC9E60 = {0x36FC9E60, 0xC465, 0x11CF, 0x80, 0x56, 0x44,
0x45, 0x53, 0x54, 0x00, 0x00};

And keep getting ERROR_NO_MORE_ITEMS even for interface number zero.


hCypress = CreateFile(\\\\.\\ezusb-0,GENERIC_WRITE,

FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

0,

NULL);

yields a good handle but then

DeviceIoControl( hCypress, IOCTL_ADAPT_GET_DRIVER_VERSION,

&Ver, sizeof(Ver),

&Ver, sizeof(Ver),

&BytesReturned, NULL)

fails with "The parameter is incorrect".



I also tried the thing I really wanted to do and it failed with "The
parameter is incorrect":



{

const unsigned iPage = 0;


const size_t BufferLength = 64;


const unsigned __int16 MemoryAddress = BufferLength * iPage;


const size_t InfoBlockSize = sizeof(SINGLE_TRANSFER) + BufferLength;

char InfoBlock[InfoBlockSize];

PSINGLE_TRANSFER pInfoBlock = (PSINGLE_TRANSFER)InfoBlock;

union

{

struct

{

UCHAR Recipient:5;

UCHAR Type:2;

UCHAR Direction:1;

} Bits;


UCHAR Byte;

} Request;

Request.Bits.Recipient = TGT_DEVICE;

Request.Bits.Type = REQ_VENDOR;

Request.Bits.Direction = DIR_FROM_DEVICE;


memset(InfoBlock,0,sizeof(InfoBlock));


pInfoBlock->SetupPacket.bmRequest = Request.Byte;

pInfoBlock->SetupPacket.bRequest = VR_ANCHOR_LOAD_INTERNAL;

pInfoBlock->SetupPacket.wVal.lowByte = LSByte(MemoryAddress);

pInfoBlock->SetupPacket.wVal.hiByte = MSByte(MemoryAddress);

pInfoBlock->SetupPacket.wIndex = 0x0000;

pInfoBlock->SetupPacket.wLen.lowByte = LSByte(BufferLength);

pInfoBlock->SetupPacket.wLen.hiByte = MSByte(BufferLength);

pInfoBlock->SetupPacket.ulTimeOut = 2; // Seconds ?

pInfoBlock->ucEndpointAddress = 0x00; // Endpoint 0

pInfoBlock->IsoPacketOffset = 0;

pInfoBlock->BufferOffset = sizeof(SINGLE_TRANSFER);

pInfoBlock->BufferLength = BufferLength;

DWORD BytesReturned = 0;


if ( ! DeviceIoControl( hCypress, IOCTL_ADAPT_SEND_EP0_CONTROL_TRANSFER,

pInfoBlock, InfoBlockSize,

pInfoBlock, InfoBlockSize,

&BytesReturned, NULL) )

{

const LastErrorC LastError;

cerr << "DeviceIoControl() returned " << LastError << endl;

return 1;

}

else if ( BytesReturned != InfoBlockSize )

{

cerr << "BytesReturned=" << BytesReturned << ", InfoBlockSize=" <<
InfoBlockSize << endl;

return 1;

}

}


Any suggestions?

Many thanks

Bill


Posted by jetmarc@hotmail.com on June 8th, 2007


Hi Bill,

I made a win32 commandline tool to personalize my product. It starts
from a blank device ("EEPROM missing") and automatically does all the
necessary steps, including what you're looking for.

Download the Cypress developper kit which comes with the source code
to EzMr. All the code is in there for you to cut&paste. You have to
use DeviceIoControl() with a VENDOR_OR_CLASS_REQUEST_CONTROL for the
A0-Upload.

Regards,
Marc

Posted by runner on June 8th, 2007



"Bill Davy" <Bill@SynectixLtd.com> wrote in message
news:mridnY3yCPM4Q_rbRVnyvAA@bt.com...
I did that, but i wrote the driver and i don't know much about the
development kit from Cypress. I only studied the examples about the
firmware. Besides, i don't get what you mean when you say "But NOT
using EZ-USB...". Do they provide different drivers for each chip?





Posted by Bill Davy on June 8th, 2007



"runner" <emb@dded> wrote in message
news:46694bda$0$4796$4fafbaef@reader4.news.tin.it. ..
EZ-USB seems to be truncating the program at 8K when the FX2LP goes to 16 K.

However, Marc's uggestion I look at EZMR may help (the wrapping is there
too, but accessible). I too am now writng a command line (console)
application to bring a chip up from the "No EEPROM" state.

Hey ho
Bill



Posted by runner on June 8th, 2007


There is no way you can upload the higher 8K by an
"A0 Request". It is written somewhere in the manual.
Don't ask me where. The last time i checked i had a
hard time. The solution is to upload a small relocator
first. It loads the higher 8K by relocating. Then you
upload the lower 8K.




Posted by jetmarc@hotmail.com on June 11th, 2007


An additional note for Bill: The Cypress devkit includes a source-
code example called "a3load" which is basically what you describe
above. Once loaded to the FX2, you can use A3 as opcode instead of
A0. It has similar semantics, but is interpreted in software and has
less limitations. The only thing to beware of is not to overwrite it
while using it.

Regards,
Marc


Posted by Bill Davy on June 12th, 2007



"runner" <emb@dded> wrote in message
news:46699ea3$0$17946$4fafbaef@reader1.news.tin.it ...
The FX2LP core seems to load the 16K fine using A0 command. At least, I
load 8K+ bytes and then verify they are as written.

Sadly, some of the Cypress utilities hardwire the 8K limit so do not work
for FX2LP. I found data intended for 8K+X was ending up in X

Sadly, there is no easy way to find out what the processor is. If it was in
a register it could be read using A0 command and a decision could be taken.

By looking at the USB traffic (using http://sysnucleus.com/ which is really
neat, and soon I will find out how to interpret the log and capture data
in), I find CyConsole downloads its own loader to RAM before loading (large)
EEPROM. I've copied the salient partsof vend_ax into my program and now
Imust find out why it does not work. Hey ho.

Thanks for the help and suggestions.

Bill



Posted by runner on June 12th, 2007



"Bill Davy" <Bill@SynectixLtd.com> wrote in message
news:_IidnQhcvPQ36PPbnZ2dnUVZ8taknZ2d@bt.com...
How do you show that?



Posted by Bill Davy on June 13th, 2007



"runner" <emb@dded> wrote in message
news:466eb097$0$37205$4fafbaef@reader3.news.tin.it ...
By loading all 9K into RAM and then checking. Had there been wrap around,
the bottom 1K would not verify, though the top 1K would, spuriously. That's
why I load all 9K in and then verify all 9K. Simple read-after-write
verification provides spurious reassurance.



Posted by runner on June 13th, 2007


and then use some library function to send 0xA0 commands to fill
memory". And then you said that you have troubles in doing so. So i
ask you "how could you issue an 0xA0 request and see it working?"

Is 0xA0 request working?
Is your vend-ax derived code working?

As i told you i don't remember where i read about the 8K limitation.
(Perhaps i had a vision). But i remember that John Hyde used the
"mover code trick" in a loader driver. I didn't base my driver on that so
i can't tell you more. Note: the driver was for the older version of the
ez-usb chip, AN21xx.





Posted by Bill Davy on June 13th, 2007



"runner" <emb@dded> wrote in message
news:466fe158$0$37202$4fafbaef@reader3.news.tin.it ...
Because I have found out how to open a handle (use Code 1 below) and then
use Code 2 belkow to read/write RAM.

It seems to be.

Eeek. Another generation! Well done on surviving.

Code 1:
os << "\\\\.\\ezusb-" << InterfaceNumber << ends;

}

hCypress = CreateFile( DeviceFileName,

GENERIC_WRITE,

FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

0,

NULL);

if (hCypress == INVALID_HANDLE_VALUE)



Code 2:

VENDOR_OR_CLASS_REQUEST_CONTROL myRequest;

myRequest.request = (BYTE) VR_ANCHOR_LOAD_INTERNAL;

myRequest.value = (WORD) Offset;

myRequest.index = (WORD) 0x00;

myRequest.direction = ReadFlag ? DIR_FROM_DEVICE : DIR_TO_DEVICE;

myRequest.requestType = REQ_VENDOR;

myRequest.recepient = TGT_DEVICE;


const BOOL bResult = DeviceIoControl ( hDevice,

IOCTL_EZUSB_VENDOR_OR_CLASS_REQUEST,

&myRequest,

sizeof(VENDOR_OR_CLASS_REQUEST_CONTROL),

(LPVOID)pData,

nBytesToTransfer,

&nBytesTransferred,

(LPOVERLAPPED)NULL);

if ( bResult == FALSE )

{




Posted by runner on June 13th, 2007



Now i recall where i read about the 8K limit. It was not in the manual, it
was at

http://pages.cpsc.ucalgary.ca/~walpo...s/fx2comms.cpp

Read the comment above the function:

FX2COMMS_API int fx2_load_firmware(char *filename)

I found a copy of the general purpose driver specs. The ANCHOR_DOWNLOAD
ioctl says that the download size must be <= 7K. "fx2_load_firmware" uses
that.

The VENDOR_OR_CLASS_REQUEST you're using now doesn't say anything about the
size. Do you write 9K in just one large transfer?




Posted by Bill Davy on June 14th, 2007


Hi

Well, it does seem to write one very big slab of RAM (in excess of 8K).
This to to an FX2LP of course. I limit EzUsb transfers to 1024 and CyUsb
transfers to 4096. Not sure why, but it works. I'd be happy to zip up the
source code, if anyone is interested; it's simple C++ under Microsoft Visual
C++ 2003'ish, but it is just a lash up.

Rgds,

Bill

Opened: \\.\ezusb-0
Writing 1 bytes of RAM at 0xe600
Writing 69 bytes of RAM at 0x0
Writing 15 bytes of RAM at 0x46
Writing 8570 bytes of RAM at 0x56
Reading 69 bytes of RAM at 0x0
Reading 15 bytes of RAM at 0x46
Reading 8570 bytes of RAM at 0x56
RAM verified
Writing 1 bytes of RAM at 0xe600
Waiting 5 seconds to enumerate
Opened:
\\?\usb#vid_16cb&pid_8f00#serno.0000#{f618a337-2b7a-4115-aeaf-578a16a66677}
Writing 8711 bytes of EEPROM at 0x0
Writing took 0.831 milliseconds
Reading 8711 bytes of EEPROM at 0x0
Reading took 0.351 milliseconds
EEPROM verified



CreatFile(\\.\ezusb-0, ...): The system cannot find the file specified.
Opened:
\\?\usb#vid_16cb&pid_8f00#serno.0000#{f618a337-2b7a-4115-aeaf-578a16a66677}
Writing 1 bytes of RAM at 0xe600
Writing 69 bytes of RAM at 0x0
Writing 15 bytes of RAM at 0x46
Writing 8570 bytes of RAM at 0x56
Reading 69 bytes of RAM at 0x0
Reading 15 bytes of RAM at 0x46
Reading 8570 bytes of RAM at 0x56
RAM verified
Writing 1 bytes of RAM at 0xe600
Waiting 5 seconds to enumerate
Opened:
\\?\usb#vid_16cb&pid_8f00#serno.0000#{f618a337-2b7a-4115-aeaf-578a16a66677}
Writing 8711 bytes of EEPROM at 0x0
Writing took 0.832 milliseconds
Reading 8711 bytes of EEPROM at 0x0
Reading took 0.34 milliseconds
EEPROM verified


"runner" <emb@dded> wrote in message
news:46706ba8$0$37203$4fafbaef@reader3.news.tin.it ...


Posted by runner on June 14th, 2007



"Bill Davy" <Bill@SynectixLtd.com> wrote in message
news:-sidnTUqfb6wkOzbRVnyiwA@bt.com...
Thanks for the code but i'm not using Cypress' tools.
I guess that this 8K limit will remain a mystery. I have the impression
that if the start address is at an offset that is lower than 8K the
transfer will succeed even if a big chunk exceeds the address 0x2000.
On the other hand, if you write a chunk that is completely contained
in the range [8k,16k[ it might fail. I don't know for sure. Anyway i don't
have much time to setup a test. I just remember that when i told the
compiler to put "initialized" xdata above 0x2000 the code didn't
find the expected data and behaved incorrectly. When i put the
xdata @ 0x1200 (for example) everything worked fine.
When i say "completely contained" i mean a line like ":LL200000..."
in the ".ihx" file, where LL is the record length.




Posted by Bill Davy on June 14th, 2007



"runner" <emb@dded> wrote in message
news:46712139$0$37204$4fafbaef@reader3.news.tin.it ...
Many thanks for that information.

And just to conclude this tale with a last curiosity, the Cypress core seems
to mishandle 0xA0 In requests (which I use to read back RAM for
verification) if the offset is odd (it is treated as next even offset
below).

And now back to real work, the code that has been downloaded.

Bill



Posted by runner on June 14th, 2007



"Bill Davy" <Bill@SynectixLtd.com> wrote in message
news:L8Gdncm3ebOhsuzbRVnytwA@bt.com...
The manual states that the start address must be word aligned.
(chapter 3.8 at the top of page 3-12)



Posted by Bill Davy on June 14th, 2007



"runner" <emb@dded> wrote in message
news:46713bda$0$4788$4fafbaef@reader4.news.tin.it. ..
Interesting. My printed copy (v2.1) does not have such a comment anywhere
is Section 3.8 (though it is on pps 3-11 and 3-12) but it does apply to the
FX2 (just tried it). I just checked EZ USB_TRM.pdf (Last Updated 21 Mar,
2007) on the Cypress web site and it does indeed note that the address must
be word aligned for Upload. Better get myself a copy.

Bill

PS Why do so many examples use EA to freeze/release interrupts when
accessing shared data? I use ES0 for the serial port, ET0 for timer 0, and
reserve EA for the global enable at start up. But then I may have a problem
with interrupts.



Posted by runner on June 14th, 2007


Which examples?



Posted by Bill Davy on June 15th, 2007



"runner" <emb@dded> wrote in message
news:46716af9$0$4789$4fafbaef@reader4.news.tin.it. ..
Cannot find one now (of course), but when next I do ...




Similar Posts