📄 lh7a400_lcd_evb_touchscreen_driver.c
字号:
* 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 + -