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

📄 lh7a400_lcd_evb_touchscreen_driver.c

📁 sharp的arm920t 7A400的评估板附带光盘Sharp KEVLH7A400 v0.3b Welcome to the SHARP KEV7A400 Evaluation board
💻 C
📖 第 1 页 / 共 2 页
字号:
*  is called from the IRQ dispatcher in response to an SSP
*  receive interrupt.
*
* Processing:
*  The function measurexy() started a differential measurement. The
*  first measurement in a given direction was to switch the FET
*  switches. The second measurement in a given direction should be
*  good data. Therefore, read the first element in the SSP receive
*  FIFO and discard it. The second measurement is valid x data.
*  Record the x data in point.x. Read the third measuremnt from the
*  SSP receive FIFO and discard it. Read the fourth measurement from
*  the SSP receive FIFO and store it in point.y. If point.x is
*  more than TS_DELTA_X_TOLERANCE from the previous measurement
*  and point.y is more than TS_DELTA_Y_TOLERANCE from the previous
*  measurement, enqueue the point in the touchscreen queue with
*  the status pen down. Enable the timer interrupt and start the
*  timer to trigger the next measurement.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*  Emptying the SSP receive FIFO clears the interrupt condition.
*
**********************************************************************/
static void lcd_coordinate_read_handler(void)
{
   static LCD_TS_STATE prev_point = {TOUCHSCREEN_PEN_UP,
                                     TOUCHSCREEN_ILLEGAL_COORDINATE,
                                     TOUCHSCREEN_ILLEGAL_COORDINATE};
   LCD_TS_STATE point;
   INT_32 delta_x, delta_y;

   /* read back the coordinates */
   ssp_receive(); /* discard first x measurement */
   point.x = ssp_receive();
   ssp_receive(); /* discard first y measurement */
   point.y = ssp_receive();
   delta_x = point.x - prev_point.x;
   if (delta_x < 0)
      delta_x = -delta_x;
   delta_y = point.y - prev_point.y;
   if (delta_y < 0)
      delta_y = -delta_y;
   if (delta_x > TS_DELTA_X_TOLERANCE || delta_y > TS_DELTA_Y_TOLERANCE)
   {
      point.pen_down = TOUCHSCREEN_PEN_DOWN;
      lcd_touchscreen_q_post(point);
      prev_point = point;
   }
   timer_int_enable(LCD_TOUCHSCREEN_TIMER);
   timer_start(LCD_TOUCHSCREEN_TIMER);
}

/**********************************************************************
*
* Function: lcd_timer_handler
*
* Purpose:
*  Measure the touchscreen at regular intervals while the pen is 
*  down, and notice the pen-up condition.
*
* Processing:
*  Clear the timer interrupt so that the interrupt doesn't retrigger.
*  Trigger a new screen coordinate measurement if the pen is still
*  down, or record a pen up condition in the touchscreen queue if
*  the pen is up, disable FIQs, and re-enable pen interrupts.
*  re-enable FIQs.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
static void lcd_timer_handler(void)
{
   LCD_TS_STATE point;
   register UNS_32 current_status;
   
   timer_stop(LCD_TOUCHSCREEN_TIMER);

   timer_int_clear(LCD_TOUCHSCREEN_TIMER);
   if (!gpio_raw_interrupt_pending(LH7A400_EVB_TOUCHSCREEN_INT_BIT) )
   {
      point.pen_down = TOUCHSCREEN_PEN_UP;
      point.x = TOUCHSCREEN_ILLEGAL_COORDINATE;
      point.y = TOUCHSCREEN_ILLEGAL_COORDINATE;
      lcd_touchscreen_q_post(point);
      
      /* get current status register */
      __asm
      {
         MRS current_status, CPSR
      }
      disable_FIQ();
      int_enable_interrupt(INTC_GPIO0FIQ_BIT);
      /* if FIQs were previously enabled, re-enable them */
      if ((current_status & ARM_FIQ) == 0)
         enable_FIQ();
   }
   else
   {
      measurexy();
   }
}

/**********************************************************************
*
* Function: lcd_touchscreen_pen_int_init
*
* Purpose:
*  Set up the system hardware for detecting pen down as an FIQ, and
*  install the pend down interrupt handler at the specified priority.
*
* Processing:
*  Make sure the pen FIQ is disabled at the interrupt controller.
*  Configure port F, bit 0 as an interrupt level triggered, active low.
*  Turn debounce circuitry for port F, bit 0. Install the FIQ handler
*  for pen down detect. Set up the touchscreen controller to 
*  assert the pen down interrupt via the SSP. Wait until the the
*  SSP transmit is complete and read back the erroneous data.
*  Enable the port F, bit 0 FIQ at the interrupt controller.
*
* Parameters:
*  priority: The FIQ priority of the pen down interrupt
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
/*
Put the touch screen controller in a mode to receive
the pen IRQ and then put the touch screen controller to sleep.
*/
static void lcd_touchscreen_pen_int_init(INT_32 priority)
{
   int_disable_interrupt(INTC_GPIO0FIQ_BIT);
   gpio_port_f_bit_is_interrupt(LH7A400_EVB_TOUCHSCREEN_INT_BIT);
   gpio_interrupt_level_triggered(LH7A400_EVB_TOUCHSCREEN_INT_BIT);
   gpio_interrupt_active_low(LH7A400_EVB_TOUCHSCREEN_INT_BIT);
   gpio_interrupt_debounce_enable(LH7A400_EVB_TOUCHSCREEN_INT_BIT);
   int_install_fiq_handler(INTC_GPIO0FIQ_BIT,
                           TOUCHSCREEN_PEN_INT_PRIORITY,
                           lcd_touchscreen_pen_down_handler);
   /* make the touch screen controller output the pen interrupt */
   ssp_transmit(LCD_TS_START | LCD_TS_DIFFERENTIAL
                | LCD_TS_MEASURE_Y | LCD_TS_POWER_DOWN_PEN_IRQ);
   /* read back and discard the measurement */
   while (ssp_busy() )
      ;
   ssp_receive();
   /* enable the interrupt at the interrupt controller */
   int_enable_interrupt(INTC_GPIO0FIQ_BIT);
}

/**********************************************************************
*
* Function: lcd_touchscreen_coordinate_read_irq_init
*
* Purpose:
*  Install the coordinate read interrupt handler at the specified
*  priority and set up the SSP to interrupt on receive FIFO containing
*  4 or more received words.
*
* Processing:
I  Disable tje SSP interrupt at the interrupt controller.
*  Install the irq handler for the SSP. Flush the receive FIFO.
*  Disable all SSP interrupts, and then enable the SSP receive 
*  interrupt. Enable the SSP interrupts at the interrupt controller.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
static void lcd_touchscreen_coordinate_read_irq_init(INT_32 priority)
{
   int_disable_interrupt(INTC_SSEOTINTR_BIT);
   int_install_irq_handler(INTC_SSEOTINTR_BIT,
                           TOUCHSCREEN_SSP_PRIORITY,
                           lcd_coordinate_read_handler);
   /* make sure the receive FIFO starts out empty */
   while (ssp_receive_fifo_not_empty() )
      ssp_receive();

   /* the only enabled SSP interrupt is the receiver interrupt */
   ssp_int_disable_all();
   ssp_int_enable_receive();
   int_enable_interrupt(INTC_SSEOTINTR_BIT);
}

/**********************************************************************
*
* Function: lcd_touchscreen_init
*
* Purpose:
*  Initialize the touchscreen driver. You must call this function 
*  before calling any other function
*
* Processing:
*  Set up the SSP for MICROWIRE mode. Set the SSP wordsize, the speed
*  turn loopback oof, enable the SSP FIFOs, connect the SSPFRM pin
*  to the touchscreen controller chip select. Initialize the
*  interrupt handlers for the pen down detect, and the coordinate read.
*  Empty the touchscreen driver queue. Initialize the timer in
*  periodic mode to overflow at the touchscreen sampling rate. Install
*  the interrupt handler for the timer.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*  Both IRQ and FIQ interrupts should be disabled when calling this
*  function. In order for the touchscreen driver to work, the
*  application must enable IRQ and FIQ interrupts.
*
**********************************************************************/
/* control */
void lcd_touchscreen_init(void)
{
   ssp_init_uwire_mode();
   ssp_set_bits_per_word(LCD_TS_WORDSIZE);
   ssp_set_speed(LCD_TS_BPS);
   ssp_loopback_off();
   ssp_enable_fifos();
   lh7a400_evb_ssp_frame_touchscreen();
   lcd_touchscreen_pen_int_init(TOUCHSCREEN_PEN_INT_PRIORITY);
   lcd_touchscreen_coordinate_read_irq_init(TOUCHSCREEN_SSP_PRIORITY);
   
   /* empty the touchscreen queue */
   front = 0;
   back = 0;
   
   timer_init(LCD_TOUCHSCREEN_TIMER);
   timer_periodic(LCD_TOUCHSCREEN_TIMER);
   timer_set_delay(LCD_TOUCHSCREEN_TIMER,TOUCHSCREEN_SAMPLE_PERIOD_US);
   timer_irq_setup(LCD_TOUCHSCREEN_TIMER, 
                   TOUCHSCREEN_TIMER_PRIORITY, 
                   lcd_timer_handler );
}

/**********************************************************************
*
* Function: lcd_touchscreen_controller_disable
*
* Purpose:
*   Disable the touchscreen driver, free interrupts, etc.
*
* Processing:
*  Disable SSP, GPIO and timer interrupts. Set GPIO port F, bit 0
*  to GPIO. Remove all installed interrupt handlers
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes:
*
**********************************************************************/
void lcd_touchscreen_controller_disable(void)
{
   int_disable_interrupt(INTC_SSEOTINTR_BIT);
   int_disable_interrupt(INTC_GPIO0FIQ_BIT);
   timer_int_disable(LCD_TOUCHSCREEN_TIMER);
   ssp_int_disable_all();
   gpio_port_f_bit_is_gpio(LH7A400_EVB_TOUCHSCREEN_INT_BIT);
   int_remove_fiq_handler(TOUCHSCREEN_PEN_INT_PRIORITY);
   int_remove_irq_handler(TOUCHSCREEN_TIMER_PRIORITY);
   int_remove_irq_handler(TOUCHSCREEN_SSP_PRIORITY);
}

⌨️ 快捷键说明

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