Exemple #1
0
static int cmd_sig(PROGRAMMER * pgm, struct avrpart * p,
		   int argc, char * argv[])
{
  int i;
  int rc;
  AVRMEM * m;

  rc = avr_signature(pgm, p);
  if (rc != 0) {
    fprintf(stderr, "error reading signature data, rc=%d\n",
            rc);
  }

  m = avr_locate_mem(p, "signature");
  if (m == NULL) {
    fprintf(stderr,
            "signature data not defined for device \"%s\"\n",
            p->desc);
  }
  else {
    fprintf(stdout, "Device signature = 0x");
    for (i=0; i<m->size; i++)
      fprintf(stdout, "%02x", m->buf[i]);
    fprintf(stdout, "\n\n");
  }

  return 0;
}
Exemple #2
0
/* TPI chip erase sequence */
int avr_tpi_chip_erase(PROGRAMMER * pgm, AVRPART * p)
{
	int err;
  AVRMEM *mem;

  if (p->flags & AVRPART_HAS_TPI) {
    pgm->pgm_led(pgm, ON);

    /* Set Pointer Register */
    mem = avr_locate_mem(p, "flash");
    if (mem == NULL) {
      fprintf(stderr, "No flash memory to erase for part %s\n",
          p->desc);
      return -1;
    }

		unsigned char cmd[] = {
			/* write pointer register high byte */
			(TPI_CMD_SSTPR | 0),
			((mem->offset & 0xFF) | 1),
			/* and low byte */
			(TPI_CMD_SSTPR | 1),
			((mem->offset >> 8) & 0xFF),
	    /* write CHIP_ERASE command to NVMCMD register */
			(TPI_CMD_SOUT | TPI_SIO_ADDR(TPI_IOREG_NVMCMD)),
			TPI_NVMCMD_CHIP_ERASE,
			/* write dummy value to start erase */
			TPI_CMD_SST,
			0xFF
		};

    while (avr_tpi_poll_nvmbsy(pgm));

		err = pgm->cmd_tpi(pgm, cmd, sizeof(cmd), NULL, 0);
		if(err)
			return err;

    while (avr_tpi_poll_nvmbsy(pgm));

    pgm->pgm_led(pgm, OFF);

    return 0;
  } else {
/* 
 * Writes the specified fuse in fusename (can be "lfuse", "hfuse", or
 * "efuse") and verifies it. Will try up to tries amount of times
 * before giving up 
 */
int safemode_writefuse (unsigned char fuse, char * fusename, PROGRAMMER * pgm,
                        AVRPART * p, int tries, int verbose)
{
  AVRMEM * m;
  unsigned char fuseread;
  int returnvalue = -1;
  
  m = avr_locate_mem(p, fusename);
  if (m == NULL) {
    return -1;
    }
 
  /* Keep trying to write then read back the fuse values */   
  while (tries > 0) {
    if (avr_write_byte(pgm, p, m, 0, fuse) != 0)
        {
        continue;
        }
    if (pgm->read_byte(pgm, p, m, 0, &fuseread) != 0)
        {
        continue;
        }
        
    /* Report information to user if needed */
    if (verbose > 0) {
      fprintf(stderr, 
              "%s: safemode: Wrote %s to %x, read as %x. %d attempts left\n",
              progname, fusename, fuse, fuseread, tries-1);
    }
    
    /* If fuse wrote OK, no need to keep going */
    if (fuse == fuseread) {
       tries = 0;
       returnvalue = 0;
    }
    tries--;
  }
  
  return returnvalue;
}
Exemple #4
0
static int cmd_write(PROGRAMMER * pgm, struct avrpart * p,
		     int argc, char * argv[])
{
  char * e;
  int len, maxsize;
  char * memtype;
  unsigned long addr, i;
  unsigned char * buf;
  unsigned char b;
  int rc;
  int werror;
  AVRMEM * mem;

  if (argc < 4) {
    fprintf(stderr, "Usage: write <memtype> <addr> <byte1> "
            "<byte2> ... byteN>\n");
    return -1;
  }

  memtype = argv[1];

  mem = avr_locate_mem(p, memtype);
  if (mem == NULL) {
    fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n",
            memtype, p->desc);
    return -1;
  }

  maxsize = mem->size;

  addr = strtoul(argv[2], &e, 0);
  if (*e || (e == argv[2])) {
    fprintf(stderr, "%s (write): can't parse address \"%s\"\n",
            progname, argv[2]);
    return -1;
  }

  if (addr > maxsize) {
    fprintf(stderr, 
            "%s (write): address 0x%05lx is out of range for %s memory\n",
            progname, addr, memtype);
    return -1;
  }

  /* number of bytes to write at the specified address */
  len = argc - 3;

  if ((addr + len) > maxsize) {
    fprintf(stderr, 
            "%s (write): selected address and # bytes exceed "
            "range for %s memory\n", 
            progname, memtype);
    return -1;
  }

  buf = malloc(len);
  if (buf == NULL) {
    fprintf(stderr, "%s (write): out of memory\n", progname);
    return -1;
  }

  for (i=3; i<argc; i++) {
    buf[i-3] = strtoul(argv[i], &e, 0);
    if (*e || (e == argv[i])) {
      fprintf(stderr, "%s (write): can't parse byte \"%s\"\n",
              progname, argv[i]);
      free(buf);
      return -1;
    }
  }

  pgm->err_led(pgm, OFF);
  for (werror=0, i=0; i<len; i++) {

    rc = avr_write_byte(pgm, p, mem, addr+i, buf[i]);
    if (rc) {
      fprintf(stderr, "%s (write): error writing 0x%02x at 0x%05lx, rc=%d\n",
              progname, buf[i], addr+i, rc);
      if (rc == -1)
        fprintf(stderr, 
                "write operation not supported on memory type \"%s\"\n",
                mem->desc);
      werror = 1;
    }

    rc = pgm->read_byte(pgm, p, mem, addr+i, &b);
    if (b != buf[i]) {
      fprintf(stderr, 
              "%s (write): error writing 0x%02x at 0x%05lx cell=0x%02x\n",
              progname, buf[i], addr+i, b);
      werror = 1;
    }

    if (werror) {
      pgm->err_led(pgm, ON);
    }
  }

  free(buf);

  fprintf(stdout, "\n");

  return 0;
}
Exemple #5
0
static int cmd_dump(PROGRAMMER * pgm, struct avrpart * p,
		    int argc, char * argv[])
{
  static char prevmem[128] = {0};
  char * e;
  unsigned char * buf;
  int maxsize;
  unsigned long i;
  static unsigned long addr=0;
  static int len=64;
  AVRMEM * mem;
  char * memtype = NULL;
  int rc;

  if (!((argc == 2) || (argc == 4))) {
    fprintf(stderr, "Usage: dump <memtype> [<addr> <len>]\n");
    return -1;
  }

  memtype = argv[1];

  if (strncmp(prevmem, memtype, strlen(memtype)) != 0) {
    addr = 0;
    len  = 64;
    strncpy(prevmem, memtype, sizeof(prevmem)-1);
    prevmem[sizeof(prevmem)-1] = 0;
  }

  mem = avr_locate_mem(p, memtype);
  if (mem == NULL) {
    fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n",
            memtype, p->desc);
    return -1;
  }

  if (argc == 4) {
    addr = strtoul(argv[2], &e, 0);
    if (*e || (e == argv[2])) {
      fprintf(stderr, "%s (dump): can't parse address \"%s\"\n",
              progname, argv[2]);
      return -1;
    }

    len = strtol(argv[3], &e, 0);
    if (*e || (e == argv[3])) {
      fprintf(stderr, "%s (dump): can't parse length \"%s\"\n",
              progname, argv[3]);
      return -1;
    }
  }

  maxsize = mem->size;

  if (addr >= maxsize) {
    if (argc == 2) {
      /* wrap around */
      addr = 0;
    }
    else {
      fprintf(stderr, 
              "%s (dump): address 0x%05lx is out of range for %s memory\n",
              progname, addr, mem->desc);
      return -1;
    }
  }

  /* trim len if nessary to not read past the end of memory */
  if ((addr + len) > maxsize)
    len = maxsize - addr;

  buf = malloc(len);
  if (buf == NULL) {
    fprintf(stderr, "%s (dump): out of memory\n", progname);
    return -1;
  }

  for (i=0; i<len; i++) {
    rc = pgm->read_byte(pgm, p, mem, addr+i, &buf[i]);
    if (rc != 0) {
      fprintf(stderr, "error reading %s address 0x%05lx of part %s\n",
              mem->desc, addr+i, p->desc);
      if (rc == -1)
        fprintf(stderr, "read operation not supported on memory type \"%s\"\n",
                mem->desc);
      return -1;
    }
  }

  hexdump_buf(stdout, addr, buf, len);

  fprintf(stdout, "\n");

  free(buf);

  addr = addr + len;

  return 0;
}
Exemple #6
0
int do_op(PROGRAMMER * pgm, struct avrpart * p, UPDATE * upd, enum updateflags flags)
{
  struct avrpart * v;
  AVRMEM * mem;
  int size, vsize;
  int rc;

  mem = avr_locate_mem(p, upd->memtype);
  if (mem == NULL) {
    fprintf(stderr, "\"%s\" memory type not defined for part \"%s\"\n",
            upd->memtype, p->desc);
    return -1;
  }

  if (upd->op == DEVICE_READ) {
    /*
     * read out the specified device memory and write it to a file
     */
    if (quell_progress < 2) {
      fprintf(stderr, "%s: reading %s memory:\n",
            progname, mem->desc);
	  }
    report_progress(0,1,"Reading");
    rc = avr_read(pgm, p, upd->memtype, 0);
    if (rc < 0) {
      fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
              progname, mem->desc, rc);
      return -1;
    }
    report_progress(1,1,NULL);
    size = rc;

    if (quell_progress < 2) {
      fprintf(stderr,
            "%s: writing output file \"%s\"\n",
            progname,
            strcmp(upd->filename, "-")==0 ? "<stdout>" : upd->filename);
    }
    rc = fileio(FIO_WRITE, upd->filename, upd->format, p, upd->memtype, size);
    if (rc < 0) {
      fprintf(stderr, "%s: write to file '%s' failed\n",
              progname, upd->filename);
      return -1;
    }
  }
  else if (upd->op == DEVICE_WRITE) {
    /*
     * write the selected device memory using data from a file; first
     * read the data from the specified file
     */
    if (quell_progress < 2) {
      fprintf(stderr,
            "%s: reading input file \"%s\"\n",
            progname,
            strcmp(upd->filename, "-")==0 ? "<stdin>" : upd->filename);
    }
    rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
    if (rc < 0) {
      fprintf(stderr, "%s: read from file '%s' failed\n",
              progname, upd->filename);
      return -1;
    }
    size = rc;

    /*
     * write the buffer contents to the selected memory type
     */
    if (quell_progress < 2) {
      fprintf(stderr, "%s: writing %s (%d bytes):\n",
            progname, mem->desc, size);
	  }

    if (!(flags & UF_NOWRITE)) {
      report_progress(0,1,"Writing");
      rc = avr_write(pgm, p, upd->memtype, size, (flags & UF_AUTO_ERASE) != 0);
      report_progress(1,1,NULL);
    }
    else {
      /*
       * test mode, don't actually write to the chip, output the buffer
       * to stdout in intel hex instead
       */
      rc = fileio(FIO_WRITE, "-", FMT_IHEX, p, upd->memtype, size);
    }

    if (rc < 0) {
      fprintf(stderr, "%s: failed to write %s memory, rc=%d\n",
              progname, mem->desc, rc);
      return -1;
    }

    vsize = rc;

    if (quell_progress < 2) {
      fprintf(stderr, "%s: %d bytes of %s written\n", progname,
            vsize, mem->desc);
    }

  }
  else if (upd->op == DEVICE_VERIFY) {
    /*
     * verify that the in memory file (p->mem[AVR_M_FLASH|AVR_M_EEPROM])
     * is the same as what is on the chip
     */
    pgm->vfy_led(pgm, ON);

    if (quell_progress < 2) {
      fprintf(stderr, "%s: verifying %s memory against %s:\n",
            progname, mem->desc, upd->filename);

      fprintf(stderr, "%s: load data %s data from input file %s:\n",
            progname, mem->desc, upd->filename);
    }

    rc = fileio(FIO_READ, upd->filename, upd->format, p, upd->memtype, -1);
    if (rc < 0) {
      fprintf(stderr, "%s: read from file '%s' failed\n",
              progname, upd->filename);
      return -1;
    }
    v = avr_dup_part(p);
    size = rc;
    if (quell_progress < 2) {
      fprintf(stderr, "%s: input file %s contains %d bytes\n",
            progname, upd->filename, size);
      fprintf(stderr, "%s: reading on-chip %s data:\n",
            progname, mem->desc);
    }

    report_progress (0,1,"Reading");
    rc = avr_read(pgm, p, upd->memtype, v);
    if (rc < 0) {
      fprintf(stderr, "%s: failed to read all of %s memory, rc=%d\n",
              progname, mem->desc, rc);
      pgm->err_led(pgm, ON);
      return -1;
    }
    report_progress (1,1,NULL);



    if (quell_progress < 2) {
      fprintf(stderr, "%s: verifying ...\n", progname);
    }
    rc = avr_verify(p, v, upd->memtype, size);
    if (rc < 0) {
      fprintf(stderr, "%s: verification error; content mismatch\n",
              progname);
      pgm->err_led(pgm, ON);
      return -1;
    }

    if (quell_progress < 2) {
      fprintf(stderr, "%s: %d bytes of %s verified\n",
              progname, rc, mem->desc);
    }

    pgm->vfy_led(pgm, OFF);
  }
  else {
    fprintf(stderr, "%s: invalid update operation (%d) requested\n",
            progname, upd->op);
    return -1;
  }

  return 0;
}
Exemple #7
0
/*
 * Reads the fuses three times, checking that all readings are the
 * same. This will ensure that the before values aren't in error!
 */
int safemode_readfuses (unsigned char * lfuse, unsigned char * hfuse,
                        unsigned char * efuse, unsigned char * fuse,
                        PROGRAMMER * pgm, AVRPART * p)
{

  unsigned char value;
  unsigned char fusegood = 0;
  unsigned char allowfuseread = 1;
  unsigned char safemode_lfuse;
  unsigned char safemode_hfuse;
  unsigned char safemode_efuse;
  unsigned char safemode_fuse;
  AVRMEM * m;

  safemode_lfuse = *lfuse;
  safemode_hfuse = *hfuse;
  safemode_efuse = *efuse;
  safemode_fuse  = *fuse;


  /* Read fuse three times */
  fusegood = 2; /* If AVR device doesn't support this fuse, don't want
                   to generate a verify error */
  m = avr_locate_mem(p, "fuse");
  if (m != NULL) {
    fusegood = 0; /* By default fuse is a failure */
    if(pgm->read_byte(pgm, p, m, 0, &safemode_fuse) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 1, fuse value: %x\n",progname, safemode_fuse);
    if(pgm->read_byte(pgm, p, m, 0, &value) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 2, fuse value: %x\n",progname,  value);
    if (value == safemode_fuse) {
        if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
            {
            allowfuseread = 0;
            }
            avrdude_message(MSG_DEBUG, "%s: safemode read 3, fuse value: %x\n",progname,  value);
        if (value == safemode_fuse)
            {
            fusegood = 1; /* Fuse read OK three times */
            }
    }
  }

    //Programmer does not allow fuse reading.... no point trying anymore
    if (allowfuseread == 0)
        {
        return -5;
        }

    if (fusegood == 0) {
        avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read fuse properly. "
                        "Programmer may not be reliable.\n", progname);
        return -1;
    }
    else if (fusegood == 1) {
        avrdude_message(MSG_NOTICE, "%s: safemode: fuse reads as %X\n", progname, safemode_fuse);
    }


  /* Read lfuse three times */
  fusegood = 2; /* If AVR device doesn't support this fuse, don't want
                   to generate a verify error */
  m = avr_locate_mem(p, "lfuse");
  if (m != NULL) {
    fusegood = 0; /* By default fuse is a failure */
    if (pgm->read_byte(pgm, p, m, 0, &safemode_lfuse) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 1, lfuse value: %x\n",progname,  safemode_lfuse);
    if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 2, lfuse value: %x\n",progname,  value);
    if (value == safemode_lfuse) {
        if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
            {
            allowfuseread = 0;
            }
            avrdude_message(MSG_DEBUG, "%s: safemode read 3, lfuse value: %x\n",progname,  value);
        if (value == safemode_lfuse){
        fusegood = 1; /* Fuse read OK three times */
        }
    }
  }

    //Programmer does not allow fuse reading.... no point trying anymore
    if (allowfuseread == 0)
        {
        return -5;
        }


    if (fusegood == 0) {
        avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read lfuse properly. "
                        "Programmer may not be reliable.\n", progname);
        return -1;
    }
    else if (fusegood == 1) {
        avrdude_message(MSG_DEBUG, "%s: safemode: lfuse reads as %X\n", progname, safemode_lfuse);
    }

  /* Read hfuse three times */
  fusegood = 2; /* If AVR device doesn't support this fuse, don't want
                   to generate a verify error */
  m = avr_locate_mem(p, "hfuse");
  if (m != NULL) {
    fusegood = 0; /* By default fuse is a failure */
    if (pgm->read_byte(pgm, p, m, 0, &safemode_hfuse) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 1, hfuse value: %x\n",progname,  safemode_hfuse);
    if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 2, hfuse value: %x\n",progname,  value);
    if (value == safemode_hfuse) {
        if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
            {
            allowfuseread = 0;
            }
            avrdude_message(MSG_DEBUG, "%s: safemode read 3, hfuse value: %x\n",progname, value);
        if (value == safemode_hfuse){
             fusegood = 1; /* Fuse read OK three times */
        }
    }
  }

    //Programmer does not allow fuse reading.... no point trying anymore
    if (allowfuseread == 0)
        {
        return -5;
        }

    if (fusegood == 0)	 {
            avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read hfuse properly. "
                            "Programmer may not be reliable.\n", progname);
       return -2;
    }
    else if (fusegood == 1){
        avrdude_message(MSG_NOTICE, "%s: safemode: hfuse reads as %X\n", progname, safemode_hfuse);
    }

  /* Read efuse three times */
  fusegood = 2; /* If AVR device doesn't support this fuse, don't want
                   to generate a verify error */
  m = avr_locate_mem(p, "efuse");
  if (m != NULL) {
    fusegood = 0; /* By default fuse is a failure */
    if (pgm->read_byte(pgm, p, m, 0, &safemode_efuse) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 1, efuse value: %x\n",progname, safemode_efuse);
    if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
        {
        allowfuseread = 0;
        }
        avrdude_message(MSG_DEBUG, "%s: safemode read 2, efuse value: %x\n",progname,  value);
    if (value == safemode_efuse) {
        if (pgm->read_byte(pgm, p, m, 0, &value) != 0)
            {
            allowfuseread = 0;
            }
            avrdude_message(MSG_DEBUG, "%s: safemode read 3, efuse value: %x\n",progname, value);
        if (value == safemode_efuse){
             fusegood = 1; /* Fuse read OK three times */
        }
    }
  }

    //Programmer does not allow fuse reading.... no point trying anymore
    if (allowfuseread == 0)
        {
        return -5;
        }

    if (fusegood == 0) {
        avrdude_message(MSG_INFO, "%s: safemode: Verify error - unable to read efuse properly. "
                        "Programmer may not be reliable.\n", progname);
        return -3;
        }
    else if (fusegood == 1) {
        avrdude_message(MSG_NOTICE, "%s: safemode: efuse reads as %X\n", progname, safemode_efuse);
        }

  *lfuse = safemode_lfuse;
  *hfuse = safemode_hfuse;
  *efuse = safemode_efuse;
  *fuse  = safemode_fuse;

  return 0;
}