simple Timer (one shot), programm-code interrupt?

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

cross mob
Anonymous
Not applicable

Hello, I have difficult to setup a simple Timer.

I use the Timer counter component with Clock + interrupt (isr_Timer1) on the interrupt connection.

I want simply be able to start the timer (one shot timer) and after the timer has finished, a interrupt function should be called and in this function I want switch off an LED.

follow Code does not works:

int main()

{

...

LED_Write(0u); // Switch On LED

ISR_Start(); Timer1_Start(); // start Timer + Interrupt isr_Timer1, ???

...

}

CY_ISR(Timer1)

{

  LED_Write(1u); //Switch OFF LED after Timer has generate an Interrupt

}

what's wrong?

thank you.

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

You are using "special" as "strange" or "odd", right?

> CY_ISR(timer_isr)

> {

>  LED_Write(0u);

>  Pin_8_Write(0u);

>  CyDelay(1000);

>  LED_Write(1u);

>  Pin_8_Write(1u);

> }

You (actually we) are not supposed to stay in the ISR very long,

so it is not recommended to put "CyDelay(1000)" inside CY_ISR().

Probably it will cause WDT or some other interrupts.

How about modify the timer_isr as below?

CY_ISR(timer_isr)

{

    LED_Write(!LED_Read()) ;

    Timer_ClearInterrupt(Timer_TC_INTERRUPT_MASK) ; /* clear interrupt flag */

    // Pin_8_Write(!Pin_8_Read()) ;

    Timer_INT_StartEx(timer_isr) ; /* may be not necessary */

    Timer_Start() ;

}

On the other hand, I noticed that the "EnterDeepSleepLowPowerMode();" in the for(;;) loop stops the timer,

so if this line is called before the timer generate interrupt, it will take very "LONG" time to generate interrupt.

moto

View solution in original post

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

You need to call

ISR_StartEx(Timer1); Timer1_Start(); // start Timer + Interrupt isr_Timer1,

Bob

Anonymous
Not applicable
ISR_StartEx(Timer1); Timer1_Start(); // start Timer + Interrupt isr_Timer1,

that gives an error:

pastedImage_0.png

follow is the TopDesign:

pastedImage_0.png

0 Likes

Your actual component name is isr_Timer1, so you need

isr_Timer1_StartEx(Timer1); Timer1_Start(); // start Timer + Interrupt isr_Timer1,

At this point Timer1() interrupt handler is unknown, so you need to declare

ISR_PROTO(Timer1);

at begin of main.c

I am not quite sure whether the handler name you used (Timer1) will conflict with the component name of the timer.

Bob

0 Likes
Anonymous
Not applicable

I changed design now as follow:

pastedImage_0.png

still have error:

pastedImage_0.png

pastedImage_1.png

main code:

int main()

{

    ISR_PROTO(Tim);

...

...

if xy

{

LED_Write(0u); ISR_StartEx(Tim); Timer1_Start();

}

..

..

}

CY_ISR(Tim)

{

  LED_Write(1u);

}

BTW: it doesn't matter if use isr_Tim or just Tim, always the same error?

0 Likes
lock attach
Attachments are accessible only for community members.
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

user_1,
Attached below is a collection of various incarnations of the 1-Shot Timer:

/odissey1

1-shot Timers.png

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

Can you please post your complete project so that we all can have a look at all of your settings. Will make corrections of your errors easier. To do so, use

Creator->File->Create Workspace Bundle (minimal)

and attach the resulting file.

Bob

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

see attachment. thank you

0 Likes
Anonymous
Not applicable

user_1,
Attached below is a collection of various incarnations of the 1-Shot Timer:

/odissey1

unfortunately I can not use the same component as you have used.

It still not works ... does anybody know why? (see my attached code in previous post)

thank you

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I wrote a simple test project similar to your ISR set up, and it worked fine for my CY8CKIT-044.

I'm wondering a couple of things.

(1) Is your program hit the line 354 in your main.c?

    If the line does not get executed, probably it will not work.

(2) I can not remember exactly when, but one time I had an experience

  that the "InterruptType" of Interrupt module needed to be "LEVEL" instead of "DERIVED".

  In my sample trial both "DERIVED" and "LEVEL" worked though.

moto

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable
I wrote a simple test project similar to your ISR set up, and it worked fine for my CY8CKIT-044.

thank you.

I have now adapted and simplified all exactly according your code. Now with that code the compiler compiles without error - so that is good.

In the interrupt function I want just for testing switch On a LED, but unfortunately it looks that the function is never called because the LED goes not ON.

I'm confused now 😞 , see attached my project / code.

Addition: If I test just your code it works, but with the whole other code it does not works. There must be somewhere a bug conflict with a component or function??

0 Likes
Anonymous
Not applicable

if I add a delay of 6000ms after Timer_Start(); the interrupt function is called, if no delay the interrupt function is never called.

So there must be something in the main code that corrupts the timer / interrupt function... but what ?

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Your Timer interrupt occurs in 5.2sec (5200ms),

so if you give the timer 6000ms, surly the interrupt will be called.

In your project there are three interrupts, Timer, EZI2C and WDT.

And the priority of them are all 3 (same).

Although I can not test it as I can not compile your project in my environment,

off my head I would like to try..

(1) move Timer_INT_StartEx() and  Timer_Start() after WDT_Start()

     Either EZI2C_Start() or WDT_Start() may be disabling the Timer_INT_StartEx()/Timer_Start()

(2) set priority of Timer_INT higher than others

    Setting an interrupt priority higher than WDT may not be a good idea though.

moto

0 Likes
Anonymous
Not applicable

(1) move Timer_INT_StartEx() and  Timer_Start() after WDT_Start()

     Either EZI2C_Start() or WDT_Start() may be disabling the Timer_INT_StartEx()/Timer_Start()

(2) set priority of Timer_INT higher than others

    Setting an interrupt priority higher than WDT may not be a good idea though.

is very special, I changed Timer_INT priority to 2, the others are 3, still the same 😞

I'm not sure if it's really a interrupt conflict, because if I exclude CapSense_Start, WDT_Start and EZI2C_Start the issue is still the same.

So if have a delay of aprox 6000ms after Timer_Start and before the whole programm, means for(;;) it works properly, otherwise not.

very special... I will now try to move down the delay line for line to see which code-line makes the problem

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Thank you very much for your trying those.

It was a very nice trouble shooting, excluding those xxx_Start().

So interrupt conflict may not be the cause of this issue.

BTW,

> So if have a delay of aprox 6000ms after Timer_Start and before the whole programm,

> means for(;;) it works properly, otherwise not.

Are you talking about the inner loop timer also works or only the first shot works?

As I wrote in my previous response, providing 6000ms delay allows the timer to trigger the first shot.

But I wonder if the second and following shot(s) can be generated in the for(;;) loop or not.

Anyway, I'm sorry for not being a good help 😉

moto

0 Likes
Anonymous
Not applicable

the delay must be after Timer_Start or somewhere in the for(;;) than it works.

regarding "one shot", I was thinking that if I select "one shot" the interrupt is only generated once.

So if I want that timer genarates a second time the interrupt I need to start the timer again, or not?

If I do follow see below, to see if interrupt is called a second time - the LEDs does not switch off.. again very special:

CY_ISR(timer_isr)

{

  LED_Write(0u);

  Pin_8_Write(0u);

  CyDelay(1000);

  LED_Write(1u);

  Pin_8_Write(1u);

}

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I re-read main.c would you let me know

(1) If you put for (;;) ; before the original for (;;) { , will the timer work? (I'm hoping so)

(2) If (1) works, the cause is in the for (;;) loop, so please remove the added for (;;) ; and try

comment out each case xxx: ~ break one at a time,

so that you can identify the case which is causing the issue.

(I'm suspecting the "case SLEEP:", though)

moto

0 Likes
Anonymous
Not applicable

see my reply above, the Delay must be somewhere after Timer_Start(), but it doesn't matter if in for(;;) or in a case etc.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

So I supposed that something in the for(;;) { is stopping the timer interrupt, but to make it sure

I wanted to have empty for (;;) ; before the original for so that we can be sure that the  cause is

in the for (;;) { loop and without it the delay is not required.

Then identify the cause I suggested to comment out one case at a time so that if you

comment out the case with the cause, the timer should work.

Then you can hunt down the cause of the issue in that particular case block.

BTW, I've started feeling that the "EnterDeepSleepLowPowerMode();" might be it.

Could you try just comment out that line and try without delay?

moto

0 Likes
Anonymous
Not applicable

if I do without the main for(;;) it works without delay, but special is that the LEDs are not switching off?? see code:

CY_ISR(timer_isr)

{

  LED_Write(0u);

  Pin_8_Write(0u);

  CyDelay(1000);

  LED_Write(1u);

  Pin_8_Write(1u);

}

int main()

{

EZI2C_Start();

...

CapSense_Start();

...

WDT_Start();

...

Timer_INT_StartEx(timer_isr);

Timer_Start();

//CyDelay(8000);

    for(;;){  }

    for(;;)

    {

...

...

...

}

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

You are using "special" as "strange" or "odd", right?

> CY_ISR(timer_isr)

> {

>  LED_Write(0u);

>  Pin_8_Write(0u);

>  CyDelay(1000);

>  LED_Write(1u);

>  Pin_8_Write(1u);

> }

You (actually we) are not supposed to stay in the ISR very long,

so it is not recommended to put "CyDelay(1000)" inside CY_ISR().

Probably it will cause WDT or some other interrupts.

How about modify the timer_isr as below?

CY_ISR(timer_isr)

{

    LED_Write(!LED_Read()) ;

    Timer_ClearInterrupt(Timer_TC_INTERRUPT_MASK) ; /* clear interrupt flag */

    // Pin_8_Write(!Pin_8_Read()) ;

    Timer_INT_StartEx(timer_isr) ; /* may be not necessary */

    Timer_Start() ;

}

On the other hand, I noticed that the "EnterDeepSleepLowPowerMode();" in the for(;;) loop stops the timer,

so if this line is called before the timer generate interrupt, it will take very "LONG" time to generate interrupt.

moto

0 Likes
Anonymous
Not applicable

if I exclude EnterDeepSleepLowPowerMode(); it is blinking now.... hmm.

So that and the correct routine in the isr function is the solution. thank you 🙂

but on the other hand, how can I use timer together with the EnterDeepSleepLowPowerMode();...

respectively how to go on with timer if it was interrupted by EnterDeepSleep ? Is it possible to go on with the latest timer count position which was interrupted by EnterDeepSleep?

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

I'd appreciate if you mark my answer as "correct" if the original issue about interrupt is solved.

Meantime, handling low power mode is quite another story and not an easy one.

For the short answer, I'd recommend you to read the Architecture Technical Reference Manual (TRM)

If you are using 4200L

http://www.cypress.com/documentation/technical-reference-manuals/psoc-4200l-family-psoc-4-architectu...

Chapter 6 Interrupts

Chapter 11 Power Modes

Chapter 19 Timer, Counter and PWM

etc.

As I  skimmed chapters regarding to the low power mode (deep sleep),

I found that at least the good news is the count of the timer is preserved.

So you can continue the timer after deep sleep. (19-4 Power Modes in TCPWM Block)

Or may be creating another question discussion about deep sleep and timer might lead you to correct answers.

moto

0 Likes