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.

TSC2046 to Tiva C Launchpad SPI interfacing

Other Parts Discussed in Thread: TSC2046

Hi,

I have been trying to interface the Stellaris Tiva C Launchpad and a LCD and touchscreen. The touchscreen controller is the TSC 2046.

Communication takes place via a SPI interface.

The SPI interface is configured for a clock rate of 1MHz. The SSI data-size is set to 8-bits.

Config for SPI:

  SSI->SSICR1=0x00u;
  SSI->SSIClockPrescale =0x10u;
  SSI->SSICR0&=0xFFC7u;
  SSI->SSICR1=0x02u;

The problem I have is that when I retrieve the x and y co-ordinates the returned values are always zero(0).

The functions I call are shown below:

unsigned int xGetData(void)
{
  unsigned int lbdata, hbdata, data;
  TouchCS=~TouchCS; // Touch Controller CS = 0
  //
  SSI2->SSIData = 0xD0u;
  while ((SSI2->SSIStatus & 16) == 16 ){}; 
  delay_us(2);
  while ((SSI2->SSIStatus & 16) == 16 ){};
  hbdata = SSI2->SSIData;
  lbdata = SSI2->SSIData;
  hbdata = (hbdata << 8);
  data = (hbdata | lbdata); 
  TouchCS=~TouchCS; //Touch controller CS = 1
  return (data >> 4);   
}


unsigned int yGetData(void)
{
  unsigned int lbdata, hbdata, data;
  TouchCS=~TouchCS;
  //
  SSI2->SSIData = 0x90u;
  while ((SSI2->SSIStatus & 16) == 16 ){}; 
  delay_us(2);
  while ((SSI2->SSIStatus & 16) == 16 ){};
  hbdata = SSI2->SSIData;
  lbdata = SSI2->SSIData;
  hbdata = (hbdata << 8);
  data = (hbdata | lbdata); 
  TouchCS=~TouchCS;
  return (data>>4); 
}

