Turn on interrupt using TCPWM.

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

cross mob
om
Level 1
Level 1
25 sign-ins 10 sign-ins 5 questions asked

I want to turn on Interrupt using TCPWM after any specific time and in ISR i want to blink LED so if anyone knows how to do general settings in TCPWM and blink LED in ISR then please help me.

0 Likes
1 Solution
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @om ,

There are few issues in the code:

1. You need to clear the interrupt using Timer_ClearInterrupt(Timer_INTR_MASK_TC). Otherwise the interrupt will keep firing again and again and your CPU won't have time (or bandwidth) to execute the for(;;). Entire CPU time will be used up in servicing the interrupt and this is not desired. You should call Timer_ClearInterrupt(Timer_INTR_MASK_TC) in the ISR.

2. Do not call CyDelay functions in the CY_ISR. This will delay the processing of other interrupts and code in your program.

3. You have set period = 2000 but I see the Timer clock is 12 Mhz. This will not give an interrupt every 1 second. Can you please change the input clock frequency to get 1 second interrupt. See my attached project in previous response for reference.

4. From your description you want to generate an interrupt every 1 second. In that interrupt, you have to increment a variable (ie every 1 second). But also you have to blink an LED for every 500 ms. For this do not call CyDelay(). This simply halts the CPU and negates the entire purpose of having Timer in the first place. 

Instead, generate a Timer interrupt for every 500 ms and in the ISR you can do the following:

uint8_t ticks = 0;

CY_ISR(isr_1_interrupt)

{

ticks++;

if(ticks == 2)

{

// 500 x 2 = 1000 ms elapsed

ms_count++; // or simply use two times of "ticks"  for your logic

ticks = 0;

}

Timer_ClearInterrupt(Timer_INTR_MASK_TC);
Timer_isr_ClearPending();

Led_Write(~LedOut_Read()); // Toggle ISR every 500 ms

}

Let us know if you have questions.

 

Regards,
Bragadeesh

View solution in original post

8 Replies
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @om ,

Please check the PSoC 4 Timer/ Counter example project.

https://www.cypress.com/documentation/code-examples/ce224594-psoc-4-timercounter

Refer device specific architecture TRM for details on the TCPWM architecture. Also, please take a look at the PSoC 4 TCPWM component datasheet for details on the APIs. 

Please get back to us know if you have further questions. We are happy to help 🙂

Regards,
Bragadeesh
om
Level 1
Level 1
25 sign-ins 10 sign-ins 5 questions asked

Hello Bragadeesh,

Thanks for your help, the main problem is that i want to turn on led in ISR and for interrupt i am using TCPWM so if i want to get interrupt at level triggered by an interrupt source. so how i should do settings in TCPWM. For example i want to get interrupt at every 1000ms so what period value i should set and on terminal count check box should be ticked or compare count tick box should be ticked. Please help me with it. 

0 Likes
lock attach
Attachments are accessible only for community members.
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @om ,

You can set the timer to expire (or reload) at 1000 ms. This means that the counter/ timer will take 1000 ms to generate a terminal count interrupt. To achieve this you need to set the period value based on the clock to the Timer block. Use the below formula,

Time taken for terminal count = Period / Timer Clock frequency. 

For example, if Timer Clock frequency is 1 KHz, then the required period is 1000. See attached project for reference in PSoC 4200 device. Change the device as required using device selector.

Regards,
Bragadeesh
om
Level 1
Level 1
25 sign-ins 10 sign-ins 5 questions asked

Thanks Sir, I have done some changes as you suggested but I have one question that since I am using level triggered interrupt source so it will keep firing ISR until it is high so my interrupt source is TCPWM so I have to use TCPWM_clearinterrupt() API inside my isr Or it will get automatically called. Because my ISR is working fine but my main program is not working properly.

Note : In my isr I am blinking led for 500 ms. And in my main function in infinite for loop I am just incrementing one variable , but in debug variable inside main is not incrementing properly. So please help me out, I will wait for your reply.

 

 

0 Likes
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @om , Could you please share your project with us for debugging the issue further?

Regards,
Bragadeesh
0 Likes
lock attach
Attachments are accessible only for community members.
om
Level 1
Level 1
25 sign-ins 10 sign-ins 5 questions asked

Hello Sir,

first let me give some brief idea what i actually want to do. I want to generate interrupt for every second using TCPWM and interrupt should be level triggered. And when i will get interrupt my program should go into the ISR and should blink LED for half second (500 ms) and increment one variable . while in my main program i have written infinite for loop, in which i have one variable which will keep incrementing so i can understand by watching that variable in watch window that my ISR and main executing continuously and properly. since you mentioned i am sending some stills of my program i hope it would be helpful for you.

