2021-11-08 04:36 PM
I have what I am sure to most a simple C question (I'm a hardware guy at this end).....
For brevity I would like to take the following statements and combine them using 1 for loop but don't know the semantics on how to do this....I am using the HAL library with CubeMX:
TIM2->CCR1 = pwmPulse[speed] - HAPTIC_PW;
TIM2->CCR2 = pwmPulse[speed] - HAPTIC_PW;
TIM2->CCR3 = pwmPulse[speed] - HAPTIC_PW;
TIM2->CCR4 = pwmPulse[speed] - HAPTIC_PW;
Below is a FAILED attempt:
for (uint8_t i = 0; i < 4; i++)
{
TIM2->(CCR1 + i) = pwmPulse[speed] - HAPTIC_PW;
}
Thanks for the help
Solved! Go to Solution.
2021-11-09 05:49 AM
Thanks everyone for the input. I have the following code and it seems to work. Can someone explain to me why (4*i) does not work? The registers are defined as __IO uint32_t, I would have thought that I would need to advance the pointer by 4*i to update the correct register but that does not seem to be the case???
pTim1 = &TIM1->CCR1;
pTim2 = &TIM2->CCR1;
for (uint8_t i = 0; i < 4; i++)
{
*(pTim1 + (i)) = (pwmPulse[speed] - HAPTIC_PW);
*(pTim2 + (i)) = (pwmPulse[speed] - HAPTIC_PW);
}
2021-11-08 05:49 PM
The only reason this works is because the registers are located consecutively, but you could do something like this:
volatile uint32_t * CCR = &TIM2->CCR1;
for (int i = 0; i < 4; ++i) {
CCR[i] = ...;
}
To avoid confusion, however, and because there are exactly 4 channels, I would recommend not making it into a loop and keeping the original syntax.
2021-11-08 06:25 PM
The 8-bit count isn't efficient, the natural size for things is 32-bit, and they will be optimal even over small ranges.
The CCR registers are 32-bit wide from the address decode perspective
This is still ugly, but viable
TIM2->(CCR1 + (4 * i)) = pwmPulse[speed] - HAPTIC_PW;
2021-11-08 09:20 PM
Or use a const lookup table containing the addresses, maybe even NULL terminated like C strings.... then you can scatter your pwms in multiple timers if their number grows....
2021-11-08 10:16 PM
For a single timer, if this to be a repeated operation, you could use the mechanism provided by TIMx_DMAR "register". Contrary to its name and description, it is not bound specifically to DMA. Caveat, you must not read it (including through debugger) outside the intended process to not lose track of currently pointed register.
JW
2021-11-09 05:49 AM
Thanks everyone for the input. I have the following code and it seems to work. Can someone explain to me why (4*i) does not work? The registers are defined as __IO uint32_t, I would have thought that I would need to advance the pointer by 4*i to update the correct register but that does not seem to be the case???
pTim1 = &TIM1->CCR1;
pTim2 = &TIM2->CCR1;
for (uint8_t i = 0; i < 4; i++)
{
*(pTim1 + (i)) = (pwmPulse[speed] - HAPTIC_PW);
*(pTim2 + (i)) = (pwmPulse[speed] - HAPTIC_PW);
}
2021-11-09 06:17 AM
> Can someone explain to me why (4*i) does not work?
Pointers advance by the size of the thing they're pointing to.