Created
September 14, 2021 19:25
-
-
Save Novakov/c24bcd407b4756589985da3d20b6be87 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
#include <cstdint> | |
#include "em_cmu.h" | |
#include "em_gpio.h" | |
#include "core_cm3.h" | |
//#include "efm32gg_etm.h" | |
static void SetupClock() | |
{ | |
CMU_OscillatorEnable(cmuOsc_HFXO, true, true); | |
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); | |
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_HFCLK); | |
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_HFCLKLE); | |
CMU_ClockEnable(cmuClock_HFPER, true); | |
CMU_ClockEnable(cmuClock_DBG, true); | |
CMU_ClockEnable(cmuClock_GPIO, true); | |
SystemCoreClockUpdate(); | |
} | |
__STATIC_INLINE uint32_t ITM_SendCharOnChannel (uint8_t channel, uint32_t ch) | |
{ | |
if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ | |
((ITM->TER & (1 << channel) ) != 0UL) ) /* ITM Port enabled */ | |
{ | |
while (ITM->PORT[channel].u32 == 0UL) | |
{ | |
__NOP(); | |
} | |
ITM->PORT[channel].u8 = (uint8_t)ch; | |
} | |
return (ch); | |
} | |
extern "C" void SysTick_Handler() | |
{ | |
static std::uint32_t i = 0; | |
i++; | |
if(i == 1000) | |
{ | |
i = 0; | |
// GPIO_PinOutToggle(gpioPortE, 2); | |
// GPIO_PinOutToggle(gpioPortE, 3); | |
static char c = 'A'; | |
// ITM_SendCharOnChannel(4, c); | |
ITM_SendChar('A'); | |
c++; | |
if ((c - 1) == 'Z') { | |
c = 'A'; | |
} | |
} | |
} | |
extern "C" void __libc_init_array(void); | |
constexpr std::uint32_t Prescaler = 14; | |
void GenericsConfigureTracing(uint32_t itmChannel, uint32_t sampleInterval, uint32_t tsPrescale) | |
{ | |
/* EFM32 specific configuration to enable the TRACESWO IO pin */ | |
CMU_AUXHFRCOBandSet(cmuAUXHFRCOBand_14MHz); | |
CMU_OscillatorEnable(cmuOsc_AUXHFRCO, true, true); | |
CMU_ClockEnable(cmuClock_DBG, true); | |
/* Enable GPIO clock. */ | |
CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO; | |
/* Enable Serial wire output pin */ | |
GPIO->ROUTE |= GPIO_ROUTE_SWOPEN; | |
/* Set location 0 */ | |
GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC0; | |
/* Enable output on pin - GPIO Port F, Pin 2 */ | |
GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK); | |
GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL; | |
GPIO_PinOutSet(gpioPortF, 2); | |
/* End of EFM32 Specific instructions */ | |
// /* Enable trace in core debug */ | |
// CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; | |
// ITM->LAR = 0xC5ACCE55; // unlock (magic number) | |
// ITM->TER = 0x0; // disable all registers | |
// ITM->TCR = 0x0; // disable everything | |
// TPI->SPPR = 2; // Asynchronous SWO, using NRZ encoding | |
// TPI->ACPR = Prescaler - 1; // Prescaler, SWO_FREQ = REF_CLK / (PRESCALER + 1) | |
// ITM->TPR = 0x0; // Unprivileged access to all registers | |
// DWT->CTRL = | |
// 0x400007FF; // CYCCNTENA = 1, POSTPRESET = 0xF, POSTINIT = 0xF, CYCTAP = 1, SYNCTAP = 01, PCSAMPLENA = 0, | |
// ITM->TCR = 0x0001000D; // Enable ITM (ITEMENA - 0), Enable sync pack transmission (SYNCENA - 2), (TXENA - 3), TSPrescale = 0, TraceBusID = 1 | |
// TPI->FFCR = 0x00000100; // Formatter and Flush Control Register | |
// ITM->TER = 0x7f; // enable all channels | |
// | |
// // Wait for TPIU sync packet | |
// auto prev = DWT->CYCCNT; | |
// while(((prev ^ DWT->CYCCNT) & (1 << 24)) == 0) | |
// { | |
// asm volatile("nop"); | |
// } | |
*((volatile unsigned *)(0xE0040010)) = 13; // Output bits at 14000000/(13+1)=1MHz. | |
*((volatile unsigned *)(0xE00400F0)) = 2; // Use Async mode pin protocol | |
if (!itmChannel) | |
{ | |
*((volatile unsigned *)(0xE0040304)) = 0; // Bypass the TPIU and send output directly | |
} | |
else | |
{ | |
*((volatile unsigned *)(0xE0040304)) = 0x102; // Use TPIU formatter and flush | |
} | |
/* Configure Trace Port Interface Unit */ | |
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; // Enable access to registers | |
// /* Configure PC sampling and exception trace */ | |
// DWT->CTRL = /* CYCEVTEN */ (1<<22) | | |
// /* Sleep event overflow */ (1<<19) | | |
// /* Enable Exception Trace */ (1 << 16) | | |
// /* PC Sample event */ (1<<12) | | |
// /* Sync Packet Interval */ ((1&0x03) << 10) | /* 0 = Off, 1 = 2^23, 2 = Every 2^25, 3 = 2^27 */ | |
// /* CYCTap position */ (1 << 9) | /* 0 = x32, 1=x512 */ | |
// /* Postscaler for PC sampling */ ((sampleInterval&0x0f) << 1) | /* Divider = value + 1 */ | |
// /* CYCCnt Enable */ (1 << 0); | |
/* Configure PC sampling and exception trace */ | |
DWT->CTRL = /* CYCEVTEN */ (0<<22) | | |
/* Sleep event overflow */ (0<<19) | | |
/* Enable Exception Trace */ (0 << 16) | | |
/* PC Sample event */ (0<<12) | | |
/* Sync Packet Interval */ ((0&0x03) << 10) | /* 0 = Off, 1 = 2^23, 2 = Every 2^25, 3 = 2^27 */ | |
/* CYCTap position */ (1 << 9) | /* 0 = x32, 1=x512 */ | |
/* Postscaler for PC sampling */ ((sampleInterval&0x0f) << 1) | /* Divider = value + 1 */ | |
/* CYCCnt Enable */ (1 << 0); | |
/* Configure instrumentation trace macroblock */ | |
ITM->LAR = 0xC5ACCE55; //ETM_LAR_KEY; | |
ITM->TCR = /* DWT Stimulus */ (1<<3)| | |
/* ITM Enable */ (1<<0)| | |
/* SYNC Enable */ (0<<2)| | |
/* TS Enable */ (0<<1)| | |
/* TC Prescale */ ((tsPrescale&0x03)<<8) | | |
((itmChannel&0x7f)<<16); /* Set trace bus ID and enable ITM */ | |
ITM->TER = 0xFFFFFFFF; // Enable all stimulus ports | |
/* Configure embedded trace macroblock */ | |
// ETM->ETMLAR = ETM_LAR_KEY; | |
// ETM_SetupMode(); | |
// ETM->ETMCR = ETM_CR_ETMEN // Enable ETM output port | |
// | ETM_CR_STALL_PROCESSOR // Stall processor when fifo is full | |
// | ETM_CR_BRANCH_OUTPUT; // Report all branches | |
// ETM->ETMTRACEIDR = 2; // Trace bus ID for TPIU | |
// ETM->ETMTECR1 = ETM_TECR1_EXCLUDE; // Trace always enabled | |
// ETM->ETMFFRR = ETM_FFRR_EXCLUDE; // Stalling always enabled | |
// ETM->ETMFFLR = 24; // Stall when less than N bytes free in FIFO (range 1..24) | |
// // Larger values mean less latency in trace, but more stalls. | |
} | |
static const int BASE = 10'000; | |
static void func1() | |
{ | |
for(int i =0 ; i < 1 * BASE; i++) { | |
asm volatile("nop"); | |
} | |
} | |
static void func2() | |
{ | |
for(int i =0 ; i < 2 * BASE; i++) { | |
asm volatile("nop"); | |
} | |
} | |
int main() | |
{ | |
__libc_init_array(); | |
SetupClock(); | |
GenericsConfigureTracing(1, 15, 0); | |
GPIO_PinModeSet(gpioPortE, 2, gpioModePushPull, 1); | |
GPIO_PinModeSet(gpioPortE, 3, gpioModePushPull, 0); | |
SysTick_Config(SystemCoreClock / 1000); | |
while(1) | |
{ | |
// func1(); | |
// func2(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment