7
\$\begingroup\$

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

\$\endgroup\$
16
  • \$\begingroup\$ what's your mcu clock speed? \$\endgroup\$
    – BeB00
    Commented May 7, 2018 at 23:18
  • \$\begingroup\$ @BeB00 , i am running at 60MIPS , 16.67ns is the instruction time ( incase you are wondering about bit banging ) \$\endgroup\$
    – ElectronS
    Commented May 8, 2018 at 9:38
  • \$\begingroup\$ well you can't change the way the SPI peripheral works, so bit banging is pretty much the only thing you can do unless you want to get an external chip. For 10MHz, 80 MIPS would be more comfortable, but 60 might work \$\endgroup\$
    – BeB00
    Commented May 8, 2018 at 13:29
  • 1
    \$\begingroup\$ Can you implement master to slave then, for the slave response, swap roles so that the original master takes the clock from the new master (the former slave). Is there enough intelligence at the slave end to implement this? \$\endgroup\$
    – Andy aka
    Commented May 11, 2018 at 22:28
  • 1
    \$\begingroup\$ Uh , i don't know if Andy meant this but answer hit me like a storm. Use SPI in slave mode and use a different pin (using output compare or something) to generate the clock signal for both PIC and BISS slave. That way the clock signal will be steady without any breaks. If you somehow gate the clock that goes to the PIC you might compensate the delay as stated in the BISS protocol \$\endgroup\$
    – Dorian
    Commented May 12, 2018 at 23:25

1 Answer 1

4
+50
\$\begingroup\$

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

\$\endgroup\$
27
  • \$\begingroup\$ regarding the first sentence , the signal get to SPI in very good shape ( i confirm with Oscillscope with short GND lead ) . the Delay should be constant for a specific configuration ( speed and length ) . \$\endgroup\$
    – ElectronS
    Commented May 9, 2018 at 21:47
  • \$\begingroup\$ what you presented is brilliant , since i am currently sampling at the falling edge , i will try changing that at the speed where it is not working and see the results , in that case , i will make a sort of calibration function that will choose the sampling polarity based on some read cycles . i will get back when i can confirm the result , thanks :) \$\endgroup\$
    – ElectronS
    Commented May 9, 2018 at 21:53
  • \$\begingroup\$ After an hour of Testing , the solution you proposed worked partially ( some bits are still mistaken ) following those error i found the problem , it is in the Pause between words sent . Since i am using 16-bit archituture , and using SPI in 16bit mode ( word not byte ) and i am sending/Receiving 2 words, there is a pause of about 3 clocks between the 2 words . This delay is causing a problem with the delay compensation algorithm , NOW it appears i have figure out if i can eliminate this delay or i have to use PIC32 ( 32bit spi ) , do you have any thought ? \$\endgroup\$
    – ElectronS
    Commented May 9, 2018 at 22:51
  • \$\begingroup\$ I have added an screen shot to question ... \$\endgroup\$
    – ElectronS
    Commented May 9, 2018 at 23:02
  • 1
    \$\begingroup\$ I knew that SPI slave must have data in SPIbuf , and i was doing that before generating the Clock ( Output compare ) in the BISS read function. however the first time the clock is generated ( in OC initalize ) at that moment there is characters in the buffer , thats why i missed the point , So it was really tricky to know the problem. I will post an answer containing The tips and tricks if that would help . but really thank you for the patience and good help i needed to interact and challenge my self with another fellow engineer , could not have done it without YOU :)) \$\endgroup\$
    – ElectronS
    Commented May 15, 2018 at 15:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.