Hi John,
First, if your customer is starting a new design based on ADS7846, I would recommend that your customer use TSC2046E instead of ADS7846. The TSC2046E is the next-generation version of the ADS7846 4-wire touch screen controller, 100% pin-compatible with the existing ADS7846, and drops into the same socket.
Second, if you look a look at the Figure 9 in its datasheet, you can find the 11th bit is the MSB and the 1st bit is the LSB.
To help your customer understand how to read the 12-bit X&Y coordinates from ADS7846 / TSC2046E, here is some example code, which is based on the timing in Figure 9:
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);
}
#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)
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);
// wait until the BUSY pin becomes low
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;
}
Andy