ECE3849/main.c
2025-04-10 10:29:04 -04:00

217 lines
6.6 KiB
C

/*
* ECE 3849 Lab2 starter project
*
* Gene Bogdanov 9/13/2017
*/
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/cfg/global.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <stdint.h>
#include <stdbool.h>
#include "driverlib/interrupt.h"
uint32_t gSystemClock = 120000000; // [Hz] system clock frequency
#define PWM_FREQUENCY 20000 // PWM frequency = 20 kHz
uint32_t gSystemClock; // [Hz] system clock frequency
volatile uint32_t gTime = 0; // time in hundredths of a second
volatile uint8_t refresh = 1;
// assumming square lcd
#define HEIGHT LCD_VERTICAL_MAX
#define WIDTH LCD_HORIZONTAL_MAX
#define PIXELS_PER_DIV 20
#define VIN_RANGE 3.3 // volts
#define ADC_BITS 12
#define ADC_OFFSET 30
#define VOLTAGE_SCALES 5
const char * const gVoltageScaleStr[VOLTAGE_SCALES] = {
"100 mV", "200 mV", "500 mV", " 1 V", " 2 V"
};
const float gVoltageScale[VOLTAGE_SCALES] = {
0.1, 0.2, 0.5, 1., 2.
};
#define TIME_SCALES 6
const char * const gTimeScaleStr[TIME_SCALES] = {
"100 ms", "50 ms", "20 ms", " 10 ms", "50 us", "20 us"
};
const uint64_t gTImeScale[TIME_SCALES] = {
100 * 1000 / PIXELS_PER_DIV,
50 * 1000 / PIXELS_PER_DIV,
20 * 1000 / PIXELS_PER_DIV,
10 * 1000 / PIXELS_PER_DIV,
50 / PIXELS_PER_DIV,
20 / PIXELS_PER_DIV,
};
int Trigger(bool rising) // search for edge trigger
{
int x = gADCBufferIndex - (WIDTH / 2); // half screen width
int x_stop = x - ADC_BUFFER_SIZE/2;
for (; x > x_stop; x--) {
if (rising) {
if ( gADCBuffer[ADC_BUFFER_WRAP(x)] >= ADC_OFFSET &&
gADCBuffer[ADC_BUFFER_WRAP(x-1)] < ADC_OFFSET) {
break;
}
} else { // falling edge trigger
if ( gADCBuffer[ADC_BUFFER_WRAP(x)] <= ADC_OFFSET &&
gADCBuffer[ADC_BUFFER_WRAP(x-1)] > ADC_OFFSET) {
break;
}
}
}
if (x == x_stop) // for loop ran to the end
x = gADCBufferIndex - (WIDTH / 2); // reset x back to how it was initialized
return x;
}
/*
* ======== main ========
*/
int main(void)
{
IntMasterDisable();
// hardware initialization goes here
/* Start BIOS */
BIOS_start();
return (0);
}
void task0_func(UArg arg1, UArg arg2)
{
IntMasterEnable();
while (true) {
// do nothing
}
}
void draw(tContext &sContext) {
// handle buttons
Button button = (Button) 0;
while (fifo_get(&button)) {
switch (button) {
case S1: // toggle edge
trigger_mode++;
trigger_mode %= 3;
break;
case S2: // draw
refresh = !refresh;
break;
case Up: // next scale
voltage_scale = (voltage_scale + 1) % VOLTAGE_SCALES;
break;
case Down: // previous scale
voltage_scale = (voltage_scale + VOLTAGE_SCALES - 1) % VOLTAGE_SCALES;
break;
case Right: // next scale
time_scale = (time_scale + 1) % TIME_SCALES;
set_frequency(gTImeScale[time_scale]);
break;
case Left: // previous scale
time_scale = (time_scale + TIME_SCALES - 1) % TIME_SCALES;
set_frequency(gTImeScale[time_scale]);
break;
}
}
GrContextForegroundSet(&sContext, ClrBlack);
GrRectFill(&sContext, &rectFullScreen); // fill screen with black
GrContextForegroundSet(&sContext, ClrBlue);
// draw gridlines from the center out
uint8_t xy_pos;
for (xy_pos = HEIGHT/2; xy_pos < HEIGHT; xy_pos += PIXELS_PER_DIV) {
GrLineDrawV(&sContext, xy_pos, 0, 128); // right
GrLineDrawV(&sContext, HEIGHT - xy_pos, 0, 128); // left
GrLineDrawH(&sContext, 0, 128, xy_pos); // down
GrLineDrawH(&sContext, 0, 128, HEIGHT - xy_pos); // up
}
// info
GrContextForegroundSet(&sContext, ClrWheat);
GrStringDraw(&sContext, gVoltageScaleStr[voltage_scale], /*length*/ -1, /*x*/ 0, /*y*/ 0, /*opaque*/ false);
GrStringDraw(&sContext, gTimeScaleStr[time_scale], /*length*/ -1, /*x*/ 60, /*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);
switch (trigger_mode) {
case 1:
GrStringDraw(&sContext, "^", /*length*/ -1, /*x*/ WIDTH - 10, /*y*/ 0, /*opaque*/ false);
break;
case 0:
GrStringDraw(&sContext, "v", /*length*/ -1, /*x*/ WIDTH - 10, /*y*/ 0, /*opaque*/ false);
break;
case 2:
GrStringDraw(&sContext, "-", /*length*/ -1, /*x*/ WIDTH - 10, /*y*/ 0, /*opaque*/ false);
break;
}
// 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 (refresh) {
int trigger;
if (trigger_mode == 2) {
trigger = gADCBufferIndex - (WIDTH / 2); // show latest if trigger disabled
} else {
trigger = Trigger(trigger_mode);
}
adc_current_index = trigger - (WIDTH / 2);
for (j=0; j<LOCAL_BUF_LEN; j++) {
local_adc_buffer[j] = gADCBuffer[ADC_BUFFER_WRAP(adc_current_index + j)];
}
}
float fVoltsPerDiv = gVoltageScale[voltage_scale];
float fScale = (VIN_RANGE * PIXELS_PER_DIV)/((1 << ADC_BITS) * fVoltsPerDiv);
GrContextForegroundSet(&sContext, ClrYellow);
for(j=0; j<LOCAL_BUF_LEN; j++) {
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define CONSTRAIN(x) MAX(MIN(HEIGHT - 1, x), 0)
#define TRANSPOSE(x) CONSTRAIN((HEIGHT/2) - (int)roundf(fScale * ((int)x - ADC_OFFSET)))
uint32_t upper,lower, current, last;
if (j==0) {
upper = TRANSPOSE(local_adc_buffer[j]);
lower = upper;
last = upper;
} else {
current = TRANSPOSE(local_adc_buffer[j]);
upper = MAX(current, last);
lower = MIN(current, last);
last = current;
}
GrLineDrawV(&sContext, j, lower, upper);
}
}