From e018ceebed74b8223482bc9d1ed0b31c938381da Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Mon, 29 Oct 2012 23:04:19 +0200 Subject: New example files --- .../capsense/capsense.c | 604 +++++++++++++++++++++ 1 file changed, 604 insertions(+) create mode 100644 boards/ek-lm4f120xl-boost-capsense/capsense/capsense.c (limited to 'boards/ek-lm4f120xl-boost-capsense/capsense/capsense.c') diff --git a/boards/ek-lm4f120xl-boost-capsense/capsense/capsense.c b/boards/ek-lm4f120xl-boost-capsense/capsense/capsense.c new file mode 100644 index 0000000..bf2afdc --- /dev/null +++ b/boards/ek-lm4f120xl-boost-capsense/capsense/capsense.c @@ -0,0 +1,604 @@ +//***************************************************************************** +// +// capsense.c - Capacitive touch example. +// +// Copyright (c) 2011-2012 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 9453 of the EK-LM4F120XL Firmware Package. +// +//***************************************************************************** + +#include +#include "inc/hw_types.h" +#include "inc/hw_gpio.h" +#include "inc/hw_memmap.h" +#include "inc/hw_nvic.h" +#include "driverlib/fpu.h" +#include "driverlib/sysctl.h" +#include "driverlib/rom.h" +#include "driverlib/pin_map.h" +#include "driverlib/gpio.h" +#include "driverlib/systick.h" +#include "driverlib/interrupt.h" +#include "driverlib/uart.h" +#include "utils/uartstdio.h" +#include "drivers/buttons.h" + +#include "drivers/CTS_structure.h" +#include "drivers/CTS_Layer.h" + +//***************************************************************************** +// +//! \addtogroup example_list +//!

Capacitive Touch Example (capsense)

