view playusb.c @ 6:3819ecaf0f14

avoiding clash with latest libjpeg
author Peter Meerwald <pmeerw@pmeerw.net>
date Tue, 10 May 2011 19:10:18 +0200
parents 71b9540bdd23
children
line wrap: on
line source

/**
 * based on usbreplay.c
 * -- takes a list of jpeg filenames (on stdin) and sends them to the device index X
 * 
 */

#include <usb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <assert.h>

struct usb_device *find_pvr(int index) {
  struct usb_bus *bus;
  struct usb_device *dev;

  usb_init();
  //usb_set_debug(999999);
  usb_find_busses();
  usb_find_devices();

  while(index >= 0) {
    for (bus = usb_busses; bus; bus = bus->next) {
      for (dev = bus->devices; dev; dev = dev->next) {
        if (dev->descriptor.idVendor == 0x04e8 &&
            dev->descriptor.idProduct == 0x2028) {
          if (index == 0)
            return dev;
          --index;
        }
      }
    }
  }
  return NULL;
}

usb_dev_handle *dev_open(struct usb_device *dev) {
  int res = -1;
  char buf[256];
  usb_dev_handle *udev;
  int numeps = 0;

  udev = usb_open(dev);

  setuid(getuid());

  res = usb_set_configuration(udev, 1);

  usb_claim_interface(udev, 0);
  numeps = dev->config[0].interface[0].altsetting[0].bNumEndpoints;
  if (numeps == 0) {
    fprintf(stderr, "** Did you forget to initialize the FX2 firmware with usbreplay -i?\n");
    exit(1);
  }

  strcpy(buf, "** no string **");
  res = usb_get_string_simple(udev, dev->descriptor.iManufacturer, buf, sizeof(buf));
  fprintf(stderr, "usb_get_string_simple => %d, %s\n", res, buf);

  {
    int eplist[] = { 0x2, 0x81, 0x83 };
    int eplength = sizeof(eplist)/sizeof(eplist[0]);
    int *endpoint = eplist;
    int i;
    for (i=0; i<eplength; i++) {
      res = usb_resetep(udev, *endpoint);
      res = usb_clear_halt(udev, *endpoint);
      endpoint++;
    }
  }

  return udev;
}


void send_jpeg(FILE *f, usb_dev_handle *udev) {
  fseek(f, 0, SEEK_END);
  int sz = ftell(f);
  fseek(f, 0, SEEK_SET);

  #define URBBUF_MAX 0x20000
  char buf[URBBUF_MAX];

  #define HDR_LEN 12
  char hdr[HDR_LEN] = {0xa5, 0x5a, 0x18, 0x04, 0xff, 0xff, 0xff, 0xff, 0x48, 0x00, 0x00, 0x00};
  *(int *)(hdr+4) = sz;

  memcpy(buf, hdr, HDR_LEN);
  int off = HDR_LEN;

  //printf("new file of size %d\n", sz);
  while(!feof(f)) {
    int nr = fread(buf+off, 1, URBBUF_MAX - off, f);
    if (nr < 0) break;
    // pad
    memset(buf + off + nr, 0, URBBUF_MAX - off - nr);

    // write it out chunk by chunk
    int timeout = 1000;
    int endpoint = 0x2;
    int res = usb_bulk_write(udev, endpoint, buf, URBBUF_MAX, timeout);
    //printf("writing chunk\n");
    assert(res >= 0);
    off = 0; // no header on subsequent chunks
  }
}

int main(int argc, char *argv[]) {
  int index = 0;
  if (argc > 1) {
    if (sscanf(argv[1], "%d", &index) != 1) {
      fprintf(stderr, "Usage: %s [device index] < filelist", argv[0]);
      return -1;
    }
  }

  struct usb_device *dev = find_pvr(index);
  assert (dev != NULL);

  usb_dev_handle *udev = dev_open(dev);

  while(1) {
    // for each file in the list
    while(!feof(stdin)) {
      char fn[256];
      fgets(fn, 256, stdin);
      int nn = strlen(fn);
      if (nn > 0) {
        if (fn[nn-1] == '\n')
          fn[nn-1] = 0;
        FILE *f = fopen(fn, "r");
        if (f == NULL) {
          fprintf(stderr, "file %s not found\n", fn);
          return 2;
        }
        send_jpeg(f, udev);
        fclose(f);
      }
    }
    fseek(stdin, 0, SEEK_SET);
  }
  return 0;
}

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.