Dangerous Prototypes

Dangerous Prototypes => Bus Pirate Development => Topic started by: ian on June 26, 2010, 09:01:30 am

Title: SPI sniffer update
Post by: ian on June 26, 2010, 09:01:30 am
Quote
We need BusPirate for SPI sniffing only (no outputs on bus, not exercising devices), but SPI mode interferes whenever connected to SPI bus!
When SPI mode is not sniffing (at SPI prompt, esp. after sniffing interrupted by keystroke), data line (at least MOSI) appears to be driven or held by BusPirate, instead of released or left open (Hi-Z). The effect is system under test ceases to operate when BusPirate at SPI> prompt is attached. Workaround is to start sniffing “macro” (1) before attaching to SPI bus.
What is needed (should be default, IMHO) is for all SPI pins to input-only except when issuing output onto the bus; or else a setting option for this.
What is SPI (1) “macro” — can it be edited, can its commands be used?
[Also, any option for BusPirate to power up back into last-used configuration and state, after power-down? We would like to "set and forget" instead of having to record/remember all configuration choice each time we re-power the device.]

This comment was left on the SPI page:
http://dangerousprototypes.com/bus-pira ... mment-2881 (http://dangerousprototypes.com/bus-pirate-manual/bus-pirate-spi-guide/#comment-2881)

IT's an interesting problem.

Here's my reply:

Your suggestion is very interesting, and I'm not sure quite sure how to integrate it into the code. The PIC hardware SPI modules actually control the pin state after the module is configured. Peripherals with the PIC PPS function override user pin configurations. Leaving all pins input unless they are outputting could adversely effect some chip clocks and CS (maybe not?). I guess we could assign and remove the SPI module from the pins between every write to make it an input, but this would probably send extra clock bits and CS line noise, especially with high-impedance bus configurations.

Maybe we could make the SPI sniffer resettable - space to reset/pause, X to exit, something like that.

Unfortunately the PIC in the Bus Pirate doesn't have an EEPROM or anything (besides flash, which is all used up) to store persistent settings. It's definitely something we have planned for the next version though.
Title: Re: SPI sniffer, SPI pins interfere with bus between sniffing
Post by: ian on July 01, 2010, 11:48:21 am
This is an ongoing discussion from here:
http://dangerousprototypes.com/2009/10/ ... mment-2944 (http://dangerousprototypes.com/2009/10/08/bus-pirate-raw-spi-mode/#comment-2944)

Quote
Any chance of logging rate above 115,200? Or more condensed log format?
We have an application that chatters away at 126 SPI byte cycles in 78msec, every 100msec. In raw binary mode, each SPI byte cycle costs 6 log bytes:
O(I)O(I)O(I)O(I)O(I)
where ‘O’ and ‘I’ are binary MOSI and MISO bytes, respectively.
So our application generates 756 bytes of log at 10Hz, or 75,600bps long-term, but about 98kbps during the 78msec active section, which overruns 115.2kbps because it’s actually a little bursty in there. [Just lucky that we "almost" fit in 115,200bps, I guess.]
The next (doubled) baudrate would have ample margin, assuming the PIC has horsepower to serve it. Or: If raw binary SPI reported each MOSI/MISO pair with single backslash and no parens, the serial burden would be half:
OIOIOIOIOIOI
I’ll try to build this myself, but anyone who can beat me to it gets my cheers!

The current issue:

