
Almost 3 years ago I developed and published ZEPPP, my Arduino-based, “Zero-External-Parts” PIC Programmer, and wrote about it here on my blog.
From time to time I hear from people using it, and, sometimes I would also get questions about whether specific PIC devices are supported.
Now, ZEPPP is pretty limited in scope, as it was made to target the 16F628A primarily, but when I wrote it I also added support for other mid-range 8-bit PICs that employed similar programming procedures, and were popular back in the day. Just to echo the list, from day one ZEPPP had support for:
- 16F87, 16F88
- 16F627A, 16F628A, 16F648A
- 16F873A, 16F874A, 16F876A, 16F877A
The Question
One of the PIC families that ZEPPP has supported from the start, is the 16F87XA line of microcontrollers. That means the 16F873A, 16F874A, and so on. They are not particularly modern devices, mind you, but in a couple of occasions, I’ve been asked whether ZEPPP could support the “non-A” variants, which predate the “A” versions although were almost functionally the same.
This is not something I get all the time, in fact, I had not heard that request in probably a couple of years, until recently a user on my blog echoed the same question, and he was apparently knowledgeable and interested enough in this, that he was already looking into adding the support himself.
It’s worth noting that the 16F628A also has a “non-A” version, and it’s not compatible with ZEPPP because it does not support LVP, which is what ZEPPP uses to program the chips. So it wouldn’t be crazy to assume that the 87X line of microcontrollers were the same, with the “non-A” parts not supporting LVP…
Except they do. The non-A plain “87X” parts, do, in fact, support LVP. So maybe it was just a matter of treating them like the “A” parts? Maybe?
Collaboration
I didn’t have any “non-A” part to try, but Ken (the user who posted the question), had a bunch of 16F876 devices, and he was more than willing to test, so we started tinkering with it. I branched the code from the repository and added settings for the 87X parts that mirrored the 87XA settings, and then asked Ken to test.
He reported very thoroughly the behavior of ZEPPP, and unfortunately the non-A parts would refuse to be programmed the way the “A” parts did, so I spent the next afternoon comparing the programming specifications of both 87XA and 87X parts trying to find the differences.
After looking at them side by side I noticed that most of the timing and the memory reading commands were the same, but the “non-A” parts did not support block writes, and had completely different erase algorithms. Fortunately there was support in ZEPPP already for non-block writes (because the 16F628A also lacks support for them), so I configured ZEPPP to use that style of programming with the 87X parts and asked Ken to try again. This led to a version of ZEPPP that was able to write and read to 87X parts, but was unable to erase them.
The Hunt for non-A Parts
This was good enough for most uses, but I wanted to have full support for all operations, and that meant having a way of testing the code myself, as new low-level routines were needed in the firmware, and that was not as straightforward.
To do this, I ordered a handful of old 16F877 from eBay, but that was not something that would arrive anytime soon.
In the meantime I found a small shop nearby, that according to their online listing had stock of 16F871 PICs, an old part of which no “A” variant exists. This store was run by a guy who’s been developing custom PIC projects for different clients for a long time, and of course had several very ancient PICs ready to sell.
In a matter of days I got a few 16F871 PICs to play with, and after another night of work I finally managed to implement the erase procedures for all memory areas, and was able to confirm that they worked with my 16F871 PICs. I also asked Ken to test on his 16F876 ICs, and he also reported success.
Polish and Fixes
I was quite happy now with ZEPPP successfully programming the 87X devices, but I also took this opportunity to improve the code a bit. There were a few places where changes were needed; From the internal structure of the code, to error messages and the behavior of some commands. There were also some assumptions inside ZEPPP that I wasn’t quite happy with.
All the changes are now in the ZEPPP Git Repository. The project now also includes a Changelog where you can check what was added/changed in more detail.
I would like to thanks Ken again for his very generous help testing the support for 87X parts, and for starting this whole endeavor that resulted in a handful of improvements to ZEPPP, and the support for a new (old?) family of devices.
Hello,
I trying to realize the SC Analyser 2005 Semiconductor Device Tester Elektor 2005 ( I could send you the hex file if you want).
I tried to program a pic16f876 using the Zeppp and I received the following error message (bellow) :
Do you have some idea to solve this problem ?
Regards
java -jar zeppp-cli.jar -c /dev/ttyUSB0 -wait 2000 -d 16f876 -ignore-bounds-error -i transistor.hex -p
Opening port /dev/ttyUSB0…
Waiting 2000 ms …
Connecting to ZEPPP interface…
— Interface detected: ZEPPP 1.0.2 20220824
Pic device ’16f876′ selected
Detecting connected device…
— Device Name: 16f876
— Device ID: 0x004f
— Device Revision: 0x0005
Reading input Hex file: transistor.hex
WARNING: Memory address 0x4010 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x4012 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x4014 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x4016 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x4018 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x401a is not mapped to any memory space in the selected device (16f876)
…
WARNING: Memory address 0x41fe is not mapped to any memory space in the selected device (16f876)
Erasing CHIP Memory…
Writing User IDs…
Verifying User IDs…
User ID Verification finished successfully.
Writing PGM Memory…
ERROR: Failed to Write PGM Memory block 0x0000. Verification failed!
Hi, having the hex file would definitely help. Now, if it was able to write ids but not PGM memory it might mean that the PIC has some memory areas protected already. Was that a brand new PIC IC?
Hello,
It’s a brand new pic.
if you give an email I could send you the hex file.
regards
Is the HEX file the one published here? https://www.elektormagazine.com/magazine/elektor-200504/17935? (Materials->Software->030451-11.zip)
Hello,
Yes it is.
You can download it on : https://www.elektroda.pl/rtvforum/topic876142.html#4684988
Hi, I couldn’t find an 876 to try it, but I checked the HEX file. It actually goes beyond 0x4000 (which doesn’t map to anything on this device) and that’s why it gives you the warnings. For some reason the HEX file contains empty data for a lot of blocks after that address but it’s just empty. Regarding your programming issues, unless I’m mistaken the code has some code protection bits ON, so it could have protected some bits of the memory against read-back (and so the verification fails). Can you try with
-ce -wa
instead of-p
?Hello,
To see if the zeppp has a bug, I tried another different file hex (3.8ko) for 16f876. the zeppp write it.
I tried your idea but it failed (the result bellow). There is a code protection on in the config flag (address 2007).
And if I tried to delete the data beyond 0x4000 ?
Regards
java -jar zeppp-cli.jar -c /dev/ttyUSB0 -wait 2000 -d 16f876 -ignore-bounds-error -i transistor.hex -ce -wa
Opening port /dev/ttyUSB0…
Waiting 2000 ms …
Connecting to ZEPPP interface…
— Interface detected: ZEPPP 1.0.2 20220824
Pic device ’16f876′ selected
Detecting connected device…
— Device Name: 16f876
— Device ID: 0x004f
— Device Revision: 0x0005
Reading input Hex file: transistor.hex
WARNING: Memory address 0x4010 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x4012 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x4014 is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x4016 is not mapped to any memory space in the selected device (16f876)
…
WARNING: Memory address 0x41fa is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x41fc is not mapped to any memory space in the selected device (16f876)
WARNING: Memory address 0x41fe is not mapped to any memory space in the selected device (16f876)
Erasing CHIP Memory…
That took 125 ms
Writing User IDs…
Writing PGM Memory…
ERROR: Failed to Write PGM Memory block 0x0000. Verification failed!
Testing with a different file was a good call, and I’m glad to hear it seems that your build of ZEPPP seems to be working. That narrows down the issues to the HEX file. Deleting the data past 0x4000 will probably just eliminate the warnings, but you can try that. Maybe the code protection bits in the config is what is throwing it off so you can try loading the HEX file in MPLAB and changing the config bits too. Loading it in the software and selecting the right target PIC might also get rid of the additional empty blocks in the HEX file
Hello,
In the file I found the line
:104000000F000F000F000F00FFFFFFFFFFFFF30B7C
where the code is protected (PIC16F877, 876) 00 = 0000h to 1FFFh
so i do 2 modifications:
I replace the line
:104000000F000F000F000F00FFFFFFFFFFFFF30B7C
by
:084000000F000F000F000F007C
:02400E00F33B82
:00000001FF
and I erase the lines
:10401000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
:10402000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
:10403000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
:10404000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
:10405000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
:10406000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
…
:1042D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEE
:1042E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDE
:1042F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCE
I try the new file with:
java -jar zeppp-cli.jar -c /dev/ttyUSB0 -wait 2000 -d 16f876 -i sca2005-v10emod.hex -p
Opening port /dev/ttyUSB0…
Waiting 2000 ms …
Connecting to ZEPPP interface…
— Interface detected: ZEPPP 1.0.2 20220824
Pic device ’16f876′ selected
Detecting connected device…
— Device Name: 16f876
— Device ID: 0x004f
— Device Revision: 0x0005
Reading input Hex file: sca2005-v10emod.hex
Erasing CHIP Memory…
Writing User IDs…
Verifying User IDs…
User ID Verification finished successfully.
Writing PGM Memory…
ERROR: Failed to Write PGM Memory block 0x0000. Verification failed!
but it failed again
if you have some idea
regards
Hello,
I read from the pic the config words :=> 03FFFh => the memory program is not protected in writing.
So I tried to program the first line of the file (sca2005) :
:1000000000003528FFFFFFFFFB00030E83120313E0
:00000001FF
=>
User ID Verification finished successfully.
Writing PGM Memory…
ERROR: Failed to Write PGM Memory block 0x0000. Verification failed!
I do the operation with the 1st line of another program for 16f876 :
:100000005129FF3FFF3FFF3F803003138312270634
:00000001FF
=>
java -jar zeppp-cli.jar -c /dev/ttyUSB0 -wait 2000 -d 16f876 -i chargeur.hex -p
Opening port /dev/ttyUSB0…
Waiting 2000 ms …
Connecting to ZEPPP interface…
— Interface detected: ZEPPP 1.0.2 20220824
Pic device ’16f876′ selected
Detecting connected device…
— Device Name: 16f876
— Device ID: 0x004f
— Device Revision: 0x0005
Reading input Hex file: chargeur.hex
Erasing CHIP Memory…
Writing User IDs…
Verifying User IDs…
User ID Verification finished successfully.
Writing PGM Memory…
Verifying PGM Memory…
PGM Memory Verification finished successfully.
Writing Data Memory…
Verifying Data Memory…
EEPROM Verification finished successfully.
Writing Config Words…
Verifying Config Words…
Config Word Verification finished successfully.
That took 3170 ms
regards
03FFFh is the equivalent to “empty” memory, but it’s also (as far as I remember) exactly what a read-protected area returns.Now, I tried the HEX file with the closest I have to a 16f876, a PIC 16F877A and it also gave me a verification error. I’m using the SCA2005-V10E.HEX I downloaded from the page where I found the article (couldn’t download it from the forum because it required an account, but the HEX I downloaded should be the same). I took the HEX file and loaded it into another PIC programmer I have (the XGPro software, from my TL866II programmer), which normally “fixes” issues with HEX files (like blocks out of bounds) and exported the fixed version. I also removed the CP bits and created this HEX file, that loads fine. Can you test it?
Hello,
There is a problem. When I tried to download your modified file from (bitofmystery.com/web/download/SCA2005-V10E_mod.HEX), I received an empty file !
regards
Thanks for letting me know. I changed the link to a GitHub Gist instead of a download here. It’s hosted on Github now and you should be able to get it. Let me know if that works for you.
Hello,
It works.
A huge thank you.
Your Zeppp is tremendous device
Regards
java -jar zeppp-cli.jar -c /dev/ttyUSB0 -wait 2000 -d 16f876 -i SCA2005-V10E_mod.HEX -p
Opening port /dev/ttyUSB0…
Waiting 2000 ms …
Connecting to ZEPPP interface…
— Interface detected: ZEPPP 1.0.2 20220824
Pic device ’16f876′ selected
Detecting connected device…
— Device Name: 16f876
— Device ID: 0x004f
— Device Revision: 0x0005
Reading input Hex file: SCA2005-V10E_mod.HEX
Erasing CHIP Memory…
Writing User IDs…
Verifying User IDs…
User ID Verification finished successfully.
Writing PGM Memory…
Verifying PGM Memory…
PGM Memory Verification finished successfully.
Writing Data Memory…
Verifying Data Memory…
EEPROM Verification finished successfully.
Writing Config Words…
Verifying Config Words…
INFO: Failed to Verify data at offset 0x0000!. Expected 0x3bf3. Got 0x3ff3 instead
INFO: Verification can fail if CP was enabled, or the Conf. Word tried to disable LVP.
That took 68775 ms
Awesome! Glad to hear that it worked! Thanks for reporting back.
I wanted to test a pic16f877 that was laying around here.
I dont have a compiler on hand and used this hex.
https://github.com/Hack-a-Day/PIC-Blink/tree/master/16f887
Zepp wasn’t able to upload all of it.
Connecting to ZEPPP interface…
— Interface detected: ZEPPP 1.0.2 20220824
Detecting connected device…
— Device Name: 16f887
— Device ID: 0x0104
— Device Revision: 0x0005
Reading input Hex file: C:\Users\roman\Downloads\blink.hex
ERROR: Memory address 0x4010 is not mapped to any memory space in the selected device (16f887)
Hi,
That’s definitely outside the programming memory space of that device (goes up to 0x1FFF). Some compilers tend to generate extra data that goes outside the memory mapping, and that could be the problem in this case. Try adding the -ignore-bounds-error flag.
Hi,
I half forgot about my comment. I’ve tested it and it works. Thanks.
Maybe i will build an serial LED matrix out of it
Glad to hear that it worked. A Serial LED matrix is a great project!
How about using a voltage tripler circuit (charge pump) based on capacitors and diodes to implement HVP as suggested here: https://diyodemag.com/projects/arduino_pic_programmer
Adding support for High-Voltage Programming can definitely be done by means of a charge pump (like in the example) or by adding an external 12V supply. I’ve been thinking about toying with adding a HVP attachment, but It would stop being “zero external parts” at that point, and Arduino-based programmers who require some circuitry to be build already exist (for example the project you just linked me). It would be an interesting experiment, and I may add it like a sort of “optional” upgrade, but I wouldn’t want to make it a core part of ZEPPP.
SEPP = Some External Parts PIC Programmer
It’s probably going to be a small circuit, so I don’t see it as terribly offensive to the concept. I will try to play around with the idea, but as mentioned, there’s already other programmers that require circuitry and do HVP, and they probably already support a whole lot more devices than ZEPPP does. Not sure if it will be of benefit, at all.
Do you think it could also work with a PIC12F629?
Hi Albert,
Unfortunately that family of devices doesn’t seem to support LVP, so they wouldn’t be compatible.