00001
00038 #ifndef CPU_TOUCH_H
00039 #define CPU_TOUCH_H
00040
00041 #include <compiler.h>
00042 #include <stdint.h>
00043 #include <gpio.h>
00044 #include <pmic.h>
00045 #include <regs/xmega_adc.h>
00046 #include <regs/xmega_portcfg.h>
00047
00069 #define TOUCH_XL_MASK (1U << CONFIG_TOUCH_XL_PIN)
00070 #define TOUCH_XR_MASK (1U << CONFIG_TOUCH_XR_PIN)
00071 #define TOUCH_YD_MASK (1U << CONFIG_TOUCH_YD_PIN)
00072 #define TOUCH_YU_MASK (1U << CONFIG_TOUCH_YU_PIN)
00073 #define TOUCH_X_MASK (TOUCH_XL_MASK | TOUCH_XR_MASK)
00074 #define TOUCH_Y_MASK (TOUCH_YD_MASK | TOUCH_YU_MASK)
00075
00076
00084 __always_inline static void touch_priv_port_init(void)
00085 {
00086
00087 port_write_reg(CONFIG_TOUCH_PORT_BASE, INT0MASK, TOUCH_Y_MASK);
00088
00089
00090
00091
00092 port_write_reg(CONFIG_TOUCH_PORT_BASE, OUTCLR, TOUCH_YD_MASK);
00093 port_write_reg(CONFIG_TOUCH_PORT_BASE, OUTSET, TOUCH_YU_MASK);
00094 }
00095
00096
00100 __always_inline static void touch_priv_port_enable_int(void)
00101 {
00102 uint8_t int_bits;
00103
00104
00105 int_bits = port_read_reg(CONFIG_TOUCH_PORT_BASE, INTCTRL);
00106 int_bits = PORT_BFINS(INTCTRL_INT0LVL, CONFIG_TOUCH_PORT_INTLVL,
00107 int_bits);
00108 port_write_reg(CONFIG_TOUCH_PORT_BASE, INTCTRL, int_bits);
00109 }
00110
00111
00115 __always_inline static void touch_priv_port_disable_int(void)
00116 {
00117 uint8_t int_bits;
00118
00119
00120 int_bits = port_read_reg(CONFIG_TOUCH_PORT_BASE, INTCTRL);
00121 int_bits = PORT_BFINS(INTCTRL_INT0LVL, PMIC_INTLVL_OFF, int_bits);
00122 port_write_reg(CONFIG_TOUCH_PORT_BASE, INTCTRL, int_bits);
00123 }
00124
00125
00132 __always_inline static bool touch_priv_port_is_int_flag_set(void)
00133 {
00134 uint8_t int_flags;
00135
00136
00137 int_flags = port_read_reg(CONFIG_TOUCH_PORT_BASE, INTFLAGS);
00138 int_flags &= PORT_BIT(INTFLAGS_INT0IF);
00139
00140 return (int_flags != 0);
00141 }
00142
00143
00147 __always_inline static void touch_priv_port_clear_int_flag(void)
00148 {
00149 port_write_reg(CONFIG_TOUCH_PORT_BASE, INTFLAGS, PORT_BIT(INTFLAGS_INT0IF));
00150 }
00151
00152
00161 __always_inline static void touch_priv_port_set_detection(void)
00162 {
00163
00164 portcfg_write_reg(PORTCFG_BASE, MPCMASK, TOUCH_Y_MASK);
00165 port_write_reg(CONFIG_TOUCH_PORT_BASE, PIN0CTRL,
00166 PORT_BF(PINCTRL_OPC, PORT_PINCTRL_PULLUP)
00167 | PORT_BF(PINCTRL_ISC, PORT_PINCTRL_ISC_LEVEL));
00168 port_write_reg(CONFIG_TOUCH_PORT_BASE, DIRCLR, TOUCH_Y_MASK);
00169
00170
00171 port_write_reg(CONFIG_TOUCH_PORT_BASE, OUTCLR, TOUCH_X_MASK);
00172 port_write_reg(CONFIG_TOUCH_PORT_BASE, DIRSET, TOUCH_X_MASK);
00173 }
00174
00175
00179 __always_inline static void touch_priv_port_set_gradient_x(void)
00180 {
00181
00182 portcfg_write_reg(PORTCFG_BASE, MPCMASK, TOUCH_Y_MASK);
00183 port_write_reg(CONFIG_TOUCH_PORT_BASE, PIN0CTRL,
00184 PORT_BF(PINCTRL_OPC, PORT_PINCTRL_TOTEM));
00185 port_write_reg(CONFIG_TOUCH_PORT_BASE, DIRCLR, TOUCH_Y_MASK);
00186
00187
00188 port_write_reg(CONFIG_TOUCH_PORT_BASE, OUTSET, TOUCH_XR_MASK);
00189 port_write_reg(CONFIG_TOUCH_PORT_BASE, DIRSET, TOUCH_X_MASK);
00190 }
00191
00192
00200 __always_inline static void touch_priv_port_set_gradient_y(void)
00201 {
00202
00203 portcfg_write_reg(PORTCFG_BASE, MPCMASK, TOUCH_X_MASK);
00204 port_write_reg(CONFIG_TOUCH_PORT_BASE, PIN0CTRL,
00205 PORT_BF(PINCTRL_OPC, PORT_PINCTRL_TOTEM));
00206 port_write_reg(CONFIG_TOUCH_PORT_BASE, DIRCLR, TOUCH_X_MASK);
00207
00208
00209 port_write_reg(CONFIG_TOUCH_PORT_BASE, DIRSET, TOUCH_Y_MASK);
00210 }
00211
00212
00218 __always_inline static void touch_priv_adc_init(void)
00219 {
00220
00221 adc_write_reg(CONFIG_TOUCH_ADC_BASE, CTRLB,
00222 ADC_BF(RESOLUTION, ADC_RESOLUTION_12BIT));
00223 adc_write_reg(CONFIG_TOUCH_ADC_BASE, PRESCALER,
00224 ADC_BF(PRESCALER, ADC_PRESCALER_DIV512));
00225 adc_write_reg(CONFIG_TOUCH_ADC_BASE, REFCTRL,
00226 ADC_BF(REFSEL, ADC_REFSEL_INTVCC));
00227
00228
00229 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH0, CTRL,
00230 ADCCH_BF(INPUTMODE, ADCCH_INPUTMODE_SINGLEENDED));
00231 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH1, CTRL,
00232 ADCCH_BF(INPUTMODE, ADCCH_INPUTMODE_SINGLEENDED));
00233
00234
00235 adc_write_reg(CONFIG_TOUCH_ADC_BASE, CTRLA, ADC_BIT(ENABLE));
00236 }
00237
00238
00244 __always_inline static void touch_priv_adc_enable_int(void)
00245 {
00246 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH1, INTCTRL,
00247 ADCCH_BF(INTLVL, CONFIG_TOUCH_ADC_INTLVL));
00248 }
00249
00250
00256 __always_inline static void touch_priv_adc_disable_int(void)
00257 {
00258 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH1, INTCTRL,
00259 ADCCH_BF(INTLVL, ADCCH_INTLVL_OFF));
00260 }
00261
00262
00266 __always_inline static void touch_priv_adc_clear_int_flag(void)
00267 {
00268 adc_write_reg(CONFIG_TOUCH_ADC_BASE, INTFLAGS, ADC_BIT(CH1IF));
00269 }
00270
00271
00282 __always_inline static void touch_priv_adc_set_surface_y(void)
00283 {
00284 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH0, MUXCTRL,
00285 ADCCH_BF(MUXPOS, CONFIG_TOUCH_XL_PIN));
00286 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH1, MUXCTRL,
00287 ADCCH_BF(MUXPOS, CONFIG_TOUCH_XR_PIN));
00288 }
00289
00290
00297 __always_inline static void touch_priv_adc_set_surface_x(void)
00298 {
00299 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH0, MUXCTRL,
00300 ADCCH_BF(MUXPOS, CONFIG_TOUCH_YD_PIN));
00301 adcch_write_reg(CONFIG_TOUCH_ADC_BASE, CH1, MUXCTRL,
00302 ADCCH_BF(MUXPOS, CONFIG_TOUCH_YU_PIN));
00303 }
00304
00305
00311 __always_inline static void touch_priv_adc_start(void)
00312 {
00313 adc_write_reg(CONFIG_TOUCH_ADC_BASE, CTRLA,
00314 ADC_BF(CHSTART, ADC_CHSTART_0 | ADC_CHSTART_1)
00315 | ADC_BIT(ENABLE));
00316 }
00317
00318
00324 __always_inline static uint16_t touch_priv_adc_get_x(void)
00325 {
00326 uint16_t adc_result;
00327
00328
00329 adc_result = adc_read_reg(CONFIG_TOUCH_ADC_BASE, CH0RESL);
00330 adc_result |= adc_read_reg(CONFIG_TOUCH_ADC_BASE, CH0RESH) << 8;
00331 adc_result += adc_read_reg(CONFIG_TOUCH_ADC_BASE, CH1RESL);
00332 adc_result += adc_read_reg(CONFIG_TOUCH_ADC_BASE, CH1RESH) << 8;
00333
00334
00335 adc_result >>= 1;
00336
00337 return (adc_result);
00338 }
00339
00340
00346 #define touch_priv_adc_get_y touch_priv_adc_get_x
00347
00349
00350 #endif