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

📄 mc68328digi.c

📁 老外写的触摸屏驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Write the SPIM (data and control). */#define SET_SPIMDATA(x) { SPIMDATA = x; }#define SET_SPIMCONT(x) { SPIMCONT = x; }/*----------------------------------------------------------------------------*/#define SPIM_ENABLE  { SET_SPIMCONT(SPIMCONT_ENABLE); }  /* enable SPIM       */#define SPIM_INIT    { SPIMCONT |= SPIMCONT_INIT; }      /* init SPIM         */#define SPIM_DISABLE { SET_SPIMCONT(0x0000); }           /* disable SPIM      *//*----------------------------------------------------------------------------*/#ifdef CONFIG_XCOPILOT_BUGS# define CARD_SELECT   # define CARD_DESELECT #else# define CARD_SELECT   { CS_DATA &= ~CS_MASK; }     /* PB4 active (=low)       */# define CARD_DESELECT { CS_DATA |=  CS_MASK; }     /* PB4 inactive (=high)    */#endif/*----------------------------------------------------------------------------*/#define ENABLE_PEN_IRQ    { IMR &= ~IMR_MPEN; }#define ENABLE_SPIM_IRQ   { IMR &= ~IMR_MSPI; SPIMCONT |= SPIMCONT_IRQEN; }#define DISABLE_PEN_IRQ   { IMR |= IMR_MPEN; }#define DISABLE_SPIM_IRQ  { SPIMCONT &= ~SPIMCONT_IRQEN; IMR |= IMR_MSPI; }#define CLEAR_SPIM_IRQ    { SPIMCONT &= ~SPIMCONT_IRQ; }/*----------------------------------------------------------------------------*//* predefinitions ------------------------------------------------------------*/static void handle_timeout(void);static void handle_pen_irq(int irq, void *dev_id, struct pt_regs *regs);static void handle_spi_irq(void);/*----------------------------------------------------------------------------*//* structure -----------------------------------------------------------------*/struct ts_pen_position { int x,y; };struct ts_queue {  unsigned long head;  unsigned long tail;  wait_queue_head_t proc_list;  struct fasync_struct *fasync;  unsigned char buf[TS_BUF_SIZE];};/*----------------------------------------------------------------------------*//* Variables -----------------------------------------------------------------*//* * driver state variable. */static int ts_drv_state;/* * first tick initiated at ts_open. */static struct timeval   first_tick;/* * pen state. */static int new_pen_state;/* * event counter. */static int ev_counter;/* * counter to differentiate a click from a move. */static int state_counter;static struct timer_list         ts_wake_time;/* * drv parameters. */static struct ts_drv_params      current_params;static int                       sample_ticks;/* * pen info variables. */static struct ts_pen_info        ts_pen;static struct ts_pen_info        ts_pen_prev;static struct ts_pen_position    current_pos;/* * driver management. */static struct ts_queue *queue;static int    device_open = 0;   /* number of open device to prevent concurrent                                  * access to the same device				  *//*----------------------------------------------------------------------------*//* Init & release functions --------------------------------------------------*/static void init_ts_state(void) {  DISABLE_SPIM_IRQ;      /* Disable SPIM interrupt */  ts_drv_state = TS_DRV_IDLE;  state_counter = 0;  ENABLE_PEN_IRQ;        /* Enable interrupt IRQ5  */}static void init_ts_pen_values(void) {  ts_pen.x = 0;ts_pen.y = 0;  ts_pen.dx = 0;ts_pen.dy = 0;  ts_pen.event = EV_PEN_UP;  ts_pen.state &= 0;ts_pen.state |= ST_PEN_UP;  ts_pen_prev.x = 0;ts_pen_prev.y = 0;  ts_pen_prev.dx = 0;ts_pen_prev.dy = 0;  ts_pen_prev.event = EV_PEN_UP;  ts_pen_prev.state &= 0;ts_pen_prev.state |= ST_PEN_UP;    new_pen_state = 0;  ev_counter = 0;  do_gettimeofday(&first_tick);}static void init_ts_timer(struct timer_list *timer) {  init_timer(timer);  timer->function = (void *)handle_timeout;}static void release_ts_timer(struct timer_list *timer) {  del_timer(timer);}/* * Set default values for the params of the driver. */static void init_ts_settings(void) {  current_params.version = MC68328DIGI_VERSION;  current_params.version_req = 0;  current_params.x_ratio_num = 1;  current_params.x_ratio_den = 1;  current_params.y_ratio_num = 1;  current_params.y_ratio_den = 1;  current_params.x_offset = 0;  current_params.y_offset = 0;  current_params.xy_swap = 1;  current_params.x_min = 0;  current_params.x_max = 4095;  current_params.y_min = 0;  current_params.y_max = 4095;  current_params.mv_thrs = 50;  current_params.follow_thrs = 5;    /* to eliminate the conversion noise */  current_params.sample_ms = 20;  current_params.deglitch_on = 1; //added by duwei 07/03/2003  current_params.deglitch_ms=1;  current_params.event_queue_on = 1;  sample_ticks = TICKS(current_params.sample_ms);}static void init_ts_hardware(void) {  /* Set bit 2 of port F for interrupt (IRQ5 for pen_irq)                 */#if 0  PENIRQ_PUEN |= PEN_MASK;     /* Port F as pull-up			*/#endif  PENIRQ_DIR &= ~PEN_MASK;    /* PF1 as input                                 */  PENIRQ_SEL &= ~PEN_MASK;    /* PF1 internal chip function is connected			       */#if 0  /* Set polarity of IRQ5 as low (interrupt occure when signal is low)    */  ICR &= ~ICR_PENPOL;#endif  /* Init stuff for port E. The 3 LSB are multiplexed with the SPIM       */  PESEL &= ~PESEL_MASK;    /* Set bit 4 of port B for the CARD_SELECT signal of ADS7843 as output. */#ifndef CONFIG_XCOPILOT_BUGS  CS_PUEN |= CS_MASK;       /* Port B as pull-up                           */  CS_DIR  |= CS_MASK;       /* PB4 as output                               */  CS_DATA |= CS_MASK;       /* PB4 inactive (=high)                        */  CS_SEL  |= CS_MASK;       /* PB4 as I/O not dedicated                    */#endif    /* Set bit 5 of port F for the BUSY signal of ADS7843 as input          */ // PFPUEN |= BUSY_MASK;     /* Port F as pull-up                           */ //PFDIR  &= ~BUSY_MASK;    /* PF5 as input                                */ // PFSEL  |= BUSY_MASK;     /* PF5 I/O port function pin is connected      *///changed by duwei 03/21/2003  PBPUEN |= BUSY_MASK;     /* Port F as pull-up                           */  PBDIR  &= ~BUSY_MASK;    /* PF5 as input                                */  PBSEL  |= BUSY_MASK;     /* PF5 I/O port function pin is connected      */#ifdef USE_PENIRQ_PULLUP  /* Set bit 4 of port D for the pen irq pull-up of ADS7843 as output.    */  PDDIR  |= PEN_MASK_2;    /* PD4 as output                               */  PDDATA |= PEN_MASK_2;    /* PD4 up (pull-up)                            */  PDPUEN |= PEN_MASK_2;    /* PD4 as pull-up                              */#ifndef CONFIG_XCOPILOT_BUGS  PDSEL  |= PEN_MASK_2;    /* PD4 I/O port function pin is connected      */#endif#endif}/* * Reset bits used in each register to their default value. */static void release_ts_hardware(void) {                          /* Register   default value */#ifndef CONFIG_XCOPILOT_BUGS  PESEL  |= PESEL_MASK;   /* PESEL      0xFF          */  CS_DIR  &= ~CS_MASK;    /* PBDIR      0x00          */  //CS_DIR |= CS_MASK;  //changed by duwei  05/29/2003  CS_DATA &= ~CS_MASK;    /* PBDATA     0x00          */  CS_PUEN |= CS_MASK;     /* PBPUEN     0xFF          */  CS_SEL  |= CS_MASK;     /* PBSEL      0xFF          */#ifdef USE_PENIRQ_PULLUP  PDDIR  |= PEN_MASK_2;   /* PDDIR      0xFF          */  PDDATA |= PEN_MASK_2;   /* PDDATA     0xF0          */  PDPUEN |= PEN_MASK_2;   /* PDPUEN     0xFF          */  PDSEL  |= PEN_MASK_2;   /* PDSEL      0xF0          */#endif  PENIRQ_PUEN |= PEN_MASK;     /* PFPUEN     0xFF          */  PENIRQ_DIR  &= ~PEN_MASK;    /* PFDIR      0x00          */  PENIRQ_SEL  |= PEN_MASK;     /* PFSEL      0xFF          */#endif  IMR    |= IMR_MPEN;     /* IMR        0xFFFFFFFF    */                          /* I release it anyway!     */ }static void init_ts_drv(void) {  printk("a\n");  init_ts_state();  printk("b\n");  init_ts_pen_values();  printk("c\n");  init_ts_timer(&ts_wake_time);  printk("d\n");  init_ts_hardware();  printk("e\n");}static void release_ts_drv(void) {  release_ts_timer(&ts_wake_time);  release_ts_hardware();}/*----------------------------------------------------------------------------*//* scaling functions ---------------------------------------------------------*/static inline void rescale_xpos(int *x) {  *x &= CONV_MASK;  *x *= current_params.x_ratio_num;  *x /= current_params.x_ratio_den;  *x += current_params.x_offset;  *x = (*x > current_params.x_max ? current_params.x_max :	(*x < current_params.x_min ? current_params.x_min :	 *x));}static inline void rescale_ypos(int *y) {  *y &= CONV_MASK;  *y *= current_params.y_ratio_num;  *y /= current_params.y_ratio_den;  *y += current_params.y_offset;  *y = (*y > current_params.y_max ? current_params.y_max :	(*y < current_params.y_min ? current_params.y_min :	 *y));}static inline void swap_xy(int *x, int *y){  if(current_params.xy_swap) {    int t = *x;    *x = *y;    *y = t;  }}/*----------------------------------------------------------------------------*//* xcopilot compatibility hacks ----------------------------------------------*/#ifdef CONFIG_XCOPILOT_BUGS/* xcopilot has the following bugs: * * - Disabling the penirq has no effect; we keep on getting irqs even when *   penirq is disabled; this is not too annoying: we just trash pen irq events *   that come when disabled. * * - SPIM interrupt is not simulated; this is not too annoying: we just read *   SPI data immediately and bypass a couple of states related to SPI irq. * * - We do not get mouse drag events; this is a known xcopilot bug. *   This is annoying: we miss all moves ! You should patch and recompile *   your xcopilot. * *   This has been reported as Debian bug #64367, and there is a patch there: *     http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=64367&repeatmerged=yes *   which is: *   +-----------------------------------------------------------------------+ *   | --- display.c   Tue Aug 25 14:56:02 1998 *   | +++ display2.c  Fri May 19 16:07:52 2000 *   | @@ -439,7 +439,7 @@ *   | static void HandleDigitizer(Widget w, XtPointer client_data, XEvent\ *   | *event, Boolean *continue_to_dispatch) *   | { *   | -  Time start; *   | +  static Time start; *   |  *   | *continue_to_dispatch = True; *   +-----------------------------------------------------------------------+ *   In short, add 'static' to the declaration of 'start' in HandleDigitizer() *   in display.c * *   With this patch, all works perfectly ! * * - The pen state can be read only in IPR, not in port D; again, we're doing *   the workaround. * * With all these workarounds in this file, and with the patch on xcopilot, * things go perfectly smoothly. * *//* * Ugly stuff to read the mouse position on xcopilot * * We get the position of the last mouse up/down only, we get no moves !!! :-( */static void xcopilot_read_now(void) {    PFDATA &= ~0xf; PFDATA |= 6;    SPIMCONT |= SPIMCONT_XCH | SPIMCONT_IRQEN;    current_pos.x = SPIMDATA;    rescale_xpos(&current_pos.x);    PFDATA &= ~0xf; PFDATA |= 9;    SPIMCONT |= SPIMCONT_XCH | SPIMCONT_IRQEN;    current_pos.y = SPIMDATA;    rescale_ypos(&current_pos.y);    swap_xy(&current_pos.x, &current_pos.y);}#endif/*----------------------------------------------------------------------------*//* flow functions ------------------------------------------------------------*//* * Set timer irq to now + delay ticks. */static void set_timer_irq(struct timer_list *timer,int delay) {  del_timer(timer);  timer->expires = jiffies + delay;  add_timer(timer);}/* * Set ADS7843 and SPIM parameters for transfer. */static void set_SPIM_transfert(void) {  /* DragonBall drive I/O 1 and I/O 2 LOW to reverse bias the PENIRQ diode   * of the ADS7843   */#ifdef USE_PENIRQ_PULLUP  PDDATA &= ~PEN_MASK_2;        /* Pull down I/0 2 of PENIRQ */#endif  PENIRQ_DIR  |= PEN_MASK;      /* I/O 1 of PENIRQ as output */  PENIRQ_DATA &= ~PEN_MASK;     /* Pull down I/O 2 of PENIRQ */  /* Initiate selection and parameters for using the Burr-Brown ADS7843   * and the DragonBall SPIM.   */  CARD_SELECT;          /* Select ADS7843.     *///  printk("Now the ADS7843 is selected!\n");  SPIM_ENABLE;          /* Enable SPIM         */  SPIM_INIT;            /* Set SPIM parameters */}/* * Clock the Burr-Brown to fall the AD_BUSY.  * With a 'start' bit and PD1,PD0 = 00 to enable PENIRQ. * Used for the first pen irq after booting. And when error occures during * conversion that need an initialisation. */static void fall_BUSY_enable_PENIRQ(void) {  SET_SPIMDATA(SPIMDATA_NOP);  SPIMCONT |= SPIMCONT_XCH;     /* initiate exchange */}/* * Release transfer settings. */static void release_SPIM_transfert(void) {  SPIM_DISABLE;  CARD_DESELECT;

⌨️ 快捷键说明

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