#include <stdint.h>
#include <stdbool.h>
#include "board.h"
#include "compiler.h"
#include "assert.h"
#include "gpio.h"
#include "intc.h"
#include "rtouch.h"
#include "conf_rtouch.h"
#include "adc.h"
Go to the source code of this file.
Data Structures | |
struct | rtouch_struct |
Typedefs | |
typedef enum rtouch_state_enum | rtouch_state_t |
Enumerations | |
enum | rtouch_state_enum { RTOUCH_DISABLED, RTOUCH_NOT_TOUCHED, RTOUCH_READING_XL, RTOUCH_READING_XH, RTOUCH_READING_YL, RTOUCH_READING_YH, RTOUCH_PROCESSING, RTOUCH_TOUCHED } |
Driver state names. More... | |
Functions | |
void | rtouch_adc_int_handler (void) |
ADC conversion complete interrupt handler. | |
static void | rtouch_clear_adc_flag (void) |
static void | rtouch_clear_detect_flag (void) |
void | rtouch_compute_calibration_matrix (rtouch_calibration_points_t const *points, rtouch_calibration_matrix_t *matrix) |
Compute a calibration matrix from three calibration points. | |
void | rtouch_detect_int_handler (void) |
Low-level detect interrupt handler. | |
void | rtouch_disable (void) |
Disable driver. | |
static void | rtouch_disable_adc_int (void) |
Disable interrupts for the touch channels. | |
static void | rtouch_disable_detect_int (void) |
static void | rtouch_disable_pullup_on_y_surface (void) |
Remove pullups from Y lines. | |
void | rtouch_enable (void) |
Enable driver. | |
static void | rtouch_enable_adc_int (void) |
Enable interrupts for the touch channels. | |
static void | rtouch_enable_detect_int (void) |
static uint32_t | rtouch_get_adc_value (void) |
Return last converted value. | |
void | rtouch_get_calibration_matrix (rtouch_calibration_matrix_t *destination) |
Get the current calibration matrix. | |
void | rtouch_get_event (rtouch_event_t *event) |
Get last event. | |
rtouch_event_handler_t | rtouch_get_event_handler (void) |
Get current event handler. | |
static void | rtouch_gradient_x_surface (void) |
Drive voltage gradient on X surface (XL=GND, XH=VDD). | |
static void | rtouch_gradient_y_surface (void) |
Drive voltage gradient on Y surface (YL=GND, YH=VDD). | |
void | rtouch_ground_x_surface (void) |
Drive X lines to ground. | |
void | rtouch_ground_y_surface (void) |
Drive Y lines to ground. | |
void | rtouch_init (void) |
Initialize touch panel driver. | |
bool | rtouch_is_detect (void) |
Test if a touch is detected. | |
bool | rtouch_is_touched (void) |
True if touched. | |
static void | rtouch_prepare_adc (void) |
Prepare ADC for touch measuring. | |
static void | rtouch_prepare_detect (void) |
Prepare the rtouch detect function. | |
static void | rtouch_process_samples (void) |
Called from soft IRQ or ADC ISR to compute coordinates from raw samples. | |
static void | rtouch_pullup_y_surface (void) |
static void | rtouch_resample (void) |
Called from rtouch_process_samples or from timer module to start a. | |
void | rtouch_set_calibration_matrix (rtouch_calibration_matrix_t const *source) |
Assign a calibration matrix to the driver. | |
void | rtouch_set_event_handler (rtouch_event_handler_t handler) |
Set new event handler. | |
static void | rtouch_start_read (uint32_t channel) |
static void | rtouch_tristate_x_surface (void) |
static void | rtouch_tristate_y_surface (void) |
Variables | |
static struct rtouch_struct | rtouch |
static const gpio_map_t | rtouch_gpio_xmap |
static const gpio_map_t | rtouch_gpio_ymap |
typedef enum rtouch_state_enum rtouch_state_t |
enum rtouch_state_enum |
Driver state names.
Definition at line 40 of file rtouch.c.
00041 { 00042 RTOUCH_DISABLED, 00043 RTOUCH_NOT_TOUCHED, 00044 RTOUCH_READING_XL, 00045 RTOUCH_READING_XH, 00046 RTOUCH_READING_YL, 00047 RTOUCH_READING_YH, 00048 RTOUCH_PROCESSING, 00049 RTOUCH_TOUCHED, 00050 } rtouch_state_t;
void rtouch_adc_int_handler | ( | void | ) |
ADC conversion complete interrupt handler.
This interrupt handler is called repeatedly as multiple samples are taken from all touch panel lines in proper order. When all samples have been taken, the ISR defers further handling to the TOUCH_ProcessSamples() function, either through a soft IRQ or directly within interrupt domain, depending on the TOUCH_USE_SOFTIRQ setting from "config_touch.h".
Definition at line 894 of file rtouch.c.
References rtouch_struct::rawX, rtouch_struct::rawY, rtouch, RTOUCH_ADC, RTOUCH_ADC_XH_CHANNEL, RTOUCH_ADC_XL_CHANNEL, RTOUCH_ADC_YH_CHANNEL, RTOUCH_ADC_YL_CHANNEL, rtouch_get_adc_value(), rtouch_gradient_x_surface(), rtouch_ground_x_surface(), RTOUCH_OVERSAMPLING, rtouch_process_samples(), RTOUCH_PROCESSING, rtouch_pullup_y_surface(), RTOUCH_READING_XH, RTOUCH_READING_XL, RTOUCH_READING_YH, RTOUCH_READING_YL, rtouch_start_read(), rtouch_tristate_y_surface(), and rtouch_struct::state.
Referenced by rtouch_prepare_adc().
00895 { 00896 static uint8_t sample_count = 0; 00897 00898 #ifdef AVR32_ADCIFA_100_H_INCLUDED 00899 volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC; 00900 adcifa->scr = 0x1; 00901 #endif 00902 switch (rtouch.state) { 00903 00904 case RTOUCH_READING_XL: 00905 // Store the raw sample value for later. 00906 rtouch.rawY += rtouch_get_adc_value(); 00907 00908 // Change state and start ADC reading of XH 00909 // when enough samples have been taken. 00910 ++sample_count; 00911 if (sample_count < RTOUCH_OVERSAMPLING) { 00912 rtouch_start_read(RTOUCH_ADC_XL_CHANNEL); 00913 } else { 00914 sample_count = 0; 00915 00916 rtouch.state = RTOUCH_READING_XH; 00917 rtouch_start_read(RTOUCH_ADC_XH_CHANNEL); 00918 } 00919 00920 break; 00921 00922 00923 case RTOUCH_READING_XH: 00924 // Add XL and XH samples to form a raw Y position reading. 00925 rtouch.rawY += rtouch_get_adc_value(); 00926 00927 // Change state and start ADC reading of X position from YL line 00928 // when enough samples have been taken. 00929 ++sample_count; 00930 if (sample_count < RTOUCH_OVERSAMPLING) { 00931 rtouch_start_read(RTOUCH_ADC_XH_CHANNEL); 00932 } else { 00933 sample_count = 0; 00934 00935 rtouch.state = RTOUCH_READING_YL; 00936 rtouch_tristate_y_surface(); 00937 rtouch_gradient_x_surface(); 00938 rtouch_start_read(RTOUCH_ADC_YL_CHANNEL); 00939 } 00940 00941 break; 00942 00943 00944 case RTOUCH_READING_YL: 00945 // Store the raw sample for later. 00946 rtouch.rawX += rtouch_get_adc_value(); 00947 00948 // Change state and start ADC reading of YH 00949 // when enough samples have been taken. 00950 ++sample_count; 00951 if (sample_count < RTOUCH_OVERSAMPLING) { 00952 rtouch_start_read(RTOUCH_ADC_YL_CHANNEL); 00953 } else { 00954 sample_count = 0; 00955 00956 rtouch.state = RTOUCH_READING_YH; 00957 rtouch_start_read(RTOUCH_ADC_YH_CHANNEL); 00958 } 00959 break; 00960 00961 00962 case RTOUCH_READING_YH: 00963 // Add YL and YH samples to form a raw X reading. 00964 rtouch.rawX += rtouch_get_adc_value(); 00965 00966 // Configure for detect again 00967 // when enough samples have been taken. 00968 ++sample_count; 00969 if (sample_count < RTOUCH_OVERSAMPLING) { 00970 rtouch_start_read(RTOUCH_ADC_YH_CHANNEL); 00971 } else { 00972 sample_count = 0; 00973 00974 //SLEEPMGR_Unlock( TOUCH_SAMPLE_SLEEP_MODE ); 00975 00976 //prepare for touch detection 00977 rtouch_ground_x_surface(); 00978 rtouch_pullup_y_surface(); 00979 00980 rtouch.state = RTOUCH_PROCESSING; 00981 00982 // The processing of sample or lack of touch is 00983 // deferred to the bottom half of the driver. 00984 #if (TOUCH_USE_SOFTIRQ == 1) 00985 //SOFTIRQ_Raise( TOUCH_SAMPLE_IRQ ); 00986 #else 00987 rtouch_process_samples(); 00988 #endif 00989 } 00990 00991 break; 00992 00993 00994 default: 00995 assert(0); // Always fail on illegal state. 00996 break; 00997 } 00998 }
static void rtouch_clear_adc_flag | ( | void | ) | [static] |
static void rtouch_clear_detect_flag | ( | void | ) | [inline, static] |
Definition at line 147 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_enable(), rtouch_process_samples(), and rtouch_resample().
00148 { 00149 gpio_clear_pin_interrupt_flag(rtouch_gpio_ymap[0].pin); 00150 //gpio_clear_pin_interrupt_flag(rtouch_gpio_ymap[1].pin); 00151 }
void rtouch_compute_calibration_matrix | ( | rtouch_calibration_points_t const * | points, | |
rtouch_calibration_matrix_t * | matrix | |||
) |
Compute a calibration matrix from three calibration points.
This function computes a calibration matrix from a set of three calibration points povided by the caller. Use the raw sample values from the event struct when filling data into the calibration point struct. The calibration matrix will be copied into the struct also provided by the user. Use the TOUCH_SetCalibrationMatrix() function to assign a calibration matrix to the driver.
points | Pointer to a calibration point set. | |
matrix | Pointer to the struct where the matrix will be copied. |
Definition at line 589 of file rtouch.c.
References rtouch_calibration_matrix_struct::A, rtouch_calibration_matrix_struct::B, rtouch_calibration_matrix_struct::C, rtouch_calibration_matrix_struct::D, rtouch_calibration_matrix_struct::E, rtouch_calibration_matrix_struct::F, rtouch_calibration_matrix_struct::K, rtouch_calibration_point_struct::panelX, rtouch_calibration_point_struct::panelY, rtouch_calibration_points_struct::point1, rtouch_calibration_points_struct::point2, rtouch_calibration_points_struct::point3, rtouch_calibration_point_struct::rawX, and rtouch_calibration_point_struct::rawY.
Referenced by rtouch_calibrate().
00592 { 00593 // Reference: http://www.embedded.com/story/OEG20020529S0046 00594 00595 // Local copies of touch readings. 00596 int32_t Xr0 = points->point1.rawX; 00597 int32_t Yr0 = points->point1.rawY; 00598 int32_t Xr1 = points->point2.rawX; 00599 int32_t Yr1 = points->point2.rawY; 00600 int32_t Xr2 = points->point3.rawX; 00601 int32_t Yr2 = points->point3.rawY; 00602 00603 // Local copies of display coordinates. 00604 int32_t Xp0 = points->point1.panelX; 00605 int32_t Yp0 = points->point1.panelY; 00606 int32_t Xp1 = points->point2.panelX; 00607 int32_t Yp1 = points->point2.panelY; 00608 int32_t Xp2 = points->point3.panelX; 00609 int32_t Yp2 = points->point3.panelY; 00610 00611 // Compute coefficients for X calibration. 00612 matrix->A = ((Xp0 - Xp2) * (Yr1 - Yr2)) - ((Xp1 - Xp2) * (Yr0 - Yr2)); 00613 matrix->B = ((Xr0 - Xr2) * (Xp1 - Xp2)) - ((Xp0 - Xp2) * (Xr1 - Xr2)); 00614 matrix->C = 00615 Yr0 * ((Xr2 * Xp1) - (Xr1 * Xp2)) + 00616 Yr1 * ((Xr0 * Xp2) - (Xr2 * Xp0)) + 00617 Yr2 * ((Xr1 * Xp0) - (Xr0 * Xp1)); 00618 00619 // Compute coefficients for X calibration. 00620 matrix->D = ((Yp0 - Yp2) * (Yr1 - Yr2)) - ((Yp1 - Yp2) * (Yr0 - Yr2)); 00621 matrix->E = ((Xr0 - Xr2) * (Yp1 - Yp2)) - ((Yp0 - Yp2) * (Xr1 - Xr2)); 00622 matrix->F = 00623 Yr0 * ((Xr2 * Yp1) - (Xr1 * Yp2)) + 00624 Yr1 * ((Xr0 * Yp2) - (Xr2 * Yp0)) + 00625 Yr2 * ((Xr1 * Yp0) - (Xr0 * Yp1)); 00626 00627 // Compute common denominator. 00628 matrix->K = ((Xr0 - Xr2) * (Yr1 - Yr2)) - ((Xr1 - Xr2) * (Yr0 - Yr2)); 00629 }
void rtouch_detect_int_handler | ( | void | ) |
Low-level detect interrupt handler.
This interrupt handler is called when a low level on the YL/YH lines is detected, which means the panel is touched. The driver sets up and starts a sample of the XL line, and defers further handling to the ADC interrupt.
Definition at line 855 of file rtouch.c.
References rtouch_struct::rawX, rtouch_struct::rawY, rtouch, RTOUCH_ADC_XL_CHANNEL, rtouch_disable_detect_int(), rtouch_gradient_y_surface(), RTOUCH_NOT_TOUCHED, RTOUCH_READING_XL, rtouch_start_read(), RTOUCH_TOUCHED, rtouch_tristate_x_surface(), and rtouch_struct::state.
Referenced by rtouch_prepare_detect().
00856 { 00857 // Change detection should only fire if previously untouched, or when 00858 // we need a resample while touched. 00859 assert( (rtouch.state == RTOUCH_NOT_TOUCHED) || 00860 (rtouch.state == RTOUCH_TOUCHED) ); 00861 00862 // Keep change detection disabled until panel is not touched anymore. 00863 rtouch_disable_detect_int(); 00864 00865 // Clear accumulators. 00866 rtouch.rawX = 0; 00867 rtouch.rawY = 0; 00868 00869 // Change state and start ADC reading of Y position from XL line. 00870 // ADC interrupt will take over further handling. 00871 rtouch.state = RTOUCH_READING_XL; 00872 rtouch_tristate_x_surface(); 00873 rtouch_gradient_y_surface(); 00874 00875 00876 rtouch_start_read(RTOUCH_ADC_XL_CHANNEL); 00877 //SLEEPMGR_Lock( TOUCH_SAMPLE_SLEEP_MODE ); 00878 }
void rtouch_disable | ( | void | ) |
Disable driver.
This function disables the driver, stopping all touch detection and sampling. This will save power.
Definition at line 495 of file rtouch.c.
References rtouch, rtouch_disable_adc_int(), rtouch_disable_detect_int(), RTOUCH_DISABLED, rtouch_ground_x_surface(), rtouch_ground_y_surface(), and rtouch_struct::state.
Referenced by rtouch_init().
00496 { 00497 // Do not try to disable if already disabled. That will mess up the 00498 // sleep manager lock state. 00499 if (rtouch.state == RTOUCH_DISABLED) { 00500 return; 00501 } 00502 00503 // Need this to be atomic, in case we are interrupting an ongoing sampling. 00504 //ENTER_CRITICAL_SECTION( DISABLE ); 00505 // Shutdown driver. 00506 rtouch_disable_detect_int(); 00507 rtouch_disable_adc_int(); 00508 //LEAVE_CRITICAL_SECTION( DISABLE ); 00509 00510 // Continue shutdown. 00511 rtouch.state = RTOUCH_DISABLED; 00512 00513 //SLEEPMGR_Unlock( TOUCH_DETECT_SLEEP_MODE ); 00514 00515 // Ground touch panel to save power. 00516 rtouch_ground_x_surface(); 00517 rtouch_ground_y_surface(); 00518 }
static void rtouch_disable_adc_int | ( | void | ) | [inline, static] |
Disable interrupts for the touch channels.
Definition at line 230 of file rtouch.c.
References RTOUCH_ADC, RTOUCH_ADC_XH_CHANNEL, RTOUCH_ADC_XL_CHANNEL, RTOUCH_ADC_YH_CHANNEL, and RTOUCH_ADC_YL_CHANNEL.
Referenced by rtouch_disable().
00231 { 00232 #ifdef AVR32_ADCIFA_100_H_INCLUDED 00233 volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC; 00234 // Enable interrupt for sequencer 0. 00235 adcifa->idr = 0x1; 00236 #else 00237 volatile avr32_adc_t *adc = &RTOUCH_ADC; 00238 adc->idr = RTOUCH_ADC_XL_CHANNEL | RTOUCH_ADC_YL_CHANNEL 00239 | RTOUCH_ADC_XH_CHANNEL | RTOUCH_ADC_YH_CHANNEL; 00240 #endif 00241 }
static void rtouch_disable_detect_int | ( | void | ) | [inline, static] |
Definition at line 153 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_detect_int_handler(), and rtouch_disable().
00154 { 00155 // disable interrupt for Y lines 00156 // clear the pin interrupt, or otherwise it will trigger when 00157 //enabled again 00158 gpio_clear_pin_interrupt_flag(rtouch_gpio_ymap[0].pin); 00159 gpio_disable_pin_interrupt(rtouch_gpio_ymap[0].pin); 00160 }
static void rtouch_disable_pullup_on_y_surface | ( | void | ) | [inline, static] |
Remove pullups from Y lines.
Definition at line 315 of file rtouch.c.
References rtouch_gpio_ymap.
00316 { 00317 gpio_disable_pin_pull_up(rtouch_gpio_ymap[0].pin); 00318 gpio_disable_pin_pull_up(rtouch_gpio_ymap[1].pin); 00319 00320 }
void rtouch_enable | ( | void | ) |
Enable driver.
This function enables the driver, resuming touch detecting and sampling.
Definition at line 524 of file rtouch.c.
References rtouch_struct::last_event, rtouch, rtouch_clear_adc_flag(), rtouch_clear_detect_flag(), RTOUCH_DISABLED, rtouch_enable_adc_int(), rtouch_enable_detect_int(), rtouch_ground_x_surface(), RTOUCH_NO_EVENT, RTOUCH_NOT_TOUCHED, rtouch_pullup_y_surface(), rtouch_struct::state, and rtouch_event_struct::type.
Referenced by main().
00525 { 00526 // Do not try to enable if already enabled. That will mess up the 00527 // sleep manager lock state. 00528 if (rtouch.state != RTOUCH_DISABLED) { 00529 return; 00530 } 00531 00532 // Setup panel for touch detection. 00533 rtouch_ground_x_surface(); 00534 rtouch_pullup_y_surface(); 00535 00536 // Initial state is untouched, but if touched, the change detect ISR 00537 // will fire immediately. 00538 rtouch.state = RTOUCH_NOT_TOUCHED; 00539 rtouch.last_event.type = RTOUCH_NO_EVENT; 00540 00541 // Start driver. 00542 //SLEEPMGR_Lock( TOUCH_DETECT_SLEEP_MODE ); 00543 rtouch_clear_adc_flag(); 00544 rtouch_enable_adc_int(); 00545 00546 rtouch_clear_detect_flag(); 00547 rtouch_enable_detect_int(); 00548 }
static void rtouch_enable_adc_int | ( | void | ) | [inline, static] |
Enable interrupts for the touch channels.
Definition at line 215 of file rtouch.c.
References RTOUCH_ADC, RTOUCH_ADC_XH_CHANNEL, RTOUCH_ADC_XL_CHANNEL, RTOUCH_ADC_YH_CHANNEL, and RTOUCH_ADC_YL_CHANNEL.
Referenced by rtouch_enable().
00216 { 00217 #ifdef AVR32_ADCIFA_100_H_INCLUDED 00218 volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC; 00219 // Enable interrupt for sequencer 0. 00220 adcifa->ier = 0x1; 00221 #else 00222 volatile avr32_adc_t *adc = &RTOUCH_ADC; 00223 adc->ier = RTOUCH_ADC_XL_CHANNEL | RTOUCH_ADC_YL_CHANNEL 00224 | RTOUCH_ADC_XH_CHANNEL | RTOUCH_ADC_YH_CHANNEL; 00225 #endif 00226 }
static void rtouch_enable_detect_int | ( | void | ) | [inline, static] |
Definition at line 140 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_enable(), rtouch_process_samples(), and rtouch_resample().
00141 { 00142 //enable interrupt for Y lines 00143 gpio_enable_pin_interrupt(rtouch_gpio_ymap[0].pin, GPIO_FALLING_EDGE); 00144 00145 }
static uint32_t rtouch_get_adc_value | ( | void | ) | [inline, static] |
Return last converted value.
Definition at line 420 of file rtouch.c.
References RTOUCH_ADC.
Referenced by rtouch_adc_int_handler().
00421 { 00422 #ifdef AVR32_ADCIFA_100_H_INCLUDED 00423 uint32_t value; 00424 00425 if (s_current_channel < 8) 00426 { 00427 value = ADCIFA_read_resx_sequencer_0(0); 00428 } 00429 else 00430 { 00431 value = (~ADCIFA_read_resx_sequencer_0(0)); 00432 } 00433 00434 return value; 00435 #else 00436 volatile avr32_adc_t *adc = &RTOUCH_ADC; 00437 return adc->lcdr; 00438 #endif 00439 }
void rtouch_get_calibration_matrix | ( | rtouch_calibration_matrix_t * | destination | ) |
Get the current calibration matrix.
This function retrieves the current calibration matrix from the driver. Use this function to store a calibration matrix to e.g. EEPROM.
destination | Pointer to struct where matrix will be copied. |
Definition at line 649 of file rtouch.c.
References rtouch_struct::calibration_matrix, and rtouch.
00650 { 00651 destination = rtouch.calibration_matrix; 00652 }
void rtouch_get_event | ( | rtouch_event_t * | event | ) |
Get last event.
This function will copy the last event information to a struct. The caller is reponsible for providing memory.
event | Pointer to the struct where event will be copied. |
Definition at line 557 of file rtouch.c.
References rtouch_struct::last_event, and rtouch.
Referenced by rtouch_calibrate().
00558 { 00559 *event = rtouch.last_event; 00560 }
rtouch_event_handler_t rtouch_get_event_handler | ( | void | ) |
Get current event handler.
This function returns the old event handler. Use this to store the old handler while replacing it for a short while, e.g. for calibration.
Definition at line 678 of file rtouch.c.
References rtouch_struct::event_handler, and rtouch.
Referenced by rtouch_calibrate().
00679 { 00680 return rtouch.event_handler; 00681 }
static void rtouch_gradient_x_surface | ( | void | ) | [inline, static] |
Drive voltage gradient on X surface (XL=GND, XH=VDD).
Definition at line 324 of file rtouch.c.
References rtouch_gpio_xmap.
Referenced by rtouch_adc_int_handler().
00325 { 00326 // control pins by gpio controller 00327 gpio_enable_gpio(rtouch_gpio_xmap, 00328 sizeof(rtouch_gpio_xmap)/ sizeof(rtouch_gpio_xmap[0])); 00329 gpio_disable_pin_pull_up(rtouch_gpio_xmap[0].pin); 00330 gpio_disable_pin_pull_up(rtouch_gpio_xmap[1].pin); 00331 00332 gpio_clr_gpio_pin(rtouch_gpio_xmap[0].pin); 00333 gpio_set_gpio_pin(rtouch_gpio_xmap[1].pin); 00334 }
static void rtouch_gradient_y_surface | ( | void | ) | [inline, static] |
Drive voltage gradient on Y surface (YL=GND, YH=VDD).
Definition at line 338 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_detect_int_handler(), and rtouch_resample().
00339 { 00340 // control pins by gpio controller 00341 gpio_enable_gpio(rtouch_gpio_ymap, 00342 sizeof(rtouch_gpio_ymap)/ sizeof(rtouch_gpio_ymap[0])); 00343 gpio_disable_pin_pull_up(rtouch_gpio_ymap[0].pin); 00344 gpio_disable_pin_pull_up(rtouch_gpio_ymap[1].pin); 00345 gpio_clr_gpio_pin(rtouch_gpio_ymap[0].pin); 00346 gpio_set_gpio_pin(rtouch_gpio_ymap[1].pin); 00347 }
void rtouch_ground_x_surface | ( | void | ) | [inline] |
Drive X lines to ground.
Definition at line 264 of file rtouch.c.
References rtouch_gpio_xmap.
Referenced by rtouch_adc_int_handler(), rtouch_disable(), and rtouch_enable().
00265 { 00266 // control pins by gpio controller 00267 //gpio_enable_gpio(rtouch_gpio_xmap, 00268 // sizeof(rtouch_gpio_xmap)/ sizeof(rtouch_gpio_xmap[0])); 00269 00270 // enable pins as gpio (sets as input) 00271 // to avoid a spike due to a Y-surface that is tristatet and 00272 // X-surface that was gradiented we need to set XH as input first. 00273 // Otherwise the voltage on the signal line will rise to VDD. This is 00274 // not an issue to the measurement but it helps to let the signal look 00275 // nice and thus we perhaps improve the EMI a bit. 00276 gpio_enable_gpio_pin(rtouch_gpio_xmap[1].pin); 00277 gpio_enable_gpio_pin(rtouch_gpio_xmap[0].pin); 00278 00279 // set ouput low 00280 gpio_clr_gpio_pin(rtouch_gpio_xmap[1].pin); 00281 gpio_clr_gpio_pin(rtouch_gpio_xmap[0].pin); 00282 }
void rtouch_ground_y_surface | ( | void | ) | [inline] |
Drive Y lines to ground.
Definition at line 286 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_disable().
00287 { 00288 // control pins by gpio controller 00289 //gpio_enable_gpio(rtouch_gpio_ymap, 00290 // sizeof(rtouch_gpio_ymap)/ sizeof(rtouch_gpio_ymap[0])); 00291 00292 gpio_enable_gpio_pin(rtouch_gpio_ymap[1].pin); 00293 gpio_enable_gpio_pin(rtouch_gpio_ymap[0].pin); 00294 // set ouput low 00295 gpio_clr_gpio_pin(rtouch_gpio_ymap[0].pin); 00296 gpio_clr_gpio_pin(rtouch_gpio_ymap[1].pin); 00297 }
void rtouch_init | ( | void | ) |
Initialize touch panel driver.
This function initializes all peripherals required to detect a touch and sample its position on a resistive touch panel. Call this function before using any other features of this driver.
The driver is disabled initially, so you must call TOUCH_Enable() before any touch events will be detected.
Definition at line 453 of file rtouch.c.
References rtouch_struct::event_handler, rtouch_struct::last_event, rtouch, rtouch_disable(), RTOUCH_NO_EVENT, RTOUCH_NOT_TOUCHED, rtouch_prepare_adc(), rtouch_prepare_detect(), rtouch_struct::state, TOUCH_SAMPLE_IRQ, and rtouch_event_struct::type.
Referenced by main().
00454 { 00455 // Start with no event handler. 00456 rtouch.event_handler = NULL; 00457 00458 #ifdef AVR32_ADCIFA_100_H_INCLUDED 00459 // GPIO pin/adc-function map. 00460 static const gpio_map_t ADCIFA_GPIO_MAP = 00461 { 00462 {AVR32_ADCREF0_PIN,AVR32_ADCREF0_FUNCTION}, 00463 {AVR32_ADCREFP_PIN,AVR32_ADCREFP_FUNCTION}, 00464 {AVR32_ADCREFN_PIN,AVR32_ADCREFN_FUNCTION} 00465 }; 00466 gpio_enable_module(ADCIFA_GPIO_MAP, sizeof(ADCIFA_GPIO_MAP) / sizeof(ADCIFA_GPIO_MAP[0])); 00467 #endif 00468 00469 // Prepare required peripherals. 00470 rtouch_prepare_adc(); 00471 rtouch_prepare_detect(); 00472 00473 #if (TOUCH_USE_SOFTIRQ == 1) 00474 // Use a soft IRQ for bottom half of driver. 00475 SOFTIRQ_SetHandler( TOUCH_SAMPLE_IRQ, TOUCH_ProcessSamples ); 00476 SOFTIRQ_Enable( TOUCH_SAMPLE_IRQ ); 00477 #endif 00478 00479 // TOUCH_Disable() will take care of the rest of the initialization. 00480 // We need to lock the sleep mode, and set a non-disable state for the 00481 // driver, since TOUCH_Disable() will unlock the sleep mode, and also 00482 // check that the driver is not disabled already. 00483 00484 //SLEEPMGR_Lock( TOUCH_DETECT_SLEEP_MODE ); 00485 rtouch.state = RTOUCH_NOT_TOUCHED; 00486 rtouch.last_event.type = RTOUCH_NO_EVENT; 00487 rtouch_disable(); 00488 }
bool rtouch_is_detect | ( | void | ) | [inline] |
Test if a touch is detected.
Checks if one of the Y lines is pulled low due to a touch on the surface. The Y lines must be pulled up and the X lines must be GND in order to work.
return True if a touch is detected and false if no touch is detected.
Definition at line 250 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_process_samples(), and rtouch_resample().
00251 { 00252 // check if one of the Y lines is pulled low 00253 if( !gpio_get_pin_value(rtouch_gpio_ymap[0].pin) 00254 || !gpio_get_pin_value(rtouch_gpio_ymap[1].pin)) 00255 { 00256 return true; 00257 } 00258 else 00259 return false; 00260 }
bool rtouch_is_touched | ( | void | ) |
True if touched.
This function returns true if the touch panel is currently touched.
Definition at line 568 of file rtouch.c.
References rtouch_struct::last_event, rtouch, RTOUCH_MOVE, RTOUCH_PRESS, and rtouch_event_struct::type.
Referenced by rtouch_calibrate().
00569 { 00570 bool is_touched = (rtouch.last_event.type == RTOUCH_PRESS) 00571 || (rtouch.last_event.type == RTOUCH_MOVE); 00572 00573 return is_touched; 00574 }
static void rtouch_prepare_adc | ( | void | ) | [inline, static] |
Prepare ADC for touch measuring.
Register the interrupt handler, set sample, hold and startup time.
Definition at line 193 of file rtouch.c.
References RTOUCH_ADC, rtouch_adc_int_handler(), RTOUCH_ADC_INT_LEVEL, and RTOUCH_ADC_IRQ.
Referenced by rtouch_init().
00194 { 00195 Disable_global_interrupt(); 00196 INTC_register_interrupt(&rtouch_adc_int_handler, RTOUCH_ADC_IRQ, 00197 RTOUCH_ADC_INT_LEVEL); 00198 Enable_global_interrupt(); 00199 00200 #ifdef AVR32_ADCIFA_100_H_INCLUDED 00201 volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC; 00202 // configure ADCIFA 00203 adcifa_configure(adcifa, &adcifa_opt, FOSC0); 00204 #else 00205 volatile avr32_adc_t *adc = &RTOUCH_ADC; 00206 adc_configure(adc); 00207 // we need to lower the adc clock under 5MHz 00208 // adc_clock = adc_input_clock /((prescaler + 1)*2) 00209 adc->mr |= 0x1 << AVR32_ADC_MR_PRESCAL_OFFSET; 00210 #endif 00211 }
static void rtouch_prepare_detect | ( | void | ) | [inline, static] |
Prepare the rtouch detect function.
A touch can be detected by setting the Y lines (or X lines) as inputs and enabling the internal pull-ups for these pins. The other lines, X in this case are connected to GND. By a touch the Y lines will be pulled low and an interrupt can be triggered on a low level detect.
This function does the registering of the interrupt handler for the touch detect. Currently we use a GPIO interrupt, but here it is only possible to trigger on edges but actually we should trigger on a low level. Anyway this should work too. Here we use the YL line as source input for the edge detection but it is also possible to use YH.
Definition at line 132 of file rtouch.c.
References rtouch_detect_int_handler(), and rtouch_gpio_ymap.
Referenced by rtouch_init().
00133 { 00134 Disable_global_interrupt(); 00135 INTC_register_interrupt(&rtouch_detect_int_handler, 00136 AVR32_GPIO_IRQ_0 + rtouch_gpio_ymap[0].pin/8, 0); 00137 Enable_global_interrupt(); 00138 }
void rtouch_process_samples | ( | void | ) | [static] |
Called from soft IRQ or ADC ISR to compute coordinates from raw samples.
This function takes care of the final processing and calibration of the raw panel sample values, or lack of touch. This function is called by the ADC interrupt handler, either via the soft IRQ module or directly from the ISR, depending on the TOUCH_USE_SOFTIRQ setting from "config_touch.h".
This function will also automatically start a resample of the panel, either immediately or delayed via the timer module, depending on the TOUCH_USE_IMMEDIATE_RESAMPLE setting from "config_touch.h".
Definition at line 696 of file rtouch.c.
References rtouch_calibration_matrix_struct::A, rtouch_calibration_matrix_struct::B, rtouch_calibration_matrix_struct::C, rtouch_struct::calibration_matrix, rtouch_calibration_matrix_struct::D, rtouch_calibration_matrix_struct::E, rtouch_struct::event_handler, rtouch_calibration_matrix_struct::F, rtouch_calibration_matrix_struct::K, rtouch_struct::last_event, rtouch_event_struct::panelX, rtouch_event_struct::panelY, rtouch_event_struct::rawX, rtouch_struct::rawX, rtouch_event_struct::rawY, rtouch_struct::rawY, rtouch, rtouch_clear_detect_flag(), rtouch_enable_detect_int(), rtouch_is_detect(), RTOUCH_MOVE, RTOUCH_NO_EVENT, RTOUCH_NOT_TOUCHED, RTOUCH_PRESS, RTOUCH_RELEASE, rtouch_resample(), RTOUCH_SAMPLESCALE, RTOUCH_TOUCHED, rtouch_struct::state, and rtouch_event_struct::type.
Referenced by rtouch_adc_int_handler().
00697 { 00698 // Catch divide-by-zero, in case matrix is not initialized. 00699 // The calibrated values will be unusable anyway, so setting tempK to 1 00700 // is ok. 00701 int32_t tempK = rtouch.calibration_matrix->K; 00702 if (tempK == 0) { 00703 tempK = 1; 00704 } 00705 00706 // Scale sample values down to 10 bit, to avoid matrix computing 00707 // overflow. 00708 // The extra 1 compensates for XL/XH and YL/YH being added together. 00709 rtouch.rawX >>= (RTOUCH_SAMPLESCALE + 1); 00710 rtouch.rawY >>= (RTOUCH_SAMPLESCALE + 1); 00711 00712 // Compute calibrated X position. 00713 int32_t panelX = 00714 (rtouch.calibration_matrix->A * rtouch.rawX) + 00715 (rtouch.calibration_matrix->B * rtouch.rawY) + 00716 rtouch.calibration_matrix->C; 00717 panelX /= tempK; 00718 00719 // Compute calibrated Y position. 00720 int32_t panelY = 00721 (rtouch.calibration_matrix->D * rtouch.rawX) + 00722 (rtouch.calibration_matrix->E * rtouch.rawY) + 00723 rtouch.calibration_matrix->F; 00724 panelY /= tempK; 00725 00726 // Finished processing, so state is now "touched". 00727 rtouch.state = RTOUCH_TOUCHED; 00728 00729 // If both YL and YH are high, the Y surface is not in contact 00730 // with the X surface anymore, so we change state. 00731 // This will happen if the release action happened while we 00732 // computed the panel coordinates. 00733 rtouch_clear_detect_flag(); 00734 if (rtouch_is_detect() == false) { 00735 rtouch.state = RTOUCH_NOT_TOUCHED; 00736 00737 // If the last event was "press" or "move", 00738 // we now have to send a "release" event. 00739 if ((rtouch.last_event.type == RTOUCH_PRESS) || 00740 (rtouch.last_event.type == RTOUCH_MOVE)) 00741 { 00742 rtouch.last_event.type = RTOUCH_RELEASE; 00743 00744 // Call event handler if registered. 00745 if (rtouch.event_handler != NULL) { 00746 rtouch.event_handler( &rtouch.last_event ); 00747 } 00748 } 00749 00750 // Enable detect ISR so that the next touch will be detected. 00751 rtouch_enable_detect_int(); 00752 } else { 00753 // Any change since last time we sampled? Just touched? 00754 // Perhaps only moved? 00755 bool sendEvent = false; 00756 00757 // If it _was_ released or no event at all, it's now touched. 00758 if ((rtouch.last_event.type == RTOUCH_NO_EVENT) || 00759 (rtouch.last_event.type == RTOUCH_RELEASE)) 00760 { 00761 rtouch.last_event.type = RTOUCH_PRESS; 00762 sendEvent = true; 00763 } 00764 // If this was not a new touch, was the "touch" moved then? 00765 else if ((rtouch.last_event.panelX != panelX) || 00766 (rtouch.last_event.panelY != panelY)) 00767 { 00768 rtouch.last_event.type = RTOUCH_MOVE; 00769 sendEvent = true; 00770 } 00771 00772 // Update coordinates and call event handler if something new 00773 // happened. 00774 if (sendEvent) { 00775 rtouch.last_event.rawX = rtouch.rawX; 00776 rtouch.last_event.rawY = rtouch.rawY; 00777 rtouch.last_event.panelX = panelX; 00778 rtouch.last_event.panelY = panelY; 00779 00780 // Call event handler if registered. 00781 if (rtouch.event_handler != NULL) { 00782 rtouch.event_handler( &rtouch.last_event ); 00783 } 00784 } 00785 00786 #if (TOUCH_USE_IMMEDIATE_RESAMPLE == 1) 00787 // Now, start an immediate resample, to keep up to date 00788 // with touch position. 00789 rtouch_resample(); 00790 #else 00791 # error "Delayed resample not implemented yet." 00792 #endif 00793 } 00794 }
static void rtouch_pullup_y_surface | ( | void | ) | [inline, static] |
Enable pull-ups for Y lines. Used to be able to trigger an interrupt upon a touch.
Definition at line 303 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_adc_int_handler(), and rtouch_enable().
00304 { 00305 // control pins by gpio controller 00306 // this means implicitely: set as input 00307 gpio_enable_gpio(rtouch_gpio_ymap, 00308 sizeof(rtouch_gpio_ymap)/ sizeof(rtouch_gpio_ymap[0])); 00309 gpio_enable_pin_pull_up(rtouch_gpio_ymap[0].pin); 00310 gpio_enable_pin_pull_up(rtouch_gpio_ymap[1].pin); 00311 }
void rtouch_resample | ( | void | ) | [static] |
Called from rtouch_process_samples or from timer module to start a.
This function starts a new sampling of the touch panel. It will be called by the driver repeatedly as long as the touch panel stays touched.
Definition at line 801 of file rtouch.c.
References rtouch_struct::event_handler, rtouch_struct::last_event, rtouch_struct::rawX, rtouch_struct::rawY, rtouch, RTOUCH_ADC_XL_CHANNEL, rtouch_clear_detect_flag(), rtouch_enable_detect_int(), rtouch_gradient_y_surface(), rtouch_is_detect(), RTOUCH_NOT_TOUCHED, RTOUCH_READING_XL, RTOUCH_RELEASE, rtouch_start_read(), RTOUCH_TOUCHED, rtouch_tristate_x_surface(), rtouch_struct::state, and rtouch_event_struct::type.
Referenced by rtouch_process_samples().
00802 { 00803 // Resampling should only occur when panel is touched. 00804 assert(rtouch.state == RTOUCH_TOUCHED ); 00805 00806 // If both YL and YH are high, the Y surface is not in contact 00807 // with the X surface anymore, so we change state. 00808 rtouch_clear_detect_flag(); 00809 if (rtouch_is_detect() == false) { 00810 // Update state. 00811 rtouch.state = RTOUCH_NOT_TOUCHED; 00812 rtouch.last_event.type = RTOUCH_RELEASE; 00813 00814 // Call event handler, if registered. 00815 if (rtouch.event_handler != NULL) { 00816 rtouch.event_handler( &rtouch.last_event ); 00817 } 00818 rtouch_enable_detect_int(); 00819 return; 00820 } 00821 00822 // Enable touch detection again. If the panel is still pressed, then the 00823 // detect ISR will fire immediately and start sampling. 00824 // TODO revisit since we can not trigger on low level interrupt, so we 00825 // have to think about something else here 00826 //rtouch_enable_detect_int(); 00827 // Clear accumulators. 00828 rtouch.rawX = 0; 00829 rtouch.rawY = 0; 00830 00831 // Change state and start ADC reading of Y position from XL line. 00832 // ADC interrupt will take over further handling. 00833 rtouch.state = RTOUCH_READING_XL; 00834 rtouch_gradient_y_surface(); 00835 rtouch_tristate_x_surface(); 00836 00837 rtouch_start_read(RTOUCH_ADC_XL_CHANNEL); 00838 }
void rtouch_set_calibration_matrix | ( | rtouch_calibration_matrix_t const * | source | ) |
Assign a calibration matrix to the driver.
This function assigns a calibration matrix to the driver.
source | Pointer to matrix data. |
Definition at line 637 of file rtouch.c.
References rtouch_struct::calibration_matrix, and rtouch.
Referenced by rtouch_calibrate().
00638 { 00639 rtouch.calibration_matrix = (rtouch_calibration_matrix_t *)source; 00640 }
void rtouch_set_event_handler | ( | rtouch_event_handler_t | handler | ) |
Set new event handler.
This function sets a new touch event handler. The handler is called whenever the position or state of the touch screen changes. The handler is called from the TOUCH_ProcessSamples and TOUCH_Resample functions.
handler | Pointer to new event handler, or NULL to disable handler. |
Definition at line 662 of file rtouch.c.
References rtouch_struct::event_handler, and rtouch.
Referenced by main(), and rtouch_calibrate().
00663 { 00664 // This needs to be an atomic operation, in case an interrupt 00665 // fires while we change the handler. 00666 //ENTER_CRITICAL_SECTION( SET_HANDLER ); 00667 rtouch.event_handler = handler; 00668 //LEAVE_CRITICAL_SECTION( SET_HANDLER ); 00669 }
static void rtouch_start_read | ( | uint32_t | channel | ) | [static] |
Definition at line 386 of file rtouch.c.
References RTOUCH_ADC, RTOUCH_ADC_XH_CHANNEL, RTOUCH_ADC_XL_CHANNEL, RTOUCH_ADC_YH_CHANNEL, and RTOUCH_ADC_YL_CHANNEL.
Referenced by rtouch_adc_int_handler(), rtouch_detect_int_handler(), and rtouch_resample().
00387 { 00388 #ifdef AVR32_ADCIFA_100_H_INCLUDED 00389 volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC; 00390 s_current_channel = channel; 00391 00392 if (channel < 8) 00393 { 00394 adcifa_sequence_conversion_opt[0].channel_p = channel; // Positive Channel 00395 adcifa_sequence_conversion_opt[0].channel_n = AVR32_ADCIFA_INN_GNDANA; // Negative Channel 00396 adcifa_sequence_conversion_opt[0].gain = ADCIFA_SHG_1; // Gain of the conversion 00397 } 00398 else 00399 { 00400 adcifa_sequence_conversion_opt[0].channel_p = AVR32_ADCIFA_INP_GNDANA; // Positive Channel 00401 adcifa_sequence_conversion_opt[0].channel_n = channel; // Negative Channel 00402 adcifa_sequence_conversion_opt[0].gain = ADCIFA_SHG_1; // Gain of the conversion 00403 } 00404 adcifa_configure_sequencer(adcifa, 0, &adcifa_sequence_opt, adcifa_sequence_conversion_opt); 00405 00406 adcifa_start_sequencer(adcifa, 0); 00407 #else 00408 volatile avr32_adc_t *adc = &RTOUCH_ADC; 00409 // disable all touch channels 00410 adc->chdr = RTOUCH_ADC_XL_CHANNEL | RTOUCH_ADC_YL_CHANNEL 00411 | RTOUCH_ADC_XH_CHANNEL | RTOUCH_ADC_YH_CHANNEL; 00412 // enable current touch channel 00413 adc->cher = channel; 00414 adc_start(adc); 00415 #endif 00416 }
static void rtouch_tristate_x_surface | ( | void | ) | [inline, static] |
Definition at line 349 of file rtouch.c.
References rtouch_gpio_xmap.
Referenced by rtouch_detect_int_handler(), and rtouch_resample().
00350 { 00351 // tristate by setting as input 00352 //gpio_enable_gpio(rtouch_gpio_xmap, 00353 // sizeof(rtouch_gpio_xmap)/ sizeof(rtouch_gpio_xmap[0])); 00354 00355 gpio_enable_gpio_pin(rtouch_gpio_xmap[1].pin); 00356 gpio_enable_gpio_pin(rtouch_gpio_xmap[0].pin); 00357 00358 00359 gpio_disable_pin_pull_up(rtouch_gpio_xmap[0].pin); 00360 gpio_disable_pin_pull_up(rtouch_gpio_xmap[1].pin); 00361 // enable ADC to control the pins 00362 gpio_enable_module(rtouch_gpio_xmap, 00363 sizeof(rtouch_gpio_xmap)/ sizeof(rtouch_gpio_xmap[0])); 00364 }
static void rtouch_tristate_y_surface | ( | void | ) | [inline, static] |
Definition at line 366 of file rtouch.c.
References rtouch_gpio_ymap.
Referenced by rtouch_adc_int_handler().
00367 { 00368 // tristate by setting as input 00369 //gpio_enable_gpio(rtouch_gpio_ymap, 00370 // sizeof(rtouch_gpio_ymap)/ sizeof(rtouch_gpio_ymap[0])); 00371 00372 gpio_enable_gpio_pin(rtouch_gpio_ymap[1].pin); 00373 gpio_enable_gpio_pin(rtouch_gpio_ymap[0].pin); 00374 00375 00376 gpio_disable_pin_pull_up(rtouch_gpio_ymap[0].pin); 00377 gpio_disable_pin_pull_up(rtouch_gpio_ymap[1].pin); 00378 // enable ADC to control the pins 00379 gpio_enable_module(rtouch_gpio_ymap, 00380 sizeof(rtouch_gpio_ymap)/ sizeof(rtouch_gpio_ymap[0])); 00381 }
struct rtouch_struct rtouch [static] |
Definition at line 71 of file rtouch.c.
Referenced by rtouch_adc_int_handler(), rtouch_detect_int_handler(), rtouch_disable(), rtouch_enable(), rtouch_get_calibration_matrix(), rtouch_get_event(), rtouch_get_event_handler(), rtouch_init(), rtouch_is_touched(), rtouch_process_samples(), rtouch_resample(), rtouch_set_calibration_matrix(), and rtouch_set_event_handler().
const gpio_map_t rtouch_gpio_xmap [static] |
Initial value:
{ { .pin = RTOUCH_XL_PIN, .function = RTOUCH_XL_PIN_FUNCTION }, { .pin = RTOUCH_XH_PIN, .function = RTOUCH_XH_PIN_FUNCTION } }
Definition at line 84 of file rtouch.c.
Referenced by rtouch_gradient_x_surface(), rtouch_ground_x_surface(), and rtouch_tristate_x_surface().
const gpio_map_t rtouch_gpio_ymap [static] |
Initial value:
{ { .pin = RTOUCH_YL_PIN, .function = RTOUCH_YL_PIN_FUNCTION }, { .pin = RTOUCH_YH_PIN, .function = RTOUCH_YH_PIN_FUNCTION } }
Definition at line 73 of file rtouch.c.
Referenced by rtouch_clear_detect_flag(), rtouch_disable_detect_int(), rtouch_disable_pullup_on_y_surface(), rtouch_enable_detect_int(), rtouch_gradient_y_surface(), rtouch_ground_y_surface(), rtouch_is_detect(), rtouch_prepare_detect(), rtouch_pullup_y_surface(), and rtouch_tristate_y_surface().