14 Replies Latest reply on Oct 16, 2019 10:25 AM by LePo_1062026

    How to get timestamp in microseconds using Psoc5lp

    PrSa_4352851

      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.

        • 1. Re: How to get timestamp in microseconds using Psoc5lp
          MoTa_728816

          Hi,

           

          Sometime ago, I posted a response to a question which requested a timestamp.

          PSoC 5LP - RTC UART output

           

          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

          • 2. Re: How to get timestamp in microseconds using Psoc5lp
            BoTa_264741

            PrSa,

            I agree with Moto, for 1us accuracy you have to use either a SysTick or a dedicated Timer component.

            /odissey1

            • 3. Re: How to get timestamp in microseconds using Psoc5lp
              LePo_1062026

              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

              • 4. Re: How to get timestamp in microseconds using Psoc5lp
                PrSa_4352851

                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.

                • 5. Re: How to get timestamp in microseconds using Psoc5lp
                  BoTa_264741

                  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

                   

                  StopWatch_P4M_01a.png

                  StopWatch_P4M_01.PNG

                  • 6. Re: How to get timestamp in microseconds using Psoc5lp
                    PrSa_4352851

                    Hello Odissey1

                     

                    I am not able to import this component for my target. I am using Psoc5LP

                    • 7. Re: How to get timestamp in microseconds using Psoc5lp
                      BoTa_264741

                      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

                      • 8. Re: How to get timestamp in microseconds using Psoc5lp
                        PrSa_4352851

                        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.

                        • 9. Re: How to get timestamp in microseconds using Psoc5lp
                          BoTa_264741

                          I will look into it. It used it on P5 as well as P4.

                          • 10. Re: How to get timestamp in microseconds using Psoc5lp
                            MoTa_728816

                            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

                            001-schematic.JPG

                            Pin assign

                            002-pin-assign.JPG

                            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

                            000-TeraTerm-log.JPG

                             

                            moto

                            • 11. Re: How to get timestamp in microseconds using Psoc5lp
                              BoTa_264741

                              PrSa,

                              Attached updated project, tested OK on PSoC5.

                              /odissey1

                               

                              StopWatch_P5_01d_demo_A.png

                              StopWatch_P5_01d_demo_B.png

                              1 of 1 people found this helpful
                              • 12. Re: How to get timestamp in microseconds using Psoc5lp
                                LePo_1062026

                                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

                                • 13. Re: How to get timestamp in microseconds using Psoc5lp
                                  BoTa_264741

                                  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

                                  • 14. Re: How to get timestamp in microseconds using Psoc5lp
                                    LePo_1062026

                                    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