Difference between revisions of "STM32 Bit Banding"

From Stm32World Wiki
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 06: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