Index: src/Global.h =================================================================== RCS file: /cvsroot/uisp/uisp/src/Global.h,v retrieving revision 1.1 diff -a -u -c -r1.1 Global.h *** src/Global.h 25 May 2002 17:59:46 -0000 1.1 --- src/Global.h 7 Oct 2003 20:06:26 -0000 *************** *** 86,91 **** --- 86,95 ---- virtual TAddr GetSegmentSize()=0; + /* Do any device-specific preparation before reading or writing. */ + virtual void Prepare() { } + virtual void Unprepare() { } + /* Read byte from active segment at address addr. */ virtual TByte ReadByte(TAddr addr)=0; *************** *** 117,122 **** --- 121,141 ---- }; typedef TPt<TDevice> PDevice; + + /* Resource acquisition is initialization for Prepare/Unprepare. */ + class TPrepareBlock { + public: + TPrepareBlock(PDevice device_arg) : device(device_arg) + { + device->Prepare(); + } + ~TPrepareBlock() + { + device->Unprepare(); + } + private: + PDevice device; + }; extern PDevice device; Index: src/Main.C =================================================================== RCS file: /cvsroot/uisp/uisp/src/Main.C,v retrieving revision 1.18 diff -a -u -c -r1.18 Main.C *** src/Main.C 7 Aug 2003 17:31:27 -0000 1.18 --- src/Main.C 7 Oct 2003 20:06:27 -0000 *************** *** 308,323 **** motintl.Write(GetCmdParam("of")); } ! if (GetCmdParam("--erase", false)){device->ChipErase();} /* Input file */ if ((val=GetCmdParam("if"))) { ! if (GetCmdParam("--upload", false)){motintl.Read(val, true, false);} ! if (GetCmdParam("--verify", false)){motintl.Read(val, false, true);} } if (GetCmdParam("--rd_fuses",false)) { TByte bits; const char *old_seg = device->TellActiveSegment(); device->SetSegment("fuse"); --- 308,335 ---- motintl.Write(GetCmdParam("of")); } ! if (GetCmdParam("--erase", false)){ ! TPrepareBlock prepare(device); ! device->ChipErase(); ! } /* Input file */ if ((val=GetCmdParam("if"))) { ! bool upload = GetCmdParam("--upload", false); ! bool verify = GetCmdParam("--verify", false); ! if (upload || verify) { ! TPrepareBlock prepare(device); ! if (upload) ! motintl.Read(val, true, false); ! if (verify) ! motintl.Read(val, false, true); ! } } if (GetCmdParam("--rd_fuses",false)) { + TPrepareBlock prepare(device); + TByte bits; const char *old_seg = device->TellActiveSegment(); device->SetSegment("fuse"); *************** *** 351,356 **** --- 363,369 ---- if (sscanf(val, "0", &bits) == 1) { + TPrepareBlock prepare(device); device->WriteByte( AVR_FUSE_LOW_ADDR, (TByte)bits ); printf("\nFuse Low Byte set to 0x00\n", (TByte)bits); } *************** *** 368,373 **** --- 381,387 ---- if (sscanf(val, "0", &bits) == 1) { + TPrepareBlock prepare(device); device->WriteByte( AVR_FUSE_HIGH_ADDR, (TByte)bits ); printf("\nFuse High Byte set to 0x00\n", (TByte)bits); } *************** *** 385,390 **** --- 399,405 ---- if (sscanf(val, "0", &bits) == 1) { + TPrepareBlock prepare(device); device->WriteByte( AVR_FUSE_EXT_ADDR, (TByte)bits ); printf("\nFuse Extended Byte set to 0x00\n", (TByte)bits); } *************** *** 400,405 **** --- 415,421 ---- if (sscanf(val, "0", &bits) == 1) { + TPrepareBlock prepare(device); device->WriteLockBits( (TByte)bits ); printf("\nLock Bits set to 0x00\n", (TByte)bits); } *************** *** 409,414 **** --- 425,431 ---- if (GetCmdParam("--lock", false)) { + TPrepareBlock prepare(device); Info(0, "NOTE: '--lock' is deprecated. Used '--wr_lock' instead.\n"); device->WriteLockBits(0xFC); printf("\nLock Bits set to 0x00\n", 0xfc); Index: src/MotIntl.C =================================================================== RCS file: /cvsroot/uisp/uisp/src/MotIntl.C,v retrieving revision 1.7 diff -a -u -c -r1.7 MotIntl.C *** src/MotIntl.C 13 May 2003 22:32:05 -0000 1.7 --- src/MotIntl.C 7 Oct 2003 20:06:28 -0000 *************** *** 106,112 **** struct timeval t1, t2; device->ResetMinMax(); ! do{ /* convert to upper case */ buf_len = strlen(line_buf); --- 106,114 ---- struct timeval t1, t2; device->ResetMinMax(); ! ! TPrepareBlock block(device); ! do{ /* convert to upper case */ buf_len = strlen(line_buf); *************** *** 243,335 **** device->ResetMinMax(); ! do{ ! /* convert to upper case */ ! buf_len = strlen(line_buf); ! for (int i=0;i<buf_len;i++){line_buf[i] = toupper(line_buf[i]);} ! ! if (line_buf[0]!=':'){throw Error_Device("Bad Intel file format.");} ! ! cc_sum = 0; ! ihex_len = Htoi(&line_buf[1]); ! p = &line_buf[3]; ! /* Check len so don't read past end of line_buf. ! 1 for ':', 1 for cnt, 2 for addr, 1 for type and 1 for checksum. */ ! if ((1+(ihex_len+1+2+1+1)*2) > MI_LINEBUF_SIZE) throw ("Bad Intel file format."); ! /* Load address */ ! addr = Htoi(p); p+=2; addr <<= 8; ! addr += Htoi(p); p+=2; ! rec_type = Htoi(p); p+=2; /* read control byte: 00-data, 01-end, 02-seg_offset */ ! addr += seg_offset; /* this allows access to more than 64K */ ! switch(rec_type) ! { ! case 0x00:{ ! /* Upload/Verify bytes */ ! total_bytes_uploaded += ihex_len; ! while(ihex_len-->0){ ! byte = Htoi(p); ! if (upload){device->WriteByte(addr, byte, false);} ! if (verify){ ! TByte rbyte = device->ReadByte(addr); ! if (rbyte != byte){ ! Info(0, " error at address 0x0: file=0x00, mem=0x00\n", ! device->TellActiveSegment(), addr, ! (int) byte, (int) rbyte); } } ! p+=2; addr++; ! if (total_bytes_uploaded >= hash_cnt+hash_marker){ ! Info(2, "#"); ! hash_cnt+=hash_marker; ! } ! } ! } break; ! case 0x01: /* end */ ! case 0x03: /* start address record */ ! case 0x05: /* start linear address record */ ! /* don't need to do anything, except calculate the checksum */ ! while (ihex_len-- > 0) { ! byte = Htoi(p); ! p += 2; ! } ! break; ! ! case 0x02:{ ! seg_offset = Htoi(p); p+=2; seg_offset <<=8; ! seg_offset += Htoi(p); p+=2; ! ! /* seg_offset is bits 4-19 of addr, so shift to that. */ ! seg_offset <<=4; ! } break; ! case 0x04: /* extended linear address record */ ! seg_offset = Htoi(p); p += 2; seg_offset <<= 8; ! seg_offset += Htoi(p); p += 2; ! seg_offset <<= 16; ! break; ! default: throw Error_Device("Bad Intel Hex record.\n"); ! } ! /* Read Check Sum and give a report */ ! ihex_cc_sum = Htoi(p); ! if (cc_sum != 0x0){ ! Info(2, "Intel check sum: 0 uisp check sum: 0\n", ! (unsigned)ihex_cc_sum, (unsigned)cc_sum); ! throw Error_Device("Check sum error.\n"); ! } ! } while(fgets(line_buf, MI_LINEBUF_SIZE, fd)!=NULL); ! ! if (upload){device->FlushWriteBuffer();} /* Print transfer statistics */ gettimeofday(&t2, NULL); timersub(&t2, &t1, &t2); --- 245,341 ---- device->ResetMinMax(); ! { ! TPrepareBlock block(device); ! do{ ! /* convert to upper case */ ! buf_len = strlen(line_buf); ! for (int i=0;i<buf_len;i++){line_buf[i] = toupper(line_buf[i]);} ! ! if (line_buf[0]!=':'){throw Error_Device("Bad Intel file format.");} ! ! cc_sum = 0; ! ihex_len = Htoi(&line_buf[1]); ! p = &line_buf[3]; ! ! /* Check len so don't read past end of line_buf. ! 1 for ':', 1 for cnt, 2 for addr, 1 for type and 1 for checksum. */ ! if ((1+(ihex_len+1+2+1+1)*2) > MI_LINEBUF_SIZE) throw ("Bad Intel file format."); ! /* Load address */ ! addr = Htoi(p); p+=2; addr <<= 8; ! addr += Htoi(p); p+=2; ! rec_type = Htoi(p); p+=2; /* read control byte: 00-data, 01-end, 02-seg_offset */ ! addr += seg_offset; /* this allows access to more than 64K */ ! switch(rec_type) ! { ! case 0x00:{ ! /* Upload/Verify bytes */ ! total_bytes_uploaded += ihex_len; ! while(ihex_len-->0){ ! byte = Htoi(p); ! if (upload){device->WriteByte(addr, byte, false);} ! if (verify){ ! TByte rbyte = device->ReadByte(addr); ! if (rbyte != byte){ ! Info(0, " error at address 0x0: file=0x00, mem=0x00\n", ! device->TellActiveSegment(), addr, ! (int) byte, (int) rbyte); ! } ! } ! p+=2; addr++; ! if (total_bytes_uploaded >= hash_cnt+hash_marker){ ! Info(2, "#"); ! hash_cnt+=hash_marker; } } ! } break; ! case 0x01: /* end */ ! case 0x03: /* start address record */ ! case 0x05: /* start linear address record */ ! /* don't need to do anything, except calculate the checksum */ ! while (ihex_len-- > 0) { ! byte = Htoi(p); ! p += 2; ! } ! break; ! case 0x02:{ ! seg_offset = Htoi(p); p+=2; seg_offset <<=8; ! seg_offset += Htoi(p); p+=2; ! ! /* seg_offset is bits 4-19 of addr, so shift to that. */ ! seg_offset <<=4; ! } break; ! ! case 0x04: /* extended linear address record */ ! seg_offset = Htoi(p); p += 2; seg_offset <<= 8; ! seg_offset += Htoi(p); p += 2; ! seg_offset <<= 16; ! break; ! default: throw Error_Device("Bad Intel Hex record.\n"); ! } ! /* Read Check Sum and give a report */ ! ihex_cc_sum = Htoi(p); ! if (cc_sum != 0x0){ ! Info(2, "Intel check sum: 0 uisp check sum: 0\n", ! (unsigned)ihex_cc_sum, (unsigned)cc_sum); ! throw Error_Device("Check sum error.\n"); ! } ! } while(fgets(line_buf, MI_LINEBUF_SIZE, fd)!=NULL); + if (upload){device->FlushWriteBuffer();} + } + /* Print transfer statistics */ gettimeofday(&t2, NULL); timersub(&t2, &t1, &t2); *************** *** 395,455 **** device->ResetMinMax(); ! size = device->GetSegmentSize(); ! /* Print first hash (except for fuse bits) */ ! if (size >= 16) ! Info(2, "#"); ! buf[0] = 0; ! buf[1] = 0; ! strncpy((char *) buf+2, seg, 16); ! buf[18] = 0; ! SrecWrite(0, buf, 2 + strlen((const char *) buf + 2)); ! ! for (addr = 0; addr < size; addr += 16) { ! int i, len; ! ! len = size - addr; ! if (len > 16) ! len = 16; ! buf[0] = (addr >> 24) & 0xFF; ! buf[1] = (addr >> 16) & 0xFF; ! buf[2] = (addr >> 8) & 0xFF; ! buf[3] = addr & 0xFF; ! for (i = 0; i < len; i++) { ! TByte rbyte = device->ReadByte(addr + i); ! buf[4 + i] = rbyte; ! total_bytes_uploaded++; ! if (total_bytes_uploaded >= hash_cnt + hash_marker) { ! Info(2, "#"); ! hash_cnt += hash_marker; } } if (addr < 0x10000) ! SrecWrite(1, buf + 2, 2 + len); else if (addr < 0x1000000) ! SrecWrite(2, buf + 1, 3 + len); else ! SrecWrite(3, buf , 4 + len); ! s5count++; } - /* number of S1/2/3 records written */ - buf[0] = (s5count >> 8) & 0xFF; - buf[1] = s5count & 0xFF; - SrecWrite(5, buf, 2 ); - - /* starting address is 0 */ - buf[0] = 0; - buf[1] = 0; - buf[2] = 0; - buf[3] = 0; - if (addr < 0x10000) - SrecWrite(9, buf+2, 2 ); - else if (addr < 0x1000000) - SrecWrite(8, buf+1, 3); - else - SrecWrite(7, buf, 4); /* Print transfer statistics */ gettimeofday(&t2, NULL); --- 401,465 ---- device->ResetMinMax(); ! { ! TPrepareBlock block(device); ! size = device->GetSegmentSize(); ! /* Print first hash (except for fuse bits) */ ! if (size >= 16) ! Info(2, "#"); ! ! buf[0] = 0; ! buf[1] = 0; ! strncpy((char *) buf+2, seg, 16); ! buf[18] = 0; ! SrecWrite(0, buf, 2 + strlen((const char *) buf + 2)); ! ! for (addr = 0; addr < size; addr += 16) { ! int i, len; ! ! len = size - addr; ! if (len > 16) ! len = 16; ! buf[0] = (addr >> 24) & 0xFF; ! buf[1] = (addr >> 16) & 0xFF; ! buf[2] = (addr >> 8) & 0xFF; ! buf[3] = addr & 0xFF; ! for (i = 0; i < len; i++) { ! TByte rbyte = device->ReadByte(addr + i); ! buf[4 + i] = rbyte; ! total_bytes_uploaded++; ! if (total_bytes_uploaded >= hash_cnt + hash_marker) { ! Info(2, "#"); ! hash_cnt += hash_marker; ! } } + if (addr < 0x10000) + SrecWrite(1, buf + 2, 2 + len); + else if (addr < 0x1000000) + SrecWrite(2, buf + 1, 3 + len); + else + SrecWrite(3, buf , 4 + len); + s5count++; } + /* number of S1/2/3 records written */ + buf[0] = (s5count >> 8) & 0xFF; + buf[1] = s5count & 0xFF; + SrecWrite(5, buf, 2 ); + + /* starting address is 0 */ + buf[0] = 0; + buf[1] = 0; + buf[2] = 0; + buf[3] = 0; if (addr < 0x10000) ! SrecWrite(9, buf+2, 2 ); else if (addr < 0x1000000) ! SrecWrite(8, buf+1, 3); else ! SrecWrite(7, buf, 4); } /* Print transfer statistics */ gettimeofday(&t2, NULL); Index: src/Stk500.C =================================================================== RCS file: /cvsroot/uisp/uisp/src/Stk500.C,v retrieving revision 1.24 diff -a -u -c -r1.24 Stk500.C *** src/Stk500.C 7 Aug 2003 17:11:26 -0000 1.24 --- src/Stk500.C 7 Oct 2003 20:06:30 -0000 *************** *** 270,275 **** --- 270,285 ---- } } + void TStk500::Prepare() + { + EnterProgrammingMode(); + } + + void TStk500::Unprepare() + { + LeaveProgrammingMode(); + } + /* Read byte from active segment at address addr. */ TByte TStk500::ReadByte(TAddr addr) { *************** *** 321,328 **** /* FIXME: TRoth/2002-05-29: This is still broken. If flash or eeprom changes after the calling ReadMem(), you won't ever see the change. */ ! if (read_buffer[segment] == NULL) ! ReadMem(); val = read_buffer[segment][addr]; } --- 331,338 ---- /* FIXME: TRoth/2002-05-29: This is still broken. If flash or eeprom changes after the calling ReadMem(), you won't ever see the change. */ ! if (read_buffer[segment] == NULL || ! read_buffer_valid[segment][addr]) ! ReadMem(addr); val = read_buffer[segment][addr]; } *************** *** 409,416 **** pagesize = 128; } - EnterProgrammingMode(); - addr = 0; for (unsigned int addr=0; addr<maxaddr; addr+=pagesize) { memcpy(buf, SetAddress, sizeof(SetAddress)); --- 419,424 ---- *************** *** 432,438 **** if (memcmp(buf, WriteMemory_Reply, sizeof(WriteMemory_Reply)) != 0) { throw Error_Device ("[FWB 2] Device is not responding correctly."); } } - LeaveProgrammingMode(); } --- 440,445 ---- *************** *** 440,453 **** void TStk500::ChipErase(){ TByte buf[100]; - EnterProgrammingMode(); - memcpy(buf, EraseDevice, sizeof(EraseDevice)); Send(buf, sizeof(EraseDevice), sizeof(EraseDevice_Reply)); if (memcmp(buf, EraseDevice_Reply, sizeof(EraseDevice_Reply)) != 0) { throw Error_Device ("[CE] Device is not responding correctly."); } - - LeaveProgrammingMode(); } --- 447,456 ---- *************** *** 481,489 **** rbits = ((rbits >> 1) & 3) | 0xFC; } else { /* if its signature returns 0,1,2 then say it's locked. */ - EnterProgrammingMode(); ReadSignature(); - LeaveProgrammingMode(); if (vendor_code == 0 && part_family == 1 && part_number == 2) --- 484,490 ---- *************** *** 678,690 **** memcpy(buf+1, cmd, 4); - EnterProgrammingMode(); - /* Expected response is { 0x14, <output>, 0x10 } */ Send(buf, sizeof(buf), 3); - LeaveProgrammingMode(); - if ((buf[0] != 0x14) || (buf[2] != 0x10)) { throw Error_Device ("[UC] Device is not responding correctly."); --- 679,687 ---- *************** *** 705,714 **** } ! void TStk500::ReadMem(){ TByte buf[0x200]; int wordsize; - TAddr addr; TByte seg; if (segment == SEG_FLASH) { --- 702,711 ---- } ! void TStk500::ReadMem(TAddr addr){ ! TAddr block_addr = addr & ~TAddr(0xff); TByte buf[0x200]; int wordsize; TByte seg; if (segment == SEG_FLASH) { *************** *** 721,747 **** throw Error_Device ("TStk500::ReadMem() called for invalid segment."); } ! read_buffer[segment] = new TByte[GetSegmentSize()]; ! ! EnterProgrammingMode(); ! ! addr = 0; ! for (unsigned int addr=0; addr<GetSegmentSize(); addr+=0x100) { ! memcpy(buf, SetAddress, sizeof(SetAddress)); ! buf[1] = (addr/wordsize) & 0xff; ! buf[2] = ((addr/wordsize) >> 8) & 0xff; ! Send(buf, sizeof(SetAddress), sizeof(SetAddress_Reply)); ! if (memcmp(buf, SetAddress_Reply, sizeof(SetAddress_Reply)) != 0) { ! throw Error_Device ("[RM] Device is not responding correctly."); } ! ! memcpy(buf, ReadMemory, sizeof(ReadMemory)); ! buf[3] = seg; ! Send(buf, sizeof(ReadMemory), 2+0x100); ! ! memcpy(read_buffer[segment]+addr, buf+1, 0x100); } ! LeaveProgrammingMode(); } static TByte --- 718,745 ---- throw Error_Device ("TStk500::ReadMem() called for invalid segment."); } ! if (! read_buffer[segment]) ! read_buffer[segment] = new TByte[GetSegmentSize()]; ! if (! read_buffer_valid[segment]) { ! read_buffer_valid[segment] = new TByte[GetSegmentSize()]; ! // Mark as invalid ! memset(read_buffer_valid[segment], 0, GetSegmentSize()); } ! memcpy(buf, SetAddress, sizeof(SetAddress)); ! buf[1] = (block_addr/wordsize) & 0xff; ! buf[2] = ((block_addr/wordsize) >> 8) & 0xff; ! Send(buf, sizeof(SetAddress), sizeof(SetAddress_Reply)); ! if (memcmp(buf, SetAddress_Reply, sizeof(SetAddress_Reply)) != 0) { ! throw Error_Device ("[RM] Device is not responding correctly."); } ! ! memcpy(buf, ReadMemory, sizeof(ReadMemory)); ! buf[3] = seg; ! Send(buf, sizeof(ReadMemory), 2+0x100); ! ! memcpy(read_buffer[segment]+block_addr, buf+1, 0x100); ! // Mark block as valid ! memset(read_buffer_valid[segment]+block_addr, 1, 0x100); } static TByte *************** *** 910,915 **** --- 908,916 ---- read_buffer[SEG_FLASH] = NULL; read_buffer[SEG_EEPROM] = NULL; + read_buffer_valid[SEG_FLASH] = NULL; + read_buffer_valid[SEG_EEPROM] = NULL; + maxaddr = 0; } *************** *** 920,923 **** --- 921,927 ---- delete read_buffer[SEG_FLASH]; delete read_buffer[SEG_EEPROM]; + + delete read_buffer_valid[SEG_FLASH]; + delete read_buffer_valid[SEG_EEPROM]; } Index: src/Stk500.h =================================================================== RCS file: /cvsroot/uisp/uisp/src/Stk500.h,v retrieving revision 1.13 diff -a -u -c -r1.13 Stk500.h *** src/Stk500.h 7 Aug 2003 17:11:26 -0000 1.13 --- src/Stk500.h 7 Oct 2003 20:06:30 -0000 *************** *** 98,103 **** --- 98,104 ---- int desired_part; TByte* write_buffer[2]; /* buffer for SEG_FLASH and SEG_EEPROM */ TByte* read_buffer[2]; /* buffer for SEG_FLASH and SEG_EEPROM */ + TByte* read_buffer_valid[2]; /* valid flags for SEG_FLASH and SEG_EEPROM */ TAddr maxaddr; static const TByte pSTK500[]; *************** *** 133,139 **** void EnterProgrammingMode(); void LeaveProgrammingMode(); void ReadSignature(); ! void ReadMem(); TByte ReadParam(TByte param); void WriteParam(TByte param, TByte val); --- 134,140 ---- void EnterProgrammingMode(); void LeaveProgrammingMode(); void ReadSignature(); ! void ReadMem(TAddr addr); TByte ReadParam(TByte param); void WriteParam(TByte param, TByte val); *************** *** 154,159 **** --- 155,164 ---- void WriteFuseExtBits(TByte bits); public: + /* Do any device-specific preparation before reading or writing. */ + void Prepare(); + void Unprepare(); + /* Read byte from active segment at address addr. */ TByte ReadByte(TAddr addr); Index: src/Terminal.C =================================================================== RCS file: /cvsroot/uisp/uisp/src/Terminal.C,v retrieving revision 1.5 diff -a -u -c -r1.5 Terminal.C *** src/Terminal.C 17 Feb 2003 17:29:45 -0000 1.5 --- src/Terminal.C 7 Oct 2003 20:06:31 -0000 *************** *** 81,86 **** --- 81,87 ---- } else if (!strcmp(cmd,"ul")) { char inputFileName [64]; scanf ("", inputFileName); + TPrepareBlock prepare(device); try{ motintl.Read(inputFileName, true, false); } *************** *** 89,94 **** --- 90,96 ---- } else if (!strcmp(cmd,"vf")) { char inputFileName [64]; scanf ("", inputFileName); + TPrepareBlock prepare(device); try{ motintl.Read(inputFileName, false, true); } *************** *** 123,128 **** --- 125,131 ---- } else {addr=0;} } else if (!strcmp(cmd,"ce")){ + TPrepareBlock prepare(device); device->ChipErase(); } /* *************** *** 139,150 **** --- 142,155 ---- */ else if (!strcmp(cmd,"rd")){ scanf ("0", &addr); + TPrepareBlock prepare(device); printf(": $00\n", device->TellActiveSegment(), device->ReadByte(addr)); } else if (!strcmp(cmd,"wr")){ unsigned x; scanf("00", &addr, &x); + TPrepareBlock prepare(device); device->WriteByte(addr, TByte(x)); } else if (!strcmp(cmd,"du")){ *************** *** 153,158 **** --- 158,164 ---- } else if (!strcmp(cmd,",")){ list_contents: + TPrepareBlock prepare(device); int i,l=0; while (l<4) { printf (" $00000: ", device->TellActiveSegment(), addr);