MINI2440 - touch screen device open with O_NONBLOCK

Rajam AP
Hello all, 

I tried opening the Touch Screen device with O_NONBLOCK option as I was
thinking that application need not wait until there is data in touch
screen. I have polling routine which is called periodically to check for
data in the touch screen. 

When I opened the device with O_NONBLOCK I was getting continuous errors on
my terminal stating that "ts device read error: resource temporarily
unavailable". 

Then I removed the flag and program was running. 

Is there any help on how to use this flag O_NONBLOCK for devices?

Thanks and regards

Rajam
QMAX Systems

open-nandra
Could you provide source code please?

marek

Rajam AP
I have provided the test code which we modified taking the base code from
the test routines available in the ts library. 

int ghw_touch_init()
{

    ts_dev = open("/dev/input/event0",O_RDONLY|O_NONBLOCK);
    if (ts_dev < 0) {
       printf("Touch screen driver: open device error!\n");
        printf("errno = %d, %s\n", errno, strerror(errno));
        return 0;
    }
    else {
    printf (" Touch screen device opened successfully! \n");
    return 1;
  }
  
  /*flush the ts device */
    ts_flush(ts_dev);
}

/*
   Simulates a touch screen input.
   Returns 1 if a touch change (an edge or pressed coordinate change) has
been detected
   Returns 0 if the touch level is unchanged (unpressed, or pressed and
same position).

   Edge  = 1, Touch screen pressed changed state.
   Edge  = 0, No touch state change.
   Level = 1, Touch screen pressed (x,y values is a (new) valid position)
   Level = 0, No touch (x,y values is the position where last touch
stopped)
*/

unsigned char ghwTouchGet(unsigned char *edgep, unsigned char *levelp, int
*xp, int *yp)
{
   int nRet=0; // index;
   static unsigned short oldx = 0;
   static unsigned short oldy = 0;
   int x;
   int y;
   struct ts_sample; // *ts_samples_data, ts_data;

  screen_pressed=0;
  
  /* read samples from touch screen device */
  /*do {
    if (ts_input_read(ts_dev, &ts_samples[0], 1) < 0) {
      perror("ts_read");
      //close_framebuffer ();
      return;
    }

  } while (ts_samples[0].pressure == 0);
*/
  /* Now collect up to MAX_SAMPLES touches into the samp array. */
/*  index = 0;
  do {
    if (index < MAX_SAMPLES-1)
      index++;
    if (ts_input_read(ts_dev, &ts_samples[index], 1) < 0) {
      perror("ts_read");
      //close_framebuffer ();
      return;
    }
  } while (ts_samples[index].pressure > 0);
  printf("Took %d samples...\n",index);
 */
   getxy (ts_dev, &x, &y);
 
 //   printf ("After ts read: x=%d, y=%d \n", x, y); 

  /* check if x, y has changed from previous values
   * update return values accordingly
   */
  if (screen_pressed == 0) {

    *edgep = 0;
    *levelp = 0;
    *xp = oldx;
    *yp = oldy;
    return 0;
  }
  else {
    *edgep = screen_pressed;
    if (x != oldx || y != oldy) {
    
      *levelp=1;
      if (xp != NULL)
             *xp = (int)(x*xres/x_ts_max);
        if (yp != NULL)
           *yp = (int) (y*yres/y_ts_max);
         
      /* x = oldx; */ /* x pos */  /* we need to remap the touch screen
co-ordinates to frame buffer pixels */
        /* y = oldy; */ /* y pos */
      }
  }

    /* Change detection */
    nRet = (screen_pressed != 0 || (x != oldx) || (y != oldy)) ? 1 : 0; 
    oldx = x;
    oldy = y;
    return nRet;
}


int ts_input_read (int ts_dev, struct ts_sample *samp, int nr)
{
  struct input_event ev;
  unsigned char *p = (unsigned char *) &ev;
  int len = sizeof(struct input_event);
static struct ts_sample ts_temp;
  int ret = nr;
  int total = 0;

  while (total < nr) {
    ret = read(ts_dev, p, len);
    if (ret == -1) {
      if (errno == EINTR) {
        continue;
      }
      break;
    }

    if (ret < (int)sizeof(struct input_event)) {
      /* short read
       * restart read to get the rest of the event
       */
      p += ret;
      len -= ret;
      continue;
    }

       // printf("type= %d, code= %d, value=0x%04x\n", ev.type, ev.code,
ev.value);
        
        /*if event is SYNC event then dont have to record the x,y - just
continue reading */
        if (ev.type == EV_SYN) continue;
        
    /* successful read of a whole event */
    if (ev.type == EV_ABS) {
      switch (ev.code) {
      case ABS_X:
        if (ev.value != 0) {
          samp->x = ts_temp.x = ev.value;
          samp->y = ts_temp.y;
          samp->pressure = ts_temp.pressure;
        } else {/*flush the ts device */
          fprintf(stderr, "tslib: dropped x = %d\n", ts_temp.x);
          continue;
        }
        break;
      case ABS_Y:
        if (ev.value != 0) {
          samp->x = ts_temp.x;
          samp->y = ts_temp.y = ev.value;
          samp->pressure = ts_temp.pressure;
        } else {
          fprintf(stderr, "tslib: dropped y = %d\n", ts_temp.y);
          continue;
        }
        break;
      case ABS_PRESSURE:
        samp->x = ts_temp.x;
        samp->y = ts_temp.y;
        samp->pressure = ts_temp.pressure = ev.value;
        samp->tv = ev.time;
        break;
        } /* end switch */
        
  #ifdef DEBUG
        fprintf(stderr, "RAW---------------------------> %d %d %d\n",
          ts_temp.x, ts_temp.y, ts_temp.pressure);
  #endif /* DEBUG */
        samp++;
        total++;
    } else if (ev.type == EV_KEY) {
      switch (ev.code) {
        case BTN_TOUCH:
          if (ev.value == 0) {
            /* pen up */
            samp->x = 0;
            samp->y = 0;
            samp->pressure = 0;
            samp->tv = ev.time;
            samp++;
            total++;
          }
          break;
        } /* end switch */
      } else {
        //fprintf(stderr, "tslib: Unknown event type %d\n", ev.type);
      }
      
    p = (unsigned char *) &ev;
    ret = total;
  }

  return (ret);
}


static int sort_by_x(const void* a, const void *b)
{
  return (((struct ts_sample *)a)->x - ((struct ts_sample *)b)->x);
}

static int sort_by_y(const void* a, const void *b)
{
  return (((struct ts_sample *)a)->y - ((struct ts_sample *)b)->y);
}

void getxy(int ts_dev, int *x, int *y)
{
  struct ts_sample samp[MAX_SAMPLES];
  int index, middle;

  do {
    if (ts_input_read(ts_dev, &samp[0], 1) < 0) {
      perror("ts_read"); 
      return;
    }
        
  } while (samp[0].pressure == 0);

  /* Now collect up to MAX_SAMPLES touches into the samp array. */
  index = 0;
  do {
    if (index < MAX_SAMPLES-1)
      index++;
    if (ts_input_read(ts_dev, &samp[index], 1) < 0) {
      perror("ts_read"); 
      //close_framebuffer ();
      return;
    }    
  } while (samp[index].pressure > 0);
  //printf("Took %d samples...\n",index);
  
  if (!index) { screen_pressed=0; return; }
  
  screen_pressed=1;

  /*
   * At this point, we have samples in indices zero to (index-1)
   * which means that we have (index) number of samples.  We want
   * to calculate the median of the samples so that wild outliers
   * don't skew the result.  First off, let's assume that arrays
   * are one-based instead of zero-based.  If this were the case
   * and index was odd, we would need sample number ((index+1)/2)
   * of a sorted array; if index was even, we would need the
   * average of sample number (index/2) and sample number
   * ((index/2)+1).  To turn this into something useful for the
   * real world, we just need to subtract one off of the sample
   * numbers.  So for when index is odd, we need sample number
   * (((index+1)/2)-1).  Due to integer division truncation, we
   * can simplify this to just (index/2).  When index is even, we
   * need the average of sample number ((index/2)-1) and sample
   * number (index/2).  Calculate (index/2) now and we'll handle
   * the even odd stuff after we sort.
   */
  middle = index/2;
  if (x) {
    qsort(samp, index, sizeof(struct ts_sample), sort_by_x);
    if (index & 1)
      *x = samp[middle].x;
    else
      *x = (samp[middle-1].x + samp[middle].x) / 2;
  }
  if (y) {
    qsort(samp, index, sizeof(struct ts_sample), sort_by_y);
    if (index & 1)
      *y = samp[middle].y;
    else
      *y = (samp[middle-1].y + samp[middle].y) / 2;
  }
}