cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 5, 3 & 1

ShVy_264716
New Contributor II

Hi All.

I want to configure a SysTick Timer in such a way that the SysTick Timer Interrupt should invoke every 1 ms. I am using 

CY8CKIT-059 PSoC® 5LP Prototyping Kit. 

In PSoC 4, I did this same functionality by using the following code :

 

 

 

 

#define NO_OF_TICKS 24000u
int *tick_CM0_ENABLE = (int *) CYREG_CM0_SYST_CSR;
uint32  SysTick_value;
CY_ISR_PROTO(MySysTickHandler);
void SysTick_Timer_Enable(void);     //Enabling SysTick Timer
void SysTick_Timer_Disable(void);    //Disabling SysTick Timer

void SysTick_Timer_Enable(void){
    *tick_CM0_ENABLE |= 1; // For Enabling the Tick Counter
    /* Enable SysTick timer with desired period/number of ticks */
    SysTick_Config(NO_OF_TICKS);
}    

void SysTick_Timer_Disable(void){
    
    *tick_CM0_ENABLE &= (~1); // For Disabling the Tick Counter    
}    
void Initialize(void)
{
    CyGlobalIntEnable;                                              
    CyIntSetSysVector((SysTick_IRQn + 16u), MySysTickHandler);
    SysTick_value = 0;
}
void main(void)
{
    Initialize();
}
CY_ISR(MySysTickHandler)
{
    SysTick_value++;
    if(SysTick_value >= 1000u)
    {
        SysTick_value = 0;
        SysTick_Timer_Disable(); // Stop after 1000 ms
    }    
}

 

 

 

 

I do not know why but this method does not work for PSoC5. 

0 Likes
1 Solution
Len_CONSULTRON
Honored Contributor II

ShVy,

I haven't verified your code listed in your first post.   However, using the SysTick is fairly easy. 

Here is working SysTick code I use ALL the time on my PSo5LP projects:

uint32_t systick = 0;
uint32_t systick_prev = 0;
CY_ISR(isr_systick)
{
	systick++;
}
/* Your Application here vvvv */
main(void)
{
...
/* SysTick init */
  CySysTickStart();  /* Start the systick */
  CySysTickSetCallback(0, isr_systick);  /* Add the Systick callback */
      /* to the standard SysTick Int Vector */
/*****/
...   /* other stuff you need to init */
/* SysTick use in the Application */
  for(;;)
  {
/* Wait for the previous SysTick event plus a set delay */
    if(systick >= (systick_prev + 1000)) 
    {    /* SysTick event occurred.  Process SysTick event in the App. */
      systick_prev = systick;    /* Set the new previous SysTick count */
      ...
      /* go do something within the systick event */
      ...
    }
}

 

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
5 Replies
Len_CONSULTRON
Honored Contributor II

ShVy,

I haven't verified your code listed in your first post.   However, using the SysTick is fairly easy. 

Here is working SysTick code I use ALL the time on my PSo5LP projects:

uint32_t systick = 0;
uint32_t systick_prev = 0;
CY_ISR(isr_systick)
{
	systick++;
}
/* Your Application here vvvv */
main(void)
{
...
/* SysTick init */
  CySysTickStart();  /* Start the systick */
  CySysTickSetCallback(0, isr_systick);  /* Add the Systick callback */
      /* to the standard SysTick Int Vector */
/*****/
...   /* other stuff you need to init */
/* SysTick use in the Application */
  for(;;)
  {
/* Wait for the previous SysTick event plus a set delay */
    if(systick >= (systick_prev + 1000)) 
    {    /* SysTick event occurred.  Process SysTick event in the App. */
      systick_prev = systick;    /* Set the new previous SysTick count */
      ...
      /* go do something within the systick event */
      ...
    }
}

 

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
ShVy_264716
New Contributor II

Hi @Len

Thank you for your input. I took your code snippet as reference and built the following code which works to blink an LED at 1 s rate using Systick Timer :

#include "project.h"
uint32_t systick = 0;
CY_ISR(isr_systick)
{
	systick++;
    if(systick >= 1000)
    {
        Status_LED_Write(~Status_LED_Read());
        systick = 0;
    }
}
int main(void)
{
    Status_LED_Write(1);
    CySysTickStart();  /* Start the systick */
    CySysTickSetCallback(0, isr_systick);  /* Add the Systick callback */
    /* to the standard SysTick Int Vector */
    CyGlobalIntEnable; /* Enable global interrupts. */
    for(;;)
    {
    }
}

Still I do want to know why the Systick interrupt gets set to 1 ms time duration. Why is not there any method to configure for other time durations like we used to have in PSoC4 (You can refer my first post code)?

0 Likes
Len_CONSULTRON
Honored Contributor II

ShVy,

You can change the SysTick period if that's what you want.

You would use the API call:

CySysTickSetReload(uint32 newperiodcnt);

newperiodcnt can be any 24-bit number.  A number larger than 0x00FFFFFF will be truncated at the high bits.

The SysTick period is based on the Source clock selection to the SysTick counter.  The default is the BUS_CLK.  Therefore to get a SysTick of 1ms using a 24 MHz BUS_CLK, we would use newperiodncnt = BUS_CLK/SysTickPeriod = 24,000,000/.001 = 24,000

If you want a different SysTick period substitute your new value into  SysTickPeriod and make sure it doesn't exceed 24-bits.

Then issue the API call:

CySysTickSetReload(newperiodcnt);

Note:  There is a call to change the SysTick clock source to ILO @ 100KHz.

void CySysTickSetClockSource(CY_SYS_SYST_CSR_CLK_SRC_LFCLK)

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
ShVy_264716
New Contributor II

Thank you, so much, @Len_CONSULTRON . I finally got it working. Here is the code snippet that blinks an LED every 500 ms using Systick Timer Interrupt.

#include "project.h"
#define COUNTS 12000
uint32_t systick = 0;
CY_ISR(isr_systick)
{
    systick++;
    if(systick >= 1000)
    {
        Status_LED_Write(~Status_LED_Read());
        systick = 0;
    }
}
int main(void)
{
    Status_LED_Write(1);
    CySysTickStart();  /* Start the systick */
    CySysTickSetReload(COUNTS);
    CySysTickSetCallback(0, isr_systick);  /* Add the Systick callback */
    /* to the standard SysTick Int Vector */
    CyGlobalIntEnable; /* Enable global interrupts. */
    for(;;)
    {
    }
}
Len_CONSULTRON
Honored Contributor II

ShVy,

I'm glad it is working for you.

If the SysTick is ONLY used for the LED blink, you can try the following change to your code:

#include "project.h"
#define COUNTS 12000000u /* This value incorporates the systick >= 1000) */
/* systick var can be eliminated */

CY_ISR(isr_systick)
{  /* simplified */
  Status_LED_Write(~Status_LED_Read());
}
int main(void)
{
    Status_LED_Write(1);
    CySysTickStart();  /* Start the systick */
    CySysTickSetReload(COUNTS);
    CySysTickSetCallback(0, isr_systick);  /* Add the Systick callback */
    /* to the standard SysTick Int Vector */
    CyGlobalIntEnable; /* Enable global interrupts. */
    for(;;)
    {
    }
}
Len
"Engineering is an Art. The Art of Compromise."
0 Likes