I have used an oscilloscope to verify that the command has been sent and the TSC2046 is responding (I don't have a digital analyser so can only use the oscilloscope).

I have used different commands (in sequence - stored into variables and later used to calculate the average value) such as:

0xD1;

0xD1,

0xD0;

when measuring the x coordinate (0x91, 0x90 for the y coordinate) - but to no avail.

Intermittently I get values but these change constantly even when pressing the same location on the screen. The default however is that the x and y coordinates are zero.

I presume that I have incorrectly configured the SPI but I cannt fathom what exactly I have done incorrectly.

Many Thanks,

Carl.

  • Hi Carl,

    Unfortunately , I am not able to verify your code since I am on a business travel now.

    Below is some reference code, which was verified by me in a Cortex M3 platform quite a long time ago.  I think you can compare your code with that code. Hopefully you will be able to fix your issue.

    tsc2046.c
    #include <board.h>
    #include <pio/pio.h>
    #include <spi/spi.h>
    
    #include "tsc2046.h"
    
    #define ADS_CTRL_PD0              (1 << 0)        // PD0
    #define ADS_CTRL_PD1              (1 << 1)        // PD1
    #define ADS_CTRL_DFR              (1 << 2)        // SER/DFR
    #define ADS_CTRL_EIGHT_BITS_MOD   (1 << 3)        // Mode
    #define ADS_CTRL_START            (1 << 7)        // Start Bit
    #define ADS_CTRL_SWITCH_SHIFT     4               // Address setting
    
    // Get X position command
    #define CMD_Y_POSITION ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
    
    // Get Y position command
    #define CMD_X_POSITION ((5 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
    
    // Enable penIRQ
    #define CMD_ENABLE_PENIRQ  ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START)
    
    #define AT91C_TOUCHSCREEN_TIMEOUT        5000000
    
    #define DELAY_BEFORE_SPCK          (200 << 16) // 2us min (tCSS) <=> 200/100 000 000 = 2us
    #define DELAY_BETWEEN_CONS_COM     (0xf << 24) // 5us min (tCSH) <=> (32 * 15) / (100 000 000) = 5us
      
    /// Pins used by SPI
    static const Pin pinsSPI[]  = {BOARD_TSC_SPI_PINS, BOARD_TSC_NPCS_PIN};
    
    /// Touch screen BUSY pin
    static const Pin pinBusy[] = {PIN_TCS_BUSY};
    
    /// Touch screen CS pin
    static const Pin pinNss[]  = {BOARD_TSC_NPCS_PIN};
    
    static unsigned int SendCommand(unsigned char bCmd)
    {
        int i;
        AT91S_SPI *spi = BOARD_TSC_SPI_BASE;
        unsigned int  uResult = 0;
        //unsigned int  uTimeout = 0;
        // (volatile declaration needed for code optimisation by compiler)
        volatile unsigned char bufferRX[3];
        volatile unsigned char bufferTX[3];
    
        bufferRX[0] = 0;
        bufferRX[1] = 0;
        bufferRX[2] = 0;
    
        bufferTX[0] = bCmd;
        bufferTX[1] = 0;
        bufferTX[2] = 0;
    
        PIO_Clear(pinNss);
        // Send command
        i = 0;
        while ((spi->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
        spi->SPI_TDR = bufferTX[i] | SPI_PCS(BOARD_TSC_NPCS);
        while ((spi->SPI_SR & AT91C_SPI_TDRE) == 0);
    
        while (PIO_Get(pinBusy) == 1);
        
        while ((spi->SPI_SR & AT91C_SPI_RDRF) == 0);
        bufferRX[i] = spi->SPI_RDR & 0xFFFF;
    
        // Read data
        for (i = 1; i < 3; i++) 
        {
            while ((spi->SPI_SR & AT91C_SPI_TXEMPTY) == 0);
            spi->SPI_TDR = bufferTX[i] | SPI_PCS(BOARD_TSC_NPCS);
            while ((spi->SPI_SR & AT91C_SPI_TDRE) == 0);
    
            while ((spi->SPI_SR & AT91C_SPI_RDRF) == 0);
            bufferRX[i] = spi->SPI_RDR & 0xFFFF;
        }
        PIO_Set(pinNss);
    
        uResult = ((unsigned int)bufferRX[1] << 8) | (unsigned int)bufferRX[2];
        uResult = uResult >> 4;
    
        return uResult;
    }
    
    void tsc2046_get_position(unsigned int* px_pos, unsigned int* py_pos)
    {
        // Get X position
        *px_pos = SendCommand(CMD_X_POSITION);
        
        // Get Y position
        *py_pos = SendCommand(CMD_Y_POSITION);
        
        // Switch to full power mode
        SendCommand(CMD_ENABLE_PENIRQ);
    }
    
    void tsc2046_init(void)
    {
        volatile unsigned int uDummy;
          
        // Configure pins
        PIO_Configure(pinsSPI, PIO_LISTSIZE(pinsSPI));
    
        PIO_Set(pinNss);
           
        PIO_Configure(pinBusy, PIO_LISTSIZE(pinBusy));
    
        SPI_Configure(AT91C_BASE_SPI0,
                      AT91C_ID_SPI0,
                      AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | SPI_PCS(BOARD_TSC_NPCS) // Value of the SPI configuration register.
        );
    
        SPI_ConfigureNPCS(AT91C_BASE_SPI0, BOARD_TSC_NPCS,
                          AT91C_SPI_NCPHA | (AT91C_SPI_DLYBS & DELAY_BEFORE_SPCK) |
                          (AT91C_SPI_DLYBCT & DELAY_BETWEEN_CONS_COM) | (0xC8 << 8) );
    
        SPI_Enable(AT91C_BASE_SPI0);
    
        for (uDummy=0; uDummy<100000; uDummy++);
    
        uDummy = AT91C_BASE_SPI0->SPI_SR;
        uDummy = AT91C_BASE_SPI0->SPI_RDR;
    
        SendCommand(CMD_ENABLE_PENIRQ);
    }
    
    void tsc2046_reset(void)
    {
        // Disable SPI 0
        SPI_Disable(AT91C_BASE_SPI0);
    }
    
    

    Andy