- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I am using Psoc Creator IDE for programming my Psoc 5LP. I want to get timestamp in microseconds to get the value for a particular function. I have tried your preprocessor __DATE__ and __TIME__ but it doesn't give value in microseconds. Do you happen to know any preprocessor which can give the timestamp in microseconds. Is there any easy way to get that apart from adding components like counter or RTC. I also tried struct timeval but I am having issues with the precision.
Solved! Go to Solution.
- Tags:
- timestamp
- 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
Hi,
Sometime ago, I posted a response to a question which requested a timestamp.
As far as I know RTC usually supports up to second,
sometimes may be to millisecond,
but probably microsecond accuracy would be difficult.
If I need to measure events in microseconds granularity,
I would use a dedicated time and let hardware event to trigger start and stop(capture).
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PrSa,
I agree with Moto, for 1us accuracy you have to use either a SysTick or a dedicated Timer component.
/odissey1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PrSa,
I believe the SysTick by default has a 1ms resolution. However there is a way to change the source clock for the resource.
When I need better resolution, I either dedicate a counter for this as indicated by moto or /odissey1 or a find a timer/counter being used by another resource in my application that is in continuous mode. I then derive the start and end timestamps from the immediate count values. The problem I run into when using a timer/counter in continuous mode is the wrap-around effect that may occur in my timestamps.
Note: __DATE__ and __TIME__ are compile-time defines. Are you looking for run-time timestamp values (as the suggestions above are addressing) or compile-time timestamp? Can you elaborate your application intent for the timestamp?
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Len,
My application is I need to find how much time it takes to write to the Flash memory. So I want to get the time taken to write a row in Flash putting the timers around CyWrite functions at various places in my code. So I do not exactly need a run-time stamp here but something that can calculate in microseconds so that I can find the difference between the time.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PrSa,
There is a custom component available to measure elapsed time (StopWatch). Demo project is attached. Import the component into you project or add it into dependencies. Usage is simple:
StopWatch_Start();
// your function here
StopWatch_Stop();
//....
StopWatch_Cycles returns number of BUS_CLK cycles elapsed between Start and Stop
StopWatch_usec returns number of microsecons elapsed between Start and Stop
This is a Draft version of the component, more testing is required, no datasheet available at this time. Works on PSoC5 and PSoC4.
/odissey1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Odissey1
I am not able to import this component for my target. I am using Psoc5LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
PrSa,
It seems that you imported entire project instead of single component.
Component importing instructions:
https://www.cypress.com/video-library/PSoC/psoc-creator-tutorial-importing-components/107756
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Odissey1,
I was following the importing instruction. But it still the same. I tried to compile your project and I found out it that your component is incompatible for CPU Cortex M3 which is my target device CY8C5888LTI-LP097 to be precise. Whenever I select the project device to any Cortex M3 version the component shows the picture above incompatible and I get error after compiling the project ofc. If I select Cortex M0 it is fine.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I will look into it. It used it on P5 as well as P4.
- 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
odissey\,
I really like that you've created a useful component for debugging and potential for application use. I love that you're using zero additional PSoC resources (except for a tiny amount of FLASH and RAM). I also love you found a way to have the timer with the resolution of the BUS_CLK. However ...
There are many projects where I'm using the ARM CMSIS SysTick for application timing. It's a darn good 'free' resource. The StopWatch component as you've currently written it assumes this System timer is not being used by the application.
Suggestion:
- Implement your StopWatch component with Exit callback hooks. This allows the user install there own SysTick ISR but has your StopWatch_Reloads variable available. You can in effect use your StopWatch component as a System Timer extension or wrapper per se.
- If the user needs a specific SysTick period (let's say the default 1ms), when you change the System Timer counter to the max value, you change the expected period for the application. Leave the System Timer count as per the user. However, using timestamps for the uint32_t StopWatch_start_ts and uint32_t StopWatch_end_ts you can use the System Timer in continuous running mode.
- To use the suggestion point above, you need to incorporate StopWatch_Reloads into bits 24 thru 31 (ie. StopWatch_Reloads<24) of the delta timestamp math. As long as the delta time being measured doesn't exceed 53.6 seconds (@ BUS_CLK=80MHz, longer if BUS_CLK is slower), you should avoid a wrap-around miscalculation.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Len,
Thank you for suggestion. I will look into it. Maybe it is time to dust-off StopWatch component. I used the component a lot, but never quite finished it. I believe that on Cortex M3 processors there is also another resource (like WDT timer), which may serve same purpose. It's on never-finished todo list...
/odissey1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
odissey\,
I know the feeling about things could always be better/more features.
I do like how you are using the BUS_CLOCK resolution which can easily be sub-microsecond which is usually more than sufficient for most application.
Len
"Engineering is an Art. The Art of Compromise."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I tried it, too 😉
call start_measure() before calling the function under test
then just after the function, calling stop_measure() returns the us.
in my sample, test_func is just calling CyDelayUs(us)
so that we can see if the measured "us" agrees with the "us" waited.
==============
start_measre() ;
test_func() ;
us_taken = stop_measure() ;
==============
As far as I tested, there seems to be 1~2 us overhead.
So in general, reducing the measured value by 1~2 will be about correct value.
The schematic
Pin assign
main.c
=============
#include "project.h"
#include "stdio.h"
volatile uint32_t tc_count = 0 ;
#define STR_LEN 128
char str[STR_LEN+1] ;
void print(char *str)
{
UART_PutString(str) ;
}
CY_ISR(timer_tc_isr)
{
Timer_ReadStatusRegister() ;
tc_count++ ;
}
void init_hardware(void)
{
UART_Start() ;
tc_int_ClearPending() ;
tc_int_StartEx(timer_tc_isr) ;
Timer_Start() ;
CyGlobalIntEnable; /* Enable global interrupts. */
}
void splash(void)
{
snprintf(str, STR_LEN, "Timer Test (%s %s)\n", __DATE__, __TIME__) ;
print(str) ;
}
void cls(void)
{
print("\033c") ; /* reset */
CyDelay(100) ;
print("\033[2J") ; /* clear screen */
CyDelay(100) ;
}
void start_measure(void)
{
Timer_Stop() ;
Timer_ReadStatusRegister() ;
Timer_WriteCounter(0) ;
tc_int_ClearPending() ;
tc_count = 0 ;
Timer_Enable() ;
}
uint32_t stop_measure(void)
{
uint32_t count ;
Timer_Stop() ;
count = Timer_ReadPeriod() - Timer_ReadCounter() ;
if (tc_count) {
count += tc_count * Timer_ReadPeriod() ;
}
return( count ) ;
}
void test_func(uint32_t us)
{
CyDelayUs(us) ;
}
int main(void)
{
uint32_t count ;
uint32_t us = 0 ;
init_hardware() ;
cls() ;
splash() ;
for(;;)
{
start_measure() ;
test_func(us) ;
count = stop_measure() ;
snprintf(str, STR_LEN, "%d: %d us\n", us, count) ;
print(str) ;
us = us + 10 ;
if (us > 10000) {
us = 0 ;
}
CyDelay(1000) ;
}
}
=============
TeraTerm Log
moto