⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ucb1400_ts_tinyx.c

📁 基于pxa270的touch screen的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
   }

   buf[head] = cur_data;

   if (++head == BUFSIZE)
      head = 0;
   if (head == tail && tail++ == BUFSIZE)
      tail = 0;

   copy_right = 1;
}



unsigned int ucb1400_adc_read( char channel )
{
   unsigned short flag=0;
   unsigned short val=0;

   flag = AE;
   pxa_ac97_write(&pxa_ac97_codec, 0x66, flag);
   flag |= AS;  
   pxa_ac97_write(&pxa_ac97_codec, 0x66, flag);
   flag |= channel;
   pxa_ac97_write(&pxa_ac97_codec, 0x66, flag);


   for(;;)
     {
        val = pxa_ac97_read(&pxa_ac97_codec, 0x68);
        if ( val & (1<<15) )
            break;
        set_current_state(TASK_INTERRUPTIBLE );
        schedule_timeout(1);
     }

 /* if (channel == AI_TSPY)
      printk(KERN_EMERG" X POSITION IS 0x%08x\n", val);
  else
      printk(KERN_EMERG" Y POSITION IS 0x%08x\n", val);  
  */
  return (val & 0x3ff);
}


static unsigned short read_x_position(void )
{
   
   pxa_ac97_write(&pxa_ac97_codec, 0x64, (1<<4) | (1<<1) | (1<<8) | (1<<11));
   pxa_ac97_write(&pxa_ac97_codec, 0x64, (1<<4) | (1<<1) | (1<<8) | (1<<11));

   pxa_ac97_write(&pxa_ac97_codec, 0x64, (1<<4) | (1<<1) | (2<<8) | (1<<11));

   udelay(55);

   return ucb1400_adc_read( AI_TSPY );
}


static unsigned short read_y_position(void )
{
   pxa_ac97_write(&pxa_ac97_codec, 0x64, (1<<6) | (1<<3) | (1<<8) | (1<<11));
   pxa_ac97_write(&pxa_ac97_codec, 0x64, (1<<6) | (1<<3) | (1<<8) | (1<<11));

   pxa_ac97_write(&pxa_ac97_codec, 0x64, (1<<6) | (1<<3) | (2<<8) | (1<<11));

   udelay(55);

   return ucb1400_adc_read( AI_TSPX );
}


static void read_xy(void )
{
  samples[0].x = read_x_position(  );   
  samples[0].y = read_y_position(  );
  samples[1].x = read_x_position(  );
  samples[1].y = read_y_position(  ); 
 
  new_data( );
 

}



static void wait_for_action(void)
{
	set_GPIO_IRQ_edge(13, GPIO_RISING_EDGE);
	enable_irq(UCB1400_IRQ);   
}


/*IRQ interrupt handle function*/
void ucb1400_IRQ_handle( void)
{

   disable_irq( UCB1400_IRQ );
   pxa_ac97_write(&pxa_ac97_codec, 0x60, 0x0);

   cur_data.pressure = 1; 
   if_pressure = 1;

   read_xy( );


   if(fasync)
        kill_fasync(&fasync, SIGIO, POLL_IN);
   wake_up_interruptible(&ts_wait);

   ts_occur = 1;
 
 return ;
}


void task_queue_timer_func(void * parm )
{
  timer_handle( );

}


static void ucb1400_ts_timer(unsigned long data)
{

   static struct tq_struct task_one=
   {
    routine : task_queue_timer_func,
    data: NULL,
    sync:0,
   };   

  schedule_task(&task_one); 

}


static int ucb1400_ts_starttimer(void)
{
   //modify here can effect other running  application
   unsigned long time_long=jiffies + 2;
    if(!in_timehandle) 
       {
        in_timehandle++;
        init_timer(&timer);
        timer.function = ucb1400_ts_timer;
        timer.expires = time_long ;
        add_timer(&timer);  
       }
   return 0;
}



static TS_EVENT get_data(void)
{
   int last = tail;

   if (++tail == BUFSIZE)
      tail = 0;
   return buf[last];
}


