diff --git a/buttons.c b/buttons.c index 0a14ab5..d3cacf3 100644 --- a/buttons.c +++ b/buttons.c @@ -28,7 +28,6 @@ uint32_t gADCSamplingRate; // [Hz] actual ADC sampling rate // imported globals extern uint32_t gSystemClock; // [Hz] system clock frequency extern volatile uint32_t gTime; // time in hundredths of a second -extern volatile uint8_t drawRequested; // initialize all button and joystick handling hardware void ButtonInit(void) diff --git a/main.c b/main.c index 1a8e09b..68f41d5 100644 --- a/main.c +++ b/main.c @@ -13,6 +13,7 @@ #include "driverlib/fpu.h" #include "driverlib/sysctl.h" #include "driverlib/interrupt.h" +#include "driverlib/timer.h" #include "Crystalfontz128x128_ST7735.h" #include #include "grlib/grlib.h" @@ -28,7 +29,7 @@ uint32_t gSystemClock; // [Hz] system clock frequency volatile uint32_t gTime = 0; // time in hundredths of a second -volatile uint8_t drawRequested = 1; +volatile uint8_t refresh = 1; // assumming square lcd #define HEIGHT LCD_VERTICAL_MAX @@ -48,6 +49,8 @@ const float gVoltageScale[VOLTAGE_SCALES] = { 0.1, 0.2, 0.5, 1., 2. }; +uint32_t cputime_unloaded; + int RisingTrigger(void); // start a pwm test signal @@ -72,6 +75,26 @@ void start_signal() { PWMGenEnable(PWM0_BASE, PWM_GEN_1); } +uint32_t cpu_load_count(void) +{ + uint32_t i = 0; + TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT); + TimerEnable(TIMER1_BASE, TIMER_A); // start one-shot timer + while (!(TimerIntStatus(TIMER1_BASE, false) & TIMER_TIMA_TIMEOUT)) + i++; + return i; +} + +void start_cputimer() { + // initialize timer 1 in one-shot mode for polled timing + SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); + TimerDisable(TIMER1_BASE, TIMER_BOTH); + TimerConfigure(TIMER1_BASE, TIMER_CFG_ONE_SHOT); + TimerLoadSet(TIMER1_BASE, TIMER_A, gSystemClock/100); // 10ms interval + // baseline load + cputime_unloaded = cpu_load_count(); +} + int main(void) { IntMasterDisable(); @@ -93,24 +116,33 @@ int main(void) { #ifdef DISPLAY_TIME uint32_t time; // local copy of gTime - char str[50]; // string buffer #endif // DISPLAY_TIME + char str[50]; // string buffer // full-screen rectangle tRectangle rectFullScreen = {0, 0, GrContextDpyWidthGet(&sContext)-1, GrContextDpyHeightGet(&sContext)-1}; ButtonInit(); + + start_cputimer(); + IntMasterEnable(); uint8_t voltage_scale = 0; while (true) { + // calculate cpu usage + uint32_t cputime_loaded; + cputime_loaded = cpu_load_count(); + float usage_percent; + usage_percent = (1.0 - (float) cputime_loaded / (float) cputime_unloaded) * (float) 100.; + // handle buttons Button button = (Button) 0; while (fifo_get(&button)) { switch (button) { case S2: // draw - drawRequested = 1; + refresh = !refresh; break; case Up: // next scale voltage_scale = (voltage_scale + 1) % VOLTAGE_SCALES; @@ -123,7 +155,6 @@ int main(void) { GrContextForegroundSet(&sContext, ClrBlack); GrRectFill(&sContext, &rectFullScreen); // fill screen with black - GrContextForegroundSet(&sContext, ClrBlue); @@ -138,24 +169,26 @@ int main(void) { } + // info + GrContextForegroundSet(&sContext, ClrWheat); + GrStringDraw(&sContext, gVoltageScaleStr[voltage_scale], /*length*/ -1, /*x*/ 0, /*y*/ 0, /*opaque*/ false); + snprintf(str, sizeof(str), "CPU Load %.1f%%", usage_percent); + GrStringDraw(&sContext, str, /*length*/ -1, /*x*/ 0, /*y*/ HEIGHT - 10, /*opaque*/ false); + // display graph #define LOCAL_BUF_LEN 128 uint16_t local_adc_buffer[LOCAL_BUF_LEN]; // copy of adc buffer int32_t adc_current_index; int32_t j; - if (drawRequested) { + if (refresh) { int trigger = RisingTrigger(); adc_current_index = trigger - (WIDTH / 2); for (j=0; j