- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I needed to do a relatively long non-blocking time delay initiated by code and running other code a fixed time later. This relatively common requirement proved surprisingly difficult even with help from Cypress support and I was wondering if anyone had a better solution.
My first attempt was to use a timer component (V2.70, 16-Bit UDB implementation on PSOC4). I attached an ISR component to its interrupt output, a logic zero to its reset pin and a 100kHz clock to its clock input. With run mode "oneshot", the ISR gets called once after the delay but there appears to be no API which allows the timer to be reset and triggered again from code. I assumed that "oneshot" meant that the timer would be stopped automatically by hardware when the terminal count (0) was reached and could afterward be restarted using the "Start" API. After extensive trial and error, and a support call to India, I was forced to conclude that there is no way to reset a "oneshot" timer from code. Support first suggested using a register hooked to the hardware reset pin, but I had used all the registers available. They then came up with a complex hardware software hybrid scheme involving a second clock which could be stopped and started from software. The solution I eventually used was to abandon "oneshot" mode and use "continuous" instead, calling the "Stop" API in the ISR explicitly to stop the timer at the end of each run (essentially converting it back to "oneshot"), then using the "Start" API when the time came to restart it for the next run.
Is this limitation intentional in the design of the component? It seems odd that the oneshot mode has no API capable of resetting it. In fact, from the documentation it seems like the Start API should achieve this, but it does not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I had a similar problem. Never got around to it but wondered if Tc inverted could supply a reset to
Timer, along with control logic to gen a 1 clock wide reset pulse, so + edge Tc user ISR invoked,
timer read, - edge inits reset to timer.
It is odd, datasheet very thin on this topic.
Consider filing a CASE to get a component update.
To create a technical or issue case at Cypress -
www.cypress.com
“Support”
“Technical Support”
“Create a Case”
You have to be registered on Cypress web site first.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
JohnHind,
attached archived project is a collection of various incarnations of 1-Shot Timer. It would be nice if Creator have had a basic 1-Shot timer availabe right out-of-the-box, but here we are...
odissey1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks guys. I've been down both these routes - the problem with the various circuits involving control registers is that these are very limited resources - only four available in the PSOC4. Also these solutions all require software support making them error prone as components. Surely there must be a way of doing this entirely in hardware (but I've not found one)? If we have to have software support, the solution of using a continuous component with an explicit "Stop" in the ISR seems simpler and uses fewer resources.
I did raise a support case which was dealt with by a department in India, they were very helpful and friendly, but I could not get them to engage with my comments as an opportunity to improve the product rather than just finding a work-around for my specific problem.
This is my mostly software work-around (see screenshots attached for component configuration):
CY_ISR(COMMS_TimerHandler) { CommsTimer_STATUS; CommsTimer_Stop(); // Payload here
} void RestartCommsTimer(uint16 delay) {
CommsTimer_Stop();
CommsTimer_WritePeriod(delay);
CommsTimer_WriteCounter(delay);
CommsTimer_Start();
}
(Sorry about formatting, I have neither the time nor the patience to wrestle with yet another buggy, badly designed web based text editor!)
This solution also allows the timer to be restarted before it has expired, which was a requirement in this case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@odissey1, would you consider filing a CASE to see if you can get
Cypress to move towards either a new component or a mod to existing
component ? A one shot ought to be restarted w/ SW intervention.
seems very basic to me.
John, you could always roll your own verilog solution and post for the benefit for the community.
But like you I still think this should get fixed.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For my understanding a one-shot is mostly usable when talking about hardware-controlled triggers. When software controlled it is an easy job to halt and restart a timer, but when under hardware-control there might be not enough time to enter an interrupt handler.
So I would suggest to use as run-mode "continuous" and halt the timer in the interrupt procedure.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Bob
Can this OneShot program works with DeepSleep?
Where will I insert the code?
CySysPmDeepSleep();
Thanks
Andrew Collins
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code uses a hardware timer, and thus should run in deep-sleep mode if you have the timer enabled.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
When I run the program, I get a current of 2.64mA (with LED_off). Also ECO turned off and IMO(3MHz0.
What is the current expected will the timer is enabled? How do I improve to get low current?
Thanks
Andrew Collins
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't know what the timer module's current draw is, but it will increase current draw when running while in deep-sleep mode.
I didn't find any way to lower current consumption when I used the timer module (perhaps changing it to use the ILO for the clock input to be able to put the CPU to sleep?)
I ended up using the WDT, since it seems to have little to no affect on the power draw while in deep sleep mode
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can take a look at the API code in the .lst file to get an idea of how much latency
the ISR approach creates, by counting cycles in ASM code execution.
The idea of discussion with Cypress takes into consideration can the
time to re-trigger via SW approach be reduced from the Start() Stop()
approach. A more targeted API rather than going thru full startup required
code...........
Regards, Dana.
- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Greetings to all,
I could able to achieve one-shot timer by using control reg in pulse mode!
Period can be changed by changing clock. Good news is, control bit resets automatically 🙂
Regards, Vikas.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK, I see now. I did not look at the schematic pages along the bottom and was changing the wrong timer.