/* * Created on: Jul 29, 2024 * * touch my pepper */ #include #include #include "touch.h" const uint16_t tbtn_adc_ch[2] = {TBTN2, TBTN1}; uint16_t tbtn_idle_cal[2]; uint16_t touch_read_adc(u8 adc_ch) { ADC_RegularChannelConfig(TBTN_ADC, adc_ch, 1, ADC_SampleTime_7Cycles5); TBTN_ADC->IDATAR1 = 0x10; // charging time TBTN_ADC->RDATAR = 0x08; // discharging time while(!ADC_GetFlagStatus(TBTN_ADC, ADC_FLAG_EOC)); return (uint16_t)TBTN_ADC->RDATAR; } uint16_t touch_read(u8 btn_ch) { if (btn_ch < 2) return touch_read_adc(tbtn_adc_ch[btn_ch]); else return 0xffff; } uint8_t touch_read_pushed(uint8_t btn_ch) { if (touch_read_adc(tbtn_adc_ch[btn_ch]) < tbtn_idle_cal[btn_ch] - TBTN_PUSHED_COUNTS) return 1; return 0; } void touch_cal() { uint8_t i, j; uint16_t val; for (i = 0; i < 2; i++) { val = 0xffff; while (val > TBTN_IDLE_WINDOW_HI) { // be warned, // we can hang here until the buttons can be calibrated val = touch_read(tbtn_adc_ch[i]); } // get average of 8 readings val = 0; for (j = 0; j < 8; j++) { val += touch_read(tbtn_adc_ch[i]); } val >>= 3; tbtn_idle_cal[i] = val; } } void touch_init() { ADC_InitTypeDef adc = {0}; // make sure ADC peripheral is clocked and // pins are configured as analog inputs before calling this function. // configure ADC for touchkey use adc.ADC_Mode = ADC_Mode_Independent; adc.ADC_ScanConvMode = DISABLE; adc.ADC_ContinuousConvMode = DISABLE; adc.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; adc.ADC_DataAlign = ADC_DataAlign_Right; adc.ADC_NbrOfChannel = 1; ADC_Init(TBTN_ADC, &adc); // enable ADC, then enable touchkey ADC_Cmd(TBTN_ADC, ENABLE); TBTN_ADC->CTLR1 |= ADC_CTLR1_BUFEN | ADC_CTLR1_TKENABLE; // calibrate idle touch touch_cal(); }