Timer16 problems - resetting??

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

Howdy,

   

I am getting ready to do a Real Project with a PSoC and am familiarizing myself with the toolset.  We have a simple board with a CY8C20437, one debug LED, ISSP header, some capacitive switches and an I/O header.

   

I wanted to do a "hello world" by blinking my LED periodically.  Fair enough...throw in an LED user module, can turn on and off.  Well and good. Timer16...big problems.  (Incidentally, I've gotten the same sort of idea to work with a Sleep Timer...and I'm not even sure I'll need a full timer on my project, but it's the thought that counts - I have to figure this out now, or it will bug me for weeks!)

   

Basically, my LED blinks every timer interrupt - even with no LED toggle call.

   

Yes, I put an lcall into the TIMERWHATEVER.ASM file.  If I don't have it, or if I comment out either the Timer_EnableInt() or Timer_Start() call, the LED stays off.  (I set the pin up to default on, then turn it off at the beginning of my code.)

   

If I didn't know better, I'd say it looks for all the world like I'm getting a watchdog reset.  But I know better, because WDT is (was) disabled.  Actually, the code I'm attaching has it enabled and fed quite regularly just in case (actually, if I don't feed the poor watchdog, the LED stays on all the time...another interesting data point).

   

Using PSoC Designer 5.4.  Project and relevant schematic attached, although I really am just trying to follow the Timer16 d/s example.  Some of the code is from other ideas I've been trying in order to troubleshoot, i.e. don't take it as exactly my project code (notice some things are commented out).  Even without the other toggley count and toggley stuff I get the same problem.

   

I can't help but think that I'm missing something really simple here, but I just can't figure it out or find it in any UM d/s....

   

Anyhow, any and all help will be appreciated!

   

Chris

0 Likes
1 Solution
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

There are many ways to a solution, but when you mix two of them you'll go astray or even get lost.

   

There are som appnotes regarding interrupt processing for PSoC1 and since the M8C is a comparable easy-to-understand CPU writing code in assembly language (for better performance) is not quite unusual as you can see from the module's datasheets which always show assembli calls for APIs wich is not the case for PSoC3/4/5.

   

 

   

To solve your riddles:

   

The difference between LJMP and LCALL is LJMP jumps to the given address, while LCALL pushes the instruction-counter onto the stack and then jumps to the given address.

   

 

   

An interrupt handler MUST BE ENDED with a RETI instruction since some more information (Processor flags) have been pushed onto the stack and the RETI will read them back. Now for your different ways to handle an interrupt.

   

Using the hints in the file with the preserve and restore and an LCALL in between ensures proper handling but with the cost of a lot of stack pushes (can overflow!) and pops (takes time!) as long as you cal a simple routine declared as void MyHandler(void).

   

Since the compiler is able to keep track of used (C-pseudo)registers there is another approach which of course may not be mixed with the prior way:

   

 

   

You may declare a void function(void) to be an interrupt handler with the appropiate #pragma instruction. The generated code for this function will have a RETI instruction at its exit point(s). As long as you do not call other functions() from within your handler, the compiler will know exactly which registers need to be pushed (and popped) and the code will be more efficient. So the preserve and restore is not needed and you MUST use an LJMP instruction to enter your handler since that will execute the RETI instruction itself.

   

 

   

Hope that clears up some mist...

   

Bob

View solution in original post

0 Likes
13 Replies
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable
        Hi ChrisJ   
Success possibility is 1% HaHa   
To find what was modified that is fun!   
Bundle back is here ...   
0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

@PSoC73

   

I got a bit lost, what did you change to help Chris? I do not want to riddle, so what was his error.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

You declare "i" as a signed int, but your tests seem to me to be looking for an

   

unsigned int.

   

 

   

Regards, Dana.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

Yes, Dana, I agree. But this is not what HaHa changed.

   

 

   

Bob

0 Likes
Anonymous
Not applicable

Thanks for looking at this.  @PSoC73, if you meant that as a challenge (find the change!), well, I'm game.  Always like a little sleuth work, and all the better if it solves my problem!

   

Unfortunately (or maybe fortunately), WinMerge makes finding changes in text files really simple.  You changed the low-voltage-detect threshold from 2.92 to 1.80.

   

Did this work for you?  Because it doesn't change anything for me.  It was something I had checked already (although I didn't go as low).  3.3V supply, from the MiniProg3 or from my bench supply, doesn't matter, behaviour is the same.  And like say, the "reset", or reset-like behaviour at any rate, goes away if the timer interrupt isn't enabled or the timer isn't started.

   

Any other ideas?  Anyone??

   

TIA,

   

Chris

0 Likes
Anonymous
Not applicable
        Oh, It was not work, have not help for you.   
Previously, I had put a preemptive apology, I said 1%.   
Regrettable to say, I have not the chip 20437.   
If I had I can say more useful advice in actually.   
   
But I would say again, That is cause from power-supply problem.   
Once before, I have a psoc device that continually working for a long time   
That has a timer, this timer occationally resetted, in a few hours   
So, I had change LVD value to most low value.   
Then that device had become working without resetting.   
Brown-Out-Detection will often happen as more we think.   
   
To supply from mini-prog is unstable in mechanically.   
Try, feed from a fixed power-supply device.   
I say again rise 50%   
0 Likes
Anonymous
Not applicable
        Or, I recalled something that LED has a back rush current.   
How many current for the LED, If around 10mA   
Decrease it below 1mA as a trial.   
0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

So when we put it all together:

   

Chris: The main bug in your code is that you have declared the variable i as an int but compare it to values which are greater than 32767 which will not work in C. Declare i as an unsigned int and that will be O.K, thanks to Dana

   

 

   

The rest of the posts are assumptions which we can take into account when the first mentioned bug does not help.

   

 

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

@PSoC73, what is back rush current in an LED ?

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

TL;DR: Not a variable issue but interrupt setup instead, stemming from bad documentation.

   

 

   

Thanks all for the comments.

   

I realize that int is the wrong data type for the values I chose - thanks for pointing that out.  I didn't take the time to think through signed/unsigned.  (I've been using a different processor and stdint, so I usually explicitly call out e.g. uint16_t.)

   

However, that whole deal is a red herring, if you will (unintentional).  Take all the variables out and I still have my resetting problem.  Eventually I realized that it seemed to be resetting - perhaps vectoring off somewhere bad and performing illegal operations, and thus resetting itself.  (The fact that it was only flashing briefly - i.e., not a 50% duty cycle but maybe 1% or 5% or whatever - was a clue too.)  This led me to wonder about how I had set up the ISR call.

   

I was originally quite confused trying to implement the Timer16 datasheet's example, because of conflicting instructions.  The d/s says:

   

The Timer16_ISR routine in timer16int.asm must be modified by adding the
line 'ljmp _myTimer_ISR_Handler' between the user code banners.

   

However, the user code block in the asm file says:

   

   ;---------------------------------------------------
   ; Insert a lcall to a C function below this banner
   ; and un-comment the lines between these banners
   ;---------------------------------------------------
  
   ;PRESERVE_CPU_CONTEXT
   ;lcall _My_C_Function
   ;RESTORE_CPU_CONTEXT

   

I had tried a number of combinations of these two directions - with the PRESERVE_CPU_CONTEXT, ljmp or lcall didn't seem to make a difference.  However, the working code in this thread led me to a way that actually produces the expected result - leaving those original lines commented out and just using ljmp.

   

Soooo.....datasheet advice good; UM auto-generated example code bad.  Can anybody hazard an explanation of why / what is going on?  Looking at the lst file, I gather that PRESERVE_CPU_CONTEXT does what it sounds like, namely stuffs register values in memory somewhere.  But why is that in the instructions, and why does doing it break my project?  What's the difference between ljmp and lcall?  Why does it matter for my situation?  One saves the register which has my count/flag variable and the other doesn't, maybe?  Why is the sky blue?  (Oh wait, I know that last one.)

   

Thanks again,
Chris

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

There are many ways to a solution, but when you mix two of them you'll go astray or even get lost.

   

There are som appnotes regarding interrupt processing for PSoC1 and since the M8C is a comparable easy-to-understand CPU writing code in assembly language (for better performance) is not quite unusual as you can see from the module's datasheets which always show assembli calls for APIs wich is not the case for PSoC3/4/5.

   

 

   

To solve your riddles:

   

The difference between LJMP and LCALL is LJMP jumps to the given address, while LCALL pushes the instruction-counter onto the stack and then jumps to the given address.

   

 

   

An interrupt handler MUST BE ENDED with a RETI instruction since some more information (Processor flags) have been pushed onto the stack and the RETI will read them back. Now for your different ways to handle an interrupt.

   

Using the hints in the file with the preserve and restore and an LCALL in between ensures proper handling but with the cost of a lot of stack pushes (can overflow!) and pops (takes time!) as long as you cal a simple routine declared as void MyHandler(void).

   

Since the compiler is able to keep track of used (C-pseudo)registers there is another approach which of course may not be mixed with the prior way:

   

 

   

You may declare a void function(void) to be an interrupt handler with the appropiate #pragma instruction. The generated code for this function will have a RETI instruction at its exit point(s). As long as you do not call other functions() from within your handler, the compiler will know exactly which registers need to be pushed (and popped) and the code will be more efficient. So the preserve and restore is not needed and you MUST use an LJMP instruction to enter your handler since that will execute the RETI instruction itself.

   

 

   

Hope that clears up some mist...

   

Bob

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Some info -

   

 

   

    

   

          http://www.cypress.com/?id=4&rID=36720

   

 

   

And GPIO interrupts -

   

 

   

    

   

          http://www.cypress.com/?rID=2900     AN2094

   

 

   

Regards, Dana.

Anonymous
Not applicable

Thanks a lot folks - that does really help.  You learn something new every day.

   

 

   

I still think they should work on their instructions a little.  Surely you can see how the instructions I came across (in the same User Module, even) could be confusing to a newbie.  I was just following instructions!

   

 

   

Did you ever hear about the engineer whose wife asked him to stop at the grocery store on his way home?

   

"Get a gallon of milk, and if they have eggs, get a dozen."

   

She was surprised when he came home with 12 gallons of milk.....

0 Likes