cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 4 MCU

Anonymous
Not applicable

 I'm trying to use a timer interrupt to generate a 1/ms interrupt. I've set up a Timer component (32-bit UDB) with interrupt set for "On TC" (Timer complete I believe.) Interrupt type is "DERIVED."

   

The code that manages this is:

   

   

CY_ISR_PROTO(SysTimerISR_Handler);
CY_ISR(SysTimerISR_Handler)
{
    static int count=0;
    sysTimer++;
    SysTimer_STATUS; // dismiss interrupt
    SysTimerISR_ClearPending();
    if( sysTimer == 1000 )
        SysTimerISR_Stop();
}

   

   

And within main():

   

   

    SysTimer_Start();

   

 

   

while(SW1_Read());                        // wait for button press to continue (gives you time to switch to a terminal window)

   

    println(welcome_string);

   

    SysTimerISR_Enable();

   
       
   
        
   
    Wlksewhere oin the code I have    
   
    
         CyGlobalIntEnable;    
   
   

Output prior to  SysTimerISR_Enable(); displays (on the USB/Serial) but once I push the button and proceed past that point, the system locks up. No more output and the bootloader reset (copied from one of the videos) does not work. I suspect that the source of the ionterrupt is not dismissed so as soon as the timer ISR returns it goes right back into the interrupt. I don;t understand why the SysTimerISR_Stop does not seem to execute. (Debug code.) If I don't enable the interrupt, the remaining code executes as expected.

   

What I want is an interrupt that can maintain a counbter that increments every millisecond. Feel free to suggest another solution, but I'm also interested in knowing why this does not work.

   

I can provide the whole project if desired. Would I jut zip it up? What about bootloader dependency (since this is on an -049.)

   

 

   

Thanks!

   
        
0 Likes
Reply
11 Replies
Esteemed Contributor

To provide a project archive -

   

 

   

    

   

         

   

“File”                                                             Creator

   

“Create Workspace Bundle”

   

 

   

 

   

To avoid eating up all your UDB resources consider Systick

   

                http://www.cypress.com/?id=4&rID=94607     PSOC 4 SysTick

   

 

   

 

   

Any variables used in ISR should be declared volatile -

   

                http://www.barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword    Volatile

   

 

   

 

   

  

   

Regards, Dana.

0 Likes
Reply
Esteemed Contributor II

Hank,

   

you probably need a

   

SysTimerISR_StartEx(SysTimerISR_Handler);

   

to associate the handler with the interrupt.. More pitfalls we can check only with the complete project as Dana already suggested.

   

 

   

Bob

0 Likes
Reply
Esteemed Contributor

This might be usefull -

   

 

   

    

   

          http://www.cypress.com/?app=forum&id=4749&rID=105401&start=21

   

 

   

Regards, Dana.

0 Likes
Reply
Anonymous
Not applicable

Many thanks for the help.

   

I added SysTimerISR_StartEx(SysTimerISR_Handler); (perhaps not in the right spot) and it did not help. I've attached the bundle for further exploration.

   

I'll have more time to look at this later (or maybe not 'til tomorrow!)

   

 

   

thanks!

0 Likes
Reply
Esteemed Contributor

Not sure why you use this variable -

   

 

   

{
    static int count=0;
    sysTimer++;
    SysTimer_STATUS; // dismiss interrupt
    SysTimerISR_ClearPending();
    if( sysTimer == 1000 )
        SysTimerISR_Stop();
}

   

 

   

sysTimer, as the interrupt automatically fires when timer outputs its 1 mS Tc interrupt. I would

   

just set a flag in ISR indicating 1 mS has occured.

   

 

   

This line,     SysTimer_STATUS; // dismiss interrupt, what is it doing ? I think it just reads

   

the contents of the status register and resets the ISR as a consequence of doing so ?

   

 

   

I can't compile the project because of bootloader error - The referenced Bootloader is invalid.

   

 

   

I would use Systick as you eat up a lot of resources doing a 32 bit timer....just a thought.

   

 

   

Regards, Dana.

0 Likes
Reply
Anonymous
Not applicable

 Hi Dana,

   

My intent is to replicate the Arduino library procedures millis() and delay(). I suppose there are Cypress library equivalents like CyDelay(), but I plan to have my custon delay() procedure go into some sort of low power state until the next interrupt.

   

The SysTick timer is a better solution to my needs but I still want to know why what I have doesn't work. Better yet might be to tie into the timer interrupt (if one exists) that CyDelay() uses. I'm still looking for the Cypress library documentation.

   

thanks!

0 Likes
Reply
Esteemed Contributor

I see one problem, you did not enable global interrupts with -

   

 

   

    CyGlobalIntEnable;                  // Uncomment this line to enable global interrupts.

   

 

   

I did the attached project, I do not have a -049 board so did it on a pioneer

   

-042 board, works fine.

   

 

   

Regards, Dana.

   

 

   

Can't seem to upload the file, but its the same code minus bootloader stuff, as you have.
 

0 Likes
Reply
Anonymous
Not applicable

 Hi Dana,

   

I just got it working too!

   

I did have CyGlobalIntEnable included but it was in the BootReloader.c file. (More on that in a moment.)

   

I also found that SysTimer_STATUS; is necessary in the ISR or it only executes once. It reads the status register and apparently rearms the interrupt.

   

I cleaned it up a bit and added a README.txt explaining how to build for non-bootloader systems like the Pioneer. I have no way of testing there so I forgot that the instructions did not accommodate CyGlobalIntEnable which needs to be put somewhere where it will execute without BOOTLOADER_RESET defined.

   

The other thing I changed was to move SysTimerISR_ClearPending(); out of the ISR and into the initialization code in main(). I think that was part of the original problem. Now it works.

   

Next step is to toss this and implement with SysTick. 😉

   

 

   

thanks!

   

 

   

Edit: Trying a second time to attach.

0 Likes
Reply
Anonymous
Not applicable

 And a third try to attach.

0 Likes
Reply
Anonymous
Not applicable

 One more revision. I have converted this to use the SysTick timer which is even easier than using a Timer component. In addition, I've put a call to CyPmSleep() in the delay() function. I've tested using a cheap USB volt/amp meter which reads in 0.01A. Without sleep the current reads reads 0.00A mostly and occasionally 0.03A. With sleep it reads 0.00 all of the time. (It seems to sample at 1s intervals.) It seems that sleep does save power (including over the CyDelay() version) but my tools are not sufifcient to determine how much. I'm also not sure if sleep is generally applicable. I have plans to implement something that uses PWM outputs and I'm not certain that they will continue while the processor sleeps.

   

 

   

Edit: Forgot to add:

   

 References:

   

  - tick timer: http://www.cypress.com/?id=4&rID=94607 for the SysTick timer

   

  - Low Power: http://www.cypress.com/?docID=43701 (But be aware that they suggest using 

   

    CyPmSleep() which should be CySysPmSleep()

0 Likes
Reply
Esteemed Contributor

If you have a pioneer board, or another board with a PSOC 3 or 5LP

   

you can set up A/D to measure current thru a 1 ohm R, placed in Vdd

   

or Vss line. You have to set up DelSig to bypass buffer so that you get the 100

   

mV allowed CM range outside rails. Up to 20 bits and 1 ohm would give

   

you a resolution of ~ 1 uA,vs the 10 mA resolution you seem to currently

   

have.

   

 

   

Some ap notes on low power, and yes depends on sleep mode what is

   

left still functioning.

   

 

   

    

   

         

   

http://www.cypress.com/?rID=78797     AN86233 - PSoC® 4 Low-Power Modes and Power Reduction Techniques

   

http://www.cypress.com/?rID=96072     AN90114 - PSoC® 4000 Family Low-Power System Design Techniques

   

 

   

 

   

Regards, Dana.

0 Likes
Reply