/*Read operation*/
static ssize_t ucb1400_ts_read(struct file *filp, char *buf, size_t count, loff_t *l)
{ 
  TS_EVENT t;
  short out_buf[4];
  int scale;
  pxa_ac97_write(&pxa_ac97_codec, 0x60, 0x0);
  ts_occur = 0;

  short tail=0;//add by bruce
  short head=0;//add by bruce
  
  
  read_xy( );

  pxa_ac97_write(&pxa_ac97_codec, 0x64, MX| PX | PXP | MXP | PYG | MYG | TM_INTERRUPT );

  if (copy_right)
       { 
         t = get_data();
         out_buf[0] = t.pressure;

      if(t.pressure==0)
        {
          tch_queue.head=0;
          tch_queue.tail=0;
          tch_queue.num=0;
          //tch_queueSumX=0;
          //tch_queueSumY=0;
        }
      else
        {
          if(tch_queue.num<QUE_LENTH)
            { 
              tch_queue.tch_queue[tch_queue.tail].x=t.x;
              tch_queue.tch_queue[tch_queue.tail].y=t.y;
              tch_queue.tch_queue[tch_queue.tail].millisecs=t.millisecs;
              tch_queue.num++;
              tch_queue.tail++;        
            }            
          else
            {
              tch_queue.tch_queue[tch_queue.tail].x=t.x;
              tch_queue.tch_queue[tch_queue.tail].y=t.y;
              tch_queue.tch_queue[tch_queue.tail].millisecs=t.millisecs;
              tch_queue.head=(++tch_queue.head)%(QUE_LENTH+1);
              tch_queue.tail=(++tch_queue.tail)%(QUE_LENTH+1);
            }
        }

      if(tch_queue.num>8)
        {
          int difX=0;
          int difY=0;
          int n=0;
          int k=0;
          int sum4Hx=0;
          int sum4Hy=0;
          int sum4Tx=0;
          int sum4Ty=0;
        
          for(n=0;n<4;n++)
            {
              sum4Hx+=tch_queue.tch_queue[(tch_queue.head+n)%(QUE_LENTH+1)].x;
              sum4Tx+=tch_queue.tch_queue[(tch_queue.tail+QUE_LENTH-n)%(QUE_LENTH+1)].x;
              sum4Ty+=tch_queue.tch_queue[(tch_queue.tail+QUE_LENTH-n)%(QUE_LENTH+1)].y;
              sum4Hy+=tch_queue.tch_queue[(tch_queue.head+n)%(QUE_LENTH+1)].y;
            }
          difX=(sum4Tx-sum4Hx)/4;
          difY=(sum4Ty-sum4Hy)/4;
          
          //printk(KERN_EMERG "head:%d ,head.x:%d head.y:%d    ,tail:%d ,tail.x:%d tail.y:%d    ,difX:%d ,difY:%d ,difM:%d  \n",tch_queue.head,tch_queue.tch_queue[tch_queue.head].x,tch_queue.tch_queue[tch_queue.head].y,tch_queue.tail,tch_queue.tch_queue[tch_queue.tail].x,tch_queue.tch_queue[tch_queue.tail].y,difX,difY,difM);

          if((difX<50&&difX>-50)&&(difY<50&&difY>-50))
            { 
              //printk(KERN_EMERG "single point mode\n");
              tch_queueSumX=0;
              tch_queueSumY=0;
              //tail=tch_queue.tail;
              head=tch_queue.head;
              for(k=0;k<tch_queue.num;k++) 
                {
                  tch_queueSumX+=(int)(tch_queue.tch_queue[head].x);
                  tch_queueSumY+=(int)(tch_queue.tch_queue[head].y);
                  head++;
                  head=head%(QUE_LENTH+1);
                }
              //printk(KERN_EMERG "tch_queueSumX: %d,tch_queueSumY: %d, tch_queue.num: %d\n",tch_queueSumX,tch_queueSumY,tch_queue.num); 
              t.x=tch_queueSumX/tch_queue.num;
              t.y=tch_queueSumY/tch_queue.num;
            }
          else
            {
              //printk(KERN_EMERG "pressMove mode\n");
              tch_queueSumX=0;
              tch_queueSumY=0;
              for(n=0;n<8;n++)
                {
                  tch_queueSumX+=tch_queue.tch_queue[(tch_queue.tail+QUE_LENTH-n)%(QUE_LENTH+1)].x;
                  tch_queueSumY+=tch_queue.tch_queue[(tch_queue.tail+QUE_LENTH-n)%(QUE_LENTH+1)].y;
                  //printk(KERN_EMERG "%d ,%d\n",tch_queue.tch_queue[(tch_queue.tail+QUE_LENTH-n)%(QUE_LENTH+1)].x,tch_queue.tch_queue[(tch_queue.tail+QUE_LENTH-n)%(QUE_LENTH+1)].y);
                }
              //printk(KERN_EMERG "Move mode: tch_queueSumX: %d,tch_queueSumY: %d\n",tch_queueSumX,tch_queueSumY);
              t.x=tch_queueSumX/8;
              t.y=tch_queueSumY/8;
            }
        } 
      else
        {
          /*
          int k=0;
          //printk(KERN_EMERG "single point mode\n");
          tch_queueSumX=0;
          tch_queueSumY=0;
          //tail=tch_queue.tail;
          head=tch_queue.head;
          for(k=0;k<tch_queue.num;k++) 
            {
              tch_queueSumX+=(int)(tch_queue.tch_queue[head].x);
              tch_queueSumY+=(int)(tch_queue.tch_queue[head].y);
              head++;
              head=head%(QUE_LENTH+1);
            }
          //printk(KERN_EMERG "tch_queueSumX: %d,tch_queueSumY: %d, tch_queue.num: %d\n",tch_queueSumX,tch_queueSumY,tch_queue.num); 
          t.x=tch_queueSumX/tch_queue.num;
          t.y=tch_queueSumY/tch_queue.num;
          */
        }     
         
      /*these codes for test by bruce begin*/
      //out_buf[1] = (res_x*(t.x-raw_min_x))/(raw_max_x-raw_min_x+35)-15+t.y*10/200;
      //out_buf[2] = (res_y*(raw_max_y-t.y))/(raw_max_y-raw_min_y+30)-16+t.x*15/200; 
      /*these codes for test by bruce end*/
         
      out_buf[1] = (res_x*(t.x-raw_min_x))/(raw_max_x-raw_min_x)+2;
      out_buf[2] = (res_y*(raw_max_y-t.y))/(raw_max_y-raw_min_y)-1; 
      
      
      int tempx=0;
      int tempy=0;
 
      tempx = (int)(out_buf[1]);
      tempy = (int)(out_buf[2]);
        
      out_buf[1]=(short)(tempx-(xConDif+x2xScaDif*tempx+y2xScaDif*tempy)/mulNum);
      out_buf[2]=(short)(tempy-(yConDif+y2yScaDif*tempy+x2yScaDif*tempx)/mulNum);
        
      //printk(KERN_EMERG "%d,%d,%d,%d  %d,%d,%d,     %d,     %d,%d,%d   ,%d,%d\n",tempx,tempy,out_buf[0],t.millisecs,xConDif,x2xScaDif,y2xScaDif,mulNum,yConDif,y2yScaDif,x2yScaDif,out_buf[1],out_buf[2]);
        
      out_buf[3] = t.millisecs;      
        
      /*adjust the touch screen*/
      //scale = 5-out_buf[2]/100;
      //out_buf[1] = out_buf[1] + 3*scale;
      //out_buf[2] = out_buf[2] + 2;
        
      //printk(KERN_EMERG "X:%d,Y:%d,Pressure:%d\n",out_buf[1],out_buf[2],out_buf[0]);
            
       copy_to_user(buf, &out_buf, sizeof(out_buf));
       copy_right = 0;
       }
 
  if (if_pressure)
        {  
           ucb1400_ts_starttimer();
           
        }
  else 
        {
          wait_for_action( ); 
          restore_interrupt(); 
          pxa_ac97_write(&pxa_ac97_codec, 0x60, 0x2000); 
        }
   
   return count;


}

/*POLL Function*/
static unsigned int ucb1400_ts_poll(struct file *filp, poll_table *wait)
{
     
	poll_wait(filp, &ts_wait, wait);
	if (ts_occur)
		return POLLIN | POLLRDNORM;
	return 0;
}

/*fasync Function */
static int ucb1400_ts_fasync(int fd, struct file *filp, int on)
{
	int retval;
      
	retval = fasync_helper(fd, filp, on, &fasync);
	if (retval < 0)
		return retval;

	return 0;
}




static void  calibrate_init(void)
{
	raw_max_x = 955;
	raw_max_y = 954;
	raw_min_x = 45;
	raw_min_y = 80;

	res_x = 640;
	res_y = 480;

	xyswap = 1;
	head = 0;
	tail = 0;

	cal_ok = 1;
	x_rev = 0;
	y_rev = 1;

	/* --bruce-- */
	tch_queue.head=0;
	tch_queue.tail=0;
	tch_queue.num=0;
	tch_queueSumX=0;
	tch_queueSumY=0;
	sumM=0;

  xConDif=i2c_read_long(0);//add by bruce
  x2xScaDif=i2c_read_long(1);//add by bruce
  y2xScaDif=i2c_read_long(2);//add by bruce
  yConDif=i2c_read_long(3);//add by bruce
  y2yScaDif=i2c_read_long(4);//add by bruce
  x2yScaDif=i2c_read_long(5);//add by bruce
  mulNum=i2c_read_long(6);//add by bruce
 
  init_waitqueue_head(&queue);
  
  wait_for_action();

  return ;
}

void bl_timer_func(unsigned long data)
{
	XSBASE270_BCR_CLEARBIT(XSB_BCR_LCD_PWR_ENB);
}


void bl_thread(void * data)
{
	struct task_struct *tsk = current;
	daemonize();
	reparent_to_init();
	tsk->tty = NULL;
	tsk->policy = SCHED_FIFO;
	tsk->rt_priority = 1;
	strcpy(tsk->comm, "bl_thread");


	init_timer(&bl_timer);
	bl_timer.function = bl_timer_func;
	bl_timer.expires = jiffies + bright_time*HZ;
	add_timer(&bl_timer);	
}

static int ucb1400_ts_open(struct inode *inode, struct file *filp)
{
  
 // init_waitqueue_head(&ts_wait); 
  ts_occur = 0;
  ts_clear( );
  //calibrate_init( );
  
  /*init_completion(&kthread_completion);
  ret=kernel_thread(ucb1400_thread, 0, CLONE_FS | CLONE_FILES);
 
 if ( ret>=0 )
    { 
      wait_for_completion(&kthread_completion);
    }
   
   */

  
  	
  ucb1400_enable_irq( );
  return 0;

}




static struct file_operations ucb1400_ts_fops=
{
 open:    ucb1400_ts_open,
 poll:     ucb1400_ts_poll,
 fasync:   ucb1400_ts_fasync,
 read:     ucb1400_ts_read,
 ioctl:     ucb1400_ts_ioctl,

};


int __init ucb1400_ts_init(void)
{  
   int res;

   res = register_chrdev(11, "UCB1400 TouchScreen Controller", &ucb1400_ts_fops);
   
   kernel_thread(bl_thread, NULL, CLONE_FS | CLONE_FILES);//add by bruce
  
   init_waitqueue_head(&ts_wait);
 
   calibrate_init( );/* --bruce-- */
   return res;

}

void __exit ucb1400_ts_cleanup(void)
{


}



module_init(ucb1400_ts_init);
module_exit(ucb1400_ts_cleanup);

EXPORT_SYMBOL(ucb1400_IRQ_handle);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -