Skip to main content
arnold_w
Senior II
March 22, 2016
Question

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

  • March 22, 2016
  • 3 replies
  • 534 views
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?
    This topic has been closed for replies.

    3 replies

    waclawek.jan
    Super User
    March 22, 2016
    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

    Tesla DeLorean
    Guru
    March 22, 2016
    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 VenmoUp vote any posts that you find helpful, it shows what's working..
    Walid FTITI_O
    Visitor II
    March 22, 2016
    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-