Bus Pirate Firmware Update (v.0c), JTAG And More

stat

Download: buspirate.v0c.zip

A few weeks ago we wrote about our Bus Pirate universal serial interface tool. We used the recent holiday to add some new features, like a JTAG programmer, macros, frequency measurement, and more. A major code reorganization makes everything easier to read and update.

Check out the a demonstration of the new features below. We’re compiling a roadmap and wish list, so share your ideas in the comments. You can also see how we used the Bus Pirate to read a smart card and test-drive an I2C crystal oscillator.

New protocols

I2C>m <–setup mode
1. HiZ <– high impedance pins (safe mode)
2. 1-WIRE <– not ready for this release
3. UART
4. I2C
5. SPI
6. JTAG <– interface and programmer
7. RAW2WIRE
8. RAW3WIRE
MODE>1
900 MODE SET
HiZ>

This firmware release lists three new protocols.

Hi-Z makes all pins high impedance/input, a safe state that won’t damage an attached circuit. To be safe, the Bus Pirate now starts in this mode.

1-Wire is listed, but we couldn’t include it in this release because we still don’t have any parts to test with our library. This is just a placeholder for now, but it will be added as soon as we get a 1-Wire part to test.

We wrote a simplified JTAG interface that includes a XSVF player for programming JTAG device chains.

**We included a hardware I2C library, but according to the device errata there’s a bug in the 24FJ64GA002 rev3 I2C module. This will work with a different chip (e.g. a 28pin dsPIC33).

Connection table

PIN
1-Wire
I2C*
SPI**
RS232
JTAG
B9
SDA
SDA
MOSI
TDI
B8
SCL
CLK
TCK
B7
MISO
RX
TDO
B6
CS
TX
TMS
B5
AUX
AUX
AUX
AUX
AUX
Ground
GND
GND
GND
GND
GND

*also raw 2 wire. **also raw 3 wire.

The new modes connect to the Bus Pirate as outlined in the table.

New features and settings

Frequency measurement

HiZ>F <– do a frequency count
9xx FREQ COUNT ON AUX: 22199552Hz (22MHz)
HiZ>

As seen in the DS1077 demonstration, we added a frequency counter to the Bus Pirate’s AUX pin.  ‘F’ measures frequency, maximum of about 50MHz.

Assign axillary control

HiZ>c <– menu c
AUX PIN
1. AUX (DEFAULT)
2. CS/TMS
MODE>1 <– set AUX control mode
9xx AUX: DEFAULT SETTING (AUX PIN)
HiZ>

Sometimes we need to control the chip select (CS) /JTAG state machine (TMS) pins manually. ‘c’ toggles the pin control between the axillary pin and the chip select pin.

Set terminal speed

HiZ>b <– menu b
Set serial port speed: (bps)
1. 300

9. 115200
SPEED>9 <– set speed
Adjust your terminal and press space to continue
HiZ>

‘b’ adjusts the PC-side serial port speed.

Macros

A new syntax addition, ‘(#)’, triggers protocol dependent macros.

JTAG>(0) <–macro 0
0.Macro menu
1.Reset chain
2.Probe chain
3.XSVF player
JTAG>

In any mode, use the macro (0) to display a menu of available macros.

I2C address search

I2C>(1) <–scan I2C addresses macro
xxx Searching 7bit I2C address space.
Found devices at:
0xB0 0xB1 <–DS1077 responds to write and read address
I2C>

The I2C library includes a macro to automatically search the I2C address range for devices. Helpful when you work with an unknown chip.

Raw2wire smart card ISO 7813-3 ATR

RAW2WIRE>(1)<–ATR and decode macro
ISO 7813-3 ATR
950 AUX LOW
951 AUX HIGH
4xx RAW2WIRE 0x01 CLOCK TICKS
950 AUX LOW
ISO 7813-3 reply: 0xA2 0x13 0x10 0x91<–ATR bytes
Protocol: 2 wire <–decoded ATR data
Read type: to end<–
Data units: 256 <–
Data unit length: 8 bits <–
RAW2WIRE>

Macro 1 resets and identifies a smart card. For more about the ISO7813-3 ATR, see how we used the Bus Pirate to read a smart card.

JTAG

JTAG is a debugging and programming interface for all kinds of electronics. The raw hardware interface can be accessed with the Bus Pirate’s raw 3 wire library, but we added a few features to make it much easier.

jtagstate

JTAG has different modes where data entry does different things. Modes are navigated with the JTAG TMS signal; there are a bunch of JTAG modes, called states.The Bus Pirate’s JTAG library is just the raw 3 wire library, enhanced to help with JTAG state changes.

We only implemented the JTAG states we need to get data in and out of a JTAG device chain: reset, idle, data register, and instruction register. Macro (1) issues a JTAG chain reset, and initializes the chain to the idle state. { puts the JTAG chain in data register mode. [ puts the chain in instruction register mode. ] or } return the chain to the idle state. The Bus Pirate has an internal state machine tracker that is smart enough to manage the chain without explicitly returning the chain to idle; in other words, you don’t have to close your tags. The state machine tracker reports every state change to help debug problems.

JTAG>[0xfe {rrrr} <– same as [0xfe]{rrrr}
xxx JTAGSM: ALREADY IDLE
xxx JTAGSM: IDLE->Instruction Register (DELAYED ONE BIT FOR TMS)
610 JTAG READY TO WRITE IR <– JTAG chain instruction register
620 JTAG WRITE: 0xFE <– request ID
xxx JTAGSM: (WROTE DELAYED BIT) IR->IDLE <–back to IDLE
xxx JTAGSM: IDLE->Data Register <–IDLE to data register
611 JTAG READY TO READ/WRITE DR
630 JTAG READ: 0x93 <–device ID
630 JTAG READ: 0x40
630 JTAG READ: 0x60
630 JTAG READ: 0x59
xxx JTAGSM: DR->IDLE <–back to idle
640 JTAG IDLE
JTAG>

Here is a short interaction with a Xilinx XC9572 CPLD. We go to the instruction register ( [ ), and send the device ID request command (0xfe). Then, we go the the data register( { ), read four bytes (rrrr, or r:4 shorthand), and return to idle ( } ).

What are delayed bit writes?

JTAG requires that the last data bit written to the instruction register be entered at the same time as the state change. Since the Bus Pirate has no way of predicting when we’ll actually change states, it delays the last bit of each byte write until one of three things happens:

  • Exit the instruction register with a }, ], or { command
  • Write another byte value
  • A read command

Pending bits are not cleared by bitwise operations (like ! or ^). Do these before writing your last byte, or change the code. We haven’t implemented pending writes to the data register, but it’s probably needed. You might need to implement this if you’re writing the data register, rather just reading, like we did.

JTAG Macros

JTAG>(1) <–macro 1
xxx JTAGSM: RESET
xxx JTAGSM: RESET->IDLE
JTAG>

JTAG macro (1) resets the JTAG chain and then advances it to the idle state.

JTAG>(2) <–macro 2
xxx JTAG INIT CHAIN
xxx JTAGSM: RESET
xxx JTAGSM: RESET->IDLE
xxx JTAGSM: IDLE->Instruction Register (DELAYED ONE BIT FOR TMS)
xxx JTAGSM: IR->IDLE
xxx JTAGSM: IDLE->Data Register
xxx JTAGSM: DR->IDLE
xxx JTAGSM: RESET
xxx JTAGSM: RESET->IDLE
xxx JTAGSM: IDLE->Data Register
xxx JTAG CHAIN REPORT: <–start of report
0x01 DEVICE(S)
#0x01 : 0x93 0x40 0x60 0x59 <–device IDs
xxx JTAGSM: DR->IDLE
JTAG>

Macro (2) resets the chain, counts the devices, and reports all the device IDs.

xsfv

JTAG>(3) <–macro 3
6xx JTAG XSVF PLAYER
xxx XON/XOFF FLOW CONTROL REQUIRED <–required!
xxx PRESS z TO CONTINUE <– press z
xxx BEGIN XSVF UPLOAD <– upload the file
6×0 XSVF OK <– result or error
YOUR PC DRIBBLED MAX 0x05 BYTES AFTER XOFF (THAT’S OK)
6xx PRESS z 5 TIMES TO CONTINUE <– continue
JTAG>

Macro 3 is an XSVF player/programmer using code from Xilinx. XSVF is byte format SVF, as described by Xilinx (pdf). XSVF files can be compiled for any chain with the correct generic JTAG definition files, even non-Xilinx devices. We successfully used the binary transfer features in Hercules and Tera Term to send XSVF files to the programmer.

JTAG sometimes pauses longer than it takes the PC to transfer a byte of data, so we implemented XON/XOFF software flow control for the XSVF player. Your terminal must be in XON/XOFF flow control mode before you upload the XSVF file, or the programmer will fail. Even with software flow control, a modern PC has already send several bytes through the layers of operating system before it receives the flow control signals. We deal with this by catching these bytes before moving on, this is reported as the maximum number of bytes “dribbled”.

If there’s an error in the upload, the PC will probably continue to spit bytes at the Bus Pirate. To keep error messages visible, and prevent garbage in the terminal, the XSVF player waits for five lower case z’s before it returns to the prompt. We chose this sequence because it will never occur in an XSVF file.

*Note that the XSVF player does not respect the JTAG Hi-Z pin setting. Went it does, it fails. Be careful mixing voltages without a buffer.

Better code structure

The biggest difference between the version 0b and 0c firmware is a massive improvement in code structure. The Bus Pirate existed in many incarnations before we packaged it for the initial article. v.0c harmonizes the code libraries and makes it easier to add new protocols.

How to add a custom protocol

The Bus Pirate code handles the user interface, and passes two variables to the active protocol library. The first variable is a command, such as CMD_READ, CMD_READBULK, or CMD_WRITE. The entire command set is defined in base.h. The second variable is an optional value. A simple CMD_READ command passes no value, a bulk read command passes the number of bytes to read, a write command passes the value to write to the bus, etc. At minimum, a custom protocol needs a function to receive these variables and translate them to bus actions.

We used three different techniques to link commands to bus actions. Simple code can go directly in a giant switch statement, like SPI.c. External libraries use an single linking function, like I2C.c, and m_i2c_1.c. More complicated protocols use the switch statement to call functions included in the library (raw2wire.c, raw3wire.c, jtag.c UART.c). Helpful functions for terminal IO are included in base.h/c.

Due to massive code improvements, it’s now only mildly confusing to register a new protocol with the Bus Pirate:

base.h – Create a definition for the protocol. The last entry is currently “#define RAW3WIRE 7”, so the next entry could be “#define MYCUSTOMWIRE 8”.

busPirate.c – Include a header file with that gives access to the processing function.  Add a menu entry in the char* mode[]  = variable list. The menu entry must be in the same position on the list as the number assigned in the base.h define. If MYCUSTOMWIRE is number 8, it must be the eight entry in the mode variable. Finally, add an additional switch to the bpProcess() function that calls the custom library processing routine when the mode is set to “MYCUSTOMWIRE”.

Taking it further: a Hack a Day wish list

We compiled the feedback we’ve gotten into three wish lists: protocols, features, and macros.

Protocols

Some protocols will require an external transceiver.

Features

  • Pulse-width modulator, frequency generator
  • “Wait until interrupt” command
  • Convert frequency measurement to input capture peripheral
  • Allow frequency measurement on any pin
  • Show a report of the current configuration settings and pin states.
  • Integer repeat values for bulk read, clock ticks, delays, etc.
  • A CRC generator

Macros

  • Transparent UART bridge
  • SD card initialization, meta data extract, and dump
  • EEPROM program/dump (I2C/SPI)
  • Nokia 6100 LCD initialization, control
  • NMEA GPS data decoder

Do you have anything to add to the list?

Firmware download: buspirate.v0c.zip

31 thoughts on “Bus Pirate Firmware Update (v.0c), JTAG And More

  1. I like the Jtag support. would it be possible to make it be able to program PICs and AVR’s as well.. so its like a all in one development tool.

    another feature that might be cool would be a 8 bit logic analyzer or maybe a low speed Oscilloscope

    I know some of those might be tall orders but you asked for suggestions :)

    Someone needs to make a batch of PCB’s for this once we get a final revision of the hardware.

    I know your trying to keep the parts/price down but USB support would be awesome.

  2. Any way we could make this interface with Automotive CAN bus systems? That would rock.
    There are already cables you can buy (with a circuit inside) that lets you use a standard terminal to talk to them, so conceptually it’s possible. There are a few different CAN bus standards though. I’m interested in the GM CAN bus so i can hack my Sky. :)
    -Taylor

  3. If you ask for suggestions, an i2c sniffer would be cool. Usually you have i2c master-devices, but that´s useless to get the data of an unknown master-slave subnet.

    For full use of CAN in GM vehicles a dual wire (anyone you like) and a singlewire (probably AU5970) transceiver would be needed. But response delay is probably too slow (over RS232) to make a proper use of it.

  4. To the author: I would be interested in making an AVR based version of the Bus Pirate sharing most of the existing code. While I could do that by forking the source code you (kindly) provided I’d rather build support for AVRs into your existing code. Contact me if you are interested.

  5. I like the hi-Z “safe mode”, you could toss on some optos too, I know that would increase the cost a bit, but something like this would really benefit from the isolation, given that the primary application for most people will be “poking around where it doesn’t belong” ;) Looks like it has the potential to be a really nice reverse-engineering tool, too.

  6. I agree with jm. An Arduino port would be a step in the right direction. Many people already have one or more of these laying around, and making/populating a shield would be trivial — much easier than making an entire board stuffed with a PIC.

    And not to get religious or philosophical, but Arduinos (and AVRs in general) fit the open source mentality a little better than a PIC — gcc and g++ support compared to a few W32 tools.. Not to mention the AVRs (and therefore Arduinos) have cross-platform support 100% nailed down. PICs OTOH not so much.

    If noone else steps up to the plate, I may have a go at the I2C and SPI parts first… I will be checking my RSS reader in the meantime.

  7. @avr-fans – We’re happy to include to additional definitions and modules to make it compatible with other processors and compilers.

    Can you share some specs of your intended target processors? We’re using a 16bit PIC @ 32MIPS with 8K SRAM and 64K program space. We only use 4K of memory, and could do with half that, but the firmware is already 33K+. Will this project fit your targets?

    Also: we use the peripheral pin select crossbar to assign different hardware modules to the same output pins (UART, SPI, I2C, frequency counter, frequency generator, etc). If the AVR doesn’t have anything similar, you’ll also need to write software libraries for those. I don’t personally have a ton of experience with Arduino, but can you get the timing accuracy you need for, say, a software UART, from such a high-level programming language?

    If it’s the PIC programming that turns you off, check out the reader-recommended sub-$40 ICD2 debugger clones on eBay (the holidays are coming).

  8. @eric

    We like the idea of galvanic isolation from the PC. It would also be nice to have a simple 74xx buffer chips between the Bus Pirate and the target chip, but it’s tough to do that with the bi-directional data lines used in I2C and 1-Wire.

  9. @ Daryl linux serial ports are usually in /dev/tty/s0 and usually work by default.

    Excellent improvement to an already good tool. Good idea on the jtag compatability. Any chance of getting an AVR version together anytime soon?

  10. Adding these features should be fairly easy, source code is provided too:
    http://mondo-technology.com/super.html

    Also, with the increasing number of features, a GUI should be nice.. maybe java or python for portability, I don’t know, I’m a windows guy (I can help develop it in c# .net if needed).
    An USB version with a 24fj256gb108 will be nice (I’m working with this pic at the moment and it is very cool!).
    Most important, a bootloader, so we don’t have to move our ICD2 around to update the firmware. I’m using the very good AN1157 (http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en533906) for my project.

  11. @njansen: Yes please create a project on SF. I am in for the arduino port. I have a couple of arduino nanos handy: 16Mhz avr168 (1k sram, 16k flash). Some features will have to go due to lack of space. We can turn them into compile time options so people can enable what they need (or use a higher spec’ed AVR). Let us know when the SF project is up!

  12. About your “//disable some default nonsense” comment inside main.c… All analog capable ports are configured as analog input at startup to consume less power: if left as digital input and disconnected, the input floats and can change its state randomly, and every time the state changes the input transistor consumes current. microchip says that for low power consumption the progammer should have every unused pin configured:
    – as an analog input
    – as an input, but tied to vcc or gnd
    – as an output, unconnected

    Since mchp doesn’t know your hardware beforehand, it places the chip in the safest state.
    Remember, nothing is nonsense, everything is carefully studied!
    ;)

  13. The Sanguino (64kb flash, 4k RAM 20MHz) would be a better fit for this project. I don’t see anything in the circuit that couldn’t be done with the standard Sanguino board. But then again, I’m not an expert… Some isolation circuitry would be nice, but as mentioned, the bi-directional interface will make that more difficult. Where can we find the source code?

  14. Hi ,

    I need to do convert SVF file into XSVF file with out Impact or any software, need to make it. Can you please refer me some document which tells about the SVF and XSVF instruction so that I can write one converter for that.

    Thanks,
    Appu

  15. Just built one and am testing it. I am seeing something odd.

    Has anyone tried the Aux pin support @/a/A commands? It seems as if the chip never pulls the output high in the A command (it goes from 0.0 to 0.25 V) it’s as if the internal pullups on that port pin are not being enabled.

    Just wondering if anyone else has seen this? I have checked for pin shorts etc… The serial interface comes up perfectly etc…

    Great project, am looking forward to putting it to use. Thanks

    –Neil.

  16. hello,I live in Brazil
    I have practiced with these devices
    I need to reset the DS2431, it goes to a printer, to check the print cartridge
    it is giving 0% of fluid inside the cartridge,
    how can I do this?
    thanks

  17. The work you have done with reprogramming the xilinx device via the pic is fantastic. Have you tried to reprogram any Altera based devices? I have a pet project where I am trying to reprogram a max II cpld using a pic24f. If you could point me in the direction of any kind of info it would be really appreciated.
    Thanks!

Leave a Reply to ericCancel reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.