2
\$\begingroup\$

There is a lot of information online for SPI bus termination, but my situation is a little bit different. I have created a system with the intention of 'plug and play' IMUs. Although the main electronics (Nucleo-F446RE) needs to be reset after each addition/removal of IMU to allow for reinitialising, the concept has shown to potentially work in ideal situations.

However, finding the best combination of resistors in series for bus termination has turned into a headache because of my unorthodox setup. There can be anywhere between 1m of SPI line, to 4m, depending on whether I have one or four IMUs connected, respectively. The system has been made to be as user friendly as possible, and the 1m cable length is necessary due to the intended application of IMU placement:

  • Each IMU has 7 lines (3.3V, ground, clock, MOSI, MISO, CS, interrupt) and has a 1m of shielded cable connected.
  • A 7 pin plug is connected to the other end of the cable, which plugs into a matching 7 pin socket. The socket is mounted in a 3D printed housing, which also houses the Nucleo.
  • From the socket to the individual pins of the Nucleo is ~10cm of unshielded multi-core conductors. These are the same conductors from the wiring listed above, although not contained within its shielded insulation. Because of space constraints and the number of Nucleo pins the wiring is attached to, I was not able to use shielded wiring within the 3D printed housing.
  • Appropriate lines are grouped within the housing as they go to a single pin on the Nucleo (3.3V, ground, clock, MOSI, MISO), but each CS and interrupt line is going to a separate Nucleo pin. Despite being grouped, each IMU has it's own ~10cm of unshielded line (the lines are grouped just before being soldered to the pins).
  • SPI clock speed tested at 5.625Mbps and 2.812Mbps. Sampling the IMUs at 1.66kHz using their data-ready interrupts to read data. Ideally I'd really like the faster clock speed, but may be able to get by with the 2.812Mbps speed.

I have given copious amounts of details, as in my experimentation this all seems to be important. The issues that I am seeing are that either some or none of the IMUs are initialising in different configurations (e.g., I have all four IMUs connected, but only two or three will initialise). I have also seen devices initialise, but after a few seconds stop responding. I have also seen seemingly successful initialisation, but there will be a lot of digital noise, square-wave responses, or otherwise bad data. To make my problem harder to diagnose, the combination of IMUs connected alters the issue. One IMU connected may respond fine, two and three as well, but four will cause issues. Likewise, maybe I can only connect two IMUs before issues appear, or I will connect four and only two will respond, despite three working seemingly well before the fourth IMU is connected.

I have drawn a quick ASCII image on my setup, and have listed what I believe to be relevant points where termination resistors can be attached, as shown in {x}:

            1m shielded cable                           ~10cm unshielded line
[IMU 1]{1}======================{2}[plug][socket]{3}-----------------------------{4}[           ]
                                                                                    [           ]
[IMU 2]{1}======================{2}[plug][socket]{3}-----------------------------{4}[           ]
                                                                                    [   Nucleo  ]
[IMU 3]{1}======================{2}[plug][socket]{3}-----------------------------{4}[           ]
                                                                                    [           ]
[IMU 4]{1}======================{2}[plug][socket]{3}-----------------------------{4}[           ]
  1. Originally, I placed a 100ohm resistor on the clock and MOSI lines at the leaving point of the Nucleo (point {4}), and a 100ohm resistor on the MISO line at the connecting point of the IMU (point {1}). When one IMU was connected, this seemed to work fine. But once four IMUs were connected there is collectively 400ohm on the MISO line, which seemed to be too much and caused the above-mentioned problems.

  2. Next, I tried removing the MISO resistors from all the IMUs at point {1}, and placed a single resistor at the same place as the other resistors, at point {4}. This sporadically worked. Originally 100ohm appeared to work, but I have also tried 22, 47, and 68ohms, and a combination of each when monitoring the lines with an oscilloscope. I have also gone as high as testing 300ohm resistors, but after that the signal becomes too saturated.

  3. Finally, where I am now. I have connected a 22ohm resistor on the clock, MISO, and MOSI lines at the Nucleo (point {4}), but also each IMU has their own 22ohm resistor on the clock, MISO, and MOSI lines at the IMU (point {1}). If one IMU is connected, each line will have around 44ohms termination, and that will increase by 22ohms for each connected IMU.

The reasoning for my placement of the resistors at these specific points, is because I had read that clock and MOSI should be terminated at the source, and MISO at the sensor end, but that has pretty much gone out the window through my numerous iterations of testing. There are too many parameters with each connected IMU for me to trial-and-error my way through this.

I would very much appreciate some theoretical know-how on how to solve my issue. I have worked with SPI before, but such short lines that I never had to deal with termination. In hindsight perhaps SPI wasn't the best choice, and I'm well aware that up to 4m is REALLY stretching the limitations, but I would love some help from professionals.

