2024-02-20 01:36 PM
Hi community,
I have a display, which has only CLK, DI and CS pin for SPI communication. It uses TI protocol.
The original driver is only working with raspberry pi, I try to import it into my custom STM32 MCU board, the CLK and CS signals seem okay, Only the MOSI signal is always low. it seems no data is really sent to the display.
here is the signal capture from logic analyzer.
The whole write sequence:
zoom in, single byte write:
what could be the reason? Thanks in advance.
Solved! Go to Solution.
2024-02-23 02:50 PM
Sounds like, you make progress. Cool.
What was the issue with MOSI?
Based on my experiences with SPI (I saw such issue, "CS signal toggles, has 'spike'", recently one a setup as well):
2024-02-24 10:41 AM
Hi @tjaekel
yes, some progress:)
If I set the logic tool to 1.8V, the signals look much better, but the MOSI signal is still not correct. Also tried with low speed.
Maybe you´re right, cross-talk could be the reason. Because the pin orders on the chip and the display connector are different, the SPI traces are not always parallel and a little long, it´s about 40mm, at some point I have to cross the clock and MOSI traces on PCB.
I will try to make a new PCB, after that I will come back and give a update again.
thanks a lot for all replies! :folded_hands:
2024-02-24 05:32 PM
"not always in parallel" - not really good to have parallel traces with high speed clocks on it (without "shielding").
Have a "pour GND" along all the SPI signals: fill all empty areas with "pour GND", so that all SPI signals are separated with a ground plane (not a "free space" between traces).
Keep signals apart from each other, esp. from high speed signals, e.g. clock signals, MCU OSC signals.
Add (optional) 33R series resistors in all driven lines, e.g. SCLK, SCS, MOSI. Place these resistors close to the output (driver): you can solder 0R or 33R later. 33R is there for "serial termination", to match the impedance of the trace (e.g. as resulting 50 Ohm), to avoid reflections ("ringing") and they also reduce "cross talk".
Have you tried to "play" with drive strength and speed setting on SPI signals? It might solve already your issue (e.g. slower speed, to avoid "cross talk" (EMI)).
When you go from header pins via "flying wires" to an external device: use double row headers: one row is got signals, the other is all GND. When you would use later a "ribbon cable": every second gauge is GND: it acts as shielding, to separate two signals with a GND wire between both signals.
Consider an option to have pull-ups (or pull-downs) on all signals: they can act a bit as "parallel termination", also helpful to deal with "impedance mismatch" etc.
Good luck.
2024-02-24 09:41 PM
Ok, I see, you mean parallel traces cause the cross-talk, understood.
I tried with different speed: HIGH, MEDIUM and LOW, got same results.
what do you mean with "drive strength"?
this is how the SPI traces look like, at some place SCK and MOSI are parallel and too close to each other, even without "pour GND"
2024-03-09 01:26 PM - edited 2024-03-09 01:38 PM
2024-03-10 03:54 AM
This is I´m using:
*****************************************************
void BSP_SPI2_Init(void)
{
/* Initialize the GPIOs associated to the SPI port */
BSP_SPI2_MISO_GPIO_CLK_ENABLE();
LL_GPIO_SetPinMode(BSP_SPI2_MISO_GPIO_PORT, BSP_SPI2_MISO_PIN, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinSpeed(BSP_SPI2_MISO_GPIO_PORT, BSP_SPI2_MISO_PIN, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType(BSP_SPI2_MISO_GPIO_PORT, BSP_SPI2_MISO_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull(BSP_SPI2_MISO_GPIO_PORT, BSP_SPI2_MISO_PIN, LL_GPIO_PULL_NO);
BSP_SPI2_MISO_GPIO_AF();
BSP_SPI2_MOSI_GPIO_CLK_ENABLE();
LL_GPIO_SetPinMode(BSP_SPI2_MOSI_GPIO_PORT, BSP_SPI2_MOSI_PIN, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinSpeed(BSP_SPI2_MOSI_GPIO_PORT, BSP_SPI2_MOSI_PIN, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType(BSP_SPI2_MOSI_GPIO_PORT, BSP_SPI2_MOSI_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull(BSP_SPI2_MOSI_GPIO_PORT, BSP_SPI2_MOSI_PIN, LL_GPIO_PULL_DOWN);
BSP_SPI2_MOSI_GPIO_AF();
BSP_SPI2_SCK_GPIO_CLK_ENABLE();
LL_GPIO_SetPinMode(BSP_SPI2_SCK_GPIO_PORT, BSP_SPI2_SCK_PIN, LL_GPIO_MODE_ALTERNATE);
LL_GPIO_SetPinSpeed(BSP_SPI2_SCK_GPIO_PORT, BSP_SPI2_SCK_PIN, LL_GPIO_SPEED_FREQ_HIGH);
LL_GPIO_SetPinOutputType(BSP_SPI2_SCK_GPIO_PORT, BSP_SPI2_SCK_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull(BSP_SPI2_SCK_GPIO_PORT, BSP_SPI2_SCK_PIN, LL_GPIO_PULL_DOWN);
BSP_SPI2_SCK_GPIO_AF();
BSP_SPI2_CS_DISPLAY_GPIO_CLK_ENABLE();
LL_GPIO_SetPinMode(BSP_SPI2_CS_DISPLAY_GPIO_PORT, BSP_SPI2_CS_DISPLAY_PIN, LL_GPIO_MODE_OUTPUT); //LL_GPIO_MODE_ALTERNATE
LL_GPIO_SetPinSpeed(BSP_SPI2_CS_DISPLAY_GPIO_PORT, BSP_SPI2_CS_DISPLAY_PIN, LL_GPIO_SPEED_FREQ_HIGH); //
LL_GPIO_SetPinOutputType(BSP_SPI2_CS_DISPLAY_GPIO_PORT, BSP_SPI2_CS_DISPLAY_PIN, LL_GPIO_OUTPUT_PUSHPULL);
LL_GPIO_SetPinPull(BSP_SPI2_CS_DISPLAY_GPIO_PORT, BSP_SPI2_CS_DISPLAY_PIN, LL_GPIO_PULL_DOWN);
LL_GPIO_ResetOutputPin(BSP_SPI2_CS_DISPLAY_GPIO_PORT, BSP_SPI2_CS_DISPLAY_PIN);
//BSP_SPI2_CS_GPIO_AF();
/* Initialize the SPI clock */
BSP_SPI2_CLK_ENABLE();
/* SPI parameter configuration*/
LL_SPI_SetMode(BSP_SPI2, LL_SPI_MODE_MASTER);
LL_SPI_SetStandard(BSP_SPI2, LL_SPI_PROTOCOL_TI); // LL_SPI_PROTOCOL_MOTOROLA
LL_SPI_SetTransferDirection(BSP_SPI2, LL_SPI_FULL_DUPLEX); // LL_SPI_HALF_DUPLEX_TX
LL_SPI_SetClockPolarity(BSP_SPI2, LL_SPI_POLARITY_LOW); // LL_SPI_POLARITY_HIGH
LL_SPI_SetClockPhase(BSP_SPI2, LL_SPI_PHASE_1EDGE); // BSP_SPI2_CLK_PHASE
LL_SPI_SetNSSMode(BSP_SPI2, LL_SPI_NSS_SOFT);//
LL_SPI_SetDataWidth(BSP_SPI2, LL_SPI_DATAWIDTH_8BIT);
LL_SPI_SetTransferBitOrder(BSP_SPI2, LL_SPI_MSB_FIRST);
LL_SPI_DisableCRC(BSP_SPI2);
LL_SPI_DisableNSSPulseMgt(BSP_SPI2);
LL_SPI_SetBaudRatePrescaler(BSP_SPI2, LL_SPI_BAUDRATEPRESCALER_DIV8); /* 8 MHz */
/* Configure the SPI RX FIFO threshold to 1 byte */
LL_SPI_SetRxFIFOThreshold(BSP_SPI2, LL_SPI_RX_FIFO_TH_QUARTER);
/* Enable the SPI */
LL_SPI_Enable(BSP_SPI2);
}
2024-03-12 02:29 PM - edited 2024-03-12 03:49 PM
new findings:
with this setting
LL_SPI_SetDataWidth(BSP_SPI2, LL_SPI_DATAWIDTH_8BIT);
the data is actually 9 bits
2024-03-12 03:51 PM
"hmmm", for me, I would be suspicious, something wrong...:
BTW: when I see your PCB layout: why to keep the SPI signals parallel for such a long distance? You have enough space to separate the 3 traces much more, with a ground pour between them. To route the high speed SPI traces for such a long distance together, without a "shielding" between them, is not the best approach to avoiding cross-talk.
2024-03-13 04:48 AM - edited 2024-03-13 04:50 AM
Hi @tjaekel
Thanks for reply.
the first byte is 0xC0, which will be sent to display.
this is capture on Raspberry Pi, it also has a peak, but it doesn´t matter.
these are the captures on my board, the data will be recognised as 0xE0 or 0x60. Of course, it has more peaks, but it doesn´t affect the data.
the biggst difference between the captures is the timing of MOSI signal, as you can see the MOSI signal on Pi board is already high, before the first clock signal comes.
which settings can affect the timing?
2024-03-13 03:16 PM
just found the peaks can be eliminated by set the pin speed to LOW
the data should be 0xC0 and 0x80, but both are recognised as 0xE0...