ole00 / afterburner

GAL chip programmer for Arduino
154 stars 43 forks source link

JTAG Support for ATF150x? #57

Open peterzieba opened 6 months ago

peterzieba commented 6 months ago

Do you think there would be enough space on the Uno to add in XSVF programming such that the ATF150x CPLD chips could be programmed via JTAG? They also work with WinCUPL...

I figure since afterburner is capable of generating the 12V required by the OE1 pin, this could fill the gap where standard JTAG programmers can't handle these devices without the additional programming voltage. Ever since the secrets of the OE1 pin have been revealed, the rest is standard JTAG to support several parts. I believe this would also work for the Altera MAX CPLDs, which are very similar, but I know less about these devices...

ole00 commented 6 months ago

It would be nice to have that option. I know there is some documentation here: https://www.hackup.net/2020/01/erasing-and-programming-the-atf1504-cpld/ and here: https://github.com/hackup/ATF2FT232HQ

Size wise: on Uno R3 there is currently about 12kb free flash. Whether a jtag code could be squeezed into 12kb - I don't know. Also, some extra memory RAM might be needed for UNO.

ole00 commented 6 months ago

BTW. Afterburner now supports ATF750C (thanks to Michael D.) which is a more capable PLD compared to ATF22V10C. It's also supported by WinCUPL. You don't seem to mention that chip on your web site (https://github.com/peterzieba/5Vpld) . Another interesting 5V PLD chip is ATF2500C - but I don't know the fuse writing protocol, so no support in Afterburner.

ole00 commented 6 months ago

Out of curiosity I compiled the following Arduino JTAG example code: https://github.com/mrjimenez/JTAG/blob/master/examples/JTAGTest/JTAGTest.ino and the compiled code size is about 11kbytes, so in theory (along with the existing Afterburner's code) it should fit into UNO's flash. OTOH, I don't know whether that code is enough to program the CPLD like ATF1502C, so more research would be required. EDIT: changed AFT1500C to ATF1502C

peterzieba commented 6 months ago

Yeah, I believe that should work. OE1 12V is only needed to unlock a part, and the Arduino JTAG project you mention looks like it might be able to do the trick so it would not be terribly difficult to test.

As for details about which parts this would work for: ATF1502, ATF1504, and ATF1508.

The ATF1500C is technically a completely different part and does not support JTAG -- in fact, it is actually more similar to the ATF750C you mention. I should mention at least why I've avoided these parts: They're more expensive and fussier to program than the rest.

Nonetheless, it would not surprise me to learn that the programming algo required is similar however, and I think I've seen a programming adapter schematic somewhere on the internet such that a mapping from the 750 to the 1500 could be achieved if it is indeed close enough in terms of programming algo. IIRC, it is a byte-wide means of programming and not a fancy serial protocol.

As for the ATF2500C, that's where my knowledge of the landscape drops off. I've looked into these before very briefly but can't remember why I did not pursue it further. I want to say they're older than the 1502, 1504, 1508, and so they don't have the benefit of JTAG and possibly also have fewer macrocells, but this should probably be confirmed.

ole00 commented 6 months ago

A brief look at the datasheets show:

ATF2500C : 24 Macrocells, 48 flip-flops, price £7.5 in single quant (mouser) ATF1502AS : 32 Macrocells : ? 32 flip-flops ? , price £2.1 in single quant (digikey). So, that makes sense why nobody uses ATF2500C these days - ATF1502AS is 3.5x cheaper and has more macro-cells than ATF2500C.

Still, Afterburner now supports many obsolete GAL chips (thanks to rhgndf, porting the code from GALBlast) which are supported mainly to allow repairs of old equipment with compatible parts. So support for ATF2500C might be useful.

Thanks for pointing out about ATF1500 - I did not know that it is not JTAG based.

Also worth noting, there is 3.3V version of ATF1502ASV, which can be damaged with Arduino's 5V VCC and IO logic.

peterzieba commented 6 months ago

Yes, the "V" parts I believe are the 3.3V parts.

There are even the "BE" parts which have two different voltage IO banks, but I believe these parts are somewhere between unobtanium and eye-watteringly expensive. whitequark did a bunch of work to figure out the fusemap for all of these parts and if I remember correctly, the BE parts were a totally different fusemap.

My scope was mostly about modern designs needing 5V and still active parts, but I do appreciate the need for archival and figuring out these programming algorithms is important work. I'll see if I can find that programming adapter schematic, as it could be useful for anyone wanting to extend programming support to the ATF1500.

Oh, speaking of IO voltages, I believe the bigger parts (like the ATF1508AS) have separate lines for VccIO and VccCore and so can technically be used at 3.3V. On the smaller parts they simply have 4 Vcc pins, however, if you hit them with a voltmeter, you'll find that two are connected to eachother, and the other two are connected to eachother. I'm pretty sure the 44-pin devices are capable of running independent VccCore at 5V and VccIO at 3.3V just as well. Not relevant for this project as everything can just be 5V (expect at ASV devices, as you pointed out), however, possibly a useful tidbit for anyone wanting to use the smaller ATF1502AS or ATF1504AS at 3.3V IO.

peterzieba commented 6 months ago

http://matthieu.benoit.free.fr/all03/adp/HiLo_ADP-ATF1500.PDF

That's the diagram I mentioned for programming the ATF1500C. It provides the names and pin mappings to the pins required for programming those devices in case this is helpful for anyone looking to extend programming to that specific device. Again, I think they're more expensive than the ATF1502 and harder to program, but maybe this will be helpful to someone.

ole00 commented 6 months ago

Thanks for that link. The web site (Matthieu's) is a trove of CPLD information. Some more interesting links (perhaps for others to explore):

http://matthieu.benoit.free.fr/120.htm

http://matthieu.benoit.free.fr/pld.htm has a link to CUPL compiler for old GALs!

Other ATF150X adapter schematics: http://matthieu.benoit.free.fr/all03/adp/HiLo_ADP-ATF1504.PDF http://matthieu.benoit.free.fr/all03/adp/HiLo_ADP-ATF1508.PDF

peterzieba commented 6 months ago

Ah, on the topic of the CUPL compiler I have some tidbits. I think using the CUPL compiler directly from the freely available WinCUPL might be the best approach and I think it includes the latest/greatest version. However, it comes bundled with support for a very limited number of chips. Inside of the 5vcomp wrapper I put together, you'll find references to other device libraries, where they come from, and their timestamps.

DEVICE_LIB="c:/Wincupl/Shared/Atmel.dl" #The library provided by Atmel WinCUPL from either 3/31/04 or 10/24/00

DEVICE_LIB="c:/Wincupl/Shared/totaldes.dl" #The library provided by Total Designer from 8/14/99

DEVICE_LIB="c:/Wincupl/Shared/pldmstr.dl" #The library provided by PLDmaster from 2/21/00

DEVICE_LIB="c:/Wincupl/Shared/palxprt.dl" #The library provided by PALexpert from 6/20/99

Swapping out the device library for one from another package will give you the ability to use CUPL.EXE for a monumental trove of old chips. I'm not sure how many people realize this...

Here you'll find a list of devices these libraries bring in: https://github.com/peterzieba/5Vpld#guide-to-cupl-itself

The equivalent windows batch file 5vcomp.bat might be more useful to those not wishing to use Linux...

Those other schematics you mention are the first original source where I found the OE1 pin's importance in programming. Where it is called "OGI" is a lead and only vaguely alluded to in the datasheet. The ATF1504 schematic also clearly shows the separation of VccIO and VccCore, which is not shown in the datasheet for the 44-pin devices to my knowledge.

ole00 commented 5 months ago

I just tried the Arduino JTAG with ATF1504ASL and it works in general. The issue is my ATF1504ASL JTAG TDO line high level is ~ 2.3V and it is not enough for a reliable reception of data on AVR Arduino where the high signal level should be at least 3V . So in about 9 attempts out of 10 I get communication errors. Also, the IC repsponds to JTAG commands even when the VPP is only 5V.

Here is the programming output while using the xsvf python script (VPP on OE1 pin was ~ 4.6V):

File: /home/ole/Arduino/libraries/JTAG/extras/python/atf1504asl_erase.xsvf
Ready to send 23126 bytes.
Sent:      102 bytes,    23024 remaining 
IMPORTANT: DR check failed!
IMPORTANT: *****************************
IMPORTANT: Failure at instruction #   13
IMPORTANT: *****************************
IMPORTANT: Last TDO: 00 00 00 3E/32 bits
IMPORTANT: Processed 13 instructions.
IMPORTANT: Checksum:  0xDA/53.
IMPORTANT: Sum: 0x00000B26/53.
Quit: DR check failed (-101).
  Expected checksum:  0xA4/23126.
  Expected sum: 0x0000165C/23126.
Elapsed time: 0.05 seconds.
ole@pc:~/Arduino/libraries/JTAG/extras/python$ ./xsvf -p /dev/ttyUSB0 atf1504asl_erase.xsvf 
File: /home/ole/Arduino/libraries/JTAG/extras/python/atf1504asl_erase.xsvf
Ready to send 23126 bytes.
Sent:    23126 bytes,        0 remaining 
IMPORTANT: ********
IMPORTANT: Success!
IMPORTANT: ********
IMPORTANT: Last TDO: 03 FF/10 bits
IMPORTANT: Processed 2645 instructions.
IMPORTANT: Checksum:  0x5E/23126.
IMPORTANT: Sum: 0x0038ABA2/23126.
Quit: No error (0).
  Expected checksum:  0x5E/23126.
  Expected sum: 0x0038ABA2/23126.
Elapsed time: 3.43 seconds.

So far it looks to me Afterburner is not even required - a direct connection to 3.3V Arduino and OE1 pin strapped to high level (or possibly 5V - needs to be checked) should do the job.

peterzieba commented 5 months ago

So, OE1 can be ignored entirely if you have a blank / brand new chip, however, in the event that a device has already been programmed, the JTAG interface might be disabled, at which point it becomes impossible to do anything more with the device unless one has a very fancy programmer (which provides Vpp to OE1).

I think it is relatively easy to accidentally disable JTAG because I want to say by default it assumes off unless it is specified in the .PLD file to remain on. This is how one would ensure that it doesn't get disabled: PROPERTY ATMEL { jtag=on };

The other way to make sure JTAG stays on is the following command line option is passed to the fitter: -strategy JTAG = ON

Forgetting to do one of those leads to a difficult to reprogram device without Vpp on OE1.

Disabling JTAG is sometimes used deliberately so that a design can use all of the pins available (repurposing the JTAG pins), but it is common that the JTAG pins are disabled by accident. Once this is the case, Vpp on OE1 then becomes important, and this is something that's not a standard thing that JTAG programmers offer which is why integrating this functionality could be really neat (there are other devices which have a similar pseudo-JTAG interface but require some manner of unusually high programming voltage. Namely the EPM7xxx devices which are very similar to these CPLDs)

ole00 commented 5 months ago

Thanks for the insight about the OE1, the Bigby's blog at hackup.net hinted that the OE1 high VPP might be required only to unlock the secured chip, but it did not go into details. Your explanation makes sense. I'm still puzzled by the 2.3V signal at the TDO pin, I'm wondering whether it is specific to the ASL IC, or whether the AS chips behave the same. Unfortunately I don't have the AS (without the 3'd letter) IC to try out (I have some ASL and ASV ICs). If all ASx chips would behave the same in that respect then a voltage level shift can be added on the ZIF socket adapter (adapter will be needed).

Unfortunately the whole JED to SVFX conversion procedure is a bit convoluted (WinCupl to produce Jed file, ATMISP7 to convert the .jed to .svf, SVF2XSVF tool to convert .svf to .xsvf), but at least it is possible (on Windows and Wined Linux). Ideally somebody would write a piece of open-sourced software to convert .jed directly to .xsvf - technically it seems possible as most of the information exists or can be derived form the produced outputs of the existing software. I'm not having high hopes that somebody would write such software these days though :) . Extracting the PLCC IC from the adapter's socket is not very convenient either, so it will need some sort of versatile adapter that can fit breadboard (to test the design) and Afterburner's ZIF socket to reprogram.

peterzieba commented 5 months ago

Ideally somebody would write a piece of open-sourced software to convert .jed directly to .xsvf

You mean like this? https://github.com/whitequark/prjbureau/blob/main/util/fuseconv.py

I'm not having high hopes that somebody would write such software these days though :)

Times are weird.

I know less about the ASL chip -- is this the one that's 5V but is supposed to be the lower power version?

ole00 commented 5 months ago

fuseconv.py: thanks for mentioning that tool, it works for me, although it "only" converts from .jed to svf.

There is also this tool: https://github.com/arduino/OpenOCD/blob/master/contrib/xsvf_tools/svf2xsvf.py which is supposed to convert from svf to xsvf, however it did not work with the .svf produced by fuseconf.py. Some effort will be required to make it work.

After re-reading the ATF1504AS(L) datasheet I found out the reason why I see 2.3V output signal on TDO - because the IC is designed to do that ! In DC characteristics of the datasheet the Voh is specified as typical 2.4V. That's a bit weird , because it implies the IC can't be used in 5V systems without a transceiver or voltage level shifter. am I missing something else?

Another interesting information in the datasheet was that the IC can also be programmed by the legacy programming algorithm. In such case the JTAG pins do not have to be reserved for programming and the pins can be used as the logic IOs.

peterzieba commented 5 months ago

In brief, I do not know why you are seeing 2.3V on TDO, but I would suspect something is loading down the signal somewhere or not all four Vcc pins are at 5V -- in any case, I do not believe this is normal/expected. The datasheet actually lists the minimum (and not typical as you mention) VOH as 2.4V

Here's what I see in the datasheet:

I think the VOH is being given under some worst case scenarios. Very specifically, in the datasheet, it specs VOH while VccIO=min and a 4mA load. The minimum VccIO is then stated to be 3.0V. Under those conditions, it should still hit 2.4V.

The interesting thing is that the 44-pin devices only show 4 VCC pins -- it is only in the larger device packages where you will see a distinction between VccIO vs VccINT pins.

This implies that the 44-pin devices cannot be run at 3.3V IO -- you have no choice but to run all four pins at 5V, however, as an undocumented aside I am almost completely certain it is possible. The pins on opposite sides from eachother measure short with an omhmeter. Adjacent side do not measure short. This implies two are VccIO in reality, and two are VccCore.

Further, this document has some peculiar details in it: http://matthieu.benoit.free.fr/all03/adp/HiLo_ADP-ATF1504.PDF

Namely it very clearly calls out VccIO vs VccINT.

It also calls the OE1 pin "OGI", which is yet another interesting detail.

Another interesting information in the datasheet was that the IC can also be programmed by the legacy programming algorithm. In such case the JTAG pins do not have to be reserved for programming and the pins can be used as the logic IOs.

The JTAG pins can always be reused for another purpose. That is what settings PROPERTY ATMEL { jtag=off }; would accomplish. You just can't reprogram it easily once you've done this, which is the very reason why your project is important -- you've solved having a convenient Vpp capable programmer.

While we don't have a formal document outlining the "legacy" programming algorithm, it is almost certainly just JTAG all the same but with the secret of knowing to apply Vpp voltage to OE1 to return those pins temporarily to their JTAG function. That's all it is.

Notice the peculiar mention in the datasheet on page 10 in the Pin Capacitance section: "The OGI pin (high-voltage pin during programming) has a maximum capacitance of 12pF."

The only other place you'll see OGI is in that programming adapter schematic. That's the clue right there of what OGI is.

ole00 commented 5 months ago

Good ideas, however this is what I found in my ATF1502AS(L) datasheet: image

This datasheet lists the 2.4V as the typical value.

ole00 commented 5 months ago

Anyway, I cobbled a voltage level shifter on the TDO line and now I get 100% success rate while using the Arduino's JTAG (tested erase and program/verify) with appropriate VPP. My observations are that the OE1 must be 5V while programming and 11V while erasing or else I get JTAG communication errors. So that all matches/confirms your information.

Here is the level shifting contraption (not pretty, will be fixed on a new ATF150X adapter revision): image

peterzieba commented 5 months ago

Ah, I see what's happening here. I looked at the datasheet for the ATF1504ASL, whereas you looked at the datasheet for the ATF1502ASL. Looks like there is a discrepancy there.

You mentioned the ATF1504ASL chip in the comment yesterday so that's where I started: "I just tried the Arduino JTAG with ATF1504ASL and it works in general. The issue is my ATF1504ASL JTAG TDO line high level is ~ 2.3V and it is not enough for a reliable reception of data on AVR Arduino where the high signal level should be at least 3V ."

So, in looking at that datasheet ATF1504AS(L) from here: https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-0950-CPLD-ATF1504AS(L)-Datasheet.pdf

That one shows "minimum". In theory this should be the same device but with more macrocells as the ATF1502... The ATF1502 does not come in a package larger than 44-pins, and so they don't even mention VccIO and VccINT on those devices.

You are powering this from 5V and this is the output you are seeing? If that's true and expected behavior then this would mean these things aren't capable of driving the VIH of a typical CMOS input. That can't be right...

Screenshot from 2024-03-25 18-12-49

peterzieba commented 5 months ago

Perhaps the concerning part is where it mentions "Output High Voltage (TTL)".

When contrasted against the above VOL where it clearly suggests VOL can drive both TTL and CMOS, this all suggests maybe it cannot actually drive CMOS.

While I would not expect a CMOS input to draw 4mA, that doesn't necessarily mean it could reach the proper voltage even under less current loading.

ole00 commented 5 months ago

You are powering this from 5V and this is the output you are seeing?

Correct - the 5V rail is straight from Arduino's 5V pin. So technically the voltage is not 5V, but in my case 4.7V because of the USB cable voltage losses and the Arduino's power diode voltage drop.

If that's true and expected behavior then this would mean these things aren't capable of driving the VIH of a typical CMOS input.

Yes it is weird. I'll have to try some real logic design on the IC and check the output voltage on normal IO pins. (not JTAG pins).

peterzieba commented 5 months ago

I had a buddy look at this and he suggested that this could be an NMOS structure these things use. There is a plot that shows the source current vs. output voltage in that datasheet. In theory, with ideal 5V Vcc and a typical CMOS load it should be able to drive an input properly, but reality is always in the details...

In theory the JTAG pins should be identical to any other I/O pin. I would expect the input only pins (GCLK1, GCLR, OE1, OE2/GCLK) to be slightly different, and then of those, the OE1 pin to be dramatically different in terms of how it behaves.

If you are seeing TDO being unable to drive the output high enough, my theory would be that any other output pin would suffer the same problem.

I'm just reading that the Arduino UNO doesn't have pulldowns, so that shouldn't be the problem. If this is on the threshold of working, I wonder if enabling the pullup on the Arduino's input would be enough to get this to work reliably?

ole00 commented 5 months ago

If this is on the threshold of working, I wonder if enabling the pullup on the Arduino's input would be enough to get this to work reliably?

Good idea, but the internal pullup was already set-up by XSVF library. I double checked that (printed out the pin mode value: is mode 2, and by multimeter measuring voltage on TDO pin when IC is not in the socket - voltage is high 4.8V). I also put few external pull-up on the TDO: 3k3, 1k5 and 1k. The 3k3 did not work well, it was not strong enough to pull the signal above 3V level. The 1k worked OK, but the Low level voltage was already at 0.68V. The 1K5 kind of worked as well, but the High level voltage was just above the 3V threshold. The best looked the level shifter. Possibly a simple solution by using 1k2 pull-up resistor would work OK, but it can't be guaranteed across all ATF150X of devices and batches and Arduino VCC voltages. Here is the picture of the TDO signal:

image

BTW. The High level voltage with internal pull-up was 2.44V so technically in the spec (although the pull-up might have helped it a tiny bit).

peterzieba commented 5 months ago

Well, after seeing all of this I can't help but think that embracing modern 3.3V parts that are 5V tolerant and using level-shifters where necessary instead of trying to use these parts (and all of the workflow-related quirks) would be easier. This sort of suggests I could get a modern 3.3V part to reach a higher VOH voltage (though still technically short of the 3.5V VIH? of usual CMOS inputs)

If it weren't for the non-free nature of the dev tools, the ispMACH4000ZE in TQFP are starting to sound compelling... Page 22 of the datasheet indicates that somewhere around 2.9V VOH should be achievable at 4mA: https://www.mouser.com/datasheet/2/225/lattice_latt_s_a0001381125_1-1736256.pdf

ole00 commented 5 months ago

I've tested an actual (yet very simple) combinatorial logic programmed into the ATF1502ASL device (2 input pins inverted to 2 output pins) and the logic levels on the outputs are fortunately 5V. So no need to despair - this IC seems to be useful for 5V designs :-) The 2.4V output might be only on the JTAG pin.

peterzieba commented 5 months ago

Was this under open-load conditions or into an input on the Arduino? I believe the open-load voltages can be very near 5V if based on that plot alone, however, I'm concerned from a practical perspective that this is not capable of driving the typical CMOS input.

I don't see why the TDO output should be special. I would expect that if any other pin were to drive the same input on the Arduino, the same 2.4V would be measured. Is there anything special about the pin that's being driven on the Arduino side?

ole00 commented 5 months ago

I've integrated the XSVF player to afterburner and pushed it to a WIP branch: ole-20240330-atf150x-wip

Now it is possible to do the following basic operations:

The identification and erase operations require specific .xsvf files, which are currently stored in 'xsvf' subdirectory (they are committed in git repo). If you have an idea how to read fuses from existing device, please let me know and I'll try to support it as well.

I've also pushed a PCB adapter for ATF150X PCLCC44 (untested ATM) to the same git branch. Iit will allow to program the chip when plugged to Afterburner and also to verify the design without removing the IC from the PLCC socket (the IC pins are broken-out to 100mil headers). So far I've opted for a simple (switchable) TDO pull up on the adapter. The reason is I've tested another 2 devices: one ATF1504ASL (different than I tested before) which reads 3.3V on the TDO pin and ATF1502ASL which reads 3.1V on the TDO pin. Arduino works OK with those without any external pull-up or level shifter. I think I was lucky/unlucky when the TDO pin was 2.44V on my first ATF150X IC I tried., but at least I know the quirk and the adapter should be able to handle that.

ole00 commented 5 months ago

Reading fuses - I can see it is described in this document: https://github.com/whitequark/prjbureau/blob/main/docs/jtag/as.rst The XSVF player implemented in afterburner has a way to dump the DR register via XCOMMENT instruction. The instruction normally prints the text specified as the argument of the instruction. I extended the functionality of the instruction, so when a pair of characters '#X' is detected then in prints the contents of the DR buffer. the X stands for number of bytes to print. For example: XCOMMENT "ID: #4" prints the 4 bytes of the internal DR buffer in HEX. That's the way how Afterburner's 'i' command (identify) is currently implemented for ATF150X: It sends an .xsvf file to the XSVF player which clocks the IDCODE IR register into the IC, then reads the 32 bits into the DR and then it uses XCOMMENT to print the buffer. To read more than 9 bytes an ASCII character following the letter 9 has to be entered. To dump 10 bytes a ':' character is used for X, to dump 16 bytes a '@' is used etc. The maximum dump is 76 bytes (624 bits) per single dump, if that would not be enough it can be extended.

fredcwbr commented 5 months ago

I didn't understand the logic to the characters that follows; Are they binary masked ?

ole00 commented 5 months ago

Are they binary masked ?

No, it's even simpler. If the comment string contains a hash key then the next character is read and that character determines the number of bytes. The number of bytes is the ASCII value of the character minus 48 (which is ASCII character '0'). For example the '@' character is ASCII value 64, when value 48 is detracted then the result is 16. In this case the '@' character means to print 16 bytes of DR JTAG register. Perhaps that's not very convenient to use when more than 9 bytes need to be printed, but it can be improved if needed.

fredcwbr commented 5 months ago

I got it... thanks for the reply.

ole00 commented 5 months ago

I've added some more information about the ATF150X Afterburner support in this discussion thread: #64