blob: adfe42fbff487e854607fb72ae6714a98476315e [file] [log] [blame]
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2011, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
/**
* \file
*
* Implementation of ADS7843 driver.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "board.h"
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
#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_X_POSITION ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
/* Get Y position command */
#define CMD_Y_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 ADS7843_TIMEOUT 5000000
#define DELAY_BEFORE_SPCK 200 /* 2us min (tCSS) <=> 200/100 000 000 = 2us */
#define DELAY_BETWEEN_CONS_COM 0xf /* 5us min (tCSH) <=> (32 * 15) / (100 000 000) = 5us */
/*----------------------------------------------------------------------------
* Local variables
*----------------------------------------------------------------------------*/
/** 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_TSC_BUSY};
/** Touch screen NPCS pin */
static const Pin pinCs[] = {BOARD_TSC_NPCS_PIN};
/*----------------------------------------------------------------------------
* Local functions
*----------------------------------------------------------------------------*/
/**
* \brief Generic function to send a command to the touchscreen controller.
*
* \param bCmd command to send
*
* \return command result
*/
static uint32_t SendCommand( uint8_t ucCmd )
{
uint32_t dwResult = 0 ;
uint32_t dw ;
Spi* pSpi ;
/* (volatile declaration needed for code optimisation by compiler) */
volatile uint8_t bufferRX[3] ;
volatile uint8_t bufferTX[3] ;
pSpi = BOARD_TSC_SPI_BASE ;
bufferRX[0] = 0 ;
bufferRX[1] = 0 ;
bufferRX[2] = 0 ;
bufferTX[0] = ucCmd ;
bufferTX[1] = 0 ;
bufferTX[2] = 0 ;
/* Send Command and data through the SPI */
PIO_PinClear( pinCs ) ;
// Send command
dw = 0 ;
while ( (pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0 ) ;
pSpi->SPI_TDR = bufferTX[dw] | SPI_PCS( BOARD_TSC_NPCS ) ;
while ( (pSpi->SPI_SR & SPI_SR_TDRE) == 0 ) ;
while ( PIO_PinGet( pinBusy ) == 1 ) ;
while ( (pSpi->SPI_SR & SPI_SR_RDRF) == 0 ) ;
bufferRX[dw] = pSpi->SPI_RDR & 0xFFFF ;
// Read data
for ( dw = 1 ; dw < 3 ; dw++ )
{
while ( (pSpi->SPI_SR & SPI_SR_TXEMPTY) == 0 ) ;
pSpi->SPI_TDR = bufferTX[dw] | SPI_PCS( BOARD_TSC_NPCS ) ;
while ( (pSpi->SPI_SR & SPI_SR_TDRE) == 0);
while ( (pSpi->SPI_SR & SPI_SR_RDRF) == 0 ) ;
bufferRX[dw] = pSpi->SPI_RDR & 0xFFFF ;
}
PIO_PinSet( pinCs ) ;
dwResult = (uint32_t)bufferRX[1] << 8 ;
dwResult |= (uint32_t)bufferRX[2] ;
dwResult = dwResult >> 4 ;
return dwResult ;
}
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Get position of the pen by ask the ADS controller (SPI).
*
* \param px_pos pointer to the horizontal position
* \param py_pos pointer to the vertical position
*
*/
extern void ADS7843_GetPosition( uint32_t *px_pos, uint32_t *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 ) ;
}
/**
* \brief Initialization of the SPI for communication with ADS7843 component.
*/
extern void ADS7843_Initialize( void )
{
volatile uint32_t dwDummy ;
/* Configure pins */
PIO_PinConfigure( pinsSPI, PIO_LISTSIZE( pinsSPI ) ) ;
PIO_PinConfigure( pinBusy, PIO_LISTSIZE( pinBusy ) ) ;
SPI_Configure( BOARD_TSC_SPI_BASE, BOARD_TSC_SPI_ID,
SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS(BOARD_TSC_NPCS) /* Value of the SPI configuration register. */
) ;
SPI_ConfigureNPCS( BOARD_TSC_SPI_BASE, BOARD_TSC_NPCS,
SPI_CSR_NCPHA | SPI_CSR_DLYBS(DELAY_BEFORE_SPCK) |
SPI_CSR_DLYBCT(DELAY_BETWEEN_CONS_COM) | SPI_CSR_SCBR(0xC8) );
SPI_Enable( BOARD_TSC_SPI_BASE ) ;
for ( dwDummy=0 ; dwDummy < 100000 ; dwDummy++ ) ;
dwDummy = BOARD_TSC_SPI_BASE->SPI_SR ;
dwDummy = BOARD_TSC_SPI_BASE->SPI_RDR ;
SendCommand( CMD_ENABLE_PENIRQ ) ;
}
/**
* \brief Reset the ADS7843
*/
void ADS7843_Reset( void )
{
/* Disable SPI */
SPI_Disable( BOARD_TSC_SPI_BASE ) ;
}