Logo Search packages:      
Sourcecode: baycomusb version File versions  Download package

writeeeprom.c

/*****************************************************************************/

/*
 *    writeeeprom.c  --  "Burn" EEPROM on the modem.
 *
 *    Copyright (C) 1999-2001
 *          Thomas Sailer (t.sailer@alumni.ethz.ch)
 *
 *    This program is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program; if not, write to the Free Software
 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  History:
 *   0.1  26.05.99  Created
 *
 */

/*****************************************************************************/

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <math.h>

#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
#include "getopt.h"
#endif

#include "baycomusb.h"
#include "usbdrv.h"
#include "firmware/reset2firmware.h"

/* ---------------------------------------------------------------------- */

static int writecpucs(struct usbdevice *dev, unsigned char buf)
{
        int r;

        r = usb_control_msg(dev, 0x40, 0xa0, 0x7F92, 0, 1, &buf, 5000);
        if (r != 1) {
                fprintf(stderr, "ezusb: writecpucs(0x%02x) failed %d\n", buf, r);
                return -1;
        }
        return 0;
}

static int loadmem(struct usbdevice *dev, const unsigned char *fw, unsigned int len)
{
        unsigned addr, sz;
        int r;

        if (writecpucs(dev, 1))
                return -1;
        for (addr = 0; addr < len; addr += 64) {
                sz = len - addr;
                if (sz > 64)
                        sz = 64;
                r = usb_control_msg(dev, 0x40, 0xa0, addr, 0, sz, (void *)(fw+addr), 5000);
                if (r != sz) {
                        fprintf(stderr, "ezusb: code download(sz=%d,addr=0x%04x) returned %d\n", sz, addr, r);
                        return -1;
                }
        }
        return 0;
}

int adapter_reset(struct usbdevice *dev)
{
        /* first download the loader firmware to the AnchorChips core */
        if (loadmem(dev, reset2firmware, sizeof(reset2firmware)) ||
            /* start AnchorChips core */
            writecpucs(dev, 0))
                return -1;
        return 0;
}

/* --------------------------------------------------------------------- */

static int displaymem(struct usbdevice *dev)
{
        unsigned char buf[16];
        unsigned addr, u;
        int r;

        printf("EZUSB Memory contents:\n");
        for (addr = 0; addr < 0x2000; addr += 16) {
                r = usb_control_msg(dev, 0xc0, 0xa0, addr, 0, 16, buf, 5000);
                if (r != 16) {
                        fprintf(stderr, "ezusb: code upload(sz=%d,addr=0x%04x) returned %d\n", 16, addr, r);
                        return -1;
                }
                printf("%04x:", addr);
                for (u = 0; u < 16; u++)
                        printf(" %02x", buf[u]);
                printf("\n");
        }
        r = usb_control_msg(dev, 0xc0, 0xa0, 0x7F92, 0, 1, buf, 5000);
        if (r != 1) {
                fprintf(stderr, "ezusb: readcpucs returned %d\n", r);
                return -1;
        }
        printf("CPUCS: %02x\n", buf[0]);
        return 0;
}

static int displaycpucs(struct usbdevice *dev)
{
        unsigned char buf;
        int r;

        r = usb_control_msg(dev, 0xc0, 0xa0, 0x7F92, 0, 1, &buf, 5000);
        if (r != 1) {
                fprintf(stderr, "ezusb: readcpucs returned %d\n", r);
                return -1;
        }
        printf("CPUCS: %02x\n", buf);
        return 0;
}

/* --------------------------------------------------------------------- */

static int write_eeprom_byte(struct usbdevice *dev, unsigned char addr, unsigned char byte)
{
      unsigned char data[2];

      data[0] = addr;
      data[1] = byte;
      if (usb_control_msg(dev, 0x40, 0xb4, 0, 0xa0, 2, data, 500) != 2)
            return -1;
      /* I2C EEPROM takes 5ms to write byte */
      usleep(10000);
      return 0;
}

