Cypress Perform

Home > Design Support > Cypress Developer CommunityTM > Cypress Forums > PSoC® 5 > Inconsistent SPI_Master behavior relative to sleep and debugging

Bookmark and Share
Cypress Developer CommunityTM
Forums | Videos | Blogs | Training | Rewards Program | Community Components



Inconsistent SPI_Master behavior relative to sleep and debugging
Moderator:
ANCY

Post Reply
Follow this topic



Inconsistent SPI_Master behavior relative to sleep and debugging

Helmut posted on 28 Jun 2012 10:10 AM PST
Top Contributor
48 Forum Posts

 Please note I am going to scour through the new PSoC3/5 sleep appnote AN77900.  But in the mean time, I wanted to go ahead and get this out there.  It may or may not (likely not) be solved for me after reading and studying AN77900, which may take a while.

My design is a little more complicated than described here, so I'm only describing what I'm pretty sure are the germane parts.

I have an SPI_Master component (V2.20) placed and configured for 16 bits.  I start it at the beginning of my program.  I have a software loop that does a WriteTxData().  After the WriteTXData(), I wait for SPI to become idel again before completing the loop iteration.  Within the loop, I toggle a debug output pin so that I can tell on my scope each time that the loop iterates.  (See Footnote 1 for non-germane detail).

As described above, the ss (Slave Select) pin will go low for each 16-bit SPI output.  This is true whether I'm debugging the program from the Creator, or if I power the target off and on and let it run free (with or without the MiniProg3 attached).

However, there's more intended inside my software loop.  I am able to include or exlude this additional stuff by using a #define.  The additional stuff relates to sleeping.  Inside each iteration, before doing any SPI, CyPmSleep surrounded by CyPmSave/RestoreClocks.  When I enable this sleeping and then run the program in the debugger, with no breakpoints and simply running free otherwise, everything behaves as expected.  However, when I power the target off and on so that it will run free without being in debug mode (whatever that means), the hardware behaves DIFFERENTLY!  The ss pin goes low and stays low.  The mosi data repeats the 16 bits over and over again, with only a multi-microsecond delay per set. At first I thought this was my loop iterating and that ss was not returning high.  However, when I probed the debug output pin that toggles every iteration, I found that it was NOT toggling.  This tells me that my code is stuck on waiting for idle, and the SPI hardware is autonomously repeating the 16-bit output over and over again.  With the addition of a 1ms CyDelay(1) call at the end of the loop iteration, and after confirming such delay in the debugger, I confirmed my suspicion that the SPI_Master is autonomously repeating the data output.  That is, no such delay was appearing between 16-bit sets.

So, with no sleep involved, the SPI_Master sends out one 16 bit set per call to WriteTXData().  With sleep involved, this continues to work in debug mode, but when free-running without debugging I get this indefinite recurring of 16 bit sets that never goes idle in order to progress to the next loop iteration.  I added explicit stop and start of the SPI_Master component before and after sleeping, but this didn't help.  The fact that I get expected behavior while debugging makes me think this is less that I'm doing something major wrong and more that theres a very subtle difference when debugging.  So, I don't expect to find the solution in the AN77900 app note.  I might, and I'll read it.  But in the mean time, I'm asking for help in advance about this.

And remember, I'm pretty sure I'm successfully waiting for idle after the WriteTXData().  When debugging, a single 16-bit set is output, the SPI_Master component goes idle, and I complete the iteration.  When freshly powered up without debugging, the SPI_Master component appears to never go idle, repeating the 16-bit output set over and over again.  And if I remove the sleep via #ifdef, the SPI_Master then acts consistently between debug and free running modes.

FOOTNOTES:

1. Note that I discovered that the ReadTxStatus() will *sometimes* (one out of four times in my testing) show idle for a moment after the WriteTXData() call.  In these cases, my code flowed through prematurely.  So what I do now is immediately after the WriteTxData() call, wait for NOT idle using a single-line while statement.  Then immediately after that I use another single-line while statement to wait for Idle.  I did try removing the first wait to BECOME idle, thinking there might be a timing difference when debugging.  But this didn't change things. 




Re: Inconsistent SPI_Master behavior relative to sleep and debugging

Helmut posted on 28 Jun 2012 10:27 AM PST
Top Contributor
48 Forum Posts

 ...ok, per AN77900, rather than bracketing the sleep with SPI_Master component stop/starts I bracketed it with SPI_Master component sleep/wakeups.  This PARTIALLY fixed the problem.  

Now, while free-running, the SPI_Master no longer repeats the 16-bit sets over and over again.  Instead, there's a single 16-bit data set on mosi that's accompanied by ss low.

However, there REMAINS a difference between debug mode and free-running.  When debugging, the ss pin remains inactive high during sleep.  When I power and and on to allow free-running, the ss pin goes low during sleep.  This is problematic for me because I am in fact using the ss pin to create specialized LE timing for a STP1612PW05 chip.

I'll continue studying AN77900, but I still suspect this remaining problem won't be cured by the app note...



Re: Inconsistent SPI_Master behavior relative to sleep and debugging

Helmut posted on 28 Jun 2012 10:33 AM PST
Top Contributor
48 Forum Posts

 ...while the remaining inconsistency persists, it's no longer an issue for me.  My intended downstream logic from ss to produce LE uses a dual PWM and some logic to combine them.  The LE result is active high.  Due to one or more of these downstream components, my LE output remains inactive low during sleep.  So I'm only getting LE active high at the moment desired relative to mosi output.  This behavior is consistent between debug and free-running modes.

