- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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();
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This might be usefull -
http://www.cypress.com/?app=forum&id=4749&rID=105401&start=21
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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()
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.