void get_wave() { uint16_t i; for(i=0; i < WAVE_LENGTH; ) { start_adc(0); wave[i++] = get_adc(); start_adc(1); wave[i++] = get_adc(); } }
/** * \brief Application entry point for adcife example. * * \return Unused (ANSI-C compatibility). */ int main(void) { uint32_t uc_key = 0; /* Initialize the SAM system */ sysclk_init(); board_init(); /* Initialize the UART console */ configure_console(); /* Output example information */ puts(STRING_HEADER); /* Set default ADCIFE test mode. */ g_adc_test_mode.uc_trigger_mode = TRIGGER_MODE_SOFTWARE; g_adc_test_mode.uc_pdc_en = 1; g_adc_test_mode.uc_gain_en = 0; display_menu(); start_dac(); start_adc(); while (1) { /* ADCIFE software trigger per 1s */ if (g_adc_test_mode.uc_trigger_mode == TRIGGER_MODE_SOFTWARE) { adc_start_software_conversion(&g_adc_inst); } if (!usart_read(CONF_UART, &uc_key)) { adc_disable_interrupt(&g_adc_inst, ADC_SEQ_SEOC); display_menu(); set_adc_test_mode(); start_adc(); puts("Press any key to display configuration menu.\r"); } delay_ms(1000); if (g_uc_condone_flag == 1) { if(g_adc_test_mode.uc_pdc_en == 0) { printf("Internal DAC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[0] * VOLT_REF / MAX_DIGITAL)); } else { printf("Internal DAC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[0] * VOLT_REF / MAX_DIGITAL)); printf("Scaled VCC Voltage = %4d mv \r\n", (int)(g_adc_sample_data[1] * VOLT_REF / MAX_DIGITAL)); } g_uc_condone_flag = 0; } } }
static irqreturn_t pen_down_up_isr(int irq, void *dev_ids) { unsigned long data0, data1; int down; data0 = ts_regs->adcdat0; data1 = ts_regs->adcdat1; down = (!(data0 & (1<<15))) && (!(data1 & (1<<15))); if (!down) { printk("pen_down_up_isr: up\n"); wait_for_pen_down(); } else { printk("pen_down_up_isr: down\n"); //wait_for_pen_up(); enter_to_measure_xy(); //enter_to_measure_x(); start_adc(); } /* clear interrupt */ //ts_regs->adcupdn = 0 ; ts_regs->adcclrintpndnup = 0; ts_regs->adcclrint = 0 ; return IRQ_HANDLED; }
/* 定时器函数 */ static void ts_timer(unsigned long data) { struct input_dev *dev = (struct input_dev *)data; /* 得到输入设备 */ struct ts_data *ts = input_get_drvdata(dev); /* 得到私有数据 */ set_adc_wait4int(ts); /* 只有在等待中断模式下才能正确查询铁笔状态 */ if (is_stylus_on(ts)) { /* 铁笔触屏 */ if (ts->count != 0) { /* 已有数据 */ ts->x /= NR_SAMPLING; /* 求 x 坐标平均值 */ ts->y /= NR_SAMPLING; /* 求 y 坐标平均值 */ input_report_abs(dev, ABS_X, ts->x); /* 报告 x 坐标事件 */ input_report_abs(dev, ABS_Y, ts->y); /* 报告 y 坐标事件 */ clear_data(ts); /* 清空坐标数据 */ } else { /* 无数据,说明铁笔刚触屏,ADC 尚未转换 */ input_report_key(dev, BTN_TOUCH, 1); /* 报告触摸事件发生 */ } input_sync(dev); /* 同步事件 */ /* 启动 ADC 转换 */ set_adc_autoxy(ts); start_adc(ts); } else { /* 铁笔离屏 */ clear_data(ts); /* 清空数据 */ input_report_key(dev, BTN_TOUCH, 0); /* 报告触摸事件消失 */ input_sync(dev); /* 同步事件 */ enable_irq(IRQ_TC); /* 使能中断 */ } }
void main() { settings = &settings_data; CyGlobalIntEnable; Backlight_Write(1); disp_reset_Write(0); CyDelayUs(10); disp_reset_Write(1); CyDelayUs(10); Display_Start(); Display_SetContrast(settings->lcd_contrast); #ifdef USE_SPLASHSCREEN load_splashscreen(); #endif IDAC_High_Start(); IDAC_Low_Start(); set_output_mode(OUTPUT_MODE_FEEDBACK); start_adc(); setup(); xTaskCreate(vTaskUI, (signed portCHAR *) "UI", 178, NULL, tskIDLE_PRIORITY + 2, &ui_task); xTaskCreate(vTaskComms, (signed portCHAR *) "UART", 141, NULL, tskIDLE_PRIORITY + 2, &comms_task); prvHardwareSetup(); vTaskStartScheduler(); }
static irqreturn_t adc_irq(int irq, void *dev_id) { static int cnt = 0; int adcdat0,adcdat1; static int x[4],y[4]; adcdat0 = s3c_ts_regs ->adcdat0; adcdat1 = s3c_ts_regs ->adcdat1; /*优化措施 2 :如果ADC完成时,发现触摸笔已经松开,则丢弃此次结果*/ if(s3c_ts_regs->adcdat0 & (1<<15)) { /*已经松开*/ enter_wait_pen_up_mode(); } else { // printk("adc_irq cnt = %d, x=%d, y=%d \n ",++cnt,adcdat0 & 0x3ff,adcdat1 & 0x3ff); /*优化措施3: 多次测量求平均值*/ x[cnt] = adcdat0 & 0x3ff; y[cnt] = adcdat1 & 0x3ff; ++cnt; if (cnt==4) { printk("adc_irq cnt = %d, x=%d, y=%d \n ",cnt,(x[0]+x[1]+x[2]+x[3])/4,(y[0]+y[1]+y[2]+y[3])/4); cnt = 0; enter_wait_pen_up_mode(); } else { enter_measure_xy_mode(); start_adc(); } } return IRQ_HANDLED; }
void irq_adc(void) { if ((ADCDAT0 & (1<<15)) == 0) /* 触摸笔仍然处于按下状态 */ { /* 如果是x坐标, 记录下来, 启动Y坐标的ADC */ if ((ADCTSC & 0x3) == 1) { x = ADCDAT0 & 0xfff; /* 清中断 */ ADCCLRINT = 0; enter_to_measure_y(); start_adc(); } else if ((ADCTSC & 0x3) == 2) { /* 如果是Y坐标, 记录下来, wait_for_pen_up */ y = ADCDAT1 & 0xfff; /* 清中断 */ ADCCLRINT = 0; wait_for_pen_up(); has_get_xy = 1; //printf("[x,y] = [%d, %d]\n\r", x, y); } } else { /* 在ADC期间, 触摸笔已经松开了 */ wait_for_pen_down(); } }
static void ts_timer_func(unsigned long time) { if(!(ts_regs->adcdat0 & (1 << 15))) { start_adc(); } }
void get_sync_wave(uint8_t ch) { uint16_t i,w1,w2; start_adc(0); w1 = get_adc(); for(;;) { start_adc(0); w2 = get_adc(); if(w1 < 512-10 && w2 > 512-10) break; w1 = w2; } for(i=0; i < WAVE_LENGTH; ) { start_adc(ch); wave[i++] = get_adc(); } }
int main() { static const int dcount = 3000; int x; // Output pins DDRB = _BV(DDB1)|_BV(DDB2)|_BV(DDB3)|_BV(DDB4)|_BV(DDB5); DDRD = _BV(DDD4)|_BV(DDD3)|_BV(DDD2)|_BV(DDD1); // Pullups MCUCR &= ~PUD; // Make sure pullups not disabled PORTB |= _BV(PORTB0); PORTD |= _BV(PORTD7)|_BV(PORTD6)|_BV(PORTD5); // CPU clock to 8 MHz (vs default 1 MHz) CLKPR = _BV(CLKPCE); // Enable divisor change CLKPR = 0b00000000; // Divisor = 1 init_adc(); init_timer(); start_adc(); for (;;) { PORTB |= _BV(PORTB1); for ( x=0; x<dcount; ++x ) keys(); PORTB &= ~_BV(PORTB1); for ( x=0; x<dcount; ++x ) keys(); } }
static void s3c_ts_timer_function(unsigned long data) { int adcdat0, adcdat1; int updown; /* 优化措施2: 如果ADC完成时, 发现触摸笔已经松开, 则丢弃此次结果 */ adcdat0 = s3c_ts_regs->adcdat0; adcdat1 = s3c_ts_regs->adcdat1; /* dat0和dat1中bit15都是0, updown才是0, 0是down state */ updown =! (!(adcdat0 & (1<<15))) && (!(adcdat1 & (1<<15))); if (s3c_ts_regs->adcdat1 & (1<<15)) // if(updown) { /* 已经松开 */ enter_wait_pen_down_mode(); } else { /* 测量X/Y坐标 */ enter_measure_xy_mode(); start_adc(); } }
__interrupt void ADC10_ISR (void) { //LED_RED_SWAP(); ChBuff[ChnlPtr&0x0001]=ADC10MEM; ChnlPtr^=0x0001; if (ChnlPtr==5) start_adc(); else AdcValReady=true; }
static void read_adc(void) { cli(); av[adcx] = ADCL; av[adcx] |= ((ADCH & 3) << 8); sei(); ADCSRA |= _BV(ADIF); // Clear interrupt flag adcx ^= 1; // Switch to the other ADC start_adc(); // Start it }
static irqreturn_t adc_irq(int irq, void *dev_id) { static int cnt = 0; static int x[4], y[4]; int adcdat0, adcdat1; /* 优化措施2: 如果ADC完成时, 发现触摸笔已经松开, 则丢弃此次结果 */ adcdat0 = s3c_ts_regs->adcdat0; adcdat1 = s3c_ts_regs->adcdat1; if (s3c_ts_regs->adcdat0 & (1<<15)) { /* 已经松开 */ cnt = 0; input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0); input_report_key(s3c_ts_dev, BTN_TOUCH, 0); input_sync(); enter_wait_pen_down_mode(); } else { // printk("adc_irq cnt = %d, x = %d, y = %d\n", ++cnt, adcdat0 & 0x3ff, adcdat1 & 0x3ff); /* 优化措施3: 多次测量求平均值 */ x[cnt] = adcdat0 & 0x3ff; y[cnt] = adcdat1 & 0x3ff; ++cnt; if (cnt == 4) { /* 优化措施4: 软件过滤 */ if (s3c_filter_ts(x, y)) { //printk("x = %d, y = %d\n", (x[0]+x[1]+x[2]+x[3])/4, (y[0]+y[1]+y[2]+y[3])/4); input_report_abs(s3c_ts_dev, ABS_X, (x[0]+x[1]+x[2]+x[3])/4); input_report_abs(s3c_ts_dev, ABS_Y, (y[0]+y[1]+y[2]+y[3])/4); input_report_abs(s3c_ts_dev, ABS_PRESSURE, 1); input_report_key(s3c_ts_dev, BTN_TOUCH, 1); input_sync(); } cnt = 0; enter_wait_pen_up_mode(); /* 启动定时器处理长按/滑动的情况 */ mod_timer(&ts_timer, jiffies + HZ/100); } else { enter_measure_xy_mode(); start_adc(); } } return IRQ_HANDLED; }
static void s3c_ts_timer_function(unsigned long data) { if(s3c_ts_regs->ADCDAT0 & (1<<15)) { /* Stylus is up */ wait4IntMode_Down(); }else { /* Measure X/Y axis values */ measure_xy_mode(); start_adc();
// 3th里面的自动分离模式启动后需要的中断函数注册,具体函数内容在4.2里面 static irqreturn_t adc_irq(int irq, void *dev_id) { static int cnt = 0; static int x[4], y[4]; // 优化措施3 测量保存4次,然后求平均值 int adcdat0, adcdat1; // 寄存器的bit[15]是判断松开还是按下的 手册447 // X,Y的值存在ADCDAT0 AND ADCDAT1寄存器里面 手册442 part3 // 最低10位为x坐标值,不过这个值是电压值而已,和坐标值没有关系 // &&&&&&&&&&&&*********** 如果ADC启动完成时,发现触摸笔已经松开,则测量值已经不准确,丢弃此次结果。 adcdat0 = s3c_ts_regs->adcdat0 ; adcdat1 = s3c_ts_regs->adcdat1 ; if (s3c_ts_regs->adcdat0 & (1<<15)) { // 如果触摸笔已经松开 cnt = 0; // 优化3 中要每4次求一次平均值 enter_wait_pen_down_mode(); } else { //printk ("adc_irq cnt = %d, x = %d, y = %d\n", ++cnt, s3c_ts_regs->adcdat0 & 0x3ff, adcdat1 & 0x3ff); // *******运行到这里,如果没有等待松开操作,则开发板只进行一次测量后就没有反映了,所以在这里要加上如下语句。 // 优化措施3 多次测量求平均值 x[cnt] = s3c_ts_regs->adcdat0 & 0x3ff; y[cnt] = s3c_ts_regs->adcdat1 & 0x3ff; ++cnt; if (cnt == 4) { //printk ("adc_irq cnt = %d, x = %d, y = %d\n", ++cnt, (x[0]+x[1]+x[2]+x[3])/4, (y[0]+y[1]+y[2]+y[3])/4); // 上面这行错误代码,错误在 ++cnt. printk (" x = %d, y = %d\n", (x[0]+x[1]+x[2]+x[3])/4, (y[0]+y[1]+y[2]+y[3])/4); cnt = 0; enter_wait_pen_up_mode(); } else { enter_measure_xy_mode(); start_adc(); } enter_wait_pen_up_mode(); // 测量完毕要等待触摸笔松开 } return IRQ_HANDLED; }
static irqreturn_t adc_irq(int irq, void *dev_id) { static int cnt = 0; int adcdat0, adcdat1; static int x[4], y[4]; int updown; #if 1 /* 优化措施2: 如果ADC完成时, 发现触摸笔已经松开, 则丢弃此次结果 */ adcdat0 = s3c_ts_regs->adcdat0; adcdat1 = s3c_ts_regs->adcdat1; /* dat0和dat1中bit15都是0, updown才是0, 0是down state */ updown =! (!(adcdat0 & (1<<15))) && (!(adcdat1 & (1<<15))); if (updown) /* 已经松开 */ { cnt = 0; enter_wait_pen_down_mode(); /* 进入等待按下模式 */ } else /* 已经按下 */ { // printk("adc_irq cnt = %d, x = %d, y = %d\n", ++cnt, adcdat0 & 0xfff, adcdat1 & 0xfff); // enter_wait_pen_up_mode(); /* 优化措施3: 多次测量求平均值 */ x[cnt] = adcdat0 & 0xfff; y[cnt] = adcdat1 & 0xfff; ++cnt; if (cnt == 4) { cnt = 0; printk("x = %d, y = %d\n", (x[0]+x[1]+x[2]+x[3])/4, (y[0]+y[1]+y[2]+y[3])/4); enter_wait_pen_up_mode(); /* 进入等待弹起模式 */ } else { enter_measure_xy_mode(); start_adc(); } } #endif #if 0 printk("adc_irq cnt = %d, x = %d, y = %d\n", ++cnt,(int) (s3c_ts_regs->adcdat0 & 0xfff), (int) (s3c_ts_regs->adcdat1 & 0xfff)); enter_wait_pen_up_mode(); #endif return IRQ_HANDLED; }
static void s3c_ts_timer_function(unsigned long data) { if (s3c_ts_regs->adcdat0 & (1<<15)) { /* 已经松开 */ enter_wait_pen_down_mode(); } else { /* 测量X/Y坐标 */ enter_measure_xy_mode(); start_adc(); } }
static irqreturn_t stylus_updown(int irq, void *dev_id) { if(s3c_ts_regs->ADCDAT0 & (1<<15)) { //printk("Stylus up\n"); wait4IntMode_Down(); }else { //printk("Stylus down\n"); //wait4IntMode_Up(); measure_xy_mode(); start_adc(); }
static irqreturn_t stylus_action(int irq, void *dev_id) { static int cnt = 0; long int adcdat0, adcdat1; static long int x[4], y[4]; /* * Extra: Optimization 2 * After the ADC interrupt is finished, if the stylus is up, then discards this results */ adcdat0 = s3c_ts_regs->ADCDAT0; adcdat1 = s3c_ts_regs->ADCDAT1; if(s3c_ts_regs->ADCDAT0 & (1<<15)) { /* Stylus is already up */ cnt = 0; wait4IntMode_Down(); }else { //printk("stylus_action cnt = %d, (x,y) = (%ld,%ld)\n", ++cnt, adcdat0 & 0x3FF, adcdat1 & 0x3FF); /* * Extra: Optimization 3 * Measure many times and calculate the average value */ x[cnt] = adcdat0 & 0x3FF; y[cnt] = adcdat1 & 0x3FF; ++cnt; if(4 == cnt) { /* * Extra: Optimization 4 * Software filter */ if(s3c_filter_ts(x, y)) { printk("(x,y) = (%ld,%ld)\n", AVG_TS(x[0],x[1],x[2],x[3]), AVG_TS(y[0],y[1],y[2],y[3])); } cnt = 0; wait4IntMode_Up(); /* Start timer for handling the slither */ mod_timer(&ts_timer, jiffies + HZ/100); /* HZ/100 = 10ms since HZ = 1s */ }else { measure_xy_mode(); start_adc(); } }
static irqreturn_t pen_down_up_irq(int irq, void *dev_id) { if(s3c_ts_regs->adcdat0 & (1<<15)) { printk("pen up\n"); enter_wait_pen_down_mode(); } else { // printk("pen down\n"); // enter_wait_pen_up_mode(); enter_measure_xy_mode(); start_adc(); } return IRQ_HANDLED; }
/* 中断 IRQ_ADC 处理函数 */ static irqreturn_t adc_handler(int irq, void *dev_id) { struct input_dev *dev = (struct input_dev *)dev_id; /* 得到输入设备 */ struct ts_data *ts = input_get_drvdata(dev); /* 得到私有数据 */ pr_debug("adc_handler: be called, %d time sampling.\n", ts->count); ts->x += ADCDAT0(ts) & S3C2410_ADCDAT0_XPDATA_MASK; /* 读 X 坐标并累加 */ ts->y += ADCDAT1(ts) & S3C2410_ADCDAT1_YPDATA_MASK; /* 读 Y 坐标并累加 */ ts->count++; /* 采样次数加 1 */ if (ts->count < NR_SAMPLING) { /* 如果未达到预定的采样次数 */ set_adc_autoxy(ts); start_adc(ts); /* 启动 ADC 进行转换 */ } else { /* 否则 */ mod_timer(&ts->timer, jiffies+HZ/100); /* 启动定时器 */ } return IRQ_HANDLED; }
// Test the mosfet void mosfet_start_up_test(void) { on_tim1_cc4 = gather_adc_values; TIM_ITConfig(TIM1, TIM_IT_CC4, ENABLE); mosfet_test_step = 1; // apply the step mosfet_test_update_phase(); // trggier a COM event TIM_GenerateEvent(TIM1, TIM_EventSource_COM); set_duty(DUTY(10), DUTY(50)); // PWM 10% duty, CC4 20% set_phase_update_freq(G5_Tone*2, mosfet_test_update_phase); initial_adc_dma_for_mosfet_test(); start_adc(CH_A, ADC_SampleTime_1_5Cycles); while(1); }
static void tiny_ts_timer_function(unsigned long data) { if (tiny_ts_regs->tsdatx1 & (1<<15)) { /* 已经松开 */ input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0); input_report_key(s3c_ts_dev, BTN_TOUCH, 0); input_sync(s3c_ts_dev); enter_wait_pen_down_mode(); } else { /* 测量X/Y坐标 */ enter_measure_xy_mode(); start_adc(); } }
/* *触摸屏触摸中断处理程序 */ static void ts_interrupt(void) { //笔尖按下中断 if((adc_reg->ADCDAT0 & (0x1 << 15)) == 0) { printf("pen down.\n\r"); //设置触摸屏为自动xy轴坐标转换模式 adc_reg->ADCTSC = AUTO_XY_POSITION; start_adc(); } //笔尖抬起中断 else { printf("pen up.\n\r"); //设置触摸屏为等待中断模式,等待按下 adc_reg->ADCTSC = WAIT_INTERRUPT; } }
static irqreturn_t pen_down_up_irq(int irq, void *dev_id) { if (s3c_ts_regs->adcdat0 & (1<<15)) { printk("pen up\n"); //松开才能等待下一次等待模式 enter_wait_pen_down_mode(); } else { // 3th 开始,进行启动ADC,转换x,y坐标 //printk("pen down\n"); //按下进入等待松开模式 //enter_wait_pen_up_mode(); // 触摸屏有xy分别分离模式和自动分离模式,我们取后一种自动分离模式,这种简单。 enter_measure_xy_mode(); start_adc(); } return IRQ_HANDLED; }
static irqreturn_t pen_down_up_irq(int irq, void *dev_id) { if (tiny_ts_regs->tsdatx1 & (1<<15)) { //printk("pen up\n"); input_report_abs(s3c_ts_dev, ABS_PRESSURE, 0); input_report_key(s3c_ts_dev, BTN_TOUCH, 0); input_sync(s3c_ts_dev); enter_wait_pen_down_mode(); } else { //printk("pen down\n"); //enter_wait_pen_up_mode(); enter_measure_xy_mode(); start_adc(); } return IRQ_HANDLED; }
void irq_pen_down_up(void) { if (ADCDAT0 & (1<<15)) { //printf("pen up\n\r"); //ADCTSC &= ~(1<<8); /* Detect Stylus Down Interrupt Signal. */ wait_for_pen_down(); } else { //printf("pen down\n\r"); //wait_for_pen_up(); enter_to_measure_x(); start_adc(); } ADCUPDN = 0; ADCCLRINTPNDNUP = 0; }
static void ts_timer_function(unsigned long data) { unsigned long data0, data1; int down; data0 = ts_regs->adcdat0; data1 = ts_regs->adcdat1; down = (!(data0 & (1<<15))) && (!(data1 & (1<<15))); if (down) { if (cnt == 4) { // report input_report_abs(ts_dev, ABS_X, x); input_report_abs(ts_dev, ABS_Y, y); input_report_key(ts_dev, BTN_TOUCH, 1); input_report_abs(ts_dev, ABS_PRESSURE, 1); input_sync(ts_dev); x = y = cnt = 0; mod_timer(&ts_timer, jiffies + HZ * 10 / 1000); } else { enter_to_measure_xy(); start_adc(); } } else { input_report_key(ts_dev, BTN_TOUCH, 0); input_report_abs(ts_dev, ABS_PRESSURE, 0); input_sync(ts_dev); x = y = cnt = 0; wait_for_pen_down(); } }
static irqreturn_t s3c_ts_pen_updown(int irq, void *dev_id) { if(ts_regs->adcdat0 & (1 << 15)) /* pen抬起 */ { //printk("pen is up.\n"); input_report_key(s3c_ts_dev, BTN_TOUCH, 0); input_sync(s3c_ts_dev); wait_pen_down(); } else { //printk("pen is down.\n"); input_report_key(s3c_ts_dev, BTN_TOUCH, 1); input_sync(s3c_ts_dev); /* 启动ADC转换 */ start_adc(); //wait_pen_up(); } return IRQ_HANDLED; }