One-shot Timer for Delayed Code Execution | Cypress Semiconductor
One-shot Timer for Delayed Code Execution
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.