Quote
It’s looking like the SPI hardware (PIC peripheral) is able to mis-sync, and stay mis-synced, if probes are attached to a live SPI bus at the wrong moment. It appears CS assertion/deassertion does not reset SPI byte framing. Here is a digested snippet [the raw 5.1 "xy" is displayed "XX(YY)", and the "..." are abbreviations for "00(00)"]:
BBIO1SPI1010101
…80(00)7E(00)80(00)50(00)80(00).80(00)7F(00)
…00(7E).00(50)…00(7F)
…80(00)7E(00)80(00)50(00)80(00).80(00)7F(00)
…00(7E).00(50)…00(7F)
…80(00)7E(00)80(00)50(00)80(00).80(00)7F(00)
…00(7E).00(50)…00(7F)
…/reconnected probes here/
…40(00)3F(00)40(00)28(00)40(00).40(00)3F(00)80(00)…00(3F).00(28)…00(3F)00(80)…40(00)3F(00)40(00)28(00)40(00)
You can see MOSI messages, 80-7E-blahblah-7F, alternating with MISO messages, 7E-blahblah-7F. Whenever I break and reconnect probes, BusPirate comes up in a different sync; sometimes I get lucky and sometimes not. If I leave probes reconnected, SPI sync never recovers by itself.
SPI setup bytes are:
Const bENTER_RAW_BITBANG_MODE As Byte = &H00 ‘ 0b00000000, 20 times
Const bENTER_RAW_SPI_SUBMODE As Byte = &H01 ‘ 0b00000001
Const bSET_CS_HI_HI_Z As Byte = &H03 ‘ 0b00000011 ‘ per HiZ setting
Const bSET_SPI_SPEED_8MHZ As Byte = &H67 ‘ 0b01100111
Const bSET_SPI_CLOCK_IDLE_HIGH As Byte = &H84 ‘ 0b10000100 (or 0b10000110 for active-to-idle edge samping?)
Const bSNIFF_WHEN_CS_LOW As Byte = &H0E ‘ 0b00001110 ‘ per HiZ setting

It looks like there is a CS sync issue. One of the problems is that we have to do it 'manually' because the hardware CS is broken according to the errata. This is something we can test though, and maybe it works on the latest chips and we can implement a work around. I'd like to try to get this working as well as possible while there's an active tester.
Title: Re: SPI sniffer, SPI pins interfere with bus between sniffing
Post by: ian on July 01, 2010, 11:52:06 am
80 7e = 10000000 1111110
40 3f =  01000000 0111111

Where is the CS in the output?
Title: Re: SPI sniffer update
Post by: ian on July 01, 2010, 11:56:07 am
Quote
19. Module: SPI
In SPI Slave mode (MSTEN = 0), with the slave
select option enabled (SSEN = 1), the peripheral
may accept transfers regardless of the SSx pin
state. The received data in SPIxBUF will be
accurate but not intended for the device.
Work around
There is a work around using the peripheral pin
select feature. One of the external interrupts (INT1
or INT2) can be mapped to the same pin as the
SSx signal or the SSx signal can be mapped to a
pin with interrupt-on-change (CNx) functionality. If
the SSx signal changes to low (active), the
interrupt flag will be set.
When an SPI data received interrupt occurs, the
interrupt flag can be tested. If the interrupt mapped
to SSx did not occur, discard the data.

Here's the errata for the CS, it effects the A3/A4 only, the workaround looks fine though, we should try it.
Title: Re: SPI sniffer update
Post by: ian on July 02, 2010, 08:15:31 am
Here's a logic capture from Pete so we know what we're working with.

One thing occurred to me: the way the sniffer loop is currently written, it just checks if the CS is the correct state, instead of looking for an edge transition. So if you attached during the middle of the byte, it would see CS low and start right away. This could be fixed with teh errata work around.

Question: does the 'r' restart option help?
Title: Re: SPI sniffer update
Post by: ian on July 05, 2010, 12:47:20 pm
SPI sniffer now verifies start with edge interrupt (untested).  Will probably need a little more work. My changes should be about here:
http://code.google.com/p/the-bus-pirate ... /SPI.c#317 (http://code.google.com/p/the-bus-pirate/source/browse/trunk/source/SPI.c#317)

( ! ) Fatal error: Uncaught exception 'Elk_Exception' with message 'Please try again. If you come back to this error screen, report the error to an administrator.' in /var/www/dangerousprototypes/forum/sources/database/Db-mysql.class.php on line 696
( ! ) Elk_Exception: Please try again. If you come back to this error screen, report the error to an administrator. in /var/www/dangerousprototypes/forum/sources/database/Db-mysql.class.php on line 696
Call Stack
#TimeMemoryFunctionLocation
10.01632075168session_write_close ( )...(null):0
20.01662206760ElkArte\sources\subs\SessionHandler\DatabaseHandler->write( )...(null):0
30.01662207536Database_MySQL->query( ).../DatabaseHandler.php:119
40.06052346264Database_MySQL->error( ).../Db-mysql.class.php:273