diff --git a/buttons.c b/buttons.c index d3cacf3..6d0b1b4 100644 --- a/buttons.c +++ b/buttons.c @@ -6,6 +6,17 @@ * * ECE 3849 Lab button handling */ + +/* XDCtools Header files */ +#include +#include +#include + +/* BIOS Header files */ +#include +#include +#include + #include #include #include @@ -32,17 +43,6 @@ extern volatile uint32_t gTime; // time in hundredths of a second // initialize all button and joystick handling hardware void ButtonInit(void) { - // initialize a general purpose timer for periodic interrupts - SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); - TimerDisable(TIMER0_BASE, TIMER_BOTH); - TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); - TimerLoadSet(TIMER0_BASE, TIMER_A, roundf((float)gSystemClock / BUTTON_SCAN_RATE) - 1); - TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT); - TimerEnable(TIMER0_BASE, TIMER_BOTH); - - // initialize interrupt controller to respond to timer interrupts - IntPrioritySet(INT_TIMER0A, BUTTON_INT_PRIORITY); - IntEnable(INT_TIMER0A); // GPIO PJ0 and PJ1 = EK-TM4C1294XL buttons 1 and 2 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ); GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE, GPIO_PIN_0 | GPIO_PIN_1); @@ -153,9 +153,19 @@ uint32_t ButtonAutoRepeat(void) return presses; } -// ISR for scanning and debouncing buttons -void ButtonISR(void) { - TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT); // clear interrupt flag +void clock_buttons(void) { + Semaphore_post(button_clock_sem); +} + +void button_task(void) { + while(1) { + Semaphore_pend(button_clock_sem, BIOS_WAIT_FOREVER); + handle_buttons(); + } +} + +// Task for scanning and debouncing buttons +void handle_buttons(void) { // read hardware button state uint32_t gpio_buttons = ~GPIOPinRead(GPIO_PORTJ_BASE, 0xff) & (GPIO_PIN_1 | GPIO_PIN_0); // EK-TM4C1294XL buttons in positions 0 and 1 @@ -181,25 +191,12 @@ void ButtonISR(void) { ButtonReadJoystick(); // Convert joystick state to button presses. The result is in gButtons. uint32_t presses = ~old_buttons & gButtons; // detect button presses (transitions from not pressed to pressed) presses |= ButtonAutoRepeat(); // autorepeat presses if a button is held long enough -#ifdef DISPLAY_TIME - static bool tic = false; - static bool running = true; - if (presses & 1) { // EK-TM4C1294XL button 1 pressed - running = !running; - } - if (presses & 2) { // EK-TM4C1294XL button 2 pressed - gTime = 0; - } - if (running) { - if (tic) gTime++; // increment time every other ISR call - tic = !tic; - } -#endif // DISPLAY_TIME + Button buttons[9]; uint8_t length, i; length = buttons_from_mask(buttons, presses); for (i=0; i= FIFO_SIZE) new_tail = 0; // wrap around - if (fifo_head != new_tail) { // if the FIFO is not full - button_fifo[fifo_tail] = data; // store data into the FIFO - fifo_tail = new_tail; // advance FIFO tail index - return 1; // success - } - return 0; // full -} - -// get data from the FIFO -// returns 1 on success, 0 if FIFO was empty -int fifo_get(DataType *data) -{ - if (fifo_head != fifo_tail) { // if the FIFO is not empty - *data = button_fifo[fifo_head]; // read data from the FIFO - - if (fifo_head >= FIFO_SIZE-1) { - fifo_head = 0; // reset if past end - } else { - fifo_head++; // increment if within buffer - } - - return 1; // success - } - return 0; // empty -} diff --git a/buttons.h b/buttons.h index 254994b..6f72f6c 100644 --- a/buttons.h +++ b/buttons.h @@ -69,9 +69,6 @@ typedef enum { // returns length uint8_t buttons_from_mask(Button *array, uint32_t buttons); -#define FIFO_SIZE 11 // FIFO capacity is 1 item fewer -typedef Button DataType; // FIFO data type -int fifo_put(DataType data); -int fifo_get(DataType *data); +void handle_buttons(void); #endif /* BUTTONS_H_ */ diff --git a/main.c b/main.c index 0c8fe10..5982e95 100644 --- a/main.c +++ b/main.c @@ -110,6 +110,7 @@ int main(void) // hardware initialization goes here start_signal(); start_sampler(); + ButtonInit(); Crystalfontz128x128_Init(); // Initialize the LCD display driver Crystalfontz128x128_SetOrientation(LCD_ORIENTATION_UP); // set screen orientation @@ -177,6 +178,35 @@ void process_waveform(UArg arg1, UArg arg2) { } } +void handle_user_input() { + // handle buttons + Button button = (Button) 0; + while (true) { + Mailbox_pend(button_mailbox, &button, BIOS_WAIT_FOREVER); + + switch (button) { + case S1: // toggle edge + trigger_mode++; + trigger_mode %= 3; + 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; + } + } +} + void display_waveform(UArg arg1, UArg arg2) { char str[50]; // string buffer diff --git a/rtos.cfg b/rtos.cfg index 9624cff..e9cb9ab 100644 --- a/rtos.cfg +++ b/rtos.cfg @@ -566,10 +566,30 @@ task2Params.priority = 2; Program.global.processing = Task.create("&process_waveform", task2Params); var task3Params = new Task.Params(); task3Params.instance.name = "display"; -task3Params.priority = 3; +task3Params.priority = 5; task3Params.stackSize = 1024; Program.global.display = Task.create("&display_waveform", task3Params); var semaphore2Params0 = new Semaphore.Params(); semaphore2Params0.instance.name = "display_sem"; semaphore2Params0.mode = Semaphore.Mode_BINARY; Program.global.display_sem = Semaphore.create(null, semaphore2Params0); +var clock0Params = new Clock.Params(); +clock0Params.instance.name = "button_clock"; +clock0Params.period = 5; +clock0Params.startFlag = true; +Program.global.button_clock = Clock.create("&clock_buttons", 1, clock0Params); +var semaphore3Params = new Semaphore.Params(); +semaphore3Params.instance.name = "button_clock_sem"; +semaphore3Params.mode = Semaphore.Mode_BINARY; +Program.global.button_clock_sem = Semaphore.create(null, semaphore3Params); +var task4Params = new Task.Params(); +task4Params.instance.name = "button"; +task4Params.priority = 14; +Program.global.button = Task.create("&button_task", task4Params); +var mailbox0Params = new Mailbox.Params(); +mailbox0Params.instance.name = "button_mailbox"; +Program.global.button_mailbox = Mailbox.create(1, 9, mailbox0Params); +var task5Params = new Task.Params(); +task5Params.instance.name = "user_input"; +task5Params.priority = 4; +Program.global.user_input = Task.create("&handle_user_input", task5Params);