⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lh7a400_lcd_evb_touchscreen_driver.c

📁 sharp的arm920t 7A400的评估板附带光盘Sharp KEVLH7A400 v0.3b Welcome to the SHARP KEV7A400 Evaluation board
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********************************************************************
 *	$Workfile:   lh7a400_lcd_evb_touchscreen_driver.c  $
 *	$Revision:   1.4  $
 *	$Author:   FergisJ  $
 *	$Date:   Aug 20 2002 16:55:16  $
 *
 *	Project: LH7A400
 *
 *	Description:
 *
 * This is driver for the LH7A400 EVB system's ADS7843 touchscreen 
 * controller from TI (formerly Burr-Brown). The AD7843 is mounted
 * on the LCD board. It communicates with the LH7A400 via the SSP.
 * This driver consumes the SSP, a timer, GPIO port F, bit 0,
 * GPIO Port K, bits 0 and 1, two IRQ interrupt priorities, and one 
 * FIQ priority.
 *
 * The following user functions are provided:
 *  lcd_touchscreen_init()--Initialize the touchscreen driver. You
 *                          must call this function before calling
 *                          any other function
 *  lcd_touchscreen_controller_disable()--Disable the touchscreen
 *                                        driver, free interrupts, etc.
 *  lcd_touchscreen_q_accept()--remove the next touchscreen pen state
 *                              and coordinates structure from this
 *                              driver's software queue and return it.
 *  lcd_touchscreen_q_empty()--return true if the touchscreen
 *                             controller driver's software queue
 *                             contains no pen state and coordinate
 *                             structures.
 *
 * Configuration options:
 *
 * A number of factors may need to be tweaked depending on the
 * application. Also, resources such as interrupt priorities and
 * timers have to be allocated. LH7A400_lcd_evb_touchscreen_driver.h
 * contains all parameters that may need to be adjusted by the user.
 *
 * Porting to an operating system environment:
 * 
 * If this driver is to exist within an operating system, it is
 * recommended that the function lcd_coordinate_read_handler()
 * post measurement results to an OS queue rather than to the
 * queue this driver creates. Also, it is recommended that an OS
 * timer is used rather than a physical timer. The functions
 * lcd_timer_handler(), lcd_touchscreen_init(), 
 * lcd_touchscreen_controller_disable(), lcd_coordinate_read_handler()
 * will have to be rewritten to use an OS timer.
 *
 * Driver Strategy: 
 *
 * Use SSP in microwire mode with 8-bit command and 
 * 12-bit data for 21 (8 bits of command, 1 bit of busy, 12 bits
 * of data) bits per conversion. Use a clock rate of 1 MHz (or less, 
 * need to experiment) for a 3 us acquisition time. Use differential
 * mode with two consecutive reads to allow for panel settling per
 * the ADS7843 APP note. This will require tweaking based on noise
 * performance. The ADS7843 sleeps between conversions to save power.
 * If 100 KHz clock works, this double conversion works at about 24 kHz
 * (about 42 us). We need two conversions per coordinate and two 
 * coordinates (x and y) so the total time is about 840 us. We will
 * sample the touch screen every 100 ms or so in real life, so
 * the device is asleep over 99% of the time. 
 *
 * Measured X-Y coordinate pairs are stored in a software queue
 * (not the same as the SSP transmit and receive FIFOS)
 * if the coordinate pair is sufficiently different from the previously
 * measured coordiante pair.
 *
 * ALGORITHM:
 * Once the touchscreen controller is initialized, the LH7A400 waits for
 * a Pen down interrupt from the touchscreen controller. On receipt of
 * a Pen down interrupt (see lcd_touchscreen_pen_down_handler()), 
 * the LH7A400 first verifies that the pen is still
 * down by polling the status of the Pen IRQ bit of the ADS7843. If the
 * pen is still down, the LH7A400 masks the Pen interrupt and sends
 * enough data out the SSP to start a coordiante measurement. (see
 * measurexy() );
 *
 * When the coordinate measurement is complete, there will be 4 data
 * elements in the SSP receiver FIFO. This triggers an SSP receiver
 * FIFO interrupt (see lcd_coordinate_read_handler() ). Since the first
 * measurement in the X and Y directions represents data taken during
 * the settling time, these measurements are discarded. If the X and
 * Y coordinates are sufficiently different from the last X and Y 
 * coordinates, then the data are place in the Touchscreen driver's
 * queue. The touchscreen timer is started.
 *
 * When the the sampling interval specified by the timer elapses, (see
 * lcd_timer_handler() ), the LH7A400 stops the timer. The LH7A400 then
 * checks the ADS7843 pen IRQ status to make sure the pen is still
 * down. If the pen is still down, then the LH7A400 calls measurexy() 
 * and repeats the process in the preceding paragraph. If the pen is
 * up, the LH7A400 posts a pen-up message in the software queue and
 * waits for a new Pen down interrupt again.
 *
 *	Revision History:
 *	$Log:   //smaicnt2/pvcs/VM/CHIPS/archives/LH7A400/Touchscreen/Drivers/lh7a400_lcd_evb_touchscreen_driver.c-arc  $
 * 
 *    Rev 1.4   Aug 20 2002 16:55:16   FergisJ
 * Update for new priority_int_driver:  uses bit-number not 1-in-bit-position.
 * 
 *    Rev 1.3   Jun 05 2002 17:59:38   MaysR
 * Corrected errors in lcd_touchscreen_controller_disable function.  
 * Changed parameter passed to int_enable/disable_interrupt function for compatibility with priority driver.
 * 
 *    Rev 1.2   Jun 05 2002 16:59:58   KovitzP
 * changed CORE_FIQ to ARM_FIQ
 * 
 *    Rev 1.1   Nov 20 2001 17:01:26   KovitzP
 * Added block comments to all functions and improved
 * comments. Corrected minor errors.
 * 
 *    Rev 1.0   Nov 19 2001 10:26:06   KovitzP
 * Initial revision.
 * 
 * 
 *	COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
 *		CAMAS, WA
 *********************************************************************/

#include "lh7a400_lcd_evb_touchscreen_driver.h"

/*
A circular buffer (queue) is implemented from the array ts_q and
the array indicies front and back. Data goes into the queue at
ts_q[back] and is read from the queue at ts_q[front]. The queue is
empty if front == back (one array location is wasted).
*/
static LCD_TS_STATE ts_q[TS_Q_LENGTH];
static INT_32 front = 0, back = 0;

/**********************************************************************
*
* Function: lcd_touchscreen_q_empty
*
* Purpose:
*  Return true if the touchscreen controller driver's software queue
*  contains no pen state and coordinate structures. Poll this function
*  to see if any data are available.
*
* Processing:
*  return front == back
*
* Parameters: None
*
* Outputs: None
*
* Returns:
*  0 if the queue contains data
*  1 if the queue is empty
*
* Notes:
*
**********************************************************************/
INT_32 lcd_touchscreen_q_empty(void)
{
   return front == back;
}

/**********************************************************************
*
* Function: lcd_touchscreen_q_post
*
* Purpose:
*  Add a touchscreen measurement to the touchscreen queue for later
*  removal by lcd_touchscreen_q_accept()
*
* Processing:
*  Check to make sure that adding data to the queue won't make the
*  new value of back == front. If it will, the queue is already full,
*  so return. Otherwise, ts_q[back] = point. 
*  back = (back + 1) % TS_Q_LENGTH
*
* Parameters:
*  point: the data to add to the queue.
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*   If the queue is full, the function returns with no complaint; 
*   however, the data will not be enqueued.
*
**********************************************************************/
static void lcd_touchscreen_q_post(LCD_TS_STATE point)
{
   INT_32 temp_back = back + 1;
   
   if (temp_back >= TS_Q_LENGTH)
      temp_back = 0;
   if (temp_back == front)
      return; /* queue is full */
   ts_q[back] = point;
   back = temp_back;
}

/**********************************************************************
*
* Function: lcd_touchscreen_q_accept
*
* Purpose:
*  remove the next touchscreen pen state and coordinates structure 
*  from this driver's software queue and return it.
*
* Processing:
*   Initialize an LCD_TS_STATE point structure to contain
*   an illegal coordinate pair with pen down.
*   If the queue is empty, return point. Otherwise, point
*   is ts_q[front]. Increment front. If front is out of 
*   bounds for the ts_q[] array's length, then front = 0.
*   Return point.
*   
*
* Parameters: None
*
* Outputs: None
*
* Returns:
*  an LCD_TS_STATE structure from the front of the queue.
*  if the queue was empty, return with PEN_DOWN at an illegal
*  coordinate pair
*
* Notes:
*
**********************************************************************/
LCD_TS_STATE lcd_touchscreen_q_accept(void)
{
   LCD_TS_STATE point={TOUCHSCREEN_PEN_DOWN,
                       TOUCHSCREEN_ILLEGAL_COORDINATE,
                       TOUCHSCREEN_ILLEGAL_COORDINATE};
   
   if (lcd_touchscreen_q_empty())
      return point;
   point = ts_q[front++];
   if (front >= TS_Q_LENGTH)
      front = 0;
   return point;
}

/**********************************************************************
*
* Function: measurexy
*
* Purpose:
*  Send enough commands to the touchscreen controller chip via the SSP  
*  to perform a differential measurement.
*
* Processing:
*  Write commands to measure in the x direction twice followed by
*  commands to measure in the y direction twice. During the first
*  measurement in a given direction, the FET switches connect for
*  that measurement. During the second measurement command in a
*  given direction, the data will be used. See the function
*  lcd_coordinate_read_handler().
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*  This function is not static because the pen down handler, an
*  FIQ function coded in assembly language, needs to IMPORT this
*  symbol during linking.
*
**********************************************************************/
void measurexy(void)
{
   /* measure X twice */
   ssp_transmit(LCD_TS_START | LCD_TS_DIFFERENTIAL
                | LCD_TS_MEASURE_X | LCD_TS_POWER_ON);
   ssp_transmit(LCD_TS_START | LCD_TS_DIFFERENTIAL
                | LCD_TS_MEASURE_X | LCD_TS_POWER_ON);
   /* measure Y twice and end in sleep mode*/
   ssp_transmit(LCD_TS_START | LCD_TS_DIFFERENTIAL
                | LCD_TS_MEASURE_Y | LCD_TS_POWER_ON);
   ssp_transmit(LCD_TS_START | LCD_TS_DIFFERENTIAL
                | LCD_TS_MEASURE_Y | LCD_TS_POWER_DOWN_PEN_IRQ);
}

/**********************************************************************
*
* Function: lcd_coordinate_read_handler
*
* Purpose:
*  read a complete measurement from the SSP receive FIFO and
*  start a new measurement if the pen is still down. This function

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -