Skip to main content
Topic: Bus Pirate "Ultra" pipelined and non-pipelined operations (Read 808 times) previous topic - next topic

Bus Pirate "Ultra" pipelined and non-pipelined operations

The Ultra has an input and output FIFO (currently 512x16, but could be much bigger) connected to a state machine in the FPGA. Pipelined commands are loaded into the FIFO and executed by the state machine with per-clock repeatability. Non-pipelined commands halt the state machine while the MCU takes over to perform the command, the delay here is unpredictable and depends on many factors such as any USB operations the MCU may be servicing.

These commands are currently pipelined:
  • Delays (ms, us)
  • Bus reads
  • Bus writes
  • Pin read/write/direction

These commands can be pipelined, but are currently handled in registers:
  • PWM
  • Frequency measurement

These commands will be pipelined in v1c and later:
  • ADC reads (on any pin, Vout)

These commands could be pipelined with some hardware updates:
  • Pull-up resistors toggle
  • Power supply enable
  • Power supply margining (DAC)

These commands cannot be pipelined because they happen outside the FPGA:
  • Mode change (reloads the FPGA)
  • Reset
  • Jump to bootloader
  • Self-test (involves tests on the MCU and FPGA)

There are also mode macros to consider, which probably need to be a combination of pipelined commands and non-pipelined commands.
Got a question? Please ask in the forum for the fastest answers.

Re: Bus Pirate "Ultra" pipelined and non-pipelined operations

Reply #1
These commands are currently pipelined:
*Delays (ms, us)
*Bus reads
*Bus writes
*Pin read/write/direction
*ADC reads (on any pin, Vout)
*Pull-up resistors toggle
*Logic analyzer start and stop

These commands will be pipelined shortly via logic updates:
*PWM
*Frequency measurement

These commands will be pipelined in v1e and later:
*Power supply enable
*Power supply margining (DAC)
Got a question? Please ask in the forum for the fastest answers.

Re: Bus Pirate "Ultra" pipelined and non-pipelined operations

Reply #2
I'm in the process of refactoring the HDL to facilitate making everything possible into a pipelined command.

Currently I'm modeling the interface after the common 3/4/8bit/16bit RGB LCD interface. An 8 bit command is entered when a command/data pin is high. This is followed by 0 or more bytes of parameters/data. This should give the best possible speed for pushing and pulling long chunks of data from connected devices (eg flash rom).

Part of this change is to expand the 16bit FIFOs to 17bits wide. The extra bit tells the Bus Pirate statemachine if the word sets a new state or if it is data for the existing state. These FIFOs sit at register 0.

What I'm still not sure about is how to process "now" commands that need to be executed immediately and don't go into the FIFO. It could be a statemachine at the front of the FIFO that intercepts "now" commands (say 1xxx xxxx are immediately processed, 0xxx xxxx are put into the fifo). A second statemachine or a few control registers/status could sit at higher address. We'll see what's actually needed after the refactoring is complete.

One of the nice things about this setup, if it works, is we can eliminate a bunch of the static memory controller address lines and free up some FPGA pins while simplifying the PCB.

I'll document the command data interface here.
Got a question? Please ask in the forum for the fastest answers.

Re: Bus Pirate "Ultra" pipelined and non-pipelined operations

Reply #3
Code: [Select]
    `define CMD_DIO_WRITE 8'h00
    `define CMD_DIO_READ 8'h01
    `define CMD_DIO_TRIS 8'h02

    `define CMD_PERIPHERAL_WRITE 8'h03
    `define CMD_PERIPHERAL_READ 8'h04

    `define CMD_DELAY 8'h05

    `define CMD_PWM_ON_PERIOD 8'h06
    `define CMD_PWM_OFF_PERIOD 8'h07

    `define CMD_ADC_READ 8'h08

    `define CMD_LA_START 8'h09
    `define CMD_LA_STOP 8'h0A

    `define CMD_REGISTER_SET_POINTER 8'h0B
    `define CMD_REGISTER_WRITE 8'h0C
    `define CMD_REGISTER_READ 8'h0D

    `define CMD_SM_HALT 8'h0F
Here is the command set I've been working with. Write these commands to FSMC address 1, then pump the options/data into address 0.

Code: [Select]
`define REG_BPIO_OE config_register[4'h0][BP_PINS-1:0]

`define REG_BPIO_OD config_register[4'h1][BP_PINS-1:0]

`define REG_HW_CONFIG config_register[4'h2]
`define REG_HW_CONFIG_PULLUPS_EN config_register[4'h2][0]

`define REG_LA_CONFIG config_register[4'h3]
`define reg_la_io_quad config_register[4'h3][0]
`define reg_la_io_quad_direction config_register[4'h3][1]
`define reg_la_io_spi config_register[4'h3][2]
`define reg_la_clear_sample_counter config_register[4'h3][3]
`define reg_la_active config_register[4'h3][5]
`define reg_la_max_samples_reached config_register[4'h3][6]
`define reg_bpsm_reset config_register[4'h3][7]

`define reg_la_io_cs0 config_register[4'h3][8] //reserve upper bits for more SRAMs
`define reg_la_io_cs1 config_register[4'h3][9]

`define reg_la_sample_count rreg[4'h4]

`define REG_ADC_CALIBRATE config_register[4'hA][0]

`define REG_PERIPHERAL_0 config_register[4'hC]
`define REG_PERIPHERAL_1 config_register[4'hD]
`define REG_PERIPHERAL_2 config_register[4'hE]
`define REG_PERIPHERAL_3 config_register[4'hF]

CMD_REGISTER_x sets a pointer and reads and writes from this set of registers that control internal functions.
Got a question? Please ask in the forum for the fastest answers.

 

Re: Bus Pirate "Ultra" pipelined and non-pipelined operations

Reply #4
Code: [Select]
    `define CMD_DIO_WRITE 8'h00
    `define CMD_DIO_READ 8'h01
    `define CMD_DIO_TRIS 8'h02
These are commands to read/write and set direction of the IO pins. Send CMD_DIO_WRITE to FSMC address 1, then push as many pin changes (as the lower 8 bits of the word, so 0x00FF for all high, 0x0000 for all low) as you want to FSMC address 0. READ and TRIS word similarly.

Code: [Select]
    `define CMD_PERIPHERAL_WRITE 8'h03
    `define CMD_PERIPHERAL_READ 8'h04
Sends a word (16 bits) to the peripheral (SPI, I2C, etc). The purpose/function of each bit depends on the peripheral. For SPI the bottom 8 bits are the data to send. The top 5 bits are how many times to repeat, and bottom 3 bits are how many bits to transmit. One the command has been issued it is possible to continue reading or writing without sending another command, this improves our throughput where it matters most.

Code: [Select]
    `define CMD_DELAY 8'h05
Send this command followed by how many clock cycles to delay as a 16 bit word.

Code: [Select]
    `define CMD_PWM_ON_PERIOD 8'h06
    `define CMD_PWM_OFF_PERIOD 8'h07
Send command followed by 16bit on/off periods. write ON first, followed by OFF to correctly reset the PWM with the new period.

Code: [Select]
    `define CMD_ADC_READ 8'h08
Send command followed by a data word to measure voltage with the ADC. the lower four bits of the data word map directly to the 74HCT4067 select pins. Like all commands, send additional address data words to get another measurement on the same or different pins.

Code: [Select]
    `define CMD_LA_START 8'h09
    `define CMD_LA_STOP 8'h0A
Start and stop logic analyzer. No data.

Code: [Select]
    `define CMD_REGISTER_SET_POINTER 8'h0B
    `define CMD_REGISTER_WRITE 8'h0C
    `define CMD_REGISTER_READ 8'h0D
There is a 16 word configuration register that can be access through the command pipeline. CMD_REGISTER_SET_POINTER followed by a data word with register to access 0-15. CMD_REGISTER_WRITE enables writing at the current pointer. Send as many data words as needed, the pointer auto increments so that the configuration can be done in full with a single command followed by 16 words of data.

CMD_REGISTER_READ plus one data word with the number of registers to read (0-15). Reads starting from the register set by the register pointer command.

Code: [Select]
`define REG_BPIO_OE config_register[4'h0][BP_PINS-1:0] //pin output enable (1=true)

`define REG_BPIO_OD config_register[4'h1][BP_PINS-1:0] //pin open drain (1=true)

`define REG_HW_CONFIG config_register[4'h2] //misc hardware config (power supply? pullups? etc)
`define REG_HW_CONFIG_PULLUPS_EN config_register[4'h2][0] //set bit to enable pullups

`define REG_LA_CONFIG config_register[4'h3] //logic analyzer configuration. About to get a major overhaul
`define reg_la_io_quad config_register[4'h3][0]
`define reg_la_io_quad_direction config_register[4'h3][1]
`define reg_la_io_spi config_register[4'h3][2]
`define reg_la_clear_sample_counter config_register[4'h3][3]
`define reg_la_active config_register[4'h3][5]
`define reg_la_max_samples_reached config_register[4'h3][6]
`define reg_bpsm_reset config_register[4'h3][7]

`define reg_la_io_cs0 config_register[4'h3][8] //reserve upper bits for more SRAMs
`define reg_la_io_cs1 config_register[4'h3][9]

`define reg_la_sample_count rreg[4'h4] //unused currently, will be reworked

`define REG_ADC_CALIBRATE config_register[4'hA][0] //when set the ADC will run in calibration mode the next time the ADC_READ command is run

`define REG_PERIPHERAL_0 config_register[4'hC] //reserved for the peripheral configuration of each mode (SPI cpol, etc)
`define REG_PERIPHERAL_1 config_register[4'hD]
`define REG_PERIPHERAL_2 config_register[4'hE]
`define REG_PERIPHERAL_3 config_register[4'hF]

These are the 16 registers currently accessible from the CMD_REGISTER_x commands.

Code: [Select]
    `define CMD_SM_HALT 8'h0F
Halts the statemachine so the MCU can take over and perform operations. No data word needed. Needs to be reworked now that the registers cannot be accessed if the statemachine is halted :) Resume will be by pin or FSMC register write, not sure yet.

Got a question? Please ask in the forum for the fastest answers.