+//! +//! An example that works with the 430BOOST-SENSE1 capactive sense +//! BoosterPack, originally designed for the MSP430 LaunchPad. +//! +//! The Stellaris LM4F120H5QR does not have the capacitive sense hardware +//! assisted peripheral features of some MSP430 chips. Therefore it is +//! required that the user install surface mount resistors on the pads +//! provided on the bottom of the capacitive sense BoosterPack. Resistor values +//! of 30 ohms are recommended. Calibration may be required for +//! resistor values other than 30 ohms. +//! +// +//***************************************************************************** + + +//***************************************************************************** +// +// Macro definitions +// +//***************************************************************************** +#define TESTMODE +#define NUM_OSCILLATIONS 100 + +#define WAKE_UP_UART_CODE 0xBE +#define WAKE_UP_UART_CODE2 0xEF +#define SLEEP_MODE_UART_CODE 0xDE +#define SLEEP_MODE_UART_CODE2 0xAD +#define MIDDLE_BUTTON_CODE 0x80 +#define INVALID_CONVERTED_POSITION 0xFD +#define GESTURE_START 0xFC +#define GESTURE_STOP 0xFB +#define COUNTER_CLOCKWISE 1 +#define CLOCKWISE 2 +#define GESTURE_POSITION_OFFSET 0x20 +#define WHEEL_POSITION_OFFSET 0x30 + +#define WHEEL_TOUCH_DELAY 12 +#define MAX_IDLE_TIME 200 +#define PROXIMITY_THRESHOLD 60 + + +//***************************************************************************** +// +// Global variables +// +//***************************************************************************** +unsigned long g_ulUpBaseline = 0; +unsigned long g_ulDownBaseline = 0; +unsigned long g_ulLeftBaseline = 0; +unsigned long g_ulRightBaseline = 0; +unsigned long g_ulCenterBaseline = 0; +unsigned long g_ulWheelPosition = ILLEGAL_SLIDER_WHEEL_POSITION; +unsigned long ulPreviousWheelPosition = ILLEGAL_SLIDER_WHEEL_POSITION; + + +//***************************************************************************** +// +// The error routine that is called if the driver library encounters an error. +// +//***************************************************************************** +#ifdef DEBUG +void +__error__(char *pcFilename, unsigned long ulLine) +{ +} +#endif + +//***************************************************************************** +// +// Delay for count milliseconds +// +//***************************************************************************** +void +DelayMs(unsigned long ulCount) +{ + SysCtlDelay((SysCtlClockGet()/3000)*ulCount); +} + +//***************************************************************************** +// +// Abstraction for LED output. +// +//***************************************************************************** +void +LEDOutput(unsigned long ulWheelPosition) +{ + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + GPIOPinTypeGPIOInput(GPIO_PORTE_BASE, GPIO_PIN_5); + GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_7); + + switch(ulWheelPosition) + { + case 0: + break; + case 1: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_PIN_4); + GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5); + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, 0); + break; + case 2: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_PIN_4); + GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5); + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, 0); + //P1-5OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, 0); + break; + case 3: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_PIN_4); + //P1-5OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, 0); + break; + case 4: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_PIN_4); + //P1-5OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, 0); + //P1-6OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, 0); + break; + case 5: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_PIN_4); + //P1-6OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, 0); + break; + case 6: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_PIN_4); + //P1-6OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, 0); + //P1-7OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_7, 0); + break; + case 7: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, GPIO_PIN_4); + //P1-7OFF + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_7, 0); + break; + case 8: + break; + case 9: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + //P1-7ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_7, GPIO_PIN_7); + break; + case 10: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + //P1-7ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_7, GPIO_PIN_7); + //P1-6ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, GPIO_PIN_6); + break; + case 11: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + //P1-6ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, GPIO_PIN_6); + break; + case 12: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + //P1-6ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_6, GPIO_PIN_6); + //P1-5ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_PIN_4); + break; + case 13: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + //P1-5ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_PIN_4); + break; + case 14: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + //P1-5ON + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_4, GPIO_PIN_4); + //P1-4ON + GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5); + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, GPIO_PIN_5); + break; + case 15: + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_4, 0); + //P1-4ON + GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5); + GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_5, GPIO_PIN_5); + break; + default: + break; + } +} +//***************************************************************************** +// +// Get Gesture. +// +//***************************************************************************** +unsigned char GetGesture(unsigned char ulWheelPosition) +{ + unsigned char gesture = INVALID_CONVERTED_POSITION; + unsigned char ucDirection, ccw_check, cw_check; + + if(ulPreviousWheelPosition != ILLEGAL_SLIDER_WHEEL_POSITION) + { + if(ulPreviousWheelPosition > ulWheelPosition) + { + ccw_check = ulPreviousWheelPosition - ulWheelPosition; + if(ccw_check < 8) + { + gesture = ccw_check; + ucDirection = COUNTER_CLOCKWISE; + } + else + { + cw_check = 16 - ulPreviousWheelPosition + ulWheelPosition; + if(cw_check < 8) + { + gesture = cw_check; + ucDirection = CLOCKWISE; + } + } + } + else + { + cw_check = ulWheelPosition - ulPreviousWheelPosition; + if(cw_check < 8) + { + gesture = cw_check; + ucDirection = CLOCKWISE; + } + else + { + ccw_check = 16 + ulPreviousWheelPosition - ulWheelPosition; + if(ccw_check < 8) + { + gesture = ccw_check; + ucDirection = COUNTER_CLOCKWISE; + } + } + } + } + if(gesture == INVALID_CONVERTED_POSITION) + return gesture; + if(ucDirection == COUNTER_CLOCKWISE) + return(gesture + 16); + else + return gesture; +} +//***************************************************************************** +// +// Main cap-touch example. +// +//***************************************************************************** +int +main(void) +{ + unsigned char ucCenterButtonTouched; + unsigned long ulWheelTouchCounter; + unsigned char ucConvertedWheelPosition; + unsigned char ucGestureDetected; + + // + // 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_FPUEnable(); + 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 + // + GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_4); + GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, GPIO_PIN_5); + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_4); + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_6); + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_7); + GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_5); + + // + // Turn on the Center LED + // + 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); + UARTStdioInitExpClk(0,9600); + + // + // First, I'm configuring the pins as outputs to take care of all of the + // non-recurring setup. + // + ROM_SysCtlGPIOAHBEnable(SYSCTL_PERIPH_GPIOA); + GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_2); + GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_3); + GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_4); + GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_6); + GPIOPinTypeGPIOOutput(GPIO_PORTA_AHB_BASE, GPIO_PIN_7); + + // + // Start up Systick to measure time + // + SysTickPeriodSet(0x00FFFFFF); + SysTickEnable(); + + // + // Set the baseline capacitance measurements for our wheel and center + // button. + // + TI_CAPT_Init_Baseline(&g_sSensorWheel); + TI_CAPT_Update_Baseline(&g_sSensorWheel,2); + TI_CAPT_Init_Baseline(&g_sMiddleButton); + TI_CAPT_Update_Baseline(&g_sMiddleButton,2); + + // + // Send the Sleep code + // + UARTprintf("\0xDE\0xAD"); + + // + // Perform the LED startup sequence, and tell the GUI we're alive. + // + UARTprintf("\0xBE\0xEF"); + + // + // Assume that the center button starts off "untouched", the wheel has no + // position, and no gestures are in progress. + // + ucCenterButtonTouched = 0; + ucConvertedWheelPosition = INVALID_CONVERTED_POSITION; + ucGestureDetected = 0; + + // + // Set the wheel counter for the default delay period. + // + ulWheelTouchCounter = WHEEL_TOUCH_DELAY - 1; + + // + // Go into active mode. + // + while(1) + { + g_ulWheelPosition = ILLEGAL_SLIDER_WHEEL_POSITION; + g_ulWheelPosition = TI_CAPT_Wheel(&g_sSensorWheel); + + if(g_ulWheelPosition != ILLEGAL_SLIDER_WHEEL_POSITION) + { + ucCenterButtonTouched = 0; + + if(g_ulWheelPosition < 0x08) + { + g_ulWheelPosition += 0x40 - 0x08; + } + else + { + g_ulWheelPosition -= 0x08; + } + + g_ulWheelPosition = g_ulWheelPosition >> 2; + + ucConvertedWheelPosition = GetGesture(g_ulWheelPosition); + + // + // Add hysteresis to reduce toggling between g_sSensorWheel + // positions if no gesture has been TRULY detected. + // + if((ucGestureDetected==0) && ((ucConvertedWheelPosition<=1) || + (ucConvertedWheelPosition==0x11) || + (ucConvertedWheelPosition==0x10))) + { + if (ulPreviousWheelPosition != ILLEGAL_SLIDER_WHEEL_POSITION) + g_ulWheelPosition = ulPreviousWheelPosition; + ucConvertedWheelPosition = 0; + } + + // + //Turn on corresponding LED(s) + // + LEDOutput(g_ulWheelPosition); + + // + // A gesture has been detected + // + if((ucConvertedWheelPosition != 0) && + (ucConvertedWheelPosition != 16) && + (ucConvertedWheelPosition != INVALID_CONVERTED_POSITION)) + { + // + // Starting of a new gesture sequence + // + if (ucGestureDetected ==0) + { + ucGestureDetected = 1; + + // + // Transmit gesture start status update & position via UART + // to PC + // + UARTCharPut(UART0_BASE, GESTURE_START); + UARTCharPut(UART0_BASE,ulPreviousWheelPosition + + GESTURE_POSITION_OFFSET); + } + + // + // Transmit gesture & position via UART to PC + // + UARTCharPut(UART0_BASE,ucConvertedWheelPosition); + UARTCharPut(UART0_BASE,g_ulWheelPosition + + GESTURE_POSITION_OFFSET); + } + else + { + // + // If no gesture was detected, this is constituted as a + // touch/tap + // + if (ucGestureDetected==0) + { + if (++ulWheelTouchCounter >= WHEEL_TOUCH_DELAY) + { + // + // Transmit wheel position [twice] via UART to PC + // + ulWheelTouchCounter = 0; + UARTCharPut(UART0_BASE,g_ulWheelPosition + + WHEEL_POSITION_OFFSET); + UARTCharPut(UART0_BASE,g_ulWheelPosition + + WHEEL_POSITION_OFFSET); + } + } + else + { + ulWheelTouchCounter = WHEEL_TOUCH_DELAY - 1; + } + } + + ulPreviousWheelPosition = g_ulWheelPosition; + } + else + { + // + // no wheel position was detected + // + + if(TI_CAPT_Button(&g_sMiddleButton)) + { + // + // Middle button was touched + // + if (ucCenterButtonTouched==0) + { + // + // Transmit center button code [twice] via UART to PC + // + UARTCharPut(UART0_BASE,MIDDLE_BUTTON_CODE); + UARTCharPut(UART0_BASE,MIDDLE_BUTTON_CODE); + + ucCenterButtonTouched = 1; + + if(GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_5)) + { + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, 0); + } + else + { + GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_5, GPIO_PIN_5); + } + } + } + else + { + // + // No touch was registered at all [Not wheel or center button] + // + ucCenterButtonTouched = 0; + + if((ucConvertedWheelPosition == INVALID_CONVERTED_POSITION) || + (ucGestureDetected ==0)) + { + // + // No gesture was registered previously + // + if(ulPreviousWheelPosition != + ILLEGAL_SLIDER_WHEEL_POSITION) + { + // + // Transmit last wheel position [twice] via UART to PC + // + UARTCharPut(UART0_BASE,ulPreviousWheelPosition + + WHEEL_POSITION_OFFSET ); + UARTCharPut(UART0_BASE,ulPreviousWheelPosition + + WHEEL_POSITION_OFFSET ); + ulWheelTouchCounter = WHEEL_TOUCH_DELAY - 1; + } + } + + if (ucGestureDetected == 1) + { + // + // A gesture was registered previously + // + + // + // Transmit status update: stop gesture tracking [twice] + // via UART to PC + // + UARTCharPut(UART0_BASE,GESTURE_STOP); + UARTCharPut(UART0_BASE,GESTURE_STOP); + } + + } + + // + // Reset all touch conditions, turn off LEDs, + // + LEDOutput(0); + ulPreviousWheelPosition= ILLEGAL_SLIDER_WHEEL_POSITION; + ucConvertedWheelPosition = INVALID_CONVERTED_POSITION; + ucGestureDetected = 0; + + } + + // + // Option: Add delay/sleep cycle here to reduce active duty cycle. This + // lowers power consumption but sacrifices wheel responsiveness. + // Additional timing refinement must be taken into consideration when + // interfacing with PC applications GUI to retain proper communication + // protocol. + // + + DelayMs(50); + + } +} -- cgit v1.3.1