ARM Cortex-M Bit Banding

March 22, 20136 comments Coded in C for the Cortex-M
#include <stdint.h>

//! @brief Convert word address + bit position to bitband address.
//!
//! @param address  Word address containing of bit
//! @param bit      Bit offset (0 = LSB,  31 = MSB)
//! @return Address of bit in bitband region.
volatile uint32_t* getBitBandAddress( volatile void* address, int bit )
{
    uint32_t addr = (uint32_t)address ;
    uint32_t word_band_base = addr & 0xf0000000 ;
    uint32_t bit_band_base = word_band_base | 0x02000000 ;
    uint32_t offset = addr - word_band_base ;

    return  (volatile uint32_t*)(bit_band_base + (offset * 32) + (bit * 4)) ;
}

--- EXAMPLES ---

// Example usage 1: 160 bit array
uint32_t physical_memory[5] = {0} ;
uint32_t* bit_array = getBitBandAddress( physical_memory, 0 ) ;
int bit_array_length = sizeof(physical_memory) * CHAR_BIT ;
for( i = 0; i < bit_array_len; i++ )
{
    bit_array[i] = rand() % 2;
}

// Example usage 2: STM32 USART1 Tx Int Enable/Disable
uint32_t* tx_intr_enable_bit_addr = getBitBandAddress( (&(USART1->CR1)), 7 ) ;

*tx_intr_enable_bit_addr = 0 ; // Disable Tx
*tx_intr_enable_bit_addr = 1 ; // Enable Tx

// Example usage 3: C++ reference version of example 2
uint32_t& tx_intr_enable_bit = *getBitBandAddress( (&(USART1->CR1)), 7 ) ;

tx_intr_enable_bit = 0 ; // Disable Tx
tx_intr_enable_bit = 1 ; // Enable Tx

Debug print trace macro

March 22, 2013 Coded in C
#if defined NDEBUG
    #define TRACE( format, ... )
#else
    #define TRACE( format, ... )   printf( "%s::%s(%d) " format, __FILE__, __FUNCTION__,  __LINE__, __VA_ARGS__ )
#endif

// Example usage
void example()
{
    unsigned var = 0xdeadbeef ;
    TRACE( "var=0x%x", var ) ;
}

// Resultant output example:
//    example.c::example(5) var=0xdeadbeef
//