Last active
April 21, 2018 00:25
-
-
Save RickKimball/55e113afdcff6e68440301d52bbceadd to your computer and use it in GitHub Desktop.
fabooh - blink with DWT/ITM debug
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* blink.cpp - simple fabooh blink | |
*/ | |
#include <fabooh.h> | |
#include <main.h> | |
#define bit_set(r,b) (r) |= (b) | |
#define bit_clr(r,b) (r) &= ~(b) | |
#define bit_tst(r,b) (r) & (b) | |
static inline void ITM_putc(uint32_t ch) | |
{ | |
if ( bit_tst(ITM->TCR, ITM_TCR_ITMENA_Msk) ) { /* ITM enabled */ | |
while (ITM->PORT[0U].u32 == 0UL); | |
ITM->PORT[0U].u8 = (uint8_t)ch; | |
} | |
} | |
static inline void ITM_putc_32(uint32_t ch) | |
{ | |
if ( bit_tst(ITM->TCR, ITM_TCR_ITMENA_Msk) ) { /* ITM enabled */ | |
while (ITM->PORT[0U].u32 == 0UL); | |
ITM->PORT[0U].u32 = ch; | |
} | |
} | |
static inline void ITM_putc_32_rev(uint32_t ch) | |
{ | |
/* swap endianness */ | |
__asm__ volatile ( | |
"nop\n" | |
"rev %0, %0" : "+r" (ch) | |
); | |
if ( bit_tst(ITM->TCR, ITM_TCR_ITMENA_Msk) ) { /* ITM enabled */ | |
while (ITM->PORT[0U].u32 == 0UL); | |
ITM->PORT[0U].u32 = ch; | |
} | |
} | |
static inline void ITM_print(const char *_s) { | |
if ( bit_tst(ITM->TCR, ITM_TCR_ITMENA_Msk) ) { /* ITM enabled */ | |
register uint8_t *s = (uint8_t *)_s; | |
while(*s) { | |
while(ITM->PORT[0].u32 == 0); | |
ITM->PORT[0U].u8 = *s++; | |
} | |
} | |
} | |
struct DWTCycles { | |
volatile uint32_t * const ptr_cycle_cnt; | |
// configure DWT/ITM, enable SWO output | |
static void init() { | |
/* STM32 specific configuration to enable the TRACESWO IO pin */ | |
bit_set(RCC->APB2ENR, RCC_APB2ENR_AFIOEN); | |
bit_set(AFIO->MAPR, 2 << 24); // Disable JTAG to release TRACESWO | |
bit_set(DBGMCU->CR, DBGMCU_CR_TRACE_IOEN); // Enable IO trace pins | |
/* Configure Trace Port Interface Unit */ | |
bit_set(CoreDebug->DEMCR, CoreDebug_DEMCR_TRCENA_Msk); // Enable access to registers | |
static const unsigned prescaler = 72000000/4000000-1; | |
TPI->ACPR = prescaler; // prescale to 4000000 USART speed | |
TPI->SPPR = 2; // NRZ/USART (1 for RZ/Manchester) | |
TPI->FFCR = 0; // Disable formatter we aren't using ETM | |
DWT->CTRL = 0x400003FE; // DWT needs to provide sync for ITM | |
ITM->LAR = 0xC5ACCE55; // Allow access to the Control Register | |
ITM->TPR = 0x0000000F; // Trace access privilege from user level code, please | |
ITM->TCR = 0x0001000D; | |
#if 1 | |
ITM->TER = 0x1; // Only Enable stimulus channel 0 | |
#else | |
ITM->TER = 0xffffffff; // Only Enable stimulus channel 0-31 | |
#endif | |
} | |
DWTCycles(volatile uint32_t * const ptr) : ptr_cycle_cnt(ptr) { | |
DWT->CYCCNT=0; | |
bit_set(DWT->CTRL, 0b1); | |
} | |
~DWTCycles() { | |
*ptr_cycle_cnt = DWT->CYCCNT; | |
bit_clr(DWT->CTRL, 0b1); | |
} | |
}; | |
// instance the built-in LED | |
LED_BUILTIN LED; | |
void setup(void) { | |
DWTCycles::init(); | |
//CPU::enable_clkout(); | |
LED.setmode_output(); | |
} | |
void loop(void) { | |
static const uint32_t Hz = 2; | |
static const uint32_t msec_delay0 = 1000 / Hz / 2; | |
while (1) { | |
volatile uint32_t inst_cnt0; | |
{ | |
DWTCycles inst0(&inst_cnt0); // instance this class, dtor measures the cycles in this code block | |
ITM_putc_32_rev('1234'); | |
} | |
(void)inst_cnt0; // contains the number of cycles used by the ITM_putc_32_rev function | |
LED.low(); | |
delay(msec_delay0); | |
ITM_print("\r\nhi>>"); | |
LED.high(); | |
delay(msec_delay0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment