#include <xc.h>
#include <stdint.h>
#include "system.h"
#include "i2c.h"
#include "msghandler.h"
#include "usb.h"
#include "usb_device_hid.h"
#include "app_led_usb_status.h"
#include "app_device_keyboard.h"

extern uint8_t i2cGestIC_len;

char gesture_char = '\0';

volatile uint8_t mgcSSPintFlag = 0,      //interrupt flags
                i2cTimerIntFlag = 0,
                mgcBCLintFlag = 0;

uint8_t i2cMsgFlag = 0,                 //new i2c message from MGC
        countDownReset = 0,             //wait timers for i2c...
        countDownI2C = 0,
        waitTSline = 0;

void main(void)
{
    SYSTEM_Init();

    USBDeviceInit();
    USBDeviceAttach();
    
    //Enable peripheral and global interrupts
    INTCONbits.PEIE = 1;
    INTCONbits.GIE = 1;

    while(1)
    {
        APP_KeyboardTasks();
        
        //ISR has set flag for I2C bus collision
        if(mgcBCLintFlag) {
            mgcBCLintFlag--;
            i2c_BCLhandler();
        }

        //TS line asserted by MGC3030
        if(!waitTSline && i2c_gestICSignalsI2C()) {
            i2c_TShandler();
        }

        //Want to start a write to MGC3030
        if(!waitTSline && i2cGestIC_len != 0) {
            i2c_startWrite();
        }

        //ISR has set SSP flag to service MGC3030
        if(!waitTSline && mgcSSPintFlag) {
            i2c_runstatemachine();
        }

        //New i2c message from MGC3030 to process
        if(i2cMsgFlag) {
            uint8_t cmd = mgcProcMsg();     //process the message
            i2cMsgFlag = 0;
            if(cmd != GI_NOGESTURE) {
                switch(cmd) {
                    case GI_TAP_WEST:
                    case GI_FLICK_WE:
                        gesture_char = 'a';
                        LED_2 ^= 1;
                        break;

                    case GI_TAP_EAST:
                    case GI_FLICK_EW:
                        gesture_char = 'b';
                        LED_2 ^= 1;
                        break;

                    case GI_TAP_SOUTH:
                    case GI_TAP_CENTER:
                    case GI_FLICK_SN:
                        gesture_char = 'c';
                        LED_2 ^= 1;
                        break;

                    case GI_TAP_NORTH:
                    case GI_FLICK_NS:
                        gesture_char = 'd';
                        LED_2 ^= 1;
                        break;

                    case GI_AIRWHEEL_CCW:
                        gesture_char = 'e';
                        LED_2 ^= 1;
                        break;

                    case GI_AIRWHEEL_CW:
                        gesture_char = 'f';
                        LED_2 ^= 1;
                        break;

                    default: break;
                }
            }
        }
        //ISR has set flag to service I2C timer
        if(i2cTimerIntFlag) {
            i2cTimerIntFlag = 0;
            if(waitTSline) {waitTSline--;}
            if(countDownI2C) {countDownI2C--;}
            if(countDownReset) {countDownReset--;}
        }
    }
}