00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <stdint.h>
00016 #include <stdbool.h>
00017 #include "board.h"
00018 #include "compiler.h"
00019 #include "assert.h"
00020 #include "gpio.h"
00021 #include "intc.h"
00022
00023
00024 #include "rtouch.h"
00025 #include "conf_rtouch.h"
00026
00027 #if (TOUCH_USE_SOFTIRQ == 1)
00028 # include "softirq.h"
00029 #endif
00030
00031 #ifdef AVR32_ADCIFA_100_H_INCLUDED
00032 #include "adcifa.h"
00033 #else
00034 #include "adc.h"
00035 #endif
00036
00037
00038
00040 typedef enum rtouch_state_enum
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;
00051
00052 struct rtouch_struct {
00053
00055 rtouch_state_t state;
00057 rtouch_event_t last_event;
00058
00060 int16_t rawX;
00062 int16_t rawY;
00064 rtouch_event_handler_t event_handler;
00066 rtouch_calibration_matrix_t *calibration_matrix;
00067 };
00068
00069
00070
00071 static struct rtouch_struct rtouch;
00072
00073 static const gpio_map_t rtouch_gpio_ymap = {
00074 {
00075 .pin = RTOUCH_YL_PIN,
00076 .function = RTOUCH_YL_PIN_FUNCTION
00077 },
00078 {
00079 .pin = RTOUCH_YH_PIN,
00080 .function = RTOUCH_YH_PIN_FUNCTION
00081 }
00082 };
00083
00084 static const gpio_map_t rtouch_gpio_xmap = {
00085 {
00086 .pin = RTOUCH_XL_PIN,
00087 .function = RTOUCH_XL_PIN_FUNCTION
00088 },
00089 {
00090 .pin = RTOUCH_XH_PIN,
00091 .function = RTOUCH_XH_PIN_FUNCTION
00092 }
00093 };
00094
00095
00096 void rtouch_adc_int_handler(void);
00097 void rtouch_detect_int_handler(void);
00098
00100 static void rtouch_process_samples(void);
00102
00103 static void rtouch_resample(void);
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00132 static void inline rtouch_prepare_detect(void)
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 }
00139
00140 static void inline rtouch_enable_detect_int(void)
00141 {
00142
00143 gpio_enable_pin_interrupt(rtouch_gpio_ymap[0].pin, GPIO_FALLING_EDGE);
00144
00145 }
00146
00147 static void inline rtouch_clear_detect_flag(void)
00148 {
00149 gpio_clear_pin_interrupt_flag(rtouch_gpio_ymap[0].pin);
00150
00151 }
00152
00153 static void inline rtouch_disable_detect_int(void)
00154 {
00155
00156
00157
00158 gpio_clear_pin_interrupt_flag(rtouch_gpio_ymap[0].pin);
00159 gpio_disable_pin_interrupt(rtouch_gpio_ymap[0].pin);
00160 }
00161
00162 #ifdef AVR32_ADCIFA_100_H_INCLUDED
00163 volatile avr32_adcifa_t *adcifa = &AVR32_ADCIFA;
00164 int adc_values[1];
00165
00166 adcifa_opt_t adcifa_opt = {
00167 .frequency = 1000000,
00168 .reference_source = ADCIFA_ADCREF0,
00169 .sample_and_hold_disable = FALSE,
00170 .single_sequencer_mode = FALSE,
00171 .free_running_mode_enable = FALSE,
00172 .sleep_mode_enable = FALSE
00173 };
00174
00175
00176 adcifa_sequencer_opt_t adcifa_sequence_opt = {
00177 .convnb = 1,
00178 .resolution = ADCIFA_SRES_12B,
00179 .trigger_selection = ADCIFA_TRGSEL_SOFT,
00180 .start_of_conversion = ADCIFA_SOCB_ALLSEQ,
00181 .oversampling = ADCIFA_CSWS_WSTATE,
00182 .half_word_adjustment = ADCIFA_HWLA_NOADJ,
00183 .software_acknowledge = ADCIFA_SA_NO_EOS_SOFTACK
00184 };
00185
00186
00187 adcifa_sequencer_conversion_opt_t adcifa_sequence_conversion_opt[1];
00188 #endif
00189
00193 static void inline rtouch_prepare_adc(void)
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
00203 adcifa_configure(adcifa, &adcifa_opt, FOSC0);
00204 #else
00205 volatile avr32_adc_t *adc = &RTOUCH_ADC;
00206 adc_configure(adc);
00207
00208
00209 adc->mr |= 0x1 << AVR32_ADC_MR_PRESCAL_OFFSET;
00210 #endif
00211 }
00212
00215 static void inline rtouch_enable_adc_int(void)
00216 {
00217 #ifdef AVR32_ADCIFA_100_H_INCLUDED
00218 volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC;
00219
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 }
00227
00230 static void inline rtouch_disable_adc_int(void)
00231 {
00232 #ifdef AVR32_ADCIFA_100_H_INCLUDED
00233 volatile avr32_adcifa_t *adcifa = &RTOUCH_ADC;
00234
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 }
00242
00250 bool inline rtouch_is_detect(void)
00251 {
00252
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 }
00261
00264 void inline rtouch_ground_x_surface(void)
00265 {
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 gpio_enable_gpio_pin(rtouch_gpio_xmap[1].pin);
00277 gpio_enable_gpio_pin(rtouch_gpio_xmap[0].pin);
00278
00279
00280 gpio_clr_gpio_pin(rtouch_gpio_xmap[1].pin);
00281 gpio_clr_gpio_pin(rtouch_gpio_xmap[0].pin);
00282 }
00283
00286 void inline rtouch_ground_y_surface(void)
00287 {
00288
00289
00290
00291
00292 gpio_enable_gpio_pin(rtouch_gpio_ymap[1].pin);
00293 gpio_enable_gpio_pin(rtouch_gpio_ymap[0].pin);
00294
00295 gpio_clr_gpio_pin(rtouch_gpio_ymap[0].pin);
00296 gpio_clr_gpio_pin(rtouch_gpio_ymap[1].pin);
00297 }
00298
00303 static void inline rtouch_pullup_y_surface(void)
00304 {
00305
00306
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 }
00312
00315 static void inline rtouch_disable_pullup_on_y_surface(void)
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 }
00321
00324 static void inline rtouch_gradient_x_surface(void)
00325 {
00326
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 }
00335
00338 static void inline rtouch_gradient_y_surface(void)
00339 {
00340
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 }
00348
00349 static void inline rtouch_tristate_x_surface(void)
00350 {
00351
00352
00353
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
00362 gpio_enable_module(rtouch_gpio_xmap,
00363 sizeof(rtouch_gpio_xmap)/ sizeof(rtouch_gpio_xmap[0]));
00364 }
00365
00366 static void inline rtouch_tristate_y_surface(void)
00367 {
00368
00369
00370
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
00379 gpio_enable_module(rtouch_gpio_ymap,
00380 sizeof(rtouch_gpio_ymap)/ sizeof(rtouch_gpio_ymap[0]));
00381 }
00382
00383 #ifdef AVR32_ADCIFA_100_H_INCLUDED
00384 static volatile int s_current_channel;
00385 #endif
00386 static void rtouch_start_read(uint32_t channel)
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;
00395 adcifa_sequence_conversion_opt[0].channel_n = AVR32_ADCIFA_INN_GNDANA;
00396 adcifa_sequence_conversion_opt[0].gain = ADCIFA_SHG_1;
00397 }
00398 else
00399 {
00400 adcifa_sequence_conversion_opt[0].channel_p = AVR32_ADCIFA_INP_GNDANA;
00401 adcifa_sequence_conversion_opt[0].channel_n = channel;
00402 adcifa_sequence_conversion_opt[0].gain = ADCIFA_SHG_1;
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
00410 adc->chdr = RTOUCH_ADC_XL_CHANNEL | RTOUCH_ADC_YL_CHANNEL
00411 | RTOUCH_ADC_XH_CHANNEL | RTOUCH_ADC_YH_CHANNEL;
00412
00413 adc->cher = channel;
00414 adc_start(adc);
00415 #endif
00416 }
00417
00420 static uint32_t inline rtouch_get_adc_value(void)
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 }
00440 static void rtouch_clear_adc_flag(void)
00441 {
00442 }
00443
00444
00453 void rtouch_init(void)
00454 {
00455
00456 rtouch.event_handler = NULL;
00457
00458 #ifdef AVR32_ADCIFA_100_H_INCLUDED
00459
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
00470 rtouch_prepare_adc();
00471 rtouch_prepare_detect();
00472
00473 #if (TOUCH_USE_SOFTIRQ == 1)
00474
00475 SOFTIRQ_SetHandler( TOUCH_SAMPLE_IRQ, TOUCH_ProcessSamples );
00476 SOFTIRQ_Enable( TOUCH_SAMPLE_IRQ );
00477 #endif
00478
00479
00480
00481
00482
00483
00484
00485 rtouch.state = RTOUCH_NOT_TOUCHED;
00486 rtouch.last_event.type = RTOUCH_NO_EVENT;
00487 rtouch_disable();
00488 }
00489
00490
00495 void rtouch_disable(void)
00496 {
00497
00498
00499 if (rtouch.state == RTOUCH_DISABLED) {
00500 return;
00501 }
00502
00503
00504
00505
00506 rtouch_disable_detect_int();
00507 rtouch_disable_adc_int();
00508
00509
00510
00511 rtouch.state = RTOUCH_DISABLED;
00512
00513
00514
00515
00516 rtouch_ground_x_surface();
00517 rtouch_ground_y_surface();
00518 }
00519
00520
00524 void rtouch_enable(void)
00525 {
00526
00527
00528 if (rtouch.state != RTOUCH_DISABLED) {
00529 return;
00530 }
00531
00532
00533 rtouch_ground_x_surface();
00534 rtouch_pullup_y_surface();
00535
00536
00537
00538 rtouch.state = RTOUCH_NOT_TOUCHED;
00539 rtouch.last_event.type = RTOUCH_NO_EVENT;
00540
00541
00542
00543 rtouch_clear_adc_flag();
00544 rtouch_enable_adc_int();
00545
00546 rtouch_clear_detect_flag();
00547 rtouch_enable_detect_int();
00548 }
00549
00550
00557 void rtouch_get_event(rtouch_event_t *event)
00558 {
00559 *event = rtouch.last_event;
00560 }
00561
00562
00568 bool rtouch_is_touched(void)
00569 {
00570 bool is_touched = (rtouch.last_event.type == RTOUCH_PRESS)
00571 || (rtouch.last_event.type == RTOUCH_MOVE);
00572
00573 return is_touched;
00574 }
00575
00576
00589 void rtouch_compute_calibration_matrix(
00590 rtouch_calibration_points_t const * points,
00591 rtouch_calibration_matrix_t * matrix )
00592 {
00593
00594
00595
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
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
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
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
00628 matrix->K = ((Xr0 - Xr2) * (Yr1 - Yr2)) - ((Xr1 - Xr2) * (Yr0 - Yr2));
00629 }
00630
00631
00637 void rtouch_set_calibration_matrix(rtouch_calibration_matrix_t const * source )
00638 {
00639 rtouch.calibration_matrix = (rtouch_calibration_matrix_t *)source;
00640 }
00641
00642
00649 void rtouch_get_calibration_matrix(rtouch_calibration_matrix_t * destination )
00650 {
00651 destination = rtouch.calibration_matrix;
00652 }
00653
00654
00662 void rtouch_set_event_handler(rtouch_event_handler_t handler)
00663 {
00664
00665
00666
00667 rtouch.event_handler = handler;
00668
00669 }
00670
00671
00678 rtouch_event_handler_t rtouch_get_event_handler(void)
00679 {
00680 return rtouch.event_handler;
00681 }
00682
00683
00684
00696 void rtouch_process_samples( void )
00697 {
00698
00699
00700
00701 int32_t tempK = rtouch.calibration_matrix->K;
00702 if (tempK == 0) {
00703 tempK = 1;
00704 }
00705
00706
00707
00708
00709 rtouch.rawX >>= (RTOUCH_SAMPLESCALE + 1);
00710 rtouch.rawY >>= (RTOUCH_SAMPLESCALE + 1);
00711
00712
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
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
00727 rtouch.state = RTOUCH_TOUCHED;
00728
00729
00730
00731
00732
00733 rtouch_clear_detect_flag();
00734 if (rtouch_is_detect() == false) {
00735 rtouch.state = RTOUCH_NOT_TOUCHED;
00736
00737
00738
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
00745 if (rtouch.event_handler != NULL) {
00746 rtouch.event_handler( &rtouch.last_event );
00747 }
00748 }
00749
00750
00751 rtouch_enable_detect_int();
00752 } else {
00753
00754
00755 bool sendEvent = false;
00756
00757
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
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
00773
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
00781 if (rtouch.event_handler != NULL) {
00782 rtouch.event_handler( &rtouch.last_event );
00783 }
00784 }
00785
00786 #if (TOUCH_USE_IMMEDIATE_RESAMPLE == 1)
00787
00788
00789 rtouch_resample();
00790 #else
00791 # error "Delayed resample not implemented yet."
00792 #endif
00793 }
00794 }
00795
00796
00801 void rtouch_resample( void )
00802 {
00803
00804 assert(rtouch.state == RTOUCH_TOUCHED );
00805
00806
00807
00808 rtouch_clear_detect_flag();
00809 if (rtouch_is_detect() == false) {
00810
00811 rtouch.state = RTOUCH_NOT_TOUCHED;
00812 rtouch.last_event.type = RTOUCH_RELEASE;
00813
00814
00815 if (rtouch.event_handler != NULL) {
00816 rtouch.event_handler( &rtouch.last_event );
00817 }
00818 rtouch_enable_detect_int();
00819 return;
00820 }
00821
00822
00823
00824
00825
00826
00827
00828 rtouch.rawX = 0;
00829 rtouch.rawY = 0;
00830
00831
00832
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 }
00839
00840
00841
00842
00843
00850 #if __GNUC__
00851 __attribute__((__interrupt__))
00852 #elif __ICCAVR32__
00853 __interrupt
00854 #endif
00855 void rtouch_detect_int_handler(void)
00856 {
00857
00858
00859 assert( (rtouch.state == RTOUCH_NOT_TOUCHED) ||
00860 (rtouch.state == RTOUCH_TOUCHED) );
00861
00862
00863 rtouch_disable_detect_int();
00864
00865
00866 rtouch.rawX = 0;
00867 rtouch.rawY = 0;
00868
00869
00870
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
00878 }
00879
00880
00889 #if __GNUC__
00890 __attribute__((__interrupt__))
00891 #elif __ICCAVR32__
00892 __interrupt
00893 #endif
00894 void rtouch_adc_int_handler(void)
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
00906 rtouch.rawY += rtouch_get_adc_value();
00907
00908
00909
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
00925 rtouch.rawY += rtouch_get_adc_value();
00926
00927
00928
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
00946 rtouch.rawX += rtouch_get_adc_value();
00947
00948
00949
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
00964 rtouch.rawX += rtouch_get_adc_value();
00965
00966
00967
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
00975
00976
00977 rtouch_ground_x_surface();
00978 rtouch_pullup_y_surface();
00979
00980 rtouch.state = RTOUCH_PROCESSING;
00981
00982
00983
00984 #if (TOUCH_USE_SOFTIRQ == 1)
00985
00986 #else
00987 rtouch_process_samples();
00988 #endif
00989 }
00990
00991 break;
00992
00993
00994 default:
00995 assert(0);
00996 break;
00997 }
00998 }
00999
01000
01001