[Japanese|English]

Various Thoughts On USB-IO

Voices from a user

The following is the various thoughts I got after I actually bought, build, and used the USB-IO.

Some Wishes

USB-IO is pretty good, but there are some points that will be better if improved. Following is the list of such wishes.

Using as a Daughter Board

USB-IO must be connected to an external circuit to be useful. When the external circuit is larger, it is desirable to built the external circuit as a main board and put the USB-IO over it as a daughter board. However, there are some problem to do so.

Usually, the main board for the external circuit is bigger than the USB-IO, and the USB connecter needs to be physically robust, so you probably want to solder USB connecter on the main board. To do so, you need to put contact pins at the solder holes for USB connector and connect them to the main board. Currently, USB-IO PCB has solder holes designed for USB connector, so you need to use 2x2 contact pins, while 1x4 pins are better. Hopefully, the USB-IO PCB had two extra holes, so that USB connector, 2x2 pins and 1x4 pins are all fit.

The Way Strobe Signal is Generated

USB-IO Ver. 2 firmware has I/O with strobe commands (command code 0x10 to 0x17.) They are convenient, but there is a problem in the current implementation of the firmware.

To generates a strobe pulse, USB-IO firmware must change one particular bit in the Port #1 and keep other bits unchanged. However, CY7C63001A hardware only allows writing entire bits on a port. So, the Ver.2 firmware read the status of the port and write to-be-unchanged bits back as they are.

This method works just fine for bits used as output, but not for those used as input.

Assume you used bit 3 of Port #1 as input and bit 0 of Port #1 as strobe output. CY7C63001A (hence USB-IO) requires a 1 to be written to a bit used as input, so you should have written a 1 to the bit 3 of Port #1. However, if the signal tied to the bit 3 of Port #1 was a 0 when you issued a strobe I/O command, the firmware read the 0 bit, and write the 0 back to the bit 3 of Port #1. Once this happens, you cannot read the signal tied to the bit 3 of Port #1 any more, until you write a 1 again.

I considered that reading a port to know the "current value" is not a smart way. Instead, the firmware should record the value written to Port #1 and use the value for those bits not used as strobe output.

As a workaround, none of the Port #1 should be used as input, if you intend to use I/O with strobe commands.

Input Commands

USB-IO has two input commands (command code 0x03 and 0x04) that are used to read status of ports. When any of the commands is issued, the firmware reads the status (value) of the specified port, but the status is not passed to the host (PC) at the moment. It is stored in a memory on the microprocessor and will be passed to the host when an interrupt transaction is requested by the host.

This operation is considered redundant.

The better way will be that the firmware reads the status (value) of the port when an interrupt transaction is requested and return the read value immediately. Interrupt transaction, however, doesn't carry the port to be read (i.e., either Port #0 or #1.) The firmware can read both ports and send them to the host always, since there are eight bytes of payloads to be sent to the host.

Input with strobe commands are used in contexts sensitive to the timing to read and/or number of generated pulses, and it is better to keep the current method that stores the value on the memory upon command execution. However, even on the response to the input with strobe commands, the firmware can read status of the ports during input transaction by putting the value read by the input with strobe commands at another offset than the values read during the input transaction.

Matching a Command with a Response

When using input commands of USB-IO, the actual value read from port is notified to the host through a response (interrupt transaction) following the command. However, a response apparently received immediately after the command may, sometimes, not carry the read value. If this happens, keep receiving responses (issuing interrupt transactions repeatedly) without requesting other commands, and the read value soon changes to the correct value.

The behaviour looks like that that command execution takes longer time and that the application is passed a response that was received before the command execution. However, testing the cases more carefully revealed that more complicated thing is happening. At this moment, I'm not sure the problem is in the USB-IO firmware or in the Windows. (I have no USB analyzer, so it is hard to pin the problem down.) Testing on other platforms may give useful information.

As a workaround, the current version of the class library puts an issuer serial at an unused byte position in the request data block, and verifies that the serial in the response matches with that in request. (The issuer serial works as a transaction ID in OLTP messages.) This is possible because a command request of USB-IO always consists of 8 bytes and there are some unused bytes. They doesn't affect USB-IO's operation, but those unused bytes are kept and sent back to the host in corresponding byte positions in the response. Issuer serial is implemented utilizing this feature.

Additional Notes:

Later, I noticed that the behaviour is caused by the driver's automatic polling and read ahead for interrupt pipes and is completely normal.