Cascading TCPWM Counters

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

cross mob
NiBu_4687336
Level 5
Level 5
5 solutions authored 50 replies posted 25 replies posted

Hi.

I need a 1 MHz counter and thought it would be a simple matter to use two TCPWM counters to create it. One counter would use a scaled clock at 1 MHz and count up to UINT32_MAX continuously, while the second would count overflow events from the first counter.

Setting up the first counter is trivial, but I can't get the second counter to do what I want.

Both counters share the same clock, which runs at 1 MHz.

Here is the configuration for counter 1:

counter1.png

Here's the configuration for counter 2:

counter2.png

I initialize the counters like this:

// configure microsecond low word timer

cy_stc_tcpwm_counter_config_t cstccCan1usLTimerConfig = TMR_CAN_1US_L_config;

cstccCan1usLTimerConfig.startInputMode = CY_TCPWM_INPUT_LEVEL;

cstccCan1usLTimerConfig.startInput = CY_TCPWM_INPUT_1;

cstccCan1usLTimerConfig.countInputMode = CY_TCPWM_INPUT_LEVEL;

cstccCan1usLTimerConfig.countInput = CY_TCPWM_INPUT_1;

Cy_TCPWM_Counter_Init( TMR_CAN_1US_L_HW, TMR_CAN_1US_L_NUM, &cstccCan1usLTimerConfig );

// configure microsecond high word timer

cy_stc_tcpwm_counter_config_t cstccCan1usHTimerConfig = TMR_CAN_1US_H_config;

cstccCan1usHTimerConfig.startInputMode = CY_TCPWM_INPUT_LEVEL;

cstccCan1usHTimerConfig.startInput = CY_TCPWM_INPUT_1;

Cy_TCPWM_Counter_Init( TMR_CAN_1US_H_HW, TMR_CAN_1US_H_NUM, &cstccCan1usHTimerConfig );

Cy_TCPWM_Counter_SetCounter( TMR_CAN_1US_L_HW, TMR_CAN_1US_L_NUM, UINT32_MAX - ( uint32_t ) 10e6 );

Cy_TCPWM_Counter_SetCounter( TMR_CAN_1US_H_HW, TMR_CAN_1US_H_NUM, 0 );

Cy_TCPWM_Counter_Enable( TMR_CAN_1US_L_HW, TMR_CAN_1US_L_NUM );

Cy_TCPWM_Counter_Enable( TMR_CAN_1US_H_HW, TMR_CAN_1US_H_NUM );

I initialize the low-word timer such that it overflows 10 second after it's started. The result is that the low-word counter 1 counts microseconds, but the high-word counter 2 never changes from its initial value of 0.

I've tried a number of variations on this theme, but haven't found the magic configuration yet.

What am I missing?

Thanks,

-Nick

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.

Hi NiBu_4687336​,

Thank you for the explanation. I understand your requirement and the issue better. I was trying to recreate your project at my end and faced the similar issue of not getting the count value to increment at the overflow event. I made the following changes to the project to make it work. Please let me know if you can use this solution.

The count signal is starting the counter to start from 0 instead of 1 on the first count signal. Therefore, the first overflow event from counter 1 is setting the counter of counter 2 to 0. To workaround this, you can do the following;

1. Start Counter 1 using reload instead of start. This will cause the first counter to generate a overflow event and the count signal is asserted in the second counter initializing it to zero. Subsequent overflow event (10 seconds event) will cause the counter 2 to set its counter value at 1.

2. Instead of setting the counter value to 2^32 - 10e6, you can set the period of the counter 1 to 10e6 so that it can generate the same result. The reason for this change is that reload event given to counter 1 will force the counter value to 0, thereby we need to set period of the counter 1 to 10e6 to generate an overflow event at 10 seconds.

3. If you can't use 2 for some reason, you can do these steps to achieve the same result:

a. Reload Counter0 (to generate first overflow event)

b. Stop Counter0

c. Load Counter as  2^32 - 10e6

d. Restart counter

4. Do not use shared clock between the two counters as it is leading to timing issues. After a TC event at the counter 1, immediately reading the counter 2's counter is giving 0. Reading it after a delay is giving 1.  If I use separate clock dividers for these counters then there is no issue.

5. If you can't use reload, then the counter 2 will read 0 after the first overflow event. You can simply read the counter + 1 in firmware to get the logic you want.

I've attached the project used to test this. Let me know if this works for you. The design.modus of the project can be found in the location Counters_Test\libs\TARGET_CY8CKIT-062-BLE\COMPONENT_BSP_DESIGN_MODUS\design.modus

Regards,

Bragadeesh

Regards,
Bragadeesh

View solution in original post

0 Likes
4 Replies
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi NiBu_4687336​,

Please let me know if my understanding of your requirement is correct. You want to count the number of times the first timer overflows? In that case the first time would overflow every 2^32/10^6 = 4294 seconds. Where have you set the lower counter to overflow every 10 seconds? Can you please help me understand your requirement better?

Regards,

Bragadeesh

Regards,
Bragadeesh
0 Likes

Hi BragadeeshV_41​.

"You want to count the number of times the first timer overflows."

Your understanding of my requirement is correct.

You seem, however, to be confusing period with phase:

Cy_TCPWM_Counter_SetCounter( TMR_CAN_1US_L_HW, TMR_CAN_1US_L_NUM, UINT32_MAX - ( uint32_t ) 10e6 );

"I initialize the low-word timer such that it overflows 10 second after it's started."

An initial count of UINT32_MAX - 10,000,000 means the timer will overflow for the first time after 10 million clocks (10 seconds). The fact that it won't overflow a second time for over an hour is irrelevant to this test.

Thanks,

-Nick

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

Hi NiBu_4687336​,

Thank you for the explanation. I understand your requirement and the issue better. I was trying to recreate your project at my end and faced the similar issue of not getting the count value to increment at the overflow event. I made the following changes to the project to make it work. Please let me know if you can use this solution.

The count signal is starting the counter to start from 0 instead of 1 on the first count signal. Therefore, the first overflow event from counter 1 is setting the counter of counter 2 to 0. To workaround this, you can do the following;

1. Start Counter 1 using reload instead of start. This will cause the first counter to generate a overflow event and the count signal is asserted in the second counter initializing it to zero. Subsequent overflow event (10 seconds event) will cause the counter 2 to set its counter value at 1.

2. Instead of setting the counter value to 2^32 - 10e6, you can set the period of the counter 1 to 10e6 so that it can generate the same result. The reason for this change is that reload event given to counter 1 will force the counter value to 0, thereby we need to set period of the counter 1 to 10e6 to generate an overflow event at 10 seconds.

3. If you can't use 2 for some reason, you can do these steps to achieve the same result:

a. Reload Counter0 (to generate first overflow event)

b. Stop Counter0

c. Load Counter as  2^32 - 10e6

d. Restart counter

4. Do not use shared clock between the two counters as it is leading to timing issues. After a TC event at the counter 1, immediately reading the counter 2's counter is giving 0. Reading it after a delay is giving 1.  If I use separate clock dividers for these counters then there is no issue.

5. If you can't use reload, then the counter 2 will read 0 after the first overflow event. You can simply read the counter + 1 in firmware to get the logic you want.

I've attached the project used to test this. Let me know if this works for you. The design.modus of the project can be found in the location Counters_Test\libs\TARGET_CY8CKIT-062-BLE\COMPONENT_BSP_DESIGN_MODUS\design.modus

Regards,

Bragadeesh

Regards,
Bragadeesh
0 Likes

Hi BragadeeshV_41​.

I was unable to get your code to compile, which led me to the discovery that the PDL has changed since I started this project. Not just a new version, but an entirely new Git repository. The function Cy_TCPWM_TriggerReloadOrIndex_Single() does not exist in the version of the library I had been using.

After going through the quite painful process of rebuilding my project with the new PDL (and HAL), I was finally able to get the overflow trigger from one counter to cause a second counter to increment its count.

I should note that it was not necessary to use separate clock dividers for the two counters.

Thanks for your help,

-Nick

0 Likes