This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

cap sense and Tiva

Hi,

Is there dedicated IO for cap sense on Tiva - if not is there a software library. Everything I see seems to be for the MSP430.

Cheers

CAlum

  • Calum,

    There is not dedicated I/O for cap sense on Tiva, and the closeset thing we have to software would be an capsense booster pack example for the launchpad (compatible with MSP430 and Tiva) which is included in TivaWare for the launchpad. If you have TivaWare installed, the example would be located under examples/boards/ek-tm4c123gxl-boost-capsense.

    -Reagan

  • Hi,

    Is there any library for Capacitive touch sensor using MPR121 or CY Capsense available using TIVA C series launchpad been released now?

    -Akella

  • Hello Sowmya,

    No, there is no released for the MPR121 in the current TivaWare

    Regards
    Amit
  • Hi Akella,

    If you're still interested, I have gotten this working on my own project, I can share the code.

    -- Lee
  • Hello Lee,

    How about posting it on the forum with a short You Tube Video Link....

    Regards
    Amit
  • Hi Lee, 

    That'll be great, yes please do share the code here and any other relevant hardware details.

    Thanks !

    Akella

  • Sowmya Akella said:
    You could email it to me

    Indeed - but is it not far better to benefit (many) than to just benefit (one)?

    And emailing requires extra time/effort from this generous poster - seems a sub-optimal (me, me, me) request...

  • An unintended habitual reply seems to have caused this.

    Edited now :)

  • Hello Sowmya

    That sounds in line with forum resources.

    Regards
    Amit
  • Below is the code I used. A few notes to explain the functionality:

    1. I am using a hardware interrupt pin.
    2. My board has four relays controlled by the relayToggle() function. I didn't include this function since I didn't think it would be relevant, you can subsitute any other function you may wish to use.
    3. I use the # key to lock and unlock the keypad, so there is a timer to measure a long press of #, as well as an idle timer to automatically lock the keypad after an idle period.

    Let me know if there are any questions, or suggestions to improve this code. I am not a programmer by training so this is largely kluged together from code I found around the internet and what I've learned about the TM4C over the last few months.

    //!*****************************************************************************
    //! INCLUSIONS
    //!*****************************************************************************
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/debug.h"
    #include "driverlib/fpu.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "uart0stdio.h"				// Console
    #include "uart1stdio.h"				// GSM
    #include "string.h"
    #include "stdio.h"
    #include <stdlib.h>
    #include "driverlib/systick.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "driverlib/i2c.h"
    #include "inc/hw_i2c.h"
    #include "driverlib/timer.h"
    #include <inttypes.h>
    
    //!*****************************************************************************
    //! DEFINITIONS
    //!*****************************************************************************
    #define K1 8				// Electrode 8 is the 1 key,
    #define K2 4				// Electrode 4 is the 2 key, etc...
    #define K3 3
    #define K4 9
    #define K5 5
    #define K6 2
    #define K7 10
    #define K8 6
    #define K9 1
    #define K0 7
    #define KS 11				// * (star)
    #define KP 0				// # (pound or hash)
    #define TOU_THRESH 0x0F		// touch threshold
    #define REL_THRESH 0x09		// release threshold
    
    //!*****************************************************************************
    //! GLOBAL VARIABLES
    //!*****************************************************************************
    char pressedKey;			// Keypad: store which key was last pressed
    bool keysUnlocked = true;	// For locking the keypad
    uint16_t touchedMap;		// Map of key status
    
    //!*****************************************************************************
    //! FUNCTIONS
    //!*****************************************************************************
    
    //*****************************************************************************
    //
    // INITIALIZE I2C MODULE 0
    // Slightly modified version of TI's example code - from:
    // eewiki.net/.../I2C Communication with the TI Tiva TM4C123GXL
    //
    //*****************************************************************************
    void 
    initI2C(void)
    {
    	//reset module
    	ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
    
    	// Configure the pin muxing for I2C0 functions on port B2 and B3.
    	ROM_GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    	ROM_GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    
    	// Select the I2C function for these pins.
    	ROM_GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    	ROM_GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
    	// Enable and initialize the I2C0 master module.  Use the system clock for
    	// the I2C0 module.  The last parameter sets the I2C data transfer rate.
    	// If false the data rate is set to 100kbps and if true the data rate will
    	// be set to 400kbps.
    	ROM_I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
    
    	//clear I2C FIFOs
    	HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000;
    }
    
    //*****************************************************************************
    //
    // READ SPECIFIED REGISTER ON I2C SLAVE
    // From:
    // eewiki.net/.../I2C Communication with the TI Tiva TM4C123GXL
    //
    //*****************************************************************************
    uint32_t 
    I2Creceive(uint32_t slave_addr, uint8_t reg)
    {
        //specify that we are writing (a register address) to the
        //slave device
        I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);
     
        //specify register to be read
        I2CMasterDataPut(I2C0_BASE, reg);
     
        //send control byte and register address byte to slave device
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
         
        //wait for MCU to finish transaction
        while(I2CMasterBusy(I2C0_BASE));
         
        //specify that we are going to read from slave device
        I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true);
         
        //send control byte and read from the register we
        //specified
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
         
        //wait for MCU to finish transaction
        while(I2CMasterBusy(I2C0_BASE));
         
        //return data pulled from the specified register
        return I2CMasterDataGet(I2C0_BASE);
    }
    
    //*****************************************************************************
    //
    // WRITE TO SPECIFIED REGISTER ON I2C SLAVE
    // From:
    // eewiki.net/.../I2C Communication with the TI Tiva TM4C123GXL
    //
    //*****************************************************************************
    void 
    I2Csend(uint8_t slave_addr, uint8_t num_of_args, ...)
    {
        // Tell the master module what address it will place on the bus when
        // communicating with the slave.
        I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false);
         
        //stores list of variable number of arguments
        va_list vargs;
         
        //specifies the va_list to "open" and the last fixed argument
        //so vargs knows where to start looking
        va_start(vargs, num_of_args);
         
        //put data to be sent into FIFO
        I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t));
         
        //if there is only one argument, we only need to use the
        //single send I2C function
        if(num_of_args == 1)
        {
            //Initiate send of data from the MCU
            I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
             
            // Wait until MCU is done transferring.
            while(I2CMasterBusy(I2C0_BASE));
             
            //"close" variable argument list
            va_end(vargs);
        }
         
        //otherwise, we start transmission of multiple bytes on the
        //I2C bus
        else
        {
            //Initiate send of data from the MCU
            I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
             
            // Wait until MCU is done transferring.
            while(I2CMasterBusy(I2C0_BASE));
             
            //send num_of_args-2 pieces of data, using the
            //BURST_SEND_CONT command of the I2C module
            for(uint8_t i = 1; i < (num_of_args - 1); i++)
            {
                //put next piece of data into I2C FIFO
                I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t));
                //send next data that was just placed into FIFO
                I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
         
                // Wait until MCU is done transferring.
                while(I2CMasterBusy(I2C0_BASE));
            }
         
            //put last piece of data into I2C FIFO
            I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t));
            //send next data that was just placed into FIFO
            I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
            // Wait until MCU is done transferring.
            while(I2CMasterBusy(I2C0_BASE));
             
            //"close" variable args list
            va_end(vargs);
        }
    }
    
    //*****************************************************************************
    //
    // INITIALIZE MPR121
    //
    //*****************************************************************************
    void 
    initMPR121(void)
    {
    	I2Csend(0x5A,2,0x80, 0x63);			// Soft reset
    	
    	// Set thresholds and other control values
    	I2Csend(0x5A,2,0x2B, 0x01);			// MHD_R
    	I2Csend(0x5A,2,0x2C, 0x01);			// NHD_R
    	I2Csend(0x5A,2,0x2D, 0x00);			// NCL_R
    	I2Csend(0x5A,2,0x2E, 0x00);			// FDL_R
    	I2Csend(0x5A,2,0x2F, 0x01);			// MHD_F
    	I2Csend(0x5A,2,0x30, 0x01);			// NHD_F
    	I2Csend(0x5A,2,0x31, 0x7F);			// NCL_F
    	I2Csend(0x5A,2,0x32, 0x09);			// FDL_F
    	I2Csend(0x5A,2,0x41, TOU_THRESH);	// ELE0_T
    	I2Csend(0x5A,2,0X42, REL_THRESH);	// ELE0_R
    	I2Csend(0x5A,2,0x43, TOU_THRESH);	// ELE1_T
    	I2Csend(0x5A,2,0X44, REL_THRESH);	// ELE1_R
    	I2Csend(0x5A,2,0x45, TOU_THRESH);	// ELE2_T
    	I2Csend(0x5A,2,0X46, REL_THRESH);	// ELE2_R
    	I2Csend(0x5A,2,0x47, TOU_THRESH);	// ELE3_T
    	I2Csend(0x5A,2,0X48, REL_THRESH);	// ELE3_R
    	I2Csend(0x5A,2,0x49, TOU_THRESH);	// ELE4_T
    	I2Csend(0x5A,2,0X4A, REL_THRESH);	// ELE4_R
    	I2Csend(0x5A,2,0x4B, TOU_THRESH);	// ELE5_T
    	I2Csend(0x5A,2,0X4C, REL_THRESH);	// ELE5_R
    	I2Csend(0x5A,2,0x4D, TOU_THRESH);	// ELE6_T
    	I2Csend(0x5A,2,0X4E, REL_THRESH);	// ELE6_R
    	I2Csend(0x5A,2,0x4F, TOU_THRESH);	// ELE7_T
    	I2Csend(0x5A,2,0X50, REL_THRESH);	// ELE7_R
    	I2Csend(0x5A,2,0x51, TOU_THRESH);	// ELE8_T
    	I2Csend(0x5A,2,0X52, REL_THRESH);	// ELE8_R
    	I2Csend(0x5A,2,0x53, TOU_THRESH);	// ELE9_T
    	I2Csend(0x5A,2,0X54, REL_THRESH);	// ELE9_R
    	I2Csend(0x5A,2,0x55, TOU_THRESH);	// ELE10_T
    	I2Csend(0x5A,2,0X56, REL_THRESH);	// ELE10_R
    	I2Csend(0x5A,2,0x57, TOU_THRESH);	// ELE11_T
    	I2Csend(0x5A,2,0X58, REL_THRESH);	// ELE11_R
    	I2Csend(0x5A,2,0x5D, 0x04);			// FIL_CFG
    	
    	// Turn on all 12 electrodes and enter run mode
    	I2Csend(0x5A,2,0x5E, 0x0C);			// ELE_CFG
    }
    
    //*****************************************************************************
    //
    // TOGGLE KEYPAD LOCK
    //
    //*****************************************************************************
    void 
    toggleKeylock(void)
    {
    	if (keysUnlocked) {
    		keysUnlocked = false;
    		GPIOPinWrite(GPIO_PORTF_BASE, LED_MAP, 0);
    		GPIOPinWrite(GPIO_PORTF_BASE, RD_LED, RD_LED);
    		UART0printf("\n\r> KEYPAD LOCKED");
    	}
    	else{
    		keysUnlocked = true;
    		GPIOPinWrite(GPIO_PORTF_BASE, LED_MAP, 0);
    		GPIOPinWrite(GPIO_PORTF_BASE, GN_LED, GN_LED);
    		UART0printf("\n\r> KEYPAD UNLOCKED");
    	}
    }
    
    //!*****************************************************************************
    //! INTERRUPT HANDLERS
    //!*****************************************************************************
    
    //*****************************************************************************
    //
    // MPR121 INTERRUPT HANDLER 
    // Modifed from Arduino code. Interrupt is active low on PC7.
    //
    //*****************************************************************************
    void
    MPR121IntHandler(void)
    {
    	int touchNumber = 0;
    	int j;
    	uint32_t touchedLSB, touchedMSB;
    	
    	// Get the status of the electrodes
    	touchedLSB = I2Creceive(0x5A,0x00);
    	touchedMSB = I2Creceive(0x5A,0x01);
    	touchedMap = ((touchedMSB << 8) | touchedLSB);
    
    	// Check how many electrodes were pressed
    	for (j=0; j<12; j++) { if ((touchedMap & (1<<j))) { touchNumber++; } }
    	// If one electrode was pressed, register it
    	if (touchNumber == 1) {
    		if (touchedMap & (1<<K1)){ 
    			pressedKey = '1'; 
    			if (keysUnlocked ) { relayToggle(1); }
    		}
    		else if (touchedMap & (1<<K2)){ 
    			pressedKey = '2'; 
    			if (keysUnlocked ) { relayToggle(2); }
    		}
    		else if (touchedMap & (1<<K3)){ 
    			pressedKey = '3'; 
    			if (keysUnlocked ) { relayToggle(3); }
    		}
    		else if (touchedMap & (1<<K4)){ 
    			pressedKey = '4'; 
    			if (keysUnlocked ) { relayToggle(4); }
    		}
    		else if (touchedMap & (1<<K5)) { pressedKey = '5'; }
    		else if (touchedMap & (1<<K6)) { pressedKey = '6'; }
    		else if (touchedMap & (1<<K7)) { pressedKey = '7'; }
    		else if (touchedMap & (1<<K8)) { pressedKey = '8'; }
    		else if (touchedMap & (1<<K9)) { pressedKey = '9'; }
    		else if (touchedMap & (1<<K0)) { pressedKey = '0'; }
    		else if (touchedMap & (1<<KS)) { pressedKey = '*'; }
    		else if (touchedMap & (1<<KP)) { 
    			pressedKey = '#';
    			ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ROM_SysCtlClockGet()* 2);
    			ROM_TimerEnable(TIMER0_BASE, TIMER_A);
    		}
    		if (keysUnlocked) { 
    			UART0printf("\n\r> %c",pressedKey); 
    			ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet()* 15);
    			ROM_TimerEnable(TIMER1_BASE, TIMER_A);
    		}
    	}
    	// If one electrode was released
    	else if (touchNumber == 0) {}
    	// Do nothing if more than one button is pressed
    	else {}
    	
    	// Clear the asserted interrupts.
    	GPIOIntClear(GPIO_PORTC_BASE, GPIO_PIN_7);
    }
    
    //*****************************************************************************
    //
    // KEYPRESS TIMER INTERRUPT HANDLER
    //
    //*****************************************************************************
    void
    KeyPressTimer0IntHandler(void)
    {
        // Clear the timer interrupt.
    	ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	
    	// Disable the timer
    	ROM_TimerDisable(TIMER0_BASE, TIMER_A);
    
    	// The timer is up! If # is still being pressed, toggle keysUnlocked
    	if (touchedMap & (1<<KP)) { 
    		if (keysUnlocked){ 
    			toggleKeylock();
    		}
    		else { 
    			toggleKeylock();
    			ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet()* 15);
    			ROM_TimerEnable(TIMER1_BASE, TIMER_A);
    		}
    	}
    }
    
    //*****************************************************************************
    //
    // KEYPAD IDLE TIMER INTERRUPT HANDLER
    //
    //*****************************************************************************
    void
    KeyIdleTimer1IntHandler(void)
    {
        // Clear the timer interrupt.
    	ROM_TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	
    	// Disable the timer
    	ROM_TimerDisable(TIMER1_BASE, TIMER_A);
    
    	// The timer is up! Lock the keypad
    	if (keysUnlocked){ toggleKeylock(); }
    }
    
    //!*****************************************************************************
    //! THE PROGRAM
    //!*****************************************************************************
    int
    main(void)
    {
    	// Initial settings
    	ROM_FPUEnable();											// Enable floating point unit
    	ROM_FPULazyStackingEnable();								// Enable lazy stacking of FPU
    	ROM_IntMasterEnable();										// Enable processor interrupts
    	
    	// Enable device clocking
    	ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
    	
    	// Enable system peripherals
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);			// Pins: I2C0SCL, I2C0SDA
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);			// Pins: Keypad interrupt (INT2)
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);			// Timer for keylock
    	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);			// Timer for keypad timeout
    	
    	// Set up the timers used to lock/unlock the keypad
    	ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_ONE_SHOT);
    	ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_ONE_SHOT);
    	ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, ROM_SysCtlClockGet()* 15);
    	// Setup the interrupts for the timer timeouts
    	ROM_IntEnable(INT_TIMER0A);
    	ROM_IntEnable(INT_TIMER1A);
    	ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
    	ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
    	
    	// Start I2C module
    	initI2C();
    
    	// Enable the I2C interrupt
    	ROM_GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_7);			// Set pin C7 as input
    	ROM_GPIOPadConfigSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);	// Pullup
    	GPIOIntDisable(GPIO_PORTC_BASE, GPIO_PIN_7);					// Disable interrupt for PC7
    	GPIOIntClear(GPIO_PORTC_BASE, GPIO_PIN_7);						// Clear pending interrupts for PC7
    	GPIOIntRegister(GPIO_PORTC_BASE, MPR121IntHandler);				// Register port C interrupt handler
    	GPIOIntTypeSet(GPIO_PORTC_BASE, GPIO_PIN_7, GPIO_LOW_LEVEL);	// Configure PC7 for falling edge
    	GPIOIntEnable(GPIO_PORTC_BASE, GPIO_PIN_7); 					// Enable interrupt
    	
    	// Start the MPR121 and set thresholds
    	initMPR121();
    	
    	// Enable the timeout timer
    	ROM_TimerEnable(TIMER1_BASE, TIMER_A);
    	
    	while(1){}
    }