Difference between revisions of "STM32 Bit Banding (or bit-banding)"

From Stm32World Wiki
Jump to navigation Jump to search
Line 1: Line 1:
 
[[Category:STM32]][[Category:STM32 Development]][[Category:C]]{{metadesc|Bit Banding in STM32 MCUs}}
 
[[Category:STM32]][[Category:STM32 Development]][[Category:C]]{{metadesc|Bit Banding in STM32 MCUs}}
In older 8-bit [[MCU]]s it was quite common to have instructions to clear or set a bit as one atomic instruction.  By atomic it means the read->modify->write can not be interrupted resulting in other bits being set wrongly.
+
In older 8-bit [[MCU]]s it was quite common to have instructions to clear or set a bit as one atomic instruction.  By atomic it means the read->modify->write can not be interrupted resulting in other bits being set wrongly.  Unfortunately [[ARM]] did not implement such instructions in the ARM cores.  They did however implement something known as "bit banding" (or bit-banding).
  
Unfortunately [[ARM]] did not implement such instructions in the ARM coresThey did however implement something known as "bit banding" (or bit-banding).
+
Bit banding is an aliased region of memory addresses where each address point to exactly one bit in the original byteThese bytes get updated accordingly to the bits in the original byte and when or if changes only that single bit of the original get set or reset. There are two of these bands.  One is covering the entire SRAM space and one is covering all the peripheral registers.
  
 
== Macro's to Calculate Bit Band Address ==
 
== Macro's to Calculate Bit Band Address ==

Revision as of 02:53, 21 October 2024

In older 8-bit MCUs it was quite common to have instructions to clear or set a bit as one atomic instruction. By atomic it means the read->modify->write can not be interrupted resulting in other bits being set wrongly. Unfortunately ARM did not implement such instructions in the ARM cores. They did however implement something known as "bit banding" (or bit-banding).

Bit banding is an aliased region of memory addresses where each address point to exactly one bit in the original byte. These bytes get updated accordingly to the bits in the original byte and when or if changes only that single bit of the original get set or reset. There are two of these bands. One is covering the entire SRAM space and one is covering all the peripheral registers.

Macro's to Calculate Bit Band Address

#define BITBAND_SRAM_REF    0x20000000
#define BITBAND_SRAM_BASE   0x22000000
#define BITBAND_PERIPH_REF  0x40000000
#define BITBAND_PERIPH_BASE 0x42000000

#define bitband_t *(volatile uint32_t*)

#define m_BITBAND_SRAM(address,bit) (BITBAND_SRAM_BASE + (((uint32_t)address) - BITBAND_SRAM_REF) * 32 + (bit) * 4)
#define m_BITBAND_PERIPH(address,bit) (BITBAND_PERIPH_BASE + (((uint32_t)address) - BITBAND_PERIPH_REF) * 32 + (bit) * 4)

Usage Examples

Considering a variable v, the bits can be individually set/reset like this:

*((uint8_t *)m_BITBAND_SRAM(&v, 7)) = 1;
*((uint8_t *)m_BITBAND_SRAM(&v, 6)) = 0;
*((uint8_t *)m_BITBAND_SRAM(&v, 5)) = 1;
*((uint8_t *)m_BITBAND_SRAM(&v, 4)) = 0;
*((uint8_t *)m_BITBAND_SRAM(&v, 3)) = 1;
*((uint8_t *)m_BITBAND_SRAM(&v, 2)) = 0;
*((uint8_t *)m_BITBAND_SRAM(&v, 1)) = 1;
*((uint8_t *)m_BITBAND_SRAM(&v, 0)) = 0;

A peripheral - for example port 13 on GPIOC can be handled like this:

uint8_t *led_pin = (uint8_t *)m_BITBAND_PERIPH(&LED_GPIO_Port->ODR, 13);

// Toggle LED
*led_pin = !*led_pin;

Miscellaneous Links

To be added