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; }
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; }