This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C129XNCZAD: after changing mode, need to enable SSI BEFORE activating chip select

Part Number: TM4C129XNCZAD

After discovering the problem with the CS being enabled while changing SSI modes in the related post, I was sure I knew how to fix the problem. Imagine my surprise when even after not activating the chip select until after the call to SSIConfigSetExpClk(), the problem with the corrupted transmission persisted! I found something interesting, and wanted to share my discovery in case it may help someone else later on.

The following code will result in the second communications session with Device A having the 0xB0 be corrupted to a 0x58, 0x00 transaction:

    uint32_t dummy = 0;

    // ***** Device A Write
    SSIDisable(SSI3_BASE);
    SSIConfigSetExpClk( SSI3_BASE, getSystemClockFreqHz(),
                            SSI_FRF_MOTO_MODE_3,
                            SSI_MODE_MASTER,
                            2000000L,
                            8 );

    GPIOPinWrite(LCD_CSn_PORT, LCD_CSn_PIN, 0); // chip select low
    SSIEnable(SSI3_BASE);

    SSIDataPutNonBlocking(SSI3_BASE, 0xB0);
    SSIDataGet(SSI3_BASE, &dummy);

    // make sure the rx fifo is empty
    while ( 0 != SSIDataGetNonBlocking (SSI3_BASE, &dummy) )
    {
    }

    GPIOPinWrite(LCD_CSn_PORT, LCD_CSn_PIN, LCD_CSn_PIN); // chip select high


    // ***** Device B Write
    SSIDisable(SSI3_BASE);
    SSIConfigSetExpClk( SSI3_BASE, getSystemClockFreqHz(),
                            SSI_FRF_MOTO_MODE_0,
                            SSI_MODE_MASTER,
                            500000L,
                            16 );
    GPIOPinWrite(AM_CSn_PORT, AM_CSn_PIN, 0); // chip select low
    SSIEnable(SSI3_BASE);

    SSIDataPutNonBlocking(SSI3_BASE, 0x1234);
    SSIDataGet(SSI3_BASE, &dummy);

    // make sure the rx fifo is empty
    while ( 0 != SSIDataGetNonBlocking (SSI3_BASE, &dummy) )
    {
    }

    GPIOPinWrite(AM_CSn_PORT, AM_CSn_PIN, AM_CSn_PIN); // chip select high

    // ***** Device A Write
    SSIDisable(SSI3_BASE);
    SSIConfigSetExpClk( SSI3_BASE, getSystemClockFreqHz(),
                            SSI_FRF_MOTO_MODE_3,
                            SSI_MODE_MASTER,
                            2000000L,
                            8 );

    GPIOPinWrite(LCD_CSn_PORT, LCD_CSn_PIN, 0); // chip select low
    SSIEnable(SSI3_BASE);

    SSIDataPutNonBlocking(SSI3_BASE, 0xB0);
    SSIDataGet(SSI3_BASE, &dummy);

    // make sure the rx fifo is empty
    while ( 0 != SSIDataGetNonBlocking (SSI3_BASE, &dummy) )
    {
    }

    GPIOPinWrite(LCD_CSn_PORT, LCD_CSn_PIN, LCD_CSn_PIN); // chip select high}

The reason is, as you can see from the logic analyzer screenshot below, that when SSIConfigSetExpClk() is called to change the mode from 0 to 3, the clock signal polarity does not actually change until SSIEnable() is called, which is my example is after the CS is asserted.

However, if I change the code slightly by enabling the SSI before asserting the CS, the clock polarity toggles before the chip select goes low, and the transaction looks fine:

In retrospect, it makes perfect sense that the changes to the SSI configuration would not become active until the peripheral is re-enabled. But when deep in the process of trying to get code working, it was not immediately obvious -- at least to me!

Regards,

Dave

  • Hi Dave,

    Well summarized! Thanks for sharing this with the community. Some of us TI'ers even stow away posts like this to help share with others when needed, so it's much appreciated :)
  • Thanks number two arrives as well.

    I would (continue) in the belief that the "SPI Peripheral Reset" - followed by the proper initialization (dedicated to the new candidate device) would reduce (likely eliminate) the "lingering" (incorrect) clock polarity.

    My trust (and confidence) in the Peripheral Reset is that one, "Always starts from "Known Conditions"" - which is a prime directive of, "KISS" - and best insures "normal/customary" (predictable) operation...    

    (It would prove of interest to observe if "Peripheral Reset" - followed by proper initialization - may eliminate the (unexpected) 'Unique Sequence of Function Calls' - reported here...)    

    This is expected as the, "Peripheral Reset - followed by proper initialization (for the newly selected slave device) will insure that the clock idle level  will always be "proper" - prior to the arrival of this Slave's enabling, 'Chip Select.'

  • Hi, cb1,

    While resetting the peripheral might be good practice in general, I don't think it would solve this particular problem. In fact, if you recall from the original thread, when I added the peripheral reset it actually made my issue occur right away. This is because the reset puts the SPI into mode 0. So when I switched to mode 3 the clock polarity changed. Regardless of whether reset is done or not, it is important that the peripheral be enabled before asserting the chip select so the device does not see the clock transition.

    Regards,

    Dave

  • Having undergone dental surgery - earlier - I may be (especially) loopy - yet still (respectfully) disagree.

    As the "About to be Addressed Slave" - has not (yet) received its Chip Select - how then can it be sensitive to a "Change in Clock Polarity?"

    Such must prove true - don't you agree - for that "polarity change" to be detected - and destructively recorded? On multiple (other) ARM Devices (newer & running 50%+ higher clock speeds) such proves, "Never the case!" (i.e. ONLY when CS is valid - is an input sensed!)
  • Hello cb1,

    Hope the surgery went well, if I may, I think I can help bridge the gap slightly.

    What Dave is saying is that when he changes the polarity with CS asserted to select it, then it detects the change in polarity and registers it as an incorrect transition.

    The peripheral reset puts the device in Mode 0, and when switching to Mode 3, then the clock polarity changes. If this switch to Mode 3 is done AFTER the CS line is asserted to select the slave, then issues occur, and the solution is to do as you were implying by changing polarity BEFORE the device is selected so it is not 'sensitive to a "Change in Clock Polarity"'.
  • Thank you Ralph (never the imposter Ralf) - much appreciated.

    May I note - that rather than "implying" - I DIRECTLY STATED - THE REQUIREMENT - TO "AVOID THE APPLICATION OF CS - UNTIL (BOTH) PERIPHERAL RESET  - AND RE-INITIALIZATION - WERE COMPLETED!"

    Yet - my direction was to, Command Peripheral Reset - then fully/properly INITIALIZE (to the exact demands of the SLAVE) and 'THEN AND ONLY THEN' assert Chip Select.     Such has ALWAYS and ONLY worked for my group - and such method "Took us Public!"

    Any method - outside the above - subjects the Slave to "ILLEGAL INPUT SENSING" - which (I believe) should be DISALLOWED!

  • Hi cb1,

    I think we may be splitting hairs a bit on that point. I agree that peripheral reset is a good idea, and I think Dave does as well. My understanding is that his comments described that even if he reset the peripheral, he still observed the issue because the problem was that his Chip Select occurred before Peripheral Configuration was finished! Therefore the order of events was not per your recommendation and the peripheral reset couldn't save him from that issue.

    So yes it's a very good practice, but the correct peripheral initialization prior to CS assertion can be an even more important key.

    Would you agree with this summary, Dave?
  • Ralph Jacobi said:
    So yes it's a very good practice, but the correct peripheral initialization prior to CS assertion can be an even more important key.

    Somehow - my point - is being "almost" camouflaged!

    From your quote - you say:

    • it is a very good practice 

    but then follow that with

    • correct peripheral initialization - prior to CS assertion ... can be even more important.

    Yet Ralph - that Correct Peripheral Initialization  HAS ALWAYS AND ONLY BEEN INCLUDED - AS MY POINT!     It is (most) safely delivered AFTER a Peripheral Reset - but such INITIALIZATION HAS ALWAYS - EVEN GOING BACK TO THE EARLIER THREAD - BEEN THE THRUST OF MY SUGGESTION!    And - again as I've ALWAYS STATED - "THEN AND ONLY THEN" should CS be asserted!

    I've NOT CHANGED!       I don't know HOW there is any confusion...

  • Hi cb1,

    Maybe I misconstrued your prior comments then.

    First we had this:

    Dave Hohl said:
    While resetting the peripheral might be good practice in general, I don't think it would solve this particular problem. In fact, if you recall from the original thread, when I added the peripheral reset it actually made my issue occur right away. This is because the reset puts the SPI into mode 0. So when I switched to mode 3 the clock polarity changed. Regardless of whether reset is done or not, it is important that the peripheral be enabled before asserting the chip select so the device does not see the clock transition.

    Then your next reply stated:

    cb1_mobile said:
    Having undergone dental surgery - earlier - I may be (especially) loopy - yet still (respectfully) disagree.

    That reply was where I thought I should step in to help clarify what Dave was saying, as it came across as the focus was on the peripheral reset portion since that was the part that Dave did not resolutely state the importance of. Sorry if I misunderstood your intent with that post!

  • cb1, as one who has undergone more than my share of dental surgeries, I feel your pain! :-)

    Yes, Ralph, I think you did a good job of summarizing what I was trying to say. And thank you for trying to clarify things.

    I think all of us are in agreement, even though we might not be completely understanding the finer nuances of what each of us is trying to get across.

    Regards,

    Dave
  • No apology was sought - nor required.     You assist so many here - and so thoughtfully - that must be applauded!

    Yet so too - the efforts of "outsiders" demands (some) agreement.    (besides "splitting hairs")       No hairs were harmed - (let alone split) - during the creation of this posting.

    Follows a "collection" (true copy) of my comments - especially focused on  the critical arrival of the Slave's Chip Select:

    Thu, May 3 2018 7:41 PM:
    This is expected as the, "Peripheral Reset - followed by proper initialization (for the newly selected slave device) will insure that the clock idle level will always be "proper" - prior to the arrival of this Slave's enabling, 'Chip Select.'

    Fri, May 4 2018 12:47 PM:
    Such must prove true - don't you agree - for that "polarity change" to be detected - and destructively recorded?     On multiple (other) ARM Devices (newer & running 50%+ higher clock speeds) such proves, "Never the case!"    (i.e. ONLY when CS is valid - is an input sensed!)

    Fri, May 4 2018 1:18 PM:
    May I note - that rather than "implying" - I DIRECTLY STATED - THE REQUIREMENT - TO "AVOID THE APPLICATION OF CS - UNTIL (BOTH) PERIPHERAL RESET - AND RE-INITIALIZATION - WERE COMPLETED!"
    and
    Yet - my direction was to, Command Peripheral Reset - then fully/properly INITIALIZE (to the exact demands of the SLAVE) and 'THEN AND ONLY THEN' assert Chip Select.
    and
    Any method - outside the above - subjects the Slave to "ILLEGAL INPUT SENSING" - which (I believe) should be DISALLOWED!

    I fail to see - in light of this overwhelming evidence - how (ANY)  "Splitting of Hairs"  - was or is - thought  (anyway)  posssible...

  • To put this dead/dying horse - effectively "Out of its misery" - one last thrust may prove of use.

    There appears (some) dispute as to the value (or effectiveness) of the "Peripheral Reset."     And - in general - I would  (sometimes, yet carefully) agree.

    Yet - during harsh conditions - or even "Not so harsh" - yet "Long Duration - Operating/Powered" some, "disturbances have been REGULARLY  noted!"    (either upon the Slave - or Master MCU - or (even) upon both.)     And it is THEN & THERE - where the "Peripheral Reset" - especially shines!

    In our, "defense and medical device work" - where "failure or disruption must be prevented" - we find it of "GREAT VALUE" to, "REGULARLY EMPLOY Peripheral Reset" - followed by Peripheral Initialization - and only then "assertion of Chip-Select."     This "FAR MORE FREQUENT "CALL to Peripheral Reset"  - BEST INSURES - that "All is Well" - and "Remains in that state!"     In addition - we may  "Reset the Slave(s) as well" - either via GPIO Commanded Power Down/Up - or via Slave Reset - if/as available.

    Believing that "ONE & DONE" - Peripheral Set-Up/Config - will insure "stable operation" - has not proved the case - especially so during "harsh conditions" and/or situations where  "failure proves UNPLEASANT."

    Regular "Forcing of the MCU and Slave Devices" - into SAFE & KNOWN OPERATING CONDITIONS  (via Peripheral RESET) - even when not (strictly) required - especially when not (strictly) required - proves a highly effective means - to, "Enhance System Robustness!"