Nevertheless, the inconsistency for SPI_Master ss pin remains, although not effecting my output.  For other forum users, they may need the ss pin behavior directly, in which case this inconsistency may be a problem.  So I am interested in further pursuing it for their benefit and my own future understanding.



Re: Inconsistent SPI_Master behavior relative to sleep and debugging

Bob Marlowe posted on 28 Jun 2012 11:00 AM PST
Top Contributor
1768 Forum Posts

There is some unwanted behaveour with debugging and interrupts that cannot be cured.

Since the hardware is not stopped at a breakpoint there might be an (or more) interrupt become pending while the program is stopped. When the program is re-started, the interrupt-routine is executed immediately and returns -----> to the breakpoint and halts again at the very same location.

From the outside it looks as if the program refuses to restart.

Sending the PSoC to sleep without waiting for a serial communication device to have COMPLETELY finished its job may cause unexpected results, even a repeated operation when woken up again might be possible. I've had the problem with an UART in that it was not quite easy to decide when it was ready because of sticky status-bit reads.

 

Bob

 



Re: Inconsistent SPI_Master behavior relative to sleep and debugging

Helmut posted on 28 Jun 2012 12:03 PM PST
Top Contributor
48 Forum Posts

 Thanks, Bob.  Do you have any recommendation for dealing with this?

FYI, since my last post I've found more inconsistencies with debugging and sleep.  Most recently, I found that the debugger wants to keep returning to the source code line with a yellow bar (suggesting instruction pointer and program paused) , even though the program is really still running as I can see on the scope.  This seems somewhat consistent with what you wrote.

I was trying to slow and speed the clocks.  Doing all the speeding (which simply reasserts if that thing not slowed) and only part of the slowing, I found that the debugger acted like this.  My scope showed the program was still running, but the debugger kept suggesting I was paused.  At first the debugger kept putting me on the first line of code and I thought the hardware might be resetting.  However, I found by clearing once then incrementing my repeating SPI data, that the program was really continuing to operate without resetting.  Then, later, by setting other breakpoints, I found that the debugger was simply reporting that I'm paused on the same statement that I was last legitimately paused on.

This seems to be a bug in the debugger to me.  Some kind of timing thing.  I recall, perhaps incorrectly, that this only happens when I *both* sleep and slow the clocks during sleep.

Next, when I un-uncomment and thus execute more parts of the clock slowing, the debugger behavior changes again.  I start coming to a CY_ISR(IntDefaultHandler) with comment "We should never get here. If we do, a serious problem occured, so go into an infinite loop."  The instruction pointer is at the beginning of the isr, not the looping while.  Meanwhile, the scope shows that the program is actually still running, SPI data still counting up having never reset to zero.

FINALLY, AND THIS IS A PROBLEM FOR ME STILL, I can't get CyFlash_SetWaitCycles() working properly.  My intent is to slow it down to CyFlash_SetWaitCycles(3) when sleeping.  This corresponds to a 3MHz IMO and master clock coming from the IMO.  After sleep, I intend to speed it back up.  But to what?  I have a 20MHz crystal, PLL going to 30MHz, and master clock driven by PLL.  I tried CyFlash_SetWaitCycles(30) and the program really does hang up.  I believe it hangs up even when I simply do the CyFlash_SetWaitCycles(30) and never do the CyFlash_SetWaitCycles(3).  And obviously it shouldn't work if I do the CyFlash_SetWaitCycles(3) without the CyFlash_SetWaitCycles(30).

Checking the doc, I can't find WHICH frequency should be used for CyFlash_SetWaitCycles().  I would assume it's the master clock, which is 30MHz for me.  But passing 3 to slow and 30 to speed didn't work.

Overall, for now, I've commented out my CyFlash_SetWaitCycles() calls.  I'll also add a"#define DEBUG_COMPATIBLE", so that when I intend to debug, I'll omit ALL of the clock slowing and speeding; I'll do this so that debugging doesn't act funky yet I can still do some sleeping so that my timing is correct.  (I just implemented this and it works.  In DEBUG_COMPATIBLE mode, I can still sleep albeit without clock slowing, and the debugger behaves as it should.  It thinks the target is running when it's so.  And when I click on "||" to pause, the debugger display and scope output both show I'm paused.  I'll just be drawing the wrong amount of power during sleep.  Whether or not this impacts my sleep timing, I haven't yet investigated.  But I'm sure I can get intended sleep timing, even if DEBUG_COMPATIBLE mode requires different settings.)

OUTSTANDING QUESTION REMAINS about CyFlash_SetWaitCycles().



Re: Inconsistent SPI_Master behavior relative to sleep and debugging

Bob Marlowe posted on 28 Jun 2012 12:37 PM PST
Top Contributor
1768 Forum Posts

To deal with these debugging problems:

First approach: set breakponts at desired line. When BP is reached, set BP at next line and remove current, run again. When stopped at next line, remove breakpoint set BP at previous line and continue continue.

Second approach: insert before your breakpoint an EnterCriticalSection and after the BP an ExitCriticalSection (to be found in "System Reference Guide") and recompile.

 

I know for sure that debuggin while in any of the sleep modes will not work at all for PSoC1, but I do not know if there are restricitions for PSoC3/5.

 

Bob






ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". CYPRESS SEMICONDUCTOR AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY CYPRESS SEMICONDUCTOR. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM CYPRESS SEMICONDUCTOR.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms and Conditions of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms and Conditions of this site. Cypress Semiconductor and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.

Spec No: None; Sunset Owner: GRAA; Secondary Owner: RAIK; Sunset Date: 01/01/20