How did you solve the precomputation?
Can't this still be done in the driver like with the Avalon miner?
Yes, this has to be done in the driver. One of the beauties of open source is we don't have to solve every problem as if it's new.
So I'll be using what I can from the Avalon driver, and modifying it to use a more cmd/reply protocol over the USB. The main reason to change anything is that it could reduce data transfer demands. Since we have a CPU on each board we don't need to repeat redundant data.
Firmware OverviewThe firmware works with simple cmds for which I've already coded a skeleton. It's a compromise between readable text and compactness. I could have gone totally binary but I'd like to be able to see USB/I2C data if I need to spy on it for debugging.
[cmd char][address- 3 digits][binary data]
eg.
W003blablahdataherecannotread...
Current cmds I have laid out:
W - start work (the meaning of life... )
E - enable/disable work (for reducing power draw when no work available)
S - get status (eg. fan speed, temperature, chip count, board count, work state)
T - set temperature limit (a safe default will be coded)
F - firmware upgrade (send new program code, don't worry will need handshake to confirm)
(maybe more as needed)
The address is always 000 for the primary USB board, and >= 001 for subsequent chained boards. For chained boards it simply relays the cmd to the I2c bus.
The primary board auto-detects what chained boards are present using "serial# as address" arbitration and assigns a unique I2C 7 bit address. So the possible range for destinations the host can talk to is 000-112 (some I2C addresses are reserved). This would be the max boards per chain. I didn't go with 10 bit addressing as it would probably be beyond the limits of what even 400kbps could support on I2C, and at first I'll be working with 100kbps until there's time to test faster. And there's no real need either - at the USB level having 100+ boards on each port of a hub is economically cheap, and more flexible.
Each PIC also auto-detects how many chips are on board and adjusts it's work splitting to match. The number of chips is relayed as status info for the host but the host doesn't really need to know - more for user overview, monitoring problems.
Just throwing this out there so everyone knows what I'm doing next: filling in the code needed to support the cmds above.
Someone told me there is a risk that the more chips are on a bus it could lead to collisions when 2 chips send a result at the same time. Is this risk valid?
Yes, remotely possible. Not boards per chain, but chips per board. I split the 16 into 2 banks primarily to reduce work load time but also it helps with this. What happens in the case of collision depends on how smart the ASIC reporting circuit is. It uses a wired-OR output logic, weak pull-up resistors, so that it is possible to detect a collision and back off. I don't know if it does that - probably not. A collision would be very rare and the only loss would be one share (even more rare to have a collision with a winning share).
The wired-OR scheme allows for arbitration of the data (it's benefit over a tri-state bus), and the ASIC could detect a collision, but it may not bother due to how rare it would be. If it detects and backs off then no data corruption occurs, but if it doesn't back off then corruption can occur.