static int read_eeprom_byte(struct usbdevice *dev, unsigned char addr)
{
      unsigned char data[1];

      data[0] = addr;
      if (usb_control_msg(dev, 0x40, 0xb4, 0, 0xa0, 1, data, 500) != 1)
            return -1;
      if (usb_control_msg(dev, 0xc0, 0xb4, 0, 0xa0, 1, data, 500) != 1)
            return -1;
      return data[0] & 0xff;
}

/* --------------------------------------------------------------------- */

static int display_eeprom(struct usbdevice *dev, unsigned int serial)
{
      unsigned char eeprom[256];
      unsigned int i;
      int r;

      for (i = 0; i < 256; i++) {
            r = read_eeprom_byte(dev, i);
            if (r == -1) {
                  fprintf(stderr, "Error reading EEPROM address 0x%02x\n", i);
                  return -1;
            }
            eeprom[i] = r;
      }
      printf("EEPROM contents:");
      for (i = 0; i < 256; i++) {
            if (!(i & 15))
                  printf("\n%04x:", i);
            printf(" %02x", eeprom[i]);
      }
      printf("\n\n"
             "VID    %04x\n"
             "PID    %04x\n"
             "DID    %02x.%02x\n"
             "Serial %c%c%c%c%c%c\n\n", 
             eeprom[1] | (eeprom[2] << 8), 
             eeprom[3] | (eeprom[4] << 8), 
             eeprom[6], eeprom[5],
             (eeprom[0x10] >= '0' && eeprom[0x10] <= '9') ? eeprom[0x10] : '.',
             (eeprom[0x11] >= '0' && eeprom[0x11] <= '9') ? eeprom[0x11] : '.',
             (eeprom[0x12] >= '0' && eeprom[0x12] <= '9') ? eeprom[0x12] : '.',
             (eeprom[0x13] >= '0' && eeprom[0x13] <= '9') ? eeprom[0x13] : '.',
             (eeprom[0x14] >= '0' && eeprom[0x14] <= '9') ? eeprom[0x14] : '.',
             (eeprom[0x15] >= '0' && eeprom[0x15] <= '9') ? eeprom[0x15] : '.');
      return 0;
}

/* --------------------------------------------------------------------- */

static int program_eeprom(struct usbdevice *dev, unsigned int serial)
{
      unsigned char eeprom[256];
      unsigned int i;
      int r, ret = 0;

      memset(eeprom, 0xff, sizeof(eeprom));
      eeprom[0] = 0xb0;
      eeprom[1] = 0xc0;
      eeprom[2] = 0xba;
      eeprom[3] = 0x34;
      eeprom[4] = 0x61;
      eeprom[5] = 0x01;
      eeprom[6] = 0x01;

      eeprom[0x10] = '0' + ((serial / 100000) % 10);
      eeprom[0x11] = '0' + ((serial / 10000) % 10);
      eeprom[0x12] = '0' + ((serial / 1000) % 10);
      eeprom[0x13] = '0' + ((serial / 100) % 10);
      eeprom[0x14] = '0' + ((serial / 10) % 10);
      eeprom[0x15] = '0' + (serial % 10);

      for (i = 0; i < 7; i++) {
            r = write_eeprom_byte(dev, i, eeprom[i]);
            if (r == -1) {
                  fprintf(stderr, "Error writing EEPROM address 0x%02x\n", i);
                  return -1;
            }
      }
      for (i = 0x10; i < 0x16; i++) {
            r = write_eeprom_byte(dev, i, eeprom[i]);
            if (r == -1) {
                  fprintf(stderr, "Error writing EEPROM address 0x%02x\n", i);
                  return -1;
            }
      }
      for (i = 0; i < 7; i++) {
            r = read_eeprom_byte(dev, i);
            if (r == -1) {
                  fprintf(stderr, "Error reading EEPROM address 0x%02x\n", i);
                  return -1;
            }
            if (r != eeprom[i]) {
                  fprintf(stderr, "Error comparing EEPROM address 0x%02x: 0x%02x != 0x%02x\n", i, r, eeprom[i]);
                  ret = -1;
            }
      }
      for (i = 0x10; i < 0x16; i++) {
            r = read_eeprom_byte(dev, i);
            if (r == -1) {
                  fprintf(stderr, "Error reading EEPROM address 0x%02x\n", i);
                  return -1;
            }
            if (r != eeprom[i]) {
                  fprintf(stderr, "Error comparing EEPROM address 0x%02x: 0x%02x != 0x%02x\n", i, r, eeprom[i]);
                  ret = -1;
            }
      }
      if (!ret)
            printf("Successfully programmed serial %c%c%c%c%c%c\n", 
                   eeprom[0x10], eeprom[0x11], eeprom[0x12], eeprom[0x13], eeprom[0x14], eeprom[0x15]);
      return ret;
}

/* --------------------------------------------------------------------- */

int main(int argc, char *argv[])
{
        static const struct option long_options[] = {
                { "drv", 1, 0, 'D' },
                { "vendor", 1, 0, 'V' },
                { "product", 1, 0, 'P' },
            { 0, 0, 0, 0 }
        };
      struct usbdevice *dev;
      struct usb_device_descriptor devdesc;
      int c, err = 0;
      unsigned int vid = 0x547, pid = 0x2131, serial;
      int (*func)(struct usbdevice *dev, unsigned int serial) = program_eeprom;
      struct timeval tv;

      printf("writeeeprom v" VERSION " (C) 1999-2001 by Thomas Sailer, HB9JNX/AE4WA\n");
      gettime(&tv);
      srand(tv.tv_sec ^ tv.tv_usec);
      serial = rand();
      while ((c = getopt_long(argc, argv, "D:V:P:dn:v:", long_options, NULL)) != EOF) {
            switch (c) {
            case 'D':
                  usb_setmountpoint(optarg);
                  break;

            case 'V':
                  vid = strtoul(optarg, NULL, 0);
                  break;

            case 'P':
                  pid = strtoul(optarg, NULL, 0);
                  break;

            case 'd':
                  func = display_eeprom;
                  break;

            case 'n':
                  serial = strtoul(optarg, NULL, 0);
                  break;

                case 'v':
                        verboselevel = strtoul(optarg, NULL, 0);
                        break;

            default:
                  err++;
                  break;
            }
      }
      if (err) {
            fprintf(stderr, "usage: %s [-v <vl>] [-D <drvpath>] [-V <vendorid>] [-P <productid>] [-n <serial>] [-d]\n", argv[0]);
            exit(1);
      }
      dev = usb_open(vid, pid, 0, 0);
      if (!dev)
            dev = usb_open(BAYCOMUSB_VENDORID, BAYCOMUSB_PRODUCTID_FPGALD, 0, 0);
      if (!dev) {
            fprintf(stderr, "Cannot open USB device with VendorID 0x%04x/ProductID 0x%04x\n", vid, pid);
            exit(1);
      }
      if (usb_getdevicedescriptor(dev, &devdesc)) {
            perror("usb_getdevicedescriptor");
            exit(1);
      }
      if ((devdesc.idVendor[0] | (devdesc.idVendor[1] << 8)) != BAYCOMUSB_VENDORID ||
          (devdesc.idProduct[0] | (devdesc.idProduct[1] << 8)) != BAYCOMUSB_PRODUCTID_FPGALD) {
            if (adapter_reset(dev)) {
                  perror("adapter_reset");
                  exit(1);
            }
            usb_close(dev);
            /*sleep(3);*/
            usleep(3000000);
            if (!(dev = usb_open(BAYCOMUSB_VENDORID, BAYCOMUSB_PRODUCTID_FPGALD, 0, 0))) {
                  fprintf(stderr, "Cannot open USB device\n");
                  exit(1);
            }
      }
      if (usb_setconfiguration(dev, 1)) {
            perror("usb_setconfiguration");
            exit(1);
      }
      c = func(dev, serial);
      usb_close(dev);
      exit(abs(c));
}

Generated by  Doxygen 1.6.0   Back to index