Exemple #1
0
int avr_read_byte_default(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                          unsigned long addr, unsigned char * value)
{
  unsigned char cmd[4];
  unsigned char res[4];
  unsigned char data;
  OPCODE * readop, * lext;

  if (pgm->cmd == NULL) {
    logprintf(LOG_ERR, "%s programmer uses avr_read_byte_default() but does not provide a cmd() method", pgm->type);
    return -1;
  }

  /*
   * figure out what opcode to use
   */
  if (mem->op[AVR_OP_READ_LO]) {
    if (addr & 0x00000001)
      readop = mem->op[AVR_OP_READ_HI];
    else
      readop = mem->op[AVR_OP_READ_LO];
    addr = addr / 2;
  }
  else {
    readop = mem->op[AVR_OP_READ];
  }

  if (readop == NULL) {
    return -1;
  }

  /*
   * If this device has a "load extended address" command, issue it.
   */
  lext = mem->op[AVR_OP_LOAD_EXT_ADDR];

  if (lext != NULL) {
    memset(cmd, 0, sizeof(cmd));

    avr_set_bits(lext, cmd);
    avr_set_addr(lext, cmd, addr);
    pgm->cmd(pgm, cmd, res);
  }

  memset(cmd, 0, sizeof(cmd));

  avr_set_bits(readop, cmd);
  avr_set_addr(readop, cmd, addr);
  pgm->cmd(pgm, cmd, res);
  data = 0;
  avr_get_output(readop, res, &data);

  *value = data;

  return 0;
}
Exemple #2
0
static int  pickit2_paged_load(PROGRAMMER * pgm, AVRPART * p, AVRMEM * mem,
                        unsigned int page_size, unsigned int addr, unsigned int n_bytes)
{
    // only supporting flash & eeprom page reads
    if ((!mem->paged || page_size <= 1) || (strcmp(mem->desc, "flash") != 0 && strcmp(mem->desc, "eeprom") != 0))
    {
        return -1;
    }

    DEBUG( "paged read ps %d, mem %s\n", page_size, mem->desc);

    OPCODE *readop = 0, *lext = mem->op[AVR_OP_LOAD_EXT_ADDR];
    uint8_t data = 0, cmd[SPI_MAX_CHUNK], res[SPI_MAX_CHUNK];
    unsigned int addr_base;
    unsigned int max_addr = addr + n_bytes;

    pgm->pgm_led(pgm, ON);

    for (addr_base = addr; addr_base < max_addr; )
    {
        if ((addr_base == 0 || (addr_base % /*ext_address_boundary*/ 65536) == 0)
                && lext != NULL)
        {
            memset(cmd, 0, sizeof(cmd));

            avr_set_bits(lext, cmd);
            avr_set_addr(lext, cmd, addr_base);
            pgm->cmd(pgm, cmd, res);
        }

        // bytes to send in the next packet -- not necessary as pickit2_spi() handles breaking up
        // the data into packets -- but we need to keep transfers frequent so that we can update the
        // status indicator bar
        uint32_t blockSize = MIN(65536 - (addr_base % 65536), MIN(max_addr - addr_base, SPI_MAX_CHUNK / 4));

        memset(cmd, 0, sizeof(cmd));
        memset(res, 0, sizeof(res));

        uint8_t addr_off;
        for (addr_off = 0; addr_off < blockSize; addr_off++)
        {
            int addr = addr_base + addr_off, caddr = addr;

            if (mem->op[AVR_OP_READ_LO] != NULL && mem->op[AVR_OP_READ_HI] != NULL)
            {
                if (addr & 0x00000001)
                    readop = mem->op[AVR_OP_READ_HI];
                else
                    readop = mem->op[AVR_OP_READ_LO];

                caddr /= 2;
            }
            else if (mem->op[AVR_OP_READ] != NULL)
            {
                readop = mem->op[AVR_OP_READ];
            }
            else
            {
                avrdude_message(MSG_INFO, "no read command specified\n");
                return -1;
            }

            avr_set_bits(readop, &cmd[addr_off*4]);
            avr_set_addr(readop, &cmd[addr_off*4], caddr);
        }

        int bytes_read = pgm->spi(pgm, cmd, res, blockSize*4);

        if (bytes_read < 0)
        {
            avrdude_message(MSG_INFO, "Failed @ pgm->spi()\n");
            pgm->err_led(pgm, ON);
            return -1;
        }

        DEBUG( "\npaged_load @ %X, wrote: %d, read: %d bytes\n", addr_base, blockSize*4, bytes_read);

        for (addr_off = 0; addr_off < bytes_read / 4; addr_off++)
        {
            data = 0;
            avr_get_output(readop, &res[addr_off*4], &data);
            mem->buf[addr_base + addr_off] = data;

            DEBUG( "%2X(%c)", (int)data, data<0x20?'.':data);
        }
        DEBUG( "\n");

        addr_base += blockSize;
    }

    pgm->pgm_led(pgm, OFF);

    return n_bytes;
}