Post
Topic
Board Hardware
Re: Klondike - 16 chip ASIC Open Source Board - Preliminary
by
eabedry
on 02/07/2013, 16:46:12 UTC
99% of my reads are 14 bytes, a status record, but a nonce result is 7 bytes. Config data is 8 bytes, but I haven't been using that yet. The max size defined by the descriptor is 64 bytes. I'm thinking of just standardizing on 15 byte reads (which allows for a 1 byte queue flag in compact 16 bytes circular queues) and ignoring extra bytes. That way libusb always waits for 15 bytes regardless of what format is being replied. Right now I poll on 31 bytes (my buffer size) and ignore any timeouts due to less bytes being returned. But doing this sometimes results in a second reply appended on the first which seems to be because two packets come in too quickly and don't get read individually.

This is what I was saying about trying to map streams (serial data) onto a bulk pipe. When reading, you never know how much data the device is going to send (ie you never know how much you *need* to read).

It could be less than you're expecting (because you read in the middle of the USB device reading data from the serial port)
It could be exactly what you're expecting (yay!)
It could be more than you're expecting (because you weren't reading data quickly enough and more data arrived at the USB device, etc)

Since there's no way to reliably predict how much data the device is going to send (and thusly how much you can safely read), you need to read in multiples of the packet size. This will ensure you read all of the data the device is going to send you but also ensure you don't run into overflow errors during the read.

It's one of the annoying things about USB. It's too simple and it requires the programmer to jump through hoops.

You can read a little more information here:

http://libusb.sourceforge.net/api-1.0/packetoverflow.html

The usbutils appears to return what I request but always with a timeout as it loops trying to get the full requested size, and fails. It's probably designed to handle larger transfers but isn't very flexible with tiny status updates. By using a fixed size I avoid this. It always returns with what I request and not less. I can easily ignore the extra myself and the sizes are so small that there will be no performance difference.

Most of the writes are only 2 bytes except pushing new work which is 47 bytes. I don't appear to have issues with writing except now and then the device just stops reading even though it continues to write out nonce data. So another bug to work on there.

BTW I've updated the driver to 3.3.1 and pushed to github along with firmware. This is working for me now but rather unreliably. I'm working on improvements.

Writes shouldn't be a problem since USB devices will generally accept whatever you give them.

The other option is to avoid libusb and just use the kernel driver. It handles all of this stuff for you and should be easier to use.