3. The next thing to do is to implement the conversion of touch screen status and coordinates in two interrupt service programs. Let’s look at the code first, as follows:
/*Define an external semaphore ADC_LOCK, because ADC_LOCK has been declared in the ADC driver,
thus ensuring mutually exclusive access of ADC resources in the ADC driver and touch screen driver*/
extern struct semaphore ADC_LOCK;
/*As a label, The X and Y coordinates are converted only after operating the touch screen */
static int OwnADC = 0;
/* Used to record the converted X coordinate value and Y coordinate value */
static long xp;
static long yp;
/* Used to Count the number of analog input conversions when the touch screen is pressed or lifted */
static int count;
/*Define an AUTOPST macro to set the ADC touch screen control register to automatic conversion mode */
#define AUTOPST (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN |
S3C2410_ADCTSC_AUTO _PST | S3C2410_ADCTSC_XY_PST(0))
/*Touch screen interrupt service routine, triggered when the touch screen is pressed or the pen is lifted*/
static irqreturn_t tc_irq(int irq, void *dev_id)
{
/*Used to record the value after AD conversion* /
unsigned long data0;
unsigned long data1;
/*Used to record whether the touch screen operation status is pressed or lifted*/
int updown;
/*ADC resources can be obtained, that is, locked*/
if (down_trylock(&ADC_LOCK) == 0)
{
/*Indicates that the touch screen has been operated*/
OwnADC = 1;
/*Read the value after AD conversion. Note that this time the main read is the status*/
data0 = readl(adc_base + S3C2410_ADCDAT0);
data1 = readl( adc_base + S3C2410_ADCDAT1);
/*Record whether the touch screen is pressed down or lifted up this time. This status is saved in the 15th bit of the data register, so it is related to S3C2410_ADCDAT0_UPDOWN*/
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!( data1 & S3C2410_ADCDAT0_UPDOWN));
/*Determine the operating status of the touch screen*/
if (updown)
{
/*If it is in the pressed state, call the touch_timer_fire function to start the ADC conversion. The function definition will be discussed later*/
touch_timer_fire(0);
}
else
{
/*If it is in the raised state, this operation is over, so the possession of ADC resources is released*/
OwnADC = 0;
up(&ADC_LOCK);
}
}
return IRQ_HANDLED;
}
static void touch_timer_fire(unsigned long data )
{
/*Used to record the value after AD conversion this time*/
unsigned long data0;
unsigned long data1;
/*Used to record whether the touch screen operation status is pressed or lifted*/
int updown;
/*Read this time AD The converted value, note that this time the main read is the status */
data0 = readl(adc_base + S3C2410_ADCDAT0);
data1 = readl(adc_base + S3C2410_ADCDAT1);
/*Record whether the touch screen is pressed down or lifted up this time, and the status is saved In the 15th bit of the data register, so it is related to S3C2410_ADCDAT0_UPDOWN*/
updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 & S3C2410_ADCDAT0_UPDOWN));
/*Judge the operating status of the touch screen*/
if (updown)
{
/* If the state is pressed and the ADC has converted, report the event and data */
if (count != 0)
{
long tmp;
tmp = xp;
xp = yp;
yp = tmp;
xp >>= 2;
yp >> = 2;
#ifdef CONFIG_TOUCHSCREEN_MY2440_DEBUG
/*Touch screen debugging information, after selecting this item when compiling the kernel, clicking the touch screen will print out the coordinate information on the terminal*/
struct timeval tv;
do_gettimeofday(&tv);
printk(KERN_DEBUG "T: %06d, X: %03ld, Y: %03ldn", (int)tv.tv_usec, xp, yp);
#endif
/*Report the absolute coordinate values of X and Y*/
input_report_abs(ts_dev, ABS_X, xp);
input_report_abs(ts_dev, ABS_Y, yp);
/*Report the status of the touch screen, 1 indicates that the touch screen is pressed*/
input_report_abs(ts_dev, ABS_PRESSURE, 1);
/*Report key events, the key value is 1 (representing that the key corresponding to the touch screen is pressed)*/
input_report_key(ts_dev, BTN_TOUCH, 1);
/*Wait for the receiver to reply with confirmation after receiving the data, for synchronization*/
input_sync(ts_dev);
}
/*If the status is pressed and the ADC has not started conversion, start the ADC for conversion*/
xp = 0;
yp = 0;
count = 0;
/*Set the touch screen mode to automatic conversion mode*/
writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, adc_base + S3C2410_ADCTSC);
/*Start ADC conversion*/
writel(readl(adc_base + S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_STAR T , adc_base + S3C2410_ADCCON);
}
else
{
/*Otherwise it is in the raised state*/
count = 0;
/*Report the key event, the key value is 0 (representing that the key corresponding to the touch screen is released)*/
input_report_key(ts_dev, BTN_TOUCH, 0 ;
Reset the touch screen to the waiting interrupt state */
writel(WAIT4INT(0), adc_base + S3C2410_ADCTSC);
/*If the touch screen is lifted, it means that the operation is over this time, so the ADC resource is released*/
if (OwnADC )
{
OwnADC = 0;
up(&ADC_LOCK);
}
}
}
/*Define and initialize a timer touch_timer, the timer service program is touch_timer_fire*/
static struct timer_list touch_timer = TIMER_INITIALIZER(touch_timer_fire, 0, 0);
/*ADC Interrupt service routine, triggered execution after AD conversion is completed*/
static irqreturn_t adc_irq(int irq, void *dev_id)
{
/*Used to record the value after AD conversion*/
unsigned long data0;
unsigned long data1;
if(OwnADC)
{
/*Read the value after AD conversion this time. Note that this time the main read is the coordinates*/
data0 = readl(adc_base + S3C2410_ADCDAT0);
data1 = readl(adc_base + S3C2410_ADCDAT1);
/*Record the value after AD conversion this time According to the data sheet, the X and Y coordinate conversion values
are stored in bits 0-9 of data registers 0 and 1 respectively, so here and above S3C2410_ADCDAT0_XPDATA_MASK takes the value of bits 0-9*/
xp += data0 & S3C2410_ADCDAT0_XPDATA_MASK;
yp += data1 & S3C2410_ADCDAT1_YPDATA_MASK;
/*Count the number of AD conversions this time*/
count++;
if (count < (1<<2))
{
/*If the number of conversions is less than 4, restart ADC conversion*/
writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, adc_base + S3C2410_ADCTSC);
writel(readl(adc_base + S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, adc_base + S3C2410_ADCCON );
}
else
{
/*otherwise , start a timer with a tick time, which will execute the timer service program to report events and data*/
mod_timer(&touch_timer, jiffies + 1);
writel(WAIT4INT(1), adc_base + S3C2410_ADCTSC);
}
}
return IRQ_HANDLED;
}
We describe the conversion process as a whole:
(1) If the touch screen senses touch, the touch screen interrupt is triggered and tc_irq is entered. After obtaining ADC_LOCK, it is judged that the touch screen status is pressed, and then touch_timer_fire is called to start the ADC conversion;
(2) When the ADC conversion After starting, the ADC interrupt is triggered and the adc_irq is entered. If the number of conversions this time is less than 4, the ADC is restarted for conversion. If 4 times are completed, a tick timer is started to stop the ADC conversion. That is to say, in this Within the time tick, ADC conversion stops;
(3) Why should ADC conversion be stopped before one time tick arrives? This is to prevent screen shaking.
(4) If a time tick arrives, enter the timer service program touch_timer_fire. If it is judged that the touch screen is still pressed, the event and converted data will be reported, and the ADC conversion will be restarted. Repeat step (2);
(5) If the touch screen is lifted If it starts, the release event is reported and the touch screen is reset to the waiting interrupt state.
Previous article:Set-top box media player based on TQ2440 development board
Next article:ARM register analysis and exception handling methods
Recommended ReadingLatest update time:2024-11-23 18:30
- Naxin Micro and Xinxian jointly launched the NS800RT series of real-time control MCUs
- How to learn embedded systems based on ARM platform
- Summary of jffs2_scan_eraseblock issues
- Application of SPCOMM Control in Serial Communication of Delphi7.0
- Using TComm component to realize serial communication in Delphi environment
- Bar chart code for embedded development practices
- Embedded Development Learning (10)
- Embedded Development Learning (8)
- Embedded Development Learning (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Intel promotes AI with multi-dimensional efforts in technology, application, and ecology
- ChinaJoy Qualcomm Snapdragon Theme Pavilion takes you to experience the new changes in digital entertainment in the 5G era
- Infineon's latest generation IGBT technology platform enables precise control of speed and position
- Two test methods for LED lighting life
- Don't Let Lightning Induced Surges Scare You
- Application of brushless motor controller ML4425/4426
- Easy identification of LED power supply quality
- World's first integrated photovoltaic solar system completed in Israel
- Sliding window mean filter for avr microcontroller AD conversion
- What does call mean in the detailed explanation of ABB robot programming instructions?
- STMicroelectronics discloses its 2027-2028 financial model and path to achieve its 2030 goals
- 2024 China Automotive Charging and Battery Swapping Ecosystem Conference held in Taiyuan
- State-owned enterprises team up to invest in solid-state battery giant
- The evolution of electronic and electrical architecture is accelerating
- The first! National Automotive Chip Quality Inspection Center established
- BYD releases self-developed automotive chip using 4nm process, with a running score of up to 1.15 million
- GEODNET launches GEO-PULSE, a car GPS navigation device
- Should Chinese car companies develop their own high-computing chips?
- Infineon and Siemens combine embedded automotive software platform with microcontrollers to provide the necessary functions for next-generation SDVs
- Continental launches invisible biometric sensor display to monitor passengers' vital signs
- Who knows how to use CMU200? I want to learn
- TMS320C2X/C5X Applications
- Six manufacturers won the bid for China Mobile's mobile phone customization
- TI supports Bluetooth technology for high-precision body temperature measurement flexible PCB reference design
- Problems of charging and discharging dual capacitors in peak detectors
- MSP430 SCH and PCB library files
- EK140P Linux-4.1.15 Test Manual
- Keil's video tutorial
- Can the lost humanity be restored? (Speech by Li Ka-shing)
- PCB LAYOUT Manual