//*****************************************************************************
//
// Main cap-touch example.
//
//*****************************************************************************
int
main(void)
{
    uint8_t ui8CenterButtonTouched;
    uint32_t ui32WheelTouchCounter;
    uint8_t ui8ConvertedWheelPosition;
    uint8_t ui8GestureDetected;
    uint8_t ui8Loop;

    //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPULazyStackingEnable();

    //
    // Set the clocking to run directly from the PLL at 80 MHz.
    //
    ROM_SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |
                       SYSCTL_OSC_MAIN);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);

    //
    // Initialize a few GPIO outputs for the LEDs
    //
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_4);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_5);

    //
    // Turn on the Center LED
    //
    ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_PIN_5);

    //
    // Initialize the UART.
    //
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
    UARTStdioConfig(0, 9600, ROM_SysCtlClockGet());

    //
    // Configure the pins needed for capacitive touch sensing.  The capsense
    // driver assumes that these pins are already configured, and that they
    // will be accessed through the AHB bus
    //
    SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPIOA);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_2);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_3);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_4);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_6);
    ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_7);

    //
    // Start up Systick to measure time.  This is also required by the capsense
    // drivers.
    //
    ROM_SysTickPeriodSet(0x00FFFFFF);
    ROM_SysTickEnable();

    //
    // Set the baseline capacitance measurements for our wheel and center
    // button.
    //
    TI_CAPT_Init_Baseline(&g_sSensorWheel);
    TI_CAPT_Update_Baseline(&g_sSensorWheel, 10);
    TI_CAPT_Init_Baseline(&g_sMiddleButton);
    TI_CAPT_Update_Baseline(&g_sMiddleButton, 10);

    //
    // Send the "sleep" code.  The TIVA C-series version of this app doesn't
    // actually sleep, but the MSP430-based GUI it interacts with expects to
    // see this code on startup, so we will provide it here.
    //
    UARTprintf("\0xDE\0xAD");

    //
    // Send the "awake" code.
    //
    UARTprintf("\0xBE\0xEF");

    //
    // Perform an LED startup sequence.
    //
    for(ui8Loop = 0; ui8Loop < 16; ui8Loop++)
    {
        LEDOutput(ui8Loop);
        DelayMs(10);
    }

    LEDOutput(0);


    //
    // Assume that the center button starts off "untouched", the wheel has no
    // position, and no gestures are in progress.
    //
    ui8CenterButtonTouched = 0;
    ui8ConvertedWheelPosition = INVALID_CONVERTED_POSITION;
    ui8GestureDetected = 0;

    //
    // This "wheel counter" gets incremented when a button on the wheel is held
    // down.  Every time it hits the value of WHEEL_TOUCH_DELAY, the device
    // sends a signal to the GUI reporting another button press.  We want this
    // delay normally, but we'll set the counter to just below the threshold
    // for now, so we'll avoid any percieved lag between the initial button
    // press and the first position report to the GUI.
    //
    ui32WheelTouchCounter = WHEEL_TOUCH_DELAY - 1;

    //
    // Begin the main capsense loop.
    //
    while(1)
    {
        //
        // Start by taking a fresh measurement from the wheel.  If it remains
        // set to ILLEGAL_SLIDER_WHEEL_POSITION, we will know it has not been
        // touched at all.  Otherwise we will have an updated position.
        //
        g_ui32WheelPosition = ILLEGAL_SLIDER_WHEEL_POSITION;
        g_ui32WheelPosition = TI_CAPT_Wheel(&g_sSensorWheel);

        //
        // If we registered a touch somewhere on the wheel, we will need to
        // figure out how to report that touch back to the GUI on the PC.
        //
        if(g_ui32WheelPosition != ILLEGAL_SLIDER_WHEEL_POSITION)
        {
            //
            // First, make sure we're not reporting center button touches while
            // the wheel is active.
            //
            ui8CenterButtonTouched = 0;

            //
            // We need to do a quick formatting change on the wheel position.
            // The "zero" postion as reported by the driver is about 40 degrees
            // off from "up" on the physical wheel.  We'll do that correction
            // here.
            //
            if(g_ui32WheelPosition < 8)
            {
                g_ui32WheelPosition += 64 - 8;
            }
            else
            {
                g_ui32WheelPosition -= 8;
            }

            //
            // We also need to reduce the effective number of positions on the
            // wheel.  The driver reports a wheel position from zero to
            // sixty-three, but the GUI only recognizes positions from zero to
            // sixteen.  Dividing our position by four accomplishes the
            // necessary conversion.
            //
            g_ui32WheelPosition = g_ui32WheelPosition >> 2;

            //
            // Now that we have a properly formatted wheel position, we will
            // use the GetGesture function to determine whether the user has
            // been sliding their finger around the wheel.  If so, this function
            // will return the magnitude and direction of the slide (Check the
            // function description for an example of how this is formated).
            // Otherwise, we will get back a zero.
            //
            ui8ConvertedWheelPosition = GetGesture(g_ui32WheelPosition);

            //
            // If the magnitude of our slide was one wheel position (of
            // sixteen) or less, don't register it.  This prevents excessive
            // reporting of toggles between two adjacent wheel positions.
            //
            if((ui8GestureDetected == 0) &&
               ((ui8ConvertedWheelPosition <= 1) ||
                (ui8ConvertedWheelPosition == 0x11) ||
                (ui8ConvertedWheelPosition == 0x10)))
            {
                //
                // If we obtained a valid wheel position last time we ran this
                // loop, keep our wheel position set to that instead of
                // updating it.  This prevents a mismatch between our recorded
                // absolute position and our recorded swipe magnitude.
                //
                if(g_ui32PreviousWheelPosition !=
                   ILLEGAL_SLIDER_WHEEL_POSITION)
                {
                    g_ui32WheelPosition = g_ui32PreviousWheelPosition;
                }

                //
                // Set the swipe magnitude to zero.
                //
                ui8ConvertedWheelPosition = 0;
            }

            //
            // We've made all of the position adjustments we're going to make,
            // so turn on LEDs to indicate that we've detected a finger on the
            // wheel.
            //
            LEDOutput(g_ui32WheelPosition);

            //
            // If the (adjusted) magnitude of the swipe we detected earlier is
            // valid and non-zero, we should alert the GUI that a gesture is
            // occurring.
            //
            if((ui8ConvertedWheelPosition != 0) &&
               (ui8ConvertedWheelPosition != 16) &&
               (ui8ConvertedWheelPosition != INVALID_CONVERTED_POSITION))
            {
                //
                // If this is a new gesture, we will need to send the gesture
                // start code.
                //
                if(ui8GestureDetected == 0)
                {
                    //
                    // Remember that we've started a gesture.
                    //
                    ui8GestureDetected = 1;

                    //
                    // Transmit gesture start status update & position via UART
                    // to PC.
                    //
                    ROM_UARTCharPut(UART0_BASE, GESTURE_START);
                    ROM_UARTCharPut(UART0_BASE, (g_ui32PreviousWheelPosition +
                                                 GESTURE_POSITION_OFFSET));
                }

                //
                // Transmit gesture & position via UART to PC
                //
                ROM_UARTCharPut(UART0_BASE, ui8ConvertedWheelPosition);
                ROM_UARTCharPut(UART0_BASE, (g_ui32WheelPosition +
                                             GESTURE_POSITION_OFFSET));
            }
            else
            {
                //
                // If we get here, the wheel has been touched, but there hasn't
                // been any sliding recently.  If there hasn't been any sliding
                // AT ALL, then this is a "press" event, and we need to start
                // sending press-style updates to the PC
                //
                if(ui8GestureDetected == 0)
                {
                    //
                    // Increment our wheel counter.
                    //
                    ui32WheelTouchCounter = ui32WheelTouchCounter + 1;

                    //
                    // If the user's finger is still in the same place...
                    //
                    if(ui32WheelTouchCounter >= WHEEL_TOUCH_DELAY)
                    {
                        //
                        // Transmit wheel position (twice) via UART to PC.
                        //
                        ui32WheelTouchCounter = 0;
                        ROM_UARTCharPut(UART0_BASE, (g_ui32WheelPosition +
                                                     WHEEL_POSITION_OFFSET));
                        ROM_UARTCharPut(UART0_BASE, (g_ui32WheelPosition +
                                                     WHEEL_POSITION_OFFSET));
                    }
                }
                else
                {
                    //
                    // We've received a slide input somewhat recently, but not
                    // during this loop instance.  This most likely means that
                    // the user started a gesture, but is currently just
                    // holding their finger in one spot.  This isn't really a
                    // "press" event, so there isn't anything to report.  We
                    // should, however, make sure the touch counter is primed
                    // for future press events.
                    //
                    ui32WheelTouchCounter = WHEEL_TOUCH_DELAY - 1;
                }
            }

            //
            // Regardless of all pressing, sliding, reporting, and LED events
            // that may have occurred, we need to record our measured
            // (adjusted) wheel position for reference for the next pass
            // through the loop.
            //
            g_ui32PreviousWheelPosition = g_ui32WheelPosition;
        }
        else
        {
            //
            // If we get here, there were no touches recorded on the slider
            // wheel.  We should check our middle button to see if it has been
            // pressed, and clean up our recorded state to prepare for future
            // possible wheel-touch events.
            //
            if(TI_CAPT_Button(&g_sMiddleButton))
/* ----------------CapTouchActiveMode----------------------------------------------
 * Determine immediate gesture based on current & previous wheel position
 *
 *
 *
 *
 *
 *
 *
 * -------------------------------------------------------------------------------*/
void CapTouchActiveMode()
{
  unsigned char idleCounter, activeCounter;
  unsigned char gesture, gestureDetected;
  unsigned char centerButtonTouched = 0;
  unsigned int wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;


  gesture = INVALID_GESTURE;            // Wipes out gesture history

  /* Send status via UART: 'wake up' = [0xBE, 0xEF] */
  SendByte(WAKE_UP_UART_CODE);
  SendByte(WAKE_UP_UART_CODE2);

  idleCounter = 0;
  activeCounter = 0;
  gestureDetected = 0;

  while (idleCounter++ < MAX_IDLE_TIME)
  {
	/* Set DCO to 8MHz */
	/* SMCLK = 8MHz/8 = 1MHz */
//	BCSCTL1 = CALBC1_8MHZ;
//	DCOCTL = CALDCO_8MHZ;
//	BCSCTL2 |= DIVS_3;

	/* SMCLK = 1MHz/4 = 250kHz */
	BCSCTL1 = CALBC1_1MHZ;
	DCOCTL = CALDCO_1MHZ;
	BCSCTL2 |= DIVS_2;
    TACCTL0 &= ~CCIE;

    wheel_position = ILLEGAL_SLIDER_WHEEL_POSITION;
    wheel_position = TI_CAPT_Wheel(&wheel);

    /* Process wheel touch/position/gesture  if a wheel touch is registered*/
    /* Wheel processing has higher priority than center button*/

    if(wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
    {
      centerButtonTouched = 0;

      /* Adjust wheel position based: rotate CCW by 2 positions */
      if (wheel_position < 0x08)
      {
         wheel_position += 0x40 - 0x08;
      }
      else
      {
         wheel_position -= 0x08;
            /* Adjust wheel position based: rotate CCW by 2 positions */
      }

      wheel_position = wheel_position >>2;  // divide by four

      gesture = GetGesture(wheel_position);

      /* Add hysteresis to reduce toggling between wheel positions if no gesture
       * has been TRULY detected. */

      if ( (gestureDetected==0) && ((gesture<=1) || (gesture==0x11) || (gesture==0x10)))
      {
        if (last_wheel_position != ILLEGAL_SLIDER_WHEEL_POSITION)
            wheel_position = last_wheel_position;
        gesture = 0;
      }

      /* Turn on corresponding LED(s) */
      P1OUT = (P1OUT & BIT0) | LedWheelPosition[wheel_position];


      if ((gesture != 0) && (gesture != 16) && (gesture != INVALID_GESTURE))
      { /* A gesture has been detected */

        if (gestureDetected ==0)
        { /* Starting of a new gesture sequence */
          gestureDetected = 1;

          /* Transmit gesture start status update & position via UART to PC */
          SendByte(GESTURE_START);
          SendByte(last_wheel_position + GESTURE_POSITION_OFFSET);
        }

        /* Transmit gesture & position via UART to PC */
        SendByte(gesture);
        SendByte(wheel_position + GESTURE_POSITION_OFFSET);
      }
      else
        if (gestureDetected==0)
        { /* If no gesture was detected, this is constituted as a touch/tap */
          if (++wheelTouchCounter >= WHEEL_TOUCH_DELAY)
          {
          	/* Transmit wheel position [twice] via UART to PC */
          	wheelTouchCounter = 0;
          	SendByte(wheel_position + WHEEL_POSITION_OFFSET );
          	SendByte(wheel_position + WHEEL_POSITION_OFFSET );
          }
        }
       	else
          wheelTouchCounter = WHEEL_TOUCH_DELAY - 1;

      idleCounter = 0;                      // Reset idle counter
      activeCounter++;
      last_wheel_position = wheel_position;
    }
    else
    { /* no wheel position was detected */

      if(TI_CAPT_Button(&middle_button))