2021-10-01 05:41 AM
Since 25 years I use functions or macros like
#define usTimeRead() ((int16_t) (SysTick->VAL >> 1))
#define usTimePlus(TP, US) ((int16_t) TP - ((int16_t) US * (int16_t) 85))
#define usTimePast(TP) (((int16_t) TP - usTimeRead()) > (int16_t) 0)
to create timeouts or to do periodical jobs on 16bit MCUs.
Porting them to STM32G4, the following code should result in a 100us square wave generated at pin B6.
int main(void) {
sysConfigMCU();
/* Loop */
int16_t tp = usTimeRead();
for(;;) {
GPIOB->BSRR = ((uint16_t)0x0040);
tp = usTimePlus(tp, 100);
for ( ; !usTimePast(tp); );
GPIOB->BRR = ((uint16_t)0x0040);
tp = usTimePlus(tp, 100);
for ( ; !usTimePast(tp); );
}
}
This doesn't work - I have to change the macro usTimePast(TP) assigning the difference to temporary variable to get the program running correctly.
#define usTimePast(TP) ((tmp = (int16_t) TP - usTimeRead()) > (int16_t) 0)
I've simulated this behaviour with TDM-GCC with the same result - for values like
usTimeRead() == -32703 and tp == 32735 the compare in usTimePast(TP) will produce differnt results depending on weather the difference of the left side of compare will be assinged to a temporary variable or not!
Using Microsoft Visual Studio will prodece in both cases (with and without aasigning the difference to a temporary variable) the behaviour i know from 16bit MCUs and their compilers.
2021-10-04 01:42 AM
Thx for the answers.
I've known about the promotion of "smaller" types to the biggest type in an expression,
it's new for me, it will be also applied to expressions with all parts of same type.
2021-10-04 01:47 AM
I I thought it was a compiler error/bug, but it was a result of my lack of knowledge about promotion in C (see above)