cancel
Showing results for 
Search instead for 
Did you mean: 

When are you allowed to change regs using |= and &= and when are you not?

arnold_w
Senior II
Posted on March 22, 2016 at 10:12

I have recently reversed-engineer some HAL source code and I see that sometimes a temporary variable is used to manipulate a register, for example

uint32_t tmp = 0;
tmp = hdma->Instance->CR;
tmp |= hdma->Init.MemBurst | hdma->Init.PeriphBurst;
hdma->Instance->CR = tmp;

At other times, the register is changed directly, for exaple:

#define __HAL_SPI_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->CR1 |= SPI_CR1_SPE)

What is the rule here?
3 REPLIES 3
Posted on March 22, 2016 at 10:42

No such rule.

Generally, you want to avoid multiple accesses to reduce execution time and code memory consumption. Many if not most RMW you see in examples/''libraries'' are unnecessary, you simply write the value you want to be in the register, the value of reserved bits is given in RM.

There are registers where extra accesses have side effects, common sense applies there. Forget about Cube, RM is your friend.

JW

Posted on March 22, 2016 at 10:51

They expect the compiler to tighten things up.

With a tmp variable there is the potential to gain more efficiency as the compiler can fold multiple operations, some thing it can't do with volatile peripheral registers directly.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Walid FTITI_O
Senior II
Posted on March 22, 2016 at 13:00

Hi arnold_w, 

We apply the direct access in the macro because we have to do just a single access update to the register (only one bit-field). I f we have multiple access, we ought to use temporary variable to gain R/W operations.

-Hanniba-