
#include <platform.h>
#include <xcore/port.h>
#include <xcore/select.h>
#include <xcore/hwtimer.h>
#include <xcore/assert.h>

#include "app_dsp.h"

#define WAIT_TICKS      (5 * XS1_TIMER_KHZ)
#define REFRESH_TICKS   (50 * XS1_TIMER_KHZ) // 20 Hz
#define BTN_IDLE_STATE  7
#define BTN0_PRESSED    6
#define BTN1_PRESSED    5
#define BTN2_PRESSED    3

port_t p_button = XS1_PORT_4E;
port_t p_leds =   XS1_PORT_4F;

void gpio_task(chanend_t c_gpio) {

    port_enable(p_button);
    port_enable(p_leds);
    hwtimer_t tmr = hwtimer_alloc();


    // delay before reading the ports
    hwtimer_set_trigger_time(tmr, hwtimer_get_time(tmr) + WAIT_TICKS);
    hwtimer_get_time(tmr);

    unsigned prev_button_state = 0;
    unsigned button_state = port_in(p_button);
    xassert(button_state == BTN_IDLE_STATE);
    port_set_trigger_in_not_equal(p_button, button_state);

    // VU meter refresh timer
    hwtimer_set_trigger_time(tmr, hwtimer_get_time(tmr) + REFRESH_TICKS);
    

    SELECT_RES(
        CASE_THEN(p_button, on_button_change),
        CASE_THEN(tmr, update_vu)
    ) {
        on_button_change : {
            prev_button_state = button_state;
            button_state = port_in(p_button);

            // Ignore multi-button press
            if(prev_button_state == BTN_IDLE_STATE) {
                if (button_state == BTN0_PRESSED) {
                    chan_out_byte(c_gpio, BASS_BOOST_SW);
                } else if (button_state == BTN1_PRESSED) {
                    chan_out_byte(c_gpio, VOLUME_UP);
                } else if (button_state == BTN2_PRESSED) {
                    chan_out_byte(c_gpio, VOLUME_DOWN);
                }
            }

            port_set_trigger_in_not_equal(p_button, button_state);
            continue;
        }
        update_vu: {
            // get vu
            chan_out_byte(c_gpio, GET_VU_LEVELS);
            uint8_t led_val = chan_in_byte(c_gpio);
            port_out(p_leds, led_val);

            // reset timer
            hwtimer_set_trigger_time(tmr, hwtimer_get_time(tmr) + REFRESH_TICKS);
        }
    }
}
