DavidGriffith / minipro-import-test

An open source program for controlling the MiniPRO TL866xx series of chip programmers
GNU General Public License v3.0
3 stars 0 forks source link

2732 will not program TL866ii plus #263

Open DavidGriffith opened 2 years ago

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 17, 2022, 13:40

Vintage 2732 EPROM's can not be programmed with minipro. Pin 18 [not ce] is being driven incorrectly, this issue also occurs with the official TL866ii plus software. Vpp and [not ce] are both asserted high, Vpp should be high (Vpp) but [not ce] should be low for programming. Guess this is a (simple???) fix in the .xml file?

DavidGriffith commented 2 years ago

In GitLab by @ea4eoz on Apr 17, 2022, 15:26

I can confirm this issue. I've just programmed a TMS2732A with the help of a piece of wire between pins 12 and 18 (GND and CE) to force CE low. Worked like a charm.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 17, 2022, 15:29

OK, nice one. Guess that works as vpp is switched rather than static high. What pulse duration did you use?

DavidGriffith commented 2 years ago

In GitLab by @ea4eoz on Apr 17, 2022, 15:31

50 milliseconds (--pulse=50000). It was slow as hell but worked.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 17, 2022, 15:33

Good to know, any documentation as to how to assign the correct signal to ZIF socke6t, assume through the .xml file? I have started to comple a spreadsheet of opt 1 - opt 8 but that's not giving me much insight as yet.

DavidGriffith commented 2 years ago

In GitLab by @ea4eoz on Apr 17, 2022, 15:44

No idea about the XML file. Sorry.

For a complete reference, the arguments I used were:

minipro -p "TMS2732A@DIP24" --skip_verify --pulse=50000 -w RNR.BIN

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 17, 2022, 15:47

Me neither, my C is not good enough to work out what is going on from the source. Would be good to find a proper fix and also add support for 2008 with external supply rail adapters.

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 18, 2022, 04:48

Unfortunately There's no xml file fix for this issue. This being a firmware bug we can only inform the manufacturer about it an wait for the fix (if will be one).
Regarding to the opts1-opts8 don't waste your time, there's nothing here to play with. Only protocol_id and variant will select the proper programming algorithm in firmware. For ex. 2716 and 2732 both chips share the same protocol id (both chips have 24 pins) but a different variant because they have a different programming algorithm.

As i'm working on a new branch (quite stalled now because of lack of free time) i can give you some details:

      <ic
          name="AM2732@DIP24"
          type="1"
          protocol_id="0x0b"
          variant="0x01"
          read_buffer_size="0x400"
          write_buffer_size="0x20"
          code_memory_size="0x1000"
          data_memory_size="0x00"
          data_memory2_size="0x00"
          page_size="0x0000"       // this is old opts2
          pages_per_block="0x0000" // this is old opts6
          chip_id="0x00000000"
          voltages="0x50f0"        // this is old opts5
          pulse_delay="0x01f4"     // this is old opts3
          flags="0x00000048"       // this is old opts4
          chip_info="0x0006"       // this is old opts7
          pin_map="0x0017"         // this is old opts8
          package_details="0x18000000"
          config="NULL"
      />

The opts1 is not needed anymore because is a duplicate of opts5. Also the chip_id_bytes_count is removed because this can be deduced from the chip_id member.

Here is the relevant part from the database.c code which will parse the xml chip definitions:

// flags
#define MP_ERASE_MASK 0x00000010
#define MP_ID_MASK 0x00000020
#define MP_DATA_MEMORY_ADDRESS 0x00001000
#define MP_DATA_BUS_WIDTH 0x00002000
#define MP_OFF_PROTECT_BEFORE 0x00004000
#define MP_PROTECT_AFTER 0x00008000
#define MP_LOCK_BIT_WRITE_ONLY 0x00040000
#define MP_CALIBRATION 0x00080000
#define MP_SUPPORTED_PROGRAMMING 0x00300000
#define MP_DATA_ORG 0x03000000

// Opts chip_info
#define MP_VOLTAGES1 0x0006
#define MP_VOLTAGES2 0x0007

// Package mask
#define PLCC_MASK 0xFF000000
#define ADAPTER_MASK 0x000000FF
#define ICSP_MASK 0x0000FF00
#define PIN_COUNT_MASK 0X7F000000
#define SMD_MASK 0X80000000
#define PLCC32_ADAPTER 0xFF000000
#define PLCC44_ADAPTER 0xFD000000

// Fill a device struct from an xml 'ic' tag
static int load_mem_device(db_data_t *db_data, const uint8_t *xml_device,
                           size_t size, device_t *device, uint8_t version) {
  int err = 0;
  uint32_t voltages, protocol_id;

  Memblock memblock = get_attribute(xml_device, size, NAME_ATTR);
  if (!memblock.b || memblock.z > sizeof(device->name)) return EXIT_FAILURE;
  memcpy(device->name, memblock.b, memblock.z);
  device->chip_type = get_attr_value(xml_device, size, "type", &err);
  protocol_id = get_attr_value(xml_device, size, "protocol_id", &err);
  device->variant = get_attr_value(xml_device, size, "variant", &err);
  device->read_buffer_size =
      get_attr_value(xml_device, size, "read_buffer_size", &err);
  device->write_buffer_size =
      get_attr_value(xml_device, size, "write_buffer_size", &err);
  device->code_memory_size =
      get_attr_value(xml_device, size, "code_memory_size", &err);
  device->data_memory_size =
      get_attr_value(xml_device, size, "data_memory_size", &err);
  device->data_memory2_size =
      get_attr_value(xml_device, size, "data_memory2_size", &err);
  device->page_size = get_attr_value(xml_device, size, "page_size", &err);
  device->chip_id = get_attr_value(xml_device, size, "chip_id", &err);
  voltages = get_attr_value(xml_device, size, "voltages", &err);
  device->pulse_delay = get_attr_value(xml_device, size, "pulse_delay", &err);
  uint32_t flags = get_attr_value(xml_device, size, "flags", &err);
  device->chip_info = get_attr_value(xml_device, size, "chip_info", &err);
  if (version == MP_TL866IIPLUS) {
    device->pin_map = get_attr_value(xml_device, size, "pin_map", &err);
    device->pages_per_block =
        get_attr_value(xml_device, size, "pages_per_block", &err);
  }
  device->package_details.packed_package =
      get_attr_value(xml_device, size, "package_details", &err);

  if (err) return EXIT_FAILURE;

  // get blank value if present
  device->blank_value = get_attr_value(xml_device, size, "blank_value", &err);
  if (err) device->blank_value = 0xff;

  // Get chip_ID bytes count
  device->chip_id_bytes_count = get_id_bytes_count(device->chip_id);

  // Parse configuration name
  memblock = get_attribute(xml_device, size, FUSE_ATTR);
  if (!memblock.b) return EXIT_FAILURE;

  // Check if there's a configuration name
  if (strncasecmp((char *)memblock.b, "null", memblock.z)) {
    // Initialize parser state machine
    state_machine_p_t sm;
    memset(&sm, 0, sizeof(sm));
    memcpy(sm.name, memblock.b, memblock.z);
    sm.db_data = db_data;

    err = parse_profiles(&sm);
    if (err) return EXIT_FAILURE;
    if (!sm.config) {
      fprintf(stderr, "No %s configuration was found.\n", sm.name);
      return EXIT_FAILURE;
    }
    device->config = sm.config;
  }

  // Unpack flags
  device->flags.raw_flags = flags;
  device->flags.can_erase = (flags & MP_ERASE_MASK) ? 1 : 0;
  device->flags.has_chip_id = (flags & MP_ID_MASK) ? 1 : 0;
  device->flags.has_data_offset = (flags & MP_DATA_MEMORY_ADDRESS) ? 1 : 0;
  device->flags.has_word = (flags & MP_DATA_BUS_WIDTH) ? 1 : 0;
  device->flags.off_protect_before = (flags & MP_OFF_PROTECT_BEFORE) ? 1 : 0;
  device->flags.protect_after = (flags & MP_PROTECT_AFTER) ? 1 : 0;
  device->flags.lock_bit_write_only = (flags & MP_LOCK_BIT_WRITE_ONLY) ? 1 : 0;
  device->flags.has_calibration = (flags & MP_CALIBRATION) ? 1 : 0;
  device->flags.prog_support = (flags & MP_SUPPORTED_PROGRAMMING) >> 20;
  device->flags.data_org = (flags & MP_DATA_ORG) >> 24;
  device->flags.word_size = (flags & MP_DATA_ORG) == 0x01000000 ? 2 : 1;
  device->flags.can_adjust_vcc = device->chip_info == MP_VOLTAGES1 ? 1 : 0;
  device->flags.can_adjust_vpp = device->chip_info == MP_VOLTAGES2 ? 1 : 0;

  // Check for custom defined protocol
  device->protocol_id = (uint8_t)protocol_id;
  if (protocol_id & CUSTOM_PROTOCOL_MASK) {
    device->flags.custom_protocol = 1;
  }

  if (device->flags.custom_protocol && device->protocol_id == CP_PROM)
    device->flags.prog_support = MP_READ_ONLY;

  // Unpack voltages
  device->voltages.raw_voltages = voltages;
  device->voltages.vdd = (voltages >> 12) & 0x0f;
  device->voltages.vcc = (voltages >> 8) & 0x0f;
  device->voltages.vpp = (voltages >> 4) & 0x0f;

  // Unpacking package details
  device->package_details.pin_count =
      get_pin_count(device->package_details.packed_package);
  device->package_details.adapter =
      device->package_details.packed_package & ADAPTER_MASK;
  device->package_details.icsp =
      (device->package_details.packed_package & ICSP_MASK) >> 8;

  // Fill some device parameters
  device->compare_mask = 0xff;
  switch (device->chip_info) {
    // PIC baseline devices
    case PIC_INSTR_WORD_WIDTH_12:
      device->compare_mask = 0x0fff;
      break;

    // PIC midrange/standard devices
    case PIC_INSTR_WORD_WIDTH_14:
      device->compare_mask = 0x3fff;
      if (CONFIG) {
        CONFIG->rev_bits = 5;
      }
      break;

    // PIC 18F/18F_J devices
    case PIC_INSTR_WORD_WIDTH_16_PIC18F:
    case PIC_INSTR_WORD_WIDTH_16_PIC18J:
      device->compare_mask = 0xffff;
      device->flags.word_size = 2;
      device->flags.has_word = 1;

      // This will tell us if PIC user id is 8bit or more
      device->flags.data_org = 0;  // User ID is 8 bit
      if (CONFIG) {
        CONFIG->rev_bits =
            device->chip_info == PIC_INSTR_WORD_WIDTH_16_PIC18F ? 4 : 5;
      }
      break;
  }
  return EXIT_SUCCESS;
}

As you see there's nothing about some low level pin mapping or something like this.
Sure for TL866II+ we can implement a custom algorithm using the "bitbanging" approach. I also introduced support for this in my new branch for some small chips like bipolar proms (read only). The only issue is that it's slow like hell for large chips.
Hope this cleared some of your confusions.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 10:54

Thank you for your response. So if I have this correct it is the combination of both protocol_id and variant that tell the firmware to map VPP to pin 20 and ce to pin 18 and to toggle both of these? So as there are only a limited number of 24 pin EPROMS then only a small number of valid 24 pin variants. The same variant on a 28 pin device will result in a completely different pin mapping I assume? I will look through your code best I can :-)

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 18, 2022, 12:06

So if I have this correct it is the combination of both protocol_id and variant that tell the firmware to map VPP to pin 20 and ce to pin 18 and to toggle both of these?

Yes. But there's a firmware bug (i guess, i have not analyzed the signals myself but i trust you). For protocol no. 0x0b there are only three variants implemented in firmware:
0x00 for all 2716 chip variants, 0x01 for all 2732 chip variants and 0x10 for 28c16/28c04 and similar. That's all.

The same variant on a 28 pin device will result in a completely different pin mapping I assume?

That's correct. Each protocol can have several sub-protocols (called variant in our database) which will inform the firmware about which exact algorithm to use for that particular chip.

Prior to any transaction we need to first initialize the programmer about the programming algorithm. So we send a data structure to the programmer (we call this begin_transaction) filled with all required parameters (see the code above in my last answer) which will tell to the programmer which voltage to use, programming pulse the exact algorithm and so on. Some of those parameters like programming voltage, programming pulse duration can be altered with --pulse, --vpp, --vdd, --vcc but not the programming algorithm itself (this is implemented in firmware for intellectual property protection and/or speed reason).
After this first and required step the chip is powered and the programmer is ready to accept data blocks to be written/read.

Then we begin to move data blocks back and forth (depending if we read or write); the size of those data blocks are defined in read_buffer_size and write_buffer_size.
Finally when our task is done we send an end_transaction command to the programmer which will reset the programmer internal state and also will reset all pin drivers.
That's all. There's no low level pin manipulation in our code for chip programming except for bad pin contact detection and pin drivers self testing which are not part of programming steps anyway.

You can further read this discussion issue #77 were i posted a schematic diagram of a pin driver used in TL866II+.

Also i must ask you how do you find that the /CE pin is held high during programming phase? have you hooked any scope to see that? I ask you this because this 2732 issue is kinda old; i remember some discussions back in 2012-2013 on eevblog forum about this but this was for TL866A programmer and if i remember correctly there was even a fix in firmware from the manufacturer (autoelectric) but it's possible to be wrong about this.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 12:13

Yes I have had a dual trace scope on pin 20 VPP and pin 18 /ce, they rise and fall in phase rather than /ce being out of phase with VPP. I will dump a trace and post.

Funny thing is I initially made the same mistake back in the 80 with a homebrew programmer when moving the code from 2716 to 2732.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 12:26

Top trace is pin 20 VPP, bottom is 18 /ce

scope

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 18, 2022, 12:40

Meh, you have unlocked me some memories from 80's with those chips. This means that we are both ancient and rare entities :smile:

Damn, the programming algorithm is indeed wrong. Can you move the high trace probe to the pin 21 and select a 2716 chip but without any chip inserted (am2716@dip24 for example). I want to see if the 2716 is properly handled by the firmware, like the /CE is held low during the VPP programming pulse.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 12:44

Will do, but I have successfully programmed 2716 with this so think it will be ok. Ancient and rare indeed, my 1st home brewed programmer used a heavily modified PET HPIB components removed to give direct access to 6522. Then BBC micro, then home built 8255 I/O card on IBM XT clone.

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 18, 2022, 12:53

Ok, i suggest you to also pass the -z flag in the command line. This one can prevent some head scratches :smile: It will do a bad contact pin testing prior to any read/write operation. That zif socket (the green one) is crap, believe me. I have replaced this socket in all my TL866 programmers with the black model (named black aries or something like this) but sometimes there can be some old chips with oxidized pins and the -z can save you from some bad moments.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 12:55

The trace for 2716 is the same as already posted, in phase but 2716 requires pin 18 to go from low to high for programming. This is where the error has occurred. As I said, I made the same mistake. Depending on the data sheet nomenclature pin 18 is (/e)/(p), if that makes sense? So the change in variant from 0x00 to 0x01 must just be the change of VPP pin I guess.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 12:57

OK on the socket, yes there is a difference between TEXTOOL and TEXTDOL!

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 18, 2022, 13:20

the data sheet nomenclature pin 18 is (/e)/(p), if that makes sense?

Yeah, i remember now. I have wrote some code in the 80's to write 2716 (with an 8255 mounted on a perfboard) but i have forgot about this. This was long time ago. So /CE and /OE low for read. For write /OE high VPP=programming voltage and pulse low to high the /CE line. For the 2732 there's the /CE line that must be pulsed low for 50ms.
You are right they copied the code from the 2716 without changing the code to pulse low the /CE line.
I will send them a bug report about this but i don't know if they will fix this soon.
Heh, TEXDOL :smile:

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 13:25

Fingers crossed, can work around it anyway for now. Will watch firmware updates but I guess they will have to introduce another variant for 24 pin.

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 18, 2022, 13:42

There's already a bug filled for this issue: http://forums.xgecu.com/viewthread.php?tid=526&extra=page%3D1 But i have posted i reply, who knows maybe..

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 18, 2022, 14:18

Maybe, lets hope. I feel a learning curve coming on. Think I need a USB connected device that can do various old EPROMS 2708... and bipolar PROMS 82s185 etc Lets see if I can fit that in with other projects and the work that keeps the wolf from the door!

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 20, 2022, 06:18

Well, had some free time today and i made a quick comparison between the old TL866A and TL866II+. Selected an AM2732 chip for both programmers. Top trace is VPP, lower is /CE:

TL866A:
20220420_154506

Then our beloved TL866II+: 20220420_154931

As we see the old TL866A programming algorithm is correct. I think that the old TL866A is more suitable for older chips (it can provide up to 21v for the programming voltage compared to only 18v for TL866II).

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 20, 2022, 09:50

Maybe, lets hope. I feel a learning curve coming on. Think I need a USB connected device that can do various old EPROMS 2708... and bipolar PROMS 82s185 etc Lets see if I can fit that in with other projects and the work that keeps the wolf from the door!

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 20, 2022, 09:53

That confirms it then. Have been looking for a 2nd hand 866A for a while now because of the higher VPP capability, but no luck. I have an adapter board to inject higher VPP. Next step is to build one for 2708 with the additional supplied voltages.

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 20, 2022, 11:21

The VPP voltage can be increased if needed using a little hardware mod explained here: https://www.eevblog.com/forum/blog/eevblog-411-minipro-tl866-universal-programmer-review/msg3946009/#msg3946009
Here is my github repo: https://github.com/radiomanV/TL866. You can find here a reverse engineered schematic diagram for both TL866A and TL866II+ (see the docs folder).

The TL866A/CS is hard to find indeed even a 2nd hand one.

DavidGriffith commented 2 years ago

In GitLab by @g4tuz on Apr 20, 2022, 15:07

Yes, I found the post re VPP increase. Thanks for the link to 866A. It also looks like the 866A code is more 'user time efficient'. At 50ms pulse the 1:1 mark/space of the 866ii results in a big increase in programming time!

DavidGriffith commented 2 years ago

In GitLab by @radiomanV on Apr 20, 2022, 22:12

Yes indeed. The 866A was designed initially for parallel eproms used in vehicles/cars ECU then extended to controllers, icsp functionality, and other things but due to the some hardware limitations like insufficient memory (only 120k available for programming algorithms), limited number of pin drivers, cpu processing power, lack of pull-up/pull-down resistors on i/o lines and the fact that after i released the schematics, firmware and software tools to convert from CS to A there was an "explosion" of clones on the market they decided to abandon the project and introduced the 866II+.

Well this was a kinda meh.. update of the hardware. They kept the same pin drivers structure, the same DC/DC converters schematic but a more fine control (4 bit/16 voltages for 866II instead of 3bit/8 voltages for 866A) and in general the same board design.
The big change was the processor (a 16 bit PIC instead of 8 bit for 866A). So, more memory, a more fine control of i/o lines (individual pull-up/down resistor on each i/o line), using the hardware spi/serial module instead of software bit-banging like in 866A, using multiple usb endpoints for pc communication and the most important one a more advanced encryption for the firmware this time (no luck to crack this one..). Of course they have added many chips not available for 866A like nand flash chips and other processors.

I did a quick search on Ebay/Amazon and indeed i have not found a seller with one TL866A/CS in stock. If i remember correctly the authorized autoelectric sellers were informed to return all their unsold stock to be "recycled" and introduced the new then 866II+ instead. But there was plenty of clones and even tons of original 866CS converted to A. I wonder where those devices are now? destroyed? i think not.
I think that some of them still have the old 866a/cs but they don't list these because nobody wants them anymore or almost nobody. So my suggestion is to ask some TL866II sellers if they still have the old 866cs/a and make an agreement with them to send an 866a instead of the new 866II.
I saw some sellers on ebay.uk (i assume you are from uk after your ham radio callsign / nickname) that can be asked if they still stock the old 866a.

DavidGriffith commented 1 year ago

In GitLab by @szilvasyz on Feb 23, 2023, 24:57

Hello Guys,

Recently I had to program some classic 2732s for an old computer rebuild and run into this programming issue using my TL866II-plus (okay, I know that my chips require 21V Vpp and the programmer is not able to generate such a high level - that's why I have made a raiser card with external Vpp and some electronics for switching the right levels to pin20 in place of levels >13V). Yesterday evening I have successfully programmed a series of D2732A chips with the pin18 hack you described above using a Win7 virtual machine with original xgecu software (surprisingly, point my TMS2732A failed to be programmed because of byte verifying stopped at the first address with "read 0xFF" - but checking with readout the device it revealed that the first byte programmed successfully yet).

I would wonder, if I buy a new T48 which can handle Vpp voltages up to 25V, will I run into the same pin18 issue with 2732s or not? Have anybody some experience with the T48 programmer and these rather old chips? Thank you for answers in advance.