Code Snippets Submitted by Clifford
Debug print trace macro
#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
//
ARM Cortex-M Bit Banding
#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
ARM Cortex-M Bit Banding
#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
#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
//