This week I’m going through each mode to make sure everything is cleaned up and there’s a good firmware available when hardware starts to arrive.
This weekend I went through the LED mode. It supports the common one and two wire LED protocols.
I noticed an issue with the single wire protocol. It’s time based, and anything more than 50uS between frames is considered a ‘reset’. The firmware currently takes about 160uS to process and output commands typed in the terminal. This results in the first LED being addressable when individual commands are used.
For example:
0x00ff00 0xff0000
would ideally turn the first LED red and the second led green. Instead, the first LED takes both commands and ends up green.
However:
0x00ff00:32
Sending the command with a 32 repeat lights 32 LEDs, this is because the repeat code has less overhead.
So, I made one major change in the code to make way for a future rework of everything:
- To ensure the speed of repeat, the repeat code now sends the commands, and then later fills the USB output ring buffer with display data.
- Because of this, we now need an array to hold the incoming data bytes so we can process them to the display later. This isn’t an issue for LED mode (no incoming data), but it will be an issue for SPI (which is the next mode I’ll rework).
- We’ll need a way to detect errors (UART frame, I2C no ACK, etc), and flag where it happened
I’m thinking through a sane way to restructure all this, and I think it may be the right time to move to a sort of compiler/bytecode type thing.
- Bus syntax is compiled to a simple bytecode that is then run full speed.
- Incoming data is stored in a second array
- When the transaction is finished (or the buffer is full) a post process function pushes all the output to the terminal
I did this previously when we had the FPGA/STM32 version, it’s doable but it makes writing modes much less flexible.
There are a couple things that could make it easier
- We allow flexible mixing of bus syntax (read, write, etc) and menu commands. This has always been kind of a pain and really dictates several aspects of how we structure the parser. It really only makes sense in terms of the power command and maybe MSB/LSB switching. I would propose that we make menu commands more like a proper command line program execution. For example
/m
for mode? This would free up the possibility to have more extensive commands for things that previously would have been scripts:
/dump 24lc1024 > dump.bin
That would also give us a way to run scripts from the SD card. Or record macros, etc.
/run script.txt
This also frees up <> from being user macros, as I want to use them for a load/dump syntax command that reads/writes from the SD card. for example:
[ 0x03 0x00 0x00 >:2048]
would dump 2048 bytes from an EEPROM to a file on the sd card.
To summarize:
- Bus syntax is processed to byte code which is then executed at full speed without gaps in output. The terminal display is processed afterwards.
- Bus Pirate configuration commands would be limited to one per line, and could no longer be mixed with syntax. Probably prefixed with / or similar. Then we could do something like:
/W (setup/configure the power supply with menu)
W [0x03 0x00 0x00 r:16] w (turn on PSU with config settings, read from eeprom, turn power off)
This separates the configuration of the bus pirate from the syntax that controls the peripherals, which seems like an improvement overall.
In the photo I’m dogfooding all our stuff while I work through each mode. The AUX cable connects to a logic analyzer without trying to get an additional test hook on the pin connections. The milled breadboard pins connect the probe cable to the LED strip without fuss.