Reverse engineering SPI like communication.  - Page 1
Forum section: electronics / projects

author: Richard1234
author_rank: Contributor
timestamp: November 13, 2018, 05:43:31 am
content: Hi All,I'm trying to reverse engineer a proprietary, but VERY SPI like databus. I'm about 90% done, but there is one aspect of the last 10% that is really slowing me down.With this SPI-like databus, the clock signal under one circumstance will drop to ground for a short period of time, which is NOT intended for a logic change on either the MOSI or MISO line. It is for another purpose - to signify a very accurate timing point.Every logic analyser program I've tried registers the clock fall and rise, and in turn, logs a bit where it shouldn't. It thereby, shifts the calculated byte structure left (off the real sets of 8bits) each time it happens, so the supposed byte is now calculated using the dodgy "bit" that it registered from the non-data-structure clock cycle, and the first 7 bits of the correct byte it should be calculating. This then makes up the 8bits for the byte it works out, ditching the last bit which should have been part of it. This last bit is then used for the first bit of the next byte, and on it goes....This can happen multiple times in a datalog, each time making the calculated bytes further 1 out of sync each time there is a registered dodgy bit that shouldn't have been there.Right now, my only way around it is to extract the HEX data into CSV, note where the dodgy bits were registered, then pass it through a python script which changes it back to binary, links all the bits into one big string, deletes the offending bits which caused the problem, then breaks it into 8s, turns it back into hex, and puts it back into comma separated values. This works, but it's time consuming and tedious noting down all the time signatures, and byte numbers to pass into the python script...If only there was a logic analyser program that would let me flag a clock cycle as effectively being ignored for SPI analysis.Also, because all the original byte "time signatures" are based around the shifted bytes, they're all wrong after the bad bit, and thereby useless.....Any other ideas?I'll post a logic analyser screenshot to give you a better idea what I'm talking about....You can see the offending clock cycle at ~5230200usAnd yes, the clock dip is used for other purposes.Richard

author: Richard1234
author_rank: Contributor
timestamp: November 13, 2018, 05:53:50 am
content: And, for reference, here's a normal section of data before it turns to poop because of the bad registered bit. As you can see, the polarity is different for some bits, but otherwise, it's SPI.I've been sitting over a coffee thinking about this. The data is already going through a buffer board before it goes to the logic analyser, so I have little chance of damaging the equipment.Now.... the buffer is open output, and has pull-up resistors on it. There are unique bytes of data right before the offending clock cycles. How about if I run the clock into two channels of the logic analyser, but on the clock channel, have a transistor to isolate the buffer from the logic analyser channel and pull up resistor (thereby leaving it sitting high), and control the transistor with something like an arduino. Get the arduino to monitor for the indicator bytes and isolate the input from the logic analyzer for enough time to prevent it sensing the clock drop. Then, with the other channel, it'll plot the whole thing including the drop, so I'll still have accurate timing information.Sound do-able?

author: T3sl4co1l
author_rank: Super Contributor
timestamp: November 13, 2018, 12:50:26 pm
content: I wonder how the receiver itself differentiates a stray clock from a data frame.Examine the timing between frames and stray clocks. Is there a minimum padding in either direction?Examine the frames. Is there always a start bit, or some kind of coding to say that the received data is a frame and not a stray clock?Implementing these in hardware to clean things up so a regular SPI analyzer can figure it out, isn't going to be the easiest thing. Well, sort of. I can imagine thesimplest possiblemethod: run SCK through a filter and schmitt trigger, so it only transmits tone bursts at the clock frequency, and not single blips. (This wouldn't play well with the inconsistent timing between frames, though.) That would require a modestly high order analog filter, and an equal (group) delay on the data so they remain aligned (you can imagine, it takes several cycles of delay before a multiple-cycle filter outputs anything).The next best thing might be a digital delay with a two-clock mask, maybe implemented with shift registers, and some logic to detect when multiple clocks appear. Basically the identical thing but with a fixed group delay (it's all going through shifts, so SCK, MOSI and MISO can all be properly timed), and with a simpler FIR filter. Naturally... this would still be a pain to implement in solder, but it would be relatively easy to synthesize in a small FPGA.You could also detect single clocks, and stuff in seven additional clock pulses, assuming there is time afterwards. That puts in an entire false frame of 0x00 that's easy to filter (assuming the intended frames are never zero).I'm not sure that an Arduino would be of much value here, due to limited clock speed, interrupt latency and so on.You can use it to capture SPI directly, and maybe hack the bit shifting yourself.It might do to receive SPI in 9-bit mode and stuff an extra clock pulse as needed (to complete a frame, when the other eight have been detected without a stray pulse), or to poll the clock pin in software while receiving to detect when a stray clock has arrived and reset the SPI register before the next frame arrives.Tim

author: Richard1234
author_rank: Contributor
timestamp: November 14, 2018, 11:01:34 am
content: T3sl4co1lThanks!Yes, there is a dead giveaway that the clock drop is coming. Several bytes before it happens, the MOSI byte is a unique indicator it is coming. I'm pretty sure there is a minimum padding either way as you described. Either way, the SPI clock for usual 8bit packets is extremely constant. Anything outside this should be easy to work out. The tricky bit is working out that it isn't the first bit of the next byte to be transferred...I'm pretty sure I can implement a work-around it with an arduino or a PIC by feeding the clock into both the SPI clock pin, and another pin, then using a transistor controlled by the arduino and a controlled isolation of the SPI clock pin like I was earlier talking about. This way, when the the unique indicator byte happens, I can isolate the SPI clock pin (thereby not getting the SPI out of sync). Yet, I can still look for the clock drop indicator on the other pin the (unfiltered) clock is fed into. After the drop has taken place, I can then , de-isolate the SPI clock pin. It's somewhat crude, but not processor heavy like bit banging, yet I can't see why it shouldn't work. With direct port manipulation on the arduino, it should be pretty fast.What makes you think this is un-doable with Arduino? I can certainly see it would be on the limit of things with bit-banging, but why not using the regular SPI pins and another as described above?Richard

author: T3sl4co1l
author_rank: Super Contributor
timestamp: November 14, 2018, 01:00:11 pm
content: Yeah, that sounds reasonable.Just, use a proper OR gate, don't try to fight a buffer with a transistor. Easier that way.The reason I at first say Arduino isn't suitable, is because I am thinking from top-down and bottom-up alternately and constantly, and because you didn't provide that information that the pulse is expected based on a code.For the premise of an unexpected bit, I started with the lowest possible solution I know of: a passive (analog) filter. Possible, but not practical.An FPGA would solve this relatively easily, and very generally. (Indeed, such filtering methods would also be generally useful for noise immunity purposes in real applications!)The lowest level software solution is polling for that bit, then doing something about it. That will give a response time of a microsecond or so on bare metal, probably tens of microseconds at best through the Arduino libraries.That rules out direct software implementations, but leaves open the consideration of hardware-enabled solutions. These are not general, and leaves you limited by the capabilities of the hardware. Which I then go into, and which may work out.If there is a signal proceeding the pulse, then absolutely, you can emit a mask pulse in time. That makes double sense, as their receiver is likely made in a similar way and needs as much time to figure things out.Tim

author: rstofer
author_rank: Super Contributor
timestamp: November 14, 2018, 02:40:50 pm
content: If you know from some data byte that the oddball clock is coming, disable the SPI device before it gets there. Then arrange to interrupt on the rising edge of the oddball clock and turn the SPI gadget back on.I don't see why it couldn't be the same pin, used for SPI part of the time and as regular input with interrupt-on-change when necessary.