I think i am doing something wrong in timer setting and interrupt setting because i want level triggered interrupt on terminal count. But should i tick (on terminal count tick box) or not and other setting please take a look at it.

0 Likes
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi @om ,

There are few issues in the code:

1. You need to clear the interrupt using Timer_ClearInterrupt(Timer_INTR_MASK_TC). Otherwise the interrupt will keep firing again and again and your CPU won't have time (or bandwidth) to execute the for(;;). Entire CPU time will be used up in servicing the interrupt and this is not desired. You should call Timer_ClearInterrupt(Timer_INTR_MASK_TC) in the ISR.

2. Do not call CyDelay functions in the CY_ISR. This will delay the processing of other interrupts and code in your program.

3. You have set period = 2000 but I see the Timer clock is 12 Mhz. This will not give an interrupt every 1 second. Can you please change the input clock frequency to get 1 second interrupt. See my attached project in previous response for reference.

4. From your description you want to generate an interrupt every 1 second. In that interrupt, you have to increment a variable (ie every 1 second). But also you have to blink an LED for every 500 ms. For this do not call CyDelay(). This simply halts the CPU and negates the entire purpose of having Timer in the first place. 

Instead, generate a Timer interrupt for every 500 ms and in the ISR you can do the following:

uint8_t ticks = 0;

CY_ISR(isr_1_interrupt)

{

ticks++;

if(ticks == 2)

{

// 500 x 2 = 1000 ms elapsed

ms_count++; // or simply use two times of "ticks"  for your logic

ticks = 0;

}

Timer_ClearInterrupt(Timer_INTR_MASK_TC);
Timer_isr_ClearPending();

Led_Write(~LedOut_Read()); // Toggle ISR every 500 ms

}

Let us know if you have questions.

 

Regards,
Bragadeesh
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,

Maybe, this is an out of place response, but, 

If all you need is a periodic timer of 500ms (or 1000ms), Cortex-M has a nice feature called "SysTick."

We can use this without consuming precious hardware component(s).

So following is another sample of 0.5 sec LED blink (using CY8CKIT-044)

Schematic (UART is optional)

000-schematic.JPG

Pins (UART pins are optional)

001-PIns.JPG

main.c

Note: SysTick_ISR is called every 1ms, we can do something else in the ISR, too.

=====================

#include "project.h"
#include "stdio.h"

#define STR_LEN 64
char    str[STR_LEN+1] ;
void    print(char *str)
{
	UART_UartPutString(str) ; /* PSoC 4 */
//	UART_PutString(str) ;     /* PSoC 5 */
}

void cls(void)
{
    print("\033c") ; /* reset */
    CyDelay(20) ;
    print("\033[2J") ; /* clear screen */
    CyDelay(20) ;
}

void splash(char *prog_name) 
{
    cls() ;
    if (prog_name && *prog_name) {
        print(prog_name) ;
    } 
    print(" (") ;
    print(__DATE__) ;
    print(" ") ;
    print(__TIME__) ;
    print(")\n") ;
}

volatile int pit_flag = 0 ;
volatile uint32_t pit_count = 0 ;
uint32_t pit_interval_ms = 500 ; // toggle each 500ms

CY_ISR(SysTick_ISR)
{
    pit_count++ ;
    if (pit_count >= pit_interval_ms) {
        pit_flag = 1 ;
        pit_count = 0 ;
    }
}

int find_empty_slot(void)
{
    int result = -1 ;
    uint32_t i ;
    for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {
        if (CySysTickGetCallback(i) == NULL) {
            result = i ;
            break ;
        }
    }
    return(result) ;
}

void init_systick(void)
{
    int sys_tick_slot = 0 ;
    
    sys_tick_slot = find_empty_slot() ;
    if (sys_tick_slot < 0) {
        while(1) { } /* halting here */
    } else {
        CySysTickStart() ;
        CySysTickSetCallback(sys_tick_slot, SysTick_ISR) ;
    }
    
    CySysTickStart();
}

void init_hardware(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    UART_Start() ;
}
        
int main(void)
{  
    init_hardware() ;  
    splash("Using SysTick Sample") ;
    
    init_systick() ;
   
          
    for(;;)
    {
        if (pit_flag) {
            pit_flag = 0 ;
            LED_Write(!LED_Read()) ; // toggle LED
        }
    }
}

=====================

moto