8
\$\begingroup\$

Forgive me if this question has already been answered, but I was unable to find an answer either on this page or in the wider Internet.

I'm an experienced developer with decent knowledge regarding low-level programming, but relatively new to embedded development. I've been teaching myself embedded systems development using an ST-NUCLEO144 board, which features an STM32F746ZG MCU. One question that seems non-obvious to me is that why logically related bit fields in a register may be in different locations.

One example is the USART_CR1 register on the STM32746ZG. The M0 and M1 bit fields together control the word length in USART TX/RX, a combined 2-bit value of 0b00 specifies 8-bits, 0b01 specifies 9-bits, etc. This is all quite straightforward, except that M0 is at bit 12 and M1 is at bit 28... why is this?

Is this for legacy design reasons, such as a new feature was inserted into previously reserved space? Is it for reasons related to the chip design, that I'm not considering, or is there a greater purpose to this that I'm not seeing?

Obviously this is pretty trivial to overcome with bit-masking, but I'm just curious.

\$\endgroup\$
  • 1
    \$\begingroup\$ In case of UART specifically, it is very old technology, so the reason is almost always backwards compatibility. The same reason why UART register bit-fields often have crappy names that give namespace collisions all over. \$\endgroup\$ – Lundin May 20 at 8:57
12
\$\begingroup\$

Is this for legacy design reasons, such as a new feature was inserted into previously reserved space?

In this particular case (and in similar cases I've seen) yes, it's done to help keep backward compatibility with older devices and minimise any changes required to the (perhaps well-tested and qualified / certified) code already written for those older devices. New features and functionality (requiring new register bits for control & configuration) therefore have to use non-contiguous bits, if the adjacent bits to the original register bits are already used.

For example, here is the USART_CR1 register of the old STM32F1xx family.


STM32F1xx register USART_CR1 bit usage

Figure 1. STM32F10xxx USART_CR1 register usage

Image source: STM32F10xxx family reference manual RM0008, section 27.6.4


That older USART (with only 2 word length options) needs only one M bit to configure the USART word length between the two options, and that is bit 12. Notice how bits 11 and 13 are also used, and therefore unavailable for future "expansion".

As you said, on the newer STM32F7 (and, for example, also the STM32F4) the USART now has 3 word length options (7, 8 and 9 bits) and so needs another configuration bit - bit 12 is M0, with M1 now in bit 28 (previously reserved in the STM32F1 register map, as you see above).


STM32F74xxx register USART_CR1 bit usage

Figure 2. STM32F74xxx USART_CR1 register usage

Image source: STM32F75xxx and STM32F74xxx family reference manual RM0385, section 31.8.1


They couldn't put the new M1 bit into register bits 11 or 13, without moving register bits already used for other functions, and so removing backwards compatibility with existing code (e.g. for the STM32F1) which used them.

So they have tried to keep some backwards compatibility, which leads to new register bits being added in unexpected places.

Maintaining register mapping for standalone UARTs, from the 8250 to the 16550, with new registers added elsewhere in the register map, was another example.

\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks so much for taking the time to point this out. Perhaps I should have checked the old F family reference material before I asked. I figured there might be more to the story though. \$\endgroup\$ – ajxs May 19 at 4:11
  • 1
    \$\begingroup\$ @ajxs - You're welcome. I can only speak from my experiences (those old UARTS were another good example). It's always possible that someone else will have other relevant experiences, and they might be put-off from spending the time writing an answer, if the question already has an accepted answer. So you could always "unaccept" my answer, wait (say) a day for anyone else to answer from different perspectives, and see if you feel they answer the question any better than mine? If not, then you can always re-accept mine :-) I just don't want you to lose other potential answer perspectives. \$\endgroup\$ – SamGibson May 19 at 4:20
  • 2
    \$\begingroup\$ That seems reasonable, I'll take your advice! Thank you for being so courteous as to make the suggestion. If no better answer has come by tomorrow I'll accept yours. Thanks again. \$\endgroup\$ – ajxs May 19 at 4:23
4
\$\begingroup\$

You are right with

"..for legacy design reasons, such as a new feature was inserted into previously reserved space..".

As far as I know, bit positions themselves have almost no design impact (in chip implementation I mean) in most cases. Designers usually try to utilise whatever is available. And in some cases like when you're trying to extend widths etc.

That said, there are however some cases where the bit positions are intentionally kept far apart. Specifically for bits that are critical and are NOT to be modified by unintentional writes (due to wrong position/masks, or scrambled for security) that can cause the system to end up in an undesired state.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.