My lasting idea is that perhaps I should be placing the termination resistors in the middle of the lines, perhaps at the plug or socket points ({2} or {3}). Maybe resistors in series are not the best strategy and someone has another suggestion? Maybe someone can help me understand the numbers behind the resistor values and cable impedance so I can select the best resistors rather than a very long-winded experimental method.

Thanks very much in advance for any help!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I think having even 1 meter SPI at 2.8 Mbps is beyond expectations with just TTL/CMOS level signals over straight wires, regardless of shielding. How much of the design you can redo? As it is unlikely that simply adjusting termination resistor values will help. \$\endgroup\$
    – Justme
    Commented Sep 20, 2022 at 10:08
  • \$\begingroup\$ I misunderstood your question first. Now, I understand your problem. Did you try any of these: Using a strong driver of the MOSI, MISO lines so that bus levels are not changed due to any interference. Indeed 1m and above is stretching the SPI protocol. Do pull ups work in keeping the bus steady for long distances on MISO, MOSI ? In doing a SPI bus implementation as the distance between master and slave increases, the clock speed has to be reduced from say 10 Mhz to 6 Mhz to a few Khz. Did you try a slower clock? \$\endgroup\$
    – Amit M
    Commented Sep 20, 2022 at 11:59

3 Answers 3

4
\$\begingroup\$

I think you are really swimming against the tide here. You are asking for theoretical background, I'll do my best.

  1. The point about SPI termination is not about bus speed, but that the whole thing depends on clean clock edges, because it is edge triggered. If you get reflections on those clock edges, you are dead. And the edges with most drivers tend to be fast - a few nanoseconds, so there are significant RF components.
  2. The basic idea of transmission line theory is that when the line length becomes significant w.r.t. signal frequency, you start getting reflections. IF the line can be characterised as a transmission line, with uniform C and L per unit length, you can calculate a "characteristic impedance", and when you terminate the line with that impedance, those reflections are minimised.
  3. You are using shielded cable (typically around 100 ohm), but there must also be connectors and so on, at least to get signal on and off the line, both for the driver and the slaves. So probably that 100 ohm Zo is not perfectly true.

In practice (at least my experience), the absolute value of the terminating resistor is not so critical - whether it is 33 or 100 or 150 ohms, if there is a problem that can be cured this way, one of these will do it. You can go between source and end termination, but that is really only helping minimise load on the drivers. if you are trying these kinds of values and still having issues, there isn't a lot more you can do - because those clock inputs are so sensitive to edges, any reflection at all will cause problems. If your bus speed is low, you COULD experiment with trying to slow down the clock with a funky CR circuit or something (i.e. try to reduce the HF on the line), but that might introduce a whole lot of other issues. You might be at a point where you spend more time trying to get a workaround (which works-around on a good day with the wind in the right direction) than fixing the issue at source.

Others may have had success with this kind of arrangement using other approaches, but this is my gut feeling on your problem.

\$\endgroup\$
4
\$\begingroup\$

Slave response delays due to cable length create a sync problem in SPI

A 4 metre cable of average sort of characteristics will delay a clock edge by about 20 ns from one end to the other. This is based on the edge travelling at about two-thirds the speed of light. In numbers, light takes 3.333 ns to travel 1 metre so, your cable will cause a clock edge to take 5 ns to travel 1 metre or, 20 ns to travel 4 metres.

So, when you initiate a master to slave transmission, it will take 20 ns for both clock and data to reach the slave. But, there shouldn't be any problem here because both clock and data are in phase and delayed the same amount. So, it's quite likely that your slave receives the master command and recognizes it.

The problem comes when the slave responds. It synchronizes its response to the clock it is receiving from the master and, that clock is fundamentally delayed by 20 ns so, by the time the slave response arrives at the master, it is 40 ns delayed from the master's clock edges.

This means that if the clock speed is such that slave data response (arriving at the master) is valid on the wrong clock edge from the master, you have garbage. That will happen at a clock speed of 12.5 MHz and you are wanting perfect operation at around maybe half this speed. However, that is the best case scenario.

Given that you have also termination issues (not the main problem) and multiple cable types (also not the main problem) I'm not surprised it doesn't work.

If you want to debug this, send a slave a message that doesn't require a response i.e. send it a simple message to toggle an IO line. I'd estimate that this type of message works just fine i.e. slaves are receiving data correctly. It then proves (fairly conclusively) that it is the return path that is the problem.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for your response. Naïve question, but is the communication really travelling 4 metres in this scenario? There can be a total of 4 metres of cable, but it's four metres in parallel, so each individual IMU only has 1m of cable between itself and the master. I wouldn't be surprised that I have numerous issues, but being as inexperienced as I am I assumed it's termination. Do you have any suggestions on things to try to recetify my issue after debugging, and assuming that it's the slave responding that's the issue? \$\endgroup\$
    – ritchie888
    Commented Sep 20, 2022 at 10:58
  • \$\begingroup\$ Well, it's your system and you know it best but I'd be worried about slave response integrity and it's easy to prove as I explained in my answer. \$\endgroup\$
    – Andy aka
    Commented Sep 20, 2022 at 11:00
  • 1
    \$\begingroup\$ by the way, here's an app note which deals with the clock delay problem: Extending the SPI bus for long-distance communication \$\endgroup\$ Commented Sep 20, 2022 at 21:59
-3
\$\begingroup\$

Edit:
Added notes making drivers of the bus stronger.

For short distance SPI communication, push pull mode, the MOSI or MISO lines need not be pulled up or terminated with a resistor when connected directly to another MCU. I did implement SPI several times within 50cm distance and there were no bus termination resistors because the pins of MOSI and MISO, CLK and Chip select were all in push pull mode.There were no reflections of any MISO or MOSI signals. Master would control CLK, MOSI and CS lines. MISO line will be controlled by a slave. An important thing to note is that SPI bus is not a multi master bus so plug and play doesn't work. A SPI bus only has a single master and one or more slaves.

Another interesting thing is that you want to implement variable numbers of slaves. How are you going to do that? The SPI master can communicate with a few slaves which are selected with Chip select signals. Usually, number of slaves connected to a SPI master are fixed. A typical SPI peripheral doesn't have more than 2 to 4 CS signals. Are you going to add a daisy change of slaves with each chip select signal? Perhaps you can draw a topology of the connections. I'm pretty sure you have use multiplexers to choose the signal paths to different slaves. This would add delays so you have to use slow baud rate and slow messaging.

There seems something wrong in your pin or bus configuration or its not adequate. Read about open drain and push pull modes of all the pins in SPI bus and look at information about using strong and weak driver for pins. I think some GPIOs have some this capability. Also, try to control the chip select manually if automatic chip doesn't work well with timing of MOSI and MISO signals.

Some things you can try one by one. Try not to make all changes at once:

Make the driver of the pins of MOSI, MISO, CS and CLK stronger.

Use a pull up resistor on bus lines to keep them steady.

Reduce clock speed. Try different clock speed settings. Start with a low clock speed of about 5 to 10 KHz and keep on increasing it until the communication on bus is steady without any data corruption. This usually works in most cases.

Try a different protocol like UART which works well in distances over 10m and has less interference problems.

A quick search seems to bring this result which may be valuable to you:

SPI Bus Termination Considerations

\$\endgroup\$
9
  • 1
    \$\begingroup\$ Where did you get the idea that SPI is used in open drain mode and only then resistors are needed? Do you understand the concept of termination used here? Also SPI can be used in multimaster mode with devices that support it, it just is not used much. But it is as old as MC68HC11E family. \$\endgroup\$
    – Justme
    Commented Sep 20, 2022 at 11:14
  • \$\begingroup\$ Its written in MCU reference manuals. . Look at NXP or some other company which produces 8 to 32 bit MCUs. I am not familiar with MC68HC11 but I know about S08, S12X and MPC 55xx type MCUs. These MCUs support push pull mode. Look at application notes too. \$\endgroup\$
    – Amit M
    Commented Sep 20, 2022 at 11:23
  • 1
    \$\begingroup\$ the OP is clearly using push pull mode, and you are confusing series termination resistors with pull-ups and mistakenly think open-drain is used. \$\endgroup\$
    – Justme
    Commented Sep 20, 2022 at 11:30
  • \$\begingroup\$ Why is series termination with a resistor needed? I dont think that a resistor is needed to be added on any line of a SPI bus. I am sort of not familiar with any peculiar behavior of some SPI peripherals. A Termination impedance is added to a signal line is just to avoid reflections of the signal in some applications. Usually, most SPI bus lines are connected to each other directly master to slave with no termination resistor on the SPI bus. \$\endgroup\$
    – Amit M
    Commented Sep 20, 2022 at 11:37
  • 1
    \$\begingroup\$ Yes but here is a 1 meter transmission line between SPI devices. Or rather, four one meter cables.The resistors are not for the SPI devices themselves, any transmission line driven with digital signals need termination to avoid reflections, and here, reflections are especially bad for the SPI protocol. \$\endgroup\$
    – Justme
    Commented Sep 20, 2022 at 11:46

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.