>> - 12c508 is "one shot one kill" and i burned out 2 micros
You mean "burnt out", or just used up? It IS a one-time programmable
device, but I don't usually equate "correctly executing a program that
doesn't work" with "burned out." (Could be a language issue.)
On that topic, does anyone care to describe techniques they use to get more
than one try out of an OTP device? Seems like both all-zeros and all-ones
are reasonable harmless instructions to have happen before you start trying
to do real work so you ought to be able to put your program as high as
possible in program memory (so it occupies the top 100 words or so.) Then
when the PIC resets it starts at 0, executes (memsize-100) NOP or ADDLW 0xFF
instructions, and then starts your program proper. If it doesn't work, you
program your next 100 word program starting at memsize-200 and try again.
(obviously, this doesn't work as well if you start needing interrupt vectors
and so on, but hopefully by the time your program gets that complex you've
got more experience and more flash alternatives. It's the really "trivial"
first time attempts and such that I want to address.)
There may be difficulties with programmers and verifies and such, which is
why I'm asking for actual experiences...
> >> - 12c508 is "one shot one kill" and i burned out 2 micros
>
> You mean "burnt out", or just used up? It IS a one-time programmable
> device, but I don't usually equate "correctly executing a program that
> doesn't work" with "burned out." (Could be a language issue.)
>
> On that topic, does anyone care to describe techniques they use to get more
> than one try out of an OTP device? Seems like both all-zeros and all-ones
> are reasonable harmless instructions to have happen before you start trying
> to do real work so you ought to be able to put your program as high as
> possible in program memory (so it occupies the top 100 words or so.) Then
> when the PIC resets it starts at 0, executes (memsize-100) NOP or ADDLW 0xFF
> instructions, and then starts your program proper. If it doesn't work, you
> program your next 100 word program starting at memsize-200 and try again.
>
> (obviously, this doesn't work as well if you start needing interrupt vectors
> and so on, but hopefully by the time your program gets that complex you've
> got more experience and more flash alternatives. It's the really "trivial"
> first time attempts and such that I want to address.)
>
> There may be difficulties with programmers and verifies and such, which is
> why I'm asking for actual experiences...
I haven't tried this on an actual chip, so take it with a grain of salt,
but I've read an article that discusses "re-using" OTP parts like the
12C508. The "trick" is that an unprogrammed chip is filled with all
1 bits (0xfff for a 12-bit chip), and 0 bits are written where needed
to program the chip.
Also, the NOP instruction is 0x000.
Thus, you initially program your chip starting at the LOWEST address (0).
When you want to update the software, program NOPs (0's) over the
current code, and follow with the updated code.
When the chip starts up, it executes (on the 12C508) the MOVLW calibration
instruction at the top of memory, a bunch of NOPs (which are the old,
erased code), and then the current program.
> When the chip starts up, it executes (on the 12C508) the MOVLW calibration
> instruction at the top of memory, a bunch of NOPs (which are the old,
> erased code), and then the current program.
>> When the chip starts up, it executes (on the 12C508) the MOVLW
>> calibration instruction at the top of memory, a bunch of NOPs (which
>> are the old, erased code), and then the current program.
>
>Whats wrong with
> org 0x0000
> ; set cal data
> org 0x0008
> ; code start version 1
>
>That fails
> org 0x0000
> ; set cal data
> org 0x0007
> ; code start version 2
> goto Code2
Well, the scheme I originally mentioned (let the pic execute "unprogrammed"
locations until it hits real code) was sort-of designed to have the minimal
effect on programming software. As long as you can restrict it's
blankcheck, program and verify steps to the specific range that your
program attempt actually occupies, it shouldn't complain. Of course, if
the programmer SW has grander ideas about blank-check and verify, it will
still complain (isn't it nice that there's so much open source programmer
software, though :-)
I guess I have enough PICs now to do some experiments :-)
I always use an "XORLW 0xFF" at the front of every major subroutine (except
those whose timing issues may preclude that - which are few & far between).
This way, if I run into troubles & have to change code in a particular
routine, I can reburn the existing code, with the appropriate subroutine's
XORLF changed to a GOTO, which points to a point just past the end of my
existing program. At that newly referenced point, I place the NEW, modified
routine.
Basically, what happens is that the chip programmer reburns what's already
there (adding the new subroutine at the end, of course), changing the 0FFF
located at the appropriate XORLF command to a GOTO pointing to the memory
location containing the new code.
This way, I can get the most bang for the buck out of a OTP chip.
I'm sure this isn't the only way, just what I use.
Dennis
What I did a few years ago with 16C73's was:-
At the start location 0x00 place a "jmp start" and at the interrupt vector
0x04 place a "jmp serv_int".
where "start" is placed in memory at location 0x10 or so and "serv_int" is
placed at 0x20 or so (work out the details for your own needs)
Then at "start" I have another "jmp main" with nothing in the following
locations until the "serv_int" label. The "serv_int" label then has a "jmp
Interrupt" & is followed by another run of unprogrammed locations until the
start of my acutal program at, say 0x30.
The amount of unprogrammed space you leave for additional trys will depend
on your program size & available space
The first try then can use the program space from 0x30 to the end of the
program area.
For subsequent reprogramming the location at "start" is changed to nop
(0x00) and the "jmp main" then follows (assuming this is a new location
for "main"). Also, it may be neccessary to insert 2 or 3? nops if page
setting bits are set - eg "ljmp main")).
The same procedure can be used for the interrupt handler.
I like the idea of the xor statement(s) already mentioned for subroutine
calls also.
Note, however, if timing is critical the additional statements will effect
this - especially wrt the interrupt latency & subroutine calls.
Hope the above is reasonably clear - I haven't used it for a while(thanks
mainly to using Atmel & flash parts lately !) so there may be detail
errors but did find it useful in the past. It sounds complicated but works
out easy enough in practice.
(Am now about to update the previous 16C73 project to 16F73 - so won't need
to use this in the future.)
Richard P
....snip
On that topic, does anyone care to describe techniques they use to get more
than one try out of an OTP device?
Good point, Alan! I'd used this trick a lot when I had a customer that
didn't know what he wanted until he saw it (I'm sure you've had those too!).
He'd like what he saw in the preproduction units (5-10 units at a time),
EXCEPT for 1 itty-bitty small change ...........
Most times clobbering the W reg wasn't a problem, even in interrupt
routines. There, I'd wait until I finished up my housekeeping, then issue
the XORLW command - that way I didn't have to repeat housekeeping chores all
over again in the modified routine in higher memory.
Hadn't thought about issuing the command twice, although it's painfully
obvious - can't see the forest for the trees, I guess!
On Tue, 19 Nov 2002, William Chops Westfield wrote:
*>On that topic, does anyone care to describe techniques they use to get more
*>than one try out of an OTP device? Seems like both all-zeros and all-ones
*>are reasonable harmless instructions to have happen before you start trying
*>to do real work so you ought to be able to put your program as high as
*>possible in program memory (so it occupies the top 100 words or so.) Then
*>when the PIC resets it starts at 0, executes (memsize-100) NOP or ADDLW 0xFF
*>instructions, and then starts your program proper. If it doesn't work, you
*>program your next 100 word program starting at memsize-200 and try again.
Yes, but if you do this often buy a 12C509JW.
*>(obviously, this doesn't work as well if you start needing interrupt vectors
*>and so on, but hopefully by the time your program gets that complex you've
*>got more experience and more flash alternatives. It's the really "trivial"
*>first time attempts and such that I want to address.)
There are NO interrupt vectors to care for. There is OSCCAL so the first
instruction is MOVLW OSCCAL but the rest is as you described.
*>There may be difficulties with programmers and verifies and such, which is
*>why I'm asking for actual experiences...
Exactly. Open sourced programmers do not have this problem ;-). Also those
written specifically to cope with this kind of problem. Like the one I
wrote for our use for example.
> *>(obviously, this doesn't work as well if you start needing interrupt
vectors
> *>and so on, but hopefully by the time your program gets that complex
you've
> *>got more experience and more flash alternatives. It's the really
"trivial"
> *>first time attempts and such that I want to address.)
>
> There are NO interrupt vectors to care for. There is OSCCAL so the first
> instruction is MOVLW OSCCAL but the rest is as you described.
There is one gotcha. These chips can only call subroutines in the low 256
bytes of each 512 byte page if I remember right.
This is all rather silly though. Switch to the 12F628, or if it's a high
volume product a few JW parts will be cheap and certainly better than
wasting time farting around reusing OTP parts. I usually get 8 JW parts
when developing with non-flash PICs (not doing that much anymore). That
allows me to keep the eraser busy and ensure there is always a blank one
when I'm ready to try new firmware.
*****************************************************************
Embed Inc, embedded system specialists in Littleton Massachusetts
(978) 742-9014, http://www.embedinc.com
> There are NO interrupt vectors to care for. There is OSCCAL so the
> first instruction is MOVLW OSCCAL but the rest is as you described.
I wasn't talking only about the 8-pin chips, but anything OTP.
This is all rather silly though. Switch to the 12F628, or if it's a
high volume product a few JW parts will be cheap and certainly better
than wasting time farting around reusing OTP parts.
Sometimes hobbyists and professionals don't seem to understand each
other's viewpoints. Here I have all these $<1.00 PICs, and you want
me to spend REAL MONEY on JW parts?
*>> *>(obviously, this doesn't work as well if you start needing interrupt
*>vectors
*>> *>and so on, but hopefully by the time your program gets that complex
*>you've
*>> *>got more experience and more flash alternatives. It's the really
*>"trivial"
*>> *>first time attempts and such that I want to address.)
*>>
*>> There are NO interrupt vectors to care for. There is OSCCAL so the first
*>> instruction is MOVLW OSCCAL but the rest is as you described.
*>
*>There is one gotcha. These chips can only call subroutines in the low 256
*>bytes of each 512 byte page if I remember right.
That is correct. Same thing for 16C54. This poses no serious problems as
the return address works as it should and one places a stub in the low
page to jump into the subroutine body which is placed wherever you wish.
The stub contains just a GOTO and costs 2 clock cycles. Not too bad.
*>This is all rather silly though. Switch to the 12F628, or if it's a high
*>volume product a few JW parts will be cheap and certainly better than
*>wasting time farting around reusing OTP parts. I usually get 8 JW parts
*>when developing with non-flash PICs (not doing that much anymore). That
*>allows me to keep the eraser busy and ensure there is always a blank one
*>when I'm ready to try new firmware.
I actually blew my last 12C509JW's MCLR pin using static (we have very low
humidity here at times). I use 16F84 for prototyping (GPIO=PORTB with a
little 18 pin to 4 pin socket adapter - I use a 4MHz crustal and caps on
the 18pin) then I burn into 12C508A and use the methods shown in this
thread to perfect the program. It is not too hard. The budget of some of
my projects probably won't buy you lunch ;-).