Electronic – Implementing line propagation delay compensation for BiSS master in software


Following up on a question I asked some time ago: Simple Implementation of BiSS C interface for a position encoder. I have implemented a simple BiSS master (point to point) to communicate with an encoder. At frequencies below 2 MHz and short cable length, the software is working perfectly using SPI module on PIC microcontroller.

However I tried high speed (3 to 10 MHz) and a 10 m cable, which should work. I stumbled across a propagation delay issue. It appears the protocol needs an implementation of cycle by cycle delay compensation.

A snippet from TI TIDU410 showing the problem

I tried an approach in which I depend on the start sequence (ACK and Start bit) and I shift the result by 1 or 2 or 3 bits depending on how many clocks was the start bit late. But it does not work all the time, the problem seems to be that the data might be shifted by any fraction of the clock (ex.: 1/8, 1/4, 1, 1.5) so MISO is not decoding at the right time all the time.

Does anyone have thoughts on proper way to implement such function in microcontroller? (I can add a couple of discrete componets and logic gates if necessary) but not an FPGA.

*EDIT ( Screen shot from oscilloscope ) using standard SPI functions *
enter image description here

Screen shot from oscilloscope when directly puting data in SPI buffer without wait or any function whatsoever
enter image description here

Screen shot when using Buffered mode , 2 spi writes . Note the signal is clean , but the oscilloscope probe and ground pin was not idle when taking the photo..
enter image description here

Best Answer

I assume that the delay is somehow constant or with small jitter and the signal gets to SPI in good shape.

Updated after OP's observations that SPI communication is not back to back as I assumed so some bits are lost between frames.

Update after Andy's hint, the right solution is to use both BISS sensor and PIC SPI in slave mode and generate two clocks either externally gated by a PIC output or internally using timer output compare, or other way

With both clocks idle in "1" start DMA for SPI receive, start BISS interface clock, pool the ACK bit then start PIC SPI clock. Sampling in the middle will ensure enough hazard margin. The data will be aligned in words, no shifting is needed. The second DMA for dummy transmitting is no more needed.

You can find in the Microchip document about output compare module page 9 how to use the output compare module to generate a clock starting from high level. The speed can be up to 1/8 system clock.

It might be possible depending on the PIC capabilities that the SPI clock pin (input because we use SPI in slave mode) to be driven by using PPS without using another pin and external hardwired connection.

In this case, using software shifting as below, the board can be used without any hardware modification.

Using OP's solution to shift delayed data:

To get reliable readings first thing to do is to change the Data Input Sample Phase bit SMPx to sample the data at the end instead of the middle as i suppose it is. Or in the middle if it is on the end now

enter image description here

(The image has a mistake, the first edge of the "sample at the end" is not an active reading edge.)

It would be better to know by software which sample edge is better to use.

The description is made for SPI slave shifting data on the first falling edge, for the BISS interface that shift ACK on the second rising edge you can make the necessary corrections adding 0.5 Tckh or 1.5 Tckh to the delay.

Put your SPI clock on the highest usable value Ckh (Tckh period), count the bits until ACK arrives, change Data Input Sample Phase bit SMPx send another message and count the bits again.

That will give you a half clock period approximation of the delay. Use that to choose the sampling point for the clock you actually use Ck (Tck period). If the speed you use it's at most half then it's enough.

If the readings have the same number of "1" until ACK then the delay is between(N_ones) x Tckh and (N_ones + 1/2) x Tckk

If the end reading has one more "1" than the delay is between (N_ones + 1/2) x Tck and N_ones+1 x Tck

Back to the clock you actually will use. If a multiply of the clock period Tck touches the delay area then use the sample at the middle, if not than use sample at the end. If you used Ckh more than double then use the sampling time that is most far from the delay area.

Update, corrected the inverted representation of the signal in the text and add some graphic for better understanding

Same number of ones using fast clock, delay between 5 and 5.5 Tckh:

enter image description here

Sampling in the middle using fast clock reads an additional "1". Delay between 5.5 and 6 Tckh. (6 "1" for sampling at the middle not 5 as is in the image)

enter image description here

Using SPI clock, use sampling edge most far from delay area. enter image description here

The diagrams were made using WaveDorm online editor