/* ---------------------------------------------------------------------------- * ATMEL Microcontroller Software Support * ---------------------------------------------------------------------------- * Copyright (c) 2009, 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_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 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}; /*---------------------------------------------------------------------------- * 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 bCmd ) { uint32_t uResult = 0; uint32_t uTimeout = 0; /* (volatile declaration needed for code optimisation by compiler) */ volatile uint8_t bufferRX[3]; volatile uint8_t bufferTX[3]; Pdc *pPdc = (Pdc *)SPI; uint32_t dStatus; bufferRX[0] = 0; bufferRX[1] = 0; bufferRX[2] = 0; bufferTX[0] = bCmd; bufferTX[1] = 0; bufferTX[2] = 0; /* Send Command and data through the SPI */ pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS; pPdc->PERIPH_RPR = (uint32_t) bufferRX; pPdc->PERIPH_RCR = 3; pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS; pPdc->PERIPH_TPR = (uint32_t) bufferTX; pPdc->PERIPH_TCR = 3; pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTEN; pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTEN; do { dStatus = REG_SPI_SR; uTimeout++; } while ((( dStatus & SPI_SR_RXBUFF) != SPI_SR_RXBUFF) && (uTimeout < ADS7843_TIMEOUT)); pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS; pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS; uResult = (uint32_t)bufferRX[1] << 8; uResult |= (uint32_t)bufferRX[2]; uResult = uResult >> 4; return uResult; } /*---------------------------------------------------------------------------- * 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 uDummy; /* Configure pins */ PIO_Configure(pinsSPI, PIO_LISTSIZE(pinsSPI)); PIO_Configure(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 (uDummy=0; uDummy<100000; uDummy++); uDummy = REG_SPI_SR; uDummy = REG_SPI_RDR; SendCommand(CMD_ENABLE_PENIRQ); } /** * \brief Reset the ADS7843 */ void ADS7843_Reset( void ) { /* Disable SPI */ SPI_Disable( BOARD_TSC_SPI_BASE ) ; }