One-shot Timer for Delayed Code Execution

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

cross mob
Anonymous
Not applicable

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.

0 Likes
14 Replies
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

0 Likes
lock attach
Attachments are accessible only for community members.
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

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

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

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.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

@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.

0 Likes
lock attach
Attachments are accessible only for community members.
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes

Hi Bob

Can this OneShot program works with DeepSleep?

Where will I insert the code?

            CySysPmDeepSleep();

Thanks

Andrew Collins

0 Likes
Anonymous
Not applicable

The code uses a hardware timer, and thus should run in deep-sleep mode if you have the timer enabled.

0 Likes

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

0 Likes
Anonymous
Not applicable

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

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

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.

0 Likes
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted
        JohnHind, It looks like you make a communication timeout timer. If UDB resources are limited you can use "free" SisTick timer same way you use Timer16. But to be started in software pure hardware timer will always need a ControlReg. odissey1   
0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Systick Timer -

   

 

   

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

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

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.

0 Likes
DaHu_285096
Level 5
Level 5
10 likes received 250 replies posted 100 replies posted

OK, I see now. I did not look at the schematic pages along the bottom and was changing the wrong timer.

0 Likes