diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/imx233/touchscreen-imx233.c | 84 |
1 files changed, 37 insertions, 47 deletions
diff --git a/firmware/target/arm/imx233/touchscreen-imx233.c b/firmware/target/arm/imx233/touchscreen-imx233.c index e76d7a49e3..c4d2f4d726 100644 --- a/firmware/target/arm/imx233/touchscreen-imx233.c +++ b/firmware/target/arm/imx233/touchscreen-imx233.c | |||
@@ -46,28 +46,53 @@ enum touch_state_t | |||
46 | TOUCH_STATE_VERIFY, /* verify touch */ | 46 | TOUCH_STATE_VERIFY, /* verify touch */ |
47 | }; | 47 | }; |
48 | 48 | ||
49 | #define DEBOUNCE_THRESHOLD 100 | 49 | #define NR_SAMPLES 10 |
50 | #define SAMPLES_THRESHOLD 4 | 50 | #define DELAY 1 |
51 | 51 | ||
52 | static enum touch_state_t touch_state; | 52 | static enum touch_state_t touch_state; |
53 | static int touch_chan = -1; | 53 | static int touch_chan = -1; |
54 | static int touch_delay = -1; | 54 | static int touch_delay = -1; |
55 | static int touch_x, touch_y, nr_samples; | 55 | static int touch_x, touch_y; |
56 | /* once a touch is confirmed, the parameters are copied to these value for | 56 | /* once a touch is confirmed, the parameters are copied to these value for |
57 | * instant readout by button code. */ | 57 | * instant readout by button code. */ |
58 | static bool old_touch_detect = false; | 58 | static bool old_touch_detect = false; |
59 | static int old_touch_x, old_touch_y; | 59 | static int old_touch_x, old_touch_y; |
60 | 60 | ||
61 | static void kick_measure(bool pull_x, bool pull_y, bool detect, int lradc_phys) | 61 | static void process(void); |
62 | |||
63 | void INT_TOUCH_DETECT(void) | ||
64 | { | ||
65 | process(); | ||
66 | } | ||
67 | |||
68 | static void touch_channel_irq(int chan) | ||
62 | { | 69 | { |
70 | imx233_icoll_enable_interrupt(INT_SRC_LRADC_CHx(chan), false); | ||
71 | imx233_lradc_enable_channel_irq(chan, false); | ||
72 | process(); | ||
73 | } | ||
74 | |||
75 | static void kick_measure(bool pull_x, bool pull_y, bool detect, int src) | ||
76 | { | ||
77 | if(touch_chan >= 0) | ||
78 | imx233_lradc_release_channel(touch_chan); | ||
79 | touch_chan = imx233_lradc_acquire_channel(src, TIMEOUT_NOBLOCK); | ||
80 | if(touch_chan < 0) | ||
81 | panicf("touchscreen: cannot get adc channel"); | ||
82 | /* enable interrupt */ | ||
83 | imx233_lradc_set_channel_irq_callback(touch_chan, &touch_channel_irq); | ||
84 | imx233_icoll_enable_interrupt(INT_SRC_LRADC_CHx(touch_chan), true); | ||
85 | imx233_lradc_enable_channel_irq(touch_chan, true); | ||
63 | /* setup measurement: x- pull down and x+ pull up */ | 86 | /* setup measurement: x- pull down and x+ pull up */ |
64 | imx233_lradc_setup_touch(pull_x, pull_y, pull_x, pull_y, detect); | 87 | imx233_lradc_setup_touch(pull_x, pull_y, pull_x, pull_y, detect); |
65 | imx233_lradc_enable_touch_detect_irq(false); | 88 | imx233_lradc_enable_touch_detect_irq(false); |
66 | imx233_lradc_enable_channel_irq(touch_chan, true); | 89 | imx233_lradc_enable_channel_irq(touch_chan, true); |
67 | /* measure channel, no accumulation */ | 90 | /* measure channel, no accumulation */ |
68 | imx233_lradc_setup_channel(touch_chan, false, false, 0, lradc_phys); | 91 | imx233_lradc_setup_channel(touch_chan, false, true, NR_SAMPLES - 1, src); |
92 | imx233_lradc_clear_channel(touch_chan); | ||
69 | /* use a delay */ | 93 | /* use a delay */ |
70 | imx233_lradc_setup_delay(touch_delay, 1 << touch_chan, 0, 0, 8); | 94 | imx233_lradc_setup_delay(touch_delay, 1 << touch_chan, 1 << touch_delay, |
95 | NR_SAMPLES -1, DELAY); | ||
71 | imx233_lradc_kick_delay(touch_delay); | 96 | imx233_lradc_kick_delay(touch_delay); |
72 | } | 97 | } |
73 | 98 | ||
@@ -78,7 +103,6 @@ static void enter_state(enum touch_state_t state) | |||
78 | { | 103 | { |
79 | case TOUCH_STATE_WAIT: | 104 | case TOUCH_STATE_WAIT: |
80 | imx233_lradc_setup_touch(false, false, false, false, true); | 105 | imx233_lradc_setup_touch(false, false, false, false, true); |
81 | imx233_lradc_enable_channel_irq(touch_chan, false); | ||
82 | imx233_lradc_enable_touch_detect_irq(true); | 106 | imx233_lradc_enable_touch_detect_irq(true); |
83 | break; | 107 | break; |
84 | case TOUCH_STATE_MEASURE_X: | 108 | case TOUCH_STATE_MEASURE_X: |
@@ -95,7 +119,6 @@ static void enter_state(enum touch_state_t state) | |||
95 | 119 | ||
96 | static void process(void) | 120 | static void process(void) |
97 | { | 121 | { |
98 | int val; | ||
99 | switch(touch_state) | 122 | switch(touch_state) |
100 | { | 123 | { |
101 | case TOUCH_STATE_WAIT: | 124 | case TOUCH_STATE_WAIT: |
@@ -110,32 +133,12 @@ static void process(void) | |||
110 | } | 133 | } |
111 | break; | 134 | break; |
112 | case TOUCH_STATE_MEASURE_X: | 135 | case TOUCH_STATE_MEASURE_X: |
113 | /* read value */ | 136 | touch_x = imx233_lradc_read_channel(touch_chan) / NR_SAMPLES; |
114 | val = imx233_lradc_read_channel(touch_chan); | 137 | enter_state(TOUCH_STATE_MEASURE_Y); |
115 | /* if value is too far from average, restart */ | ||
116 | if(nr_samples > 0 && abs(val - touch_x) > DEBOUNCE_THRESHOLD) | ||
117 | nr_samples = 0; | ||
118 | touch_x = (touch_x * nr_samples + val) / (nr_samples + 1); | ||
119 | nr_samples++; | ||
120 | /* if we have enough samples, measure Y */ | ||
121 | if(nr_samples > SAMPLES_THRESHOLD) | ||
122 | enter_state(TOUCH_STATE_MEASURE_Y); | ||
123 | else | ||
124 | imx233_lradc_kick_delay(touch_delay); | ||
125 | break; | 138 | break; |
126 | case TOUCH_STATE_MEASURE_Y: | 139 | case TOUCH_STATE_MEASURE_Y: |
127 | /* read value */ | 140 | touch_y = imx233_lradc_read_channel(touch_chan) / NR_SAMPLES; |
128 | val = imx233_lradc_read_channel(touch_chan); | ||
129 | /* if value is too far from average, restart */ | ||
130 | if(nr_samples > 0 && abs(val - touch_y) > DEBOUNCE_THRESHOLD) | ||
131 | nr_samples = 0; | ||
132 | touch_y = (touch_y * nr_samples + val) / (nr_samples + 1); | ||
133 | nr_samples++; | ||
134 | /* if we have enough samples, verify touch */ | ||
135 | if(nr_samples > SAMPLES_THRESHOLD) | ||
136 | enter_state(TOUCH_STATE_VERIFY); | 141 | enter_state(TOUCH_STATE_VERIFY); |
137 | else | ||
138 | imx233_lradc_kick_delay(touch_delay); | ||
139 | break; | 142 | break; |
140 | case TOUCH_STATE_VERIFY: | 143 | case TOUCH_STATE_VERIFY: |
141 | if(imx233_lradc_read_touch_detect()) | 144 | if(imx233_lradc_read_touch_detect()) |
@@ -154,31 +157,18 @@ static void process(void) | |||
154 | } | 157 | } |
155 | } | 158 | } |
156 | 159 | ||
157 | void INT_TOUCH_DETECT(void) | ||
158 | { | ||
159 | process(); | ||
160 | } | ||
161 | |||
162 | static void touch_channel_irq(int chan) | ||
163 | { | ||
164 | (void) chan; | ||
165 | process(); | ||
166 | } | ||
167 | |||
168 | void imx233_touchscreen_init(void) | 160 | void imx233_touchscreen_init(void) |
169 | { | 161 | { |
170 | touch_chan = imx233_lradc_acquire_channel(LRADC_SRC_XPLUS, TIMEOUT_NOBLOCK); | ||
171 | touch_delay = imx233_lradc_acquire_delay(TIMEOUT_NOBLOCK); | 162 | touch_delay = imx233_lradc_acquire_delay(TIMEOUT_NOBLOCK); |
172 | if(touch_chan < 0 || touch_delay < 0) | 163 | if(touch_delay < 0) |
173 | panicf("Cannot acquire channel and delays for touchscreen measurement"); | 164 | panicf("Cannot acquire channel and delays for touchscreen measurement"); |
174 | imx233_touchscreen_enable(false); | 165 | imx233_touchscreen_enable(false); |
175 | } | 166 | } |
176 | 167 | ||
177 | void imx233_touchscreen_enable(bool enable) | 168 | void imx233_touchscreen_enable(bool enable) |
178 | { | 169 | { |
179 | enter_state(TOUCH_STATE_WAIT); | 170 | if(enable) |
180 | imx233_lradc_set_channel_irq_callback(touch_chan, &touch_channel_irq); | 171 | enter_state(TOUCH_STATE_WAIT); |
181 | imx233_icoll_enable_interrupt(INT_SRC_LRADC_CHx(touch_chan), enable); | ||
182 | imx233_icoll_enable_interrupt(INT_SRC_TOUCH_DETECT, enable); | 172 | imx233_icoll_enable_interrupt(INT_SRC_TOUCH_DETECT, enable); |
183 | } | 173 | } |
184 | 174 | ||