Skip to main content
Explorer II
February 20, 2024
Solved

SPI communication with 3 wire display

  • February 20, 2024
  • 9 replies
  • 9064 views

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: 

Danny0007_1-1708464524960.png

zoom in, single byte write:

Danny0007_2-1708464622941.png

what could be the reason? Thanks in advance.

 

 

    This topic has been closed for replies.
    Best answer by Danny0007

    Hi @tjaekel 

    good news!!!

    it works with this kind of CS signal:

    Danny0007_0-1710455099874.png

    the CS signal keeps always active until the last transfer session.

    not works, when just set CS active for every transfer session like this:

    Danny0007_1-1710455301709.png

    *****************************************************************

    Danny0007_0-1710455480916.png

    I used Motorola mode(CPOL=0,CPHA=0) and keep the CS always active the whole transfer.

    ******************************************************************

    @tjaekel Thanks a lot again!!! I learned also a lot:)

     

     

    9 replies

    Graduate II
    February 20, 2024

    Bit pointless to guess why.

    Diagram all the connections, and provide a data sheet to the module or controller you're attaching too.

    Either it isn't strapped in SPI mode, or expects CS to be low going.

    Visitor II
    February 21, 2024

    Are you sure your SPI Enable (NCS) is high active?
    I see, your SPI enable is high when SPIC SCLK is sent.

    OK, not related to "why MOSI" is not there:

    • have you configured and connected the MOSI signal properly?
    • if you ALT config for MOSI is wrong or you grab the signal on a wrong pin...

    Your waveform should be correct, even nothing is connected: check the config for the MOSI signal (pin and ALT).
    And check if NCS should be high.

    Hint: configure MOSI pin as GPIO and see, when you toggle GPIO, if it comes out on the correct header pin. If not: you are on the wrong pin. If it works, but not with SPI: you have not configured the right pin as MOSI.

    Danny0007Author
    Explorer II
    February 21, 2024

    Hi @Tesla DeLorean @tjaekel 

    thanks for reply!

    this is signal capture from raspiberry pi, you can see the CS pin is also high during write-operation.

    Danny0007_0-1708547870384.png

    there are only 3 pins(clock, MOSI, CS), I thought the data are transformed only in this direction: uC----> display. how to explain the read-operation in the sequence?

    Danny0007_5-1708549951248.png

     

    *********************************************************

    Here is my hardware connection to display:

    Danny0007_6-1708550850413.png

    datasheet

     

    here is SPI2 init function:

    Danny0007_3-1708548338761.png

    here is pin definition:

    Danny0007_4-1708548476361.png

     

     

     

     

    Graduate II
    February 21, 2024

    Show the code sending the data

    Danny0007Author
    Explorer II
    February 21, 2024

    Danny0007_0-1708554003773.png

     

    Danny0007Author
    Explorer II
    February 22, 2024

    Hi @tjaekel @Tesla DeLorean ,

    thanks again for your reply, very appreciate it. 

    1. the slave part is a display, CS is high activ, pretty sure.

             the master part is BlueNRG-LP, these 3pins are used as SPI2 and PA6 is MOSI.

    Danny0007_1-1708636036994.png

     2. without display, all these 3 pins are able to be toggled. 

     sorry for the confusion, I did something wrong. Now the question is only it´s not working properly in SPI mode.

     

     

    Super User
    February 22, 2024

    @Danny0007 wrote:
    1. the slave part is a display, CS is high activ, pretty sure.

    You need to be more than just "pretty sure" - do you not have a datasheet or specification which states this?

    As the others have said, it would be extremely unusual - so it should be easy to find reference to it.

    Do you have a part number?

    Link to manufacturer's or seller's page for it?

    Danny0007Author
    Explorer II
    February 22, 2024

    Danny0007_0-1708638713301.png

     

    Danny0007Author
    Explorer II
    March 9, 2024

    @tjaekel 

    I made a new PCB, but the result is the same.

    The same SPI2 settings I tested on IDB011V2 and also get the same result.

    So I think the issue is not caused by hardware design, could you please also test SPI2(PA4/PA5/PA6) on a IDB011V2 board and confirm it?

    Danny0007Author
    Explorer II
    March 10, 2024
    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);
    
    }
    Danny0007Author
    Explorer II
    March 12, 2024

    new findings:

    with this setting 

     LL_SPI_SetDataWidth(BSP_SPI2, LL_SPI_DATAWIDTH_8BIT);

    the data is actually 9 bits

    Danny0007_2-1710283656800.png

     

    Visitor II
    March 12, 2024

    "hmmm", for me, I would be suspicious, something wrong...:

    • You have one CLK edge, before the bursts with always 9 clocks - why is this CLK edge there and would it "confuse" your slave device?
      (it comes at the same time as nCS gets active high
    • At the end is always a clock edge, together with nCS right to go inactive (back to low here). Your slave device might still see the "spurious" clock edges. I would try to figure out why and how to get rid of it.
    • All data as ones - looks clean, but all as zero? Why do you have high pulses there? Even they might not be considered as "one" (outside the sampling clock edge) - but why and what is driving the data line in between?
      Are there pull-ups? Is the data line floating in between? (I cannot imagine).
    • Here, I would also try to understand what causes the high pulses when data line should be constant zero.
      It could be "cross-talk" (again) because: it corelates with the rising edge of CLK signal, not always, but when - the high pulses on data line are "in sync" with the CLK signal. A scope, sampling and rounding up to logic level 0 or 1 could look like this. You might need to use scope in analog mode and see the real waveform of the data line: potentially, you will see everywhere "when CLK goes high - there is also a pulse on data line".
    • Have you "played" with drive strengths or speed setting of the SPI pin signals? (the pin signal config)? Try to use "slow speed", e.g. on CLK signal... "Fast speed" can cause more EMI and cross-talk issues.
    • You could also try to add pull-up or pull-down on data line - hoping to get rid of the "wrong pulses".
    • Try to "get rid" of these "wrong pulses". Otherwise, any other data line bit pattern can be affected by this (and would be 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.

    Danny0007Author
    Explorer II
    March 13, 2024

    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.

    Danny0007_0-1710329273073.png

    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. 

    Danny0007_2-1710329542457.png

    Danny0007_3-1710330432663.png

     

    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?

     

     

     

     

    Danny0007Author
    Explorer II
    March 13, 2024

    just found the peaks can be eliminated by set the pin speed to LOW

    Danny0007_0-1710368094316.png

    the data should be 0xC0 and 0x80, but both are recognised as 0xE0...

    Visitor II
    March 14, 2024

    "yeah", what I thought: very high speed as pin config is very sharp edges, creating a lot of EMI and cross-talks. Lower speed setting helps to get rid of cross talk.

    Regarding your "E0 vs. C0":

    I think, I see, your scope tries to decode SPI Mode 0: with the rising edge to sample the MOSI/MISO. But potentially you have configured SPI Mode 1 in the MCU:

    https://www.analog.com/en/resources/analog-dialogue/articles/introduction-to-spi-interface.html

    If you would sample with SPI Mode 1 - you should get a very clean C0 - at least on the second MOSI transaction.
    Why the first one is longer as the second one - no idea. But on the second MOSI pulse, SPI Mode 1 (sampling with falling edge), would be the correct one.

    Check your SPI Mode:

    • which SPI Mode do you need for your Slave device (often Mode 0 or Mode 3, Mode 1 and 2 are pretty uncommon)
    • check what is used by the scope as SPI Mode to decode (it looks like SPI Mode 0 to sample, but for sure "wrong" because it looks more like a SPI Mode 1 is generated)

    It works actually this way (assuming SPI Mode 0):

    When SPI Tx generates MOSI and the Slave (!) wants to receive as SPI Mode 0: it will sample MOSI with the rising edge.

    Therefore, the data has to be changed on MOSI with the falling edge, so that it is stable long before the rising edge comes where MOSI will be sampled. One edge is to "setup" MOSI, the other edge is the "sampling" edge. Signal should be stable for a half clock period before the sampling edge and it changes again after a half clock period (again with the other edge).

    But in your scope picture: MOSI changes with the same edge as SCLK would be used to sample. This cannot be right: you would not have any "setup time" for the MOSI signal. Very timing sensitive! Any offset in trace length between SCLK and MOSI line would change the timing relation for this "set and sampling" edge, depending on if MOSI or SCLK is delayed a tiny bit - you get wrong bits sampled.

    At least your scope configuration is wrong, compared to what is configured for MCU to send SPI. Check also which SPI mode is needed by the Slave Device. Actually, your scope should use the same SPI Mode as your real slave device.

    You are on the right track, just to check if the SPI Mode is the issue (and I think so).

    Danny0007AuthorAnswer
    Explorer II
    March 14, 2024

    Hi @tjaekel 

    good news!!!

    it works with this kind of CS signal:

    Danny0007_0-1710455099874.png

    the CS signal keeps always active until the last transfer session.

    not works, when just set CS active for every transfer session like this:

    Danny0007_1-1710455301709.png

    *****************************************************************

    Danny0007_0-1710455480916.png

    I used Motorola mode(CPOL=0,CPHA=0) and keep the CS always active the whole transfer.

    ******************************************************************

    @tjaekel Thanks a lot again!!! I learned also a lot:)

     

     

    Visitor II
    March 15, 2024

    Great, nice job.

    The TI-mode I have never understood (why it is there, I have never used). The Motorola nCS behavior is the most common: nCS is active for the entire period of the SPI transaction. It toggles between SPI transactions (gets inactive). In your case: the nCS is a high active signal (not very common).

    But good to know it works now for you. Well done.