How to measure milliseconds in a code with PSoC Creator timer TCPWM for PSoC 6

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

cross mob
Gio0_1
Level 2
Level 2
First solution authored 10 likes given 5 replies posted

Hello guys,

I will try to make this post clear as is my first one in the community, also if I did something wrong let me know (I chose PSoC 6 because I'm working with that).

I would like to use a Timer TCPWM from the Hardware part of my PSoC 6 to count the number of milliseconds it takes to execute any line of code, being a simple "wait(2000)" function for example (I know is different the name for PSoC Creator, I'll show you later) or a function itself that do many things and returns to the main() code after, this with the purpose of measuring how much a function takes to execute.

I will copy paste my code, if you need the project tell me but I need to separate it because I created many projects in the same workspace (so I'm not sure if the Create Workspace Bundle... will include all of them). But to give more information: I'm working with the Infineon-CY8CPROTO-063-BLE_PSoC_6 board (the manual itself is Infineon-CY8CPROTO-063-BLE_PSoC_6_BLE_Prototyping_Board_Guide-UserManual-v01_00-EN in Infineon's website), when creating a new project I select PSoC 6 >> CYBLE-416045-02 and I leave by default the next steps, the thing is that I added the TCPWM in the schematics, as shown in the screenshot I'm leaving attached, and UART to show results in RealTerm... But the seconds I get are non-sense, I changed in different ways the frequency, the period of the TCPWM and still nothing, I achieved to get the right seconds for wait(1000) or wait(2000) 3000, etc. it showed me 1, 2, 3, etc. but for hundreds showed me random values. I think it was with 1MHz and 1000 of period but I tried many things that I cannot recall it now. I know that the frequency out = f in/(period+1) (counting clock) but tbh I'm not sure how is that helping me, I read the datasheet from TCPWM but it says most of its components and stuff, not much information about how to use it as a timer or even the equation I had to get it from somewhere else here in the posts.
The code I'm using in M4 only (ignore the 2 includes in the middle I wanted to try the StartTick function but I got to know is something from PSoC 4 only). Also the unsigned int32 that I'm using is according to the function of capture (GetCounter), that's the type of variable it returns, but in the sprintf I'm using %u instead of %lu because it dropped me a warning or some kind of error:

 

#include "project.h"
#include "cy_systick.h"
#include "cy_syslib.h"
#include "stdio.h"

int main(void)
{
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
//wait(100);
//CySysTickStart();
Uart_Printf_Start();
char String[128];
TimerCounter_Start();
TimerCounter_TriggerStart();
CyDelay(6500);
TimerCounter_TriggerStop();

uint32_t result = TimerCounter_GetCounter();

sprintf(String,"\nThe time is: %u",result);
Uart_Printf_PutString(String);

}

I hope it is clear what I want to achieve, and with my code you can be able to help me. I'm using the Start and Stop triggers because it is an easier/faster way that using interrupts. And the GetCounter is showing results, the only thing is that my timer is not set up properly to show the milliseconds, I have no clue how to do that.

Thanks in advance!

Gio

 

0 Likes
1 Solution
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Gio,

If you're interested only in millisecond resolution the Cy_SysTick resource should be enough.

You can use a TCPWM timer as the timing resource.  However, it "eats up" that resource.  It would be difficult to use it for something else in your application.

The Cy_SysTick is an ARM-defined resource that can used as a timing source across multiple threads in your application.   It was intended to be a sharable resource.   The Cy_SysTick resource, by default, is opened with a 1ms timing.  You create your own ISR that will get executed every 1ms.  In your ISR, you can increment a global variable (let's call it "uint32 Tick_1ms")  each 1ms.    At the main() task level, your code can store the value in Tick_1ms before you start a operation and then subtract this stored value from the current Tick_1ms when the operation is done.   This should give you a reasonable execution time of the operation +/- 1ms.

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
2 Replies
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Gio,

If you're interested only in millisecond resolution the Cy_SysTick resource should be enough.

You can use a TCPWM timer as the timing resource.  However, it "eats up" that resource.  It would be difficult to use it for something else in your application.

The Cy_SysTick is an ARM-defined resource that can used as a timing source across multiple threads in your application.   It was intended to be a sharable resource.   The Cy_SysTick resource, by default, is opened with a 1ms timing.  You create your own ISR that will get executed every 1ms.  In your ISR, you can increment a global variable (let's call it "uint32 Tick_1ms")  each 1ms.    At the main() task level, your code can store the value in Tick_1ms before you start a operation and then subtract this stored value from the current Tick_1ms when the operation is done.   This should give you a reasonable execution time of the operation +/- 1ms.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Hi Len,

Thanks for the soon reply!

Edit: Ignore the *** I just left it for the sake of completeness, I could find the functions with the name you provide me, https://infineon.github.io/psoc6pdl/pdl_api_reference_manual/html/group__group__arm__system__timer.h... there, the thing is that I'm not sure what do interval means in Cy_SysTick_Init(clock source, interval); I'm not sure if is a time inside where my code could take or what it refers to, because I guess I need to use that function before using the interrupt. My code might be a bit messy, but I'm trying to do a lot of things, so judge me as you want, haha. I'm open to feedback, because I'm trying to apply what you told me with the ISR, in a interruption function I created.

With the value of Tick_ms variable I get 0, with the function GetValue() I only get a value close to 10000, but when I reduce the time 9500, 6500, whatever below 10 seconds it gets me weird values, when I go to 20000 I still getting no more than the value close to 10000. I know it has to be with the Tick_ms global variable as you told me to get the difference. But I'm still not sure if the interruption is being called.

The code is the following:

#include "project.h"
#include "stdio.h"

uint32 Tick_1ms; //global variable to count milliseconds

void SysTickIsrHandler(void)
{
Tick_1ms++;
}

int main(void)
{

/* Place your initialization/startup code here (e.g. MyInst_Start()) */

//CySysTickStart();
Uart_Printf_Start();
char String[128];
////TimerCounter_Start();
////TimerCounter_TriggerStart();
Cy_SysTick_Init(CY_SYSTICK_CLOCK_SOURCE_CLK_CPU,10000);
Cy_SysTick_EnableInterrupt();
/* Find unused callback slot. */
for (uint32 i = 0u; i < CY_SYS_SYST_NUM_OF_CALLBACKS; ++i)
{
if (Cy_SysTick_GetCallback(i) == NULL)
{
/* Set callback */
Cy_SysTick_SetCallback(i, SysTickIsrHandler);
break;
}
}
CyDelay(10000);

////TimerCounter_TriggerStop();
////uint32_t result = TimerCounter_GetCounter();
uint32_t result = Cy_SysTick_GetValue();
//uint32_t result = Tick_1ms;
Uart_Printf_PutString("\n\rHii Gio testing text in UART (RealTerm):\n");
sprintf(String,"\n\rThe time is: %u",result);
Uart_Printf_PutString(String);

}

______________________________________________________________________________

Edit2:

I could get the values but only up to 24000 ms. With only the value of Tick_1ms stored after the call function and the "Wait()" alike, and putting that directly in the sprintf(), but deleting the GetValue() thing, and it works fine but for further values it shows gibberish, and for the correct values from 1 to 24k milliseconds (ms) I had to use an interval of 100111 I just tried many values to get this value, I have no clue why this is happening, something with the resolution I thought, but is weird that it only works up to 24k being 100111 greater than the value, so should work for other values as well (because with 10k it show values 10 times bigger than they should be). It partially works, but I'm still having no idea how this is really working, and that worries me because I cannot rely on a code that is working for some values (even I don't think the code I'm going to time takes longer than 24 seconds).

_________________________________________________________________________________________

 

 

 

 

 

***If it's going to be easier and it will allow me to use the TCPWM for other purposes I would like to go for the Cy_SysTick, but which library should I use? I couldn't find the function in the includes I put there, where normally the SysTick should be, but I didn't and all the examples and topics related to it are from PSoC 4, not 6, here in the community also. As you've seen in my code documented is a SysTickStart() function.***

****Where do I get this library from if is not by default in the PDL files****

 

Gio

0 Likes