Difference between revisions of "STM32 Bit Banding (or bit-banding)"
Jump to navigation
Jump to search
Line 14: | Line 14: | ||
#define m_BITBAND_SRAM(address,bit) (BITBAND_SRAM_BASE + (((uint32_t)address) - BITBAND_SRAM_REF) * 32 + (bit) * 4) | #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) | #define m_BITBAND_PERIPH(address,bit) (BITBAND_PERIPH_BASE + (((uint32_t)address) - BITBAND_PERIPH_REF) * 32 + (bit) * 4) | ||
+ | </pre> | ||
+ | |||
+ | == Usage Examples == | ||
+ | |||
+ | Considering a variable v, the bits can be individually set/reset like this: | ||
+ | |||
+ | <pre> | ||
+ | *((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; | ||
+ | </pre> | ||
+ | |||
+ | A peripheral - for example port 13 on GPIOC can be handled like this: | ||
+ | |||
+ | <pre> | ||
+ | uint8_t *led_pin = (uint8_t *)m_BITBAND_PERIPH(&LED_GPIO_Port->ODR, 13); | ||
+ | |||
+ | // Toggle LED | ||
+ | *led_pin = !*led_pin; | ||
</pre> | </pre> | ||
Revision as of 05:53, 20 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.
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