This is a multi-part message in MIME format. ------=_NextPart_000_004B_01C27A6C.4A63B420 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit > > VPP before VCC > > 12F675, 16F62xA, 16F630/676, 16C7xx > > Funny, or actually not funny, for me. > > Now for the other question: has enyone actually seen a (flash) PIC that > could not be programmed by applying Vcc first and then rising Vpp? The > 12F675s and 12F629s that I can *can* be programmed this way. This is now my third attempt to respond to this thread. The first time I attached too much source code and it got bounced back by the list server because of the 1000 line limit. The second time must have been under that limit, but I haven't seen that message come back over 12 hours later. I have received other message back that I have sent since then, so I have no idea what happened. Anyway, I have found that some of the 16F87x family (I think I was testing with a 16F876 at the time) reacts in a flaky way when Vpp is applied before Vdd. Sometimes it does not respond at all. This is determined by it not driving the data line when expected. Other times it drives the data line but the ID word is all 0. The attached file is the host souce code for the module that determines what type of PIC is in the socket. It first tries the Vpp before Vdd method. If that is inconclusive it tries Vdd before Vpp. No matter how it gets the ID, the Vpp/Vdd reset method is later set for that specific ID in a different module. I think you are asking whether you can get away with always using Vdd before Vpp. This sounds like a very bad idea to me. As an example, look at the 16F62x programming specification (DS30034D). See Figure 2-2 on page 5. Microchip is being very clear about Vpp required before Vdd to the extent of specifying that Vpp must be high 5uS before Vdd is raised, then another 5uS is required before you are allowed to do the serial communication. I am not sure I ever saw a failure using Vdd before Vpp with a chip that wanted it the other way around. There might have been something with a 16F628, but don't remember for sure. Once my auto-ID code was working this issue didn't come up anymore. ------=_NextPart_000_004B_01C27A6C.4A63B420 Content-Type: application/octet-stream; name="picprg_id.pas" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="picprg_id.pas" { Subroutine PICPRG_ID (PR, ID, STAT) * * Determine the hard coded ID of the target chip. Each different PIC * has a different ID. ID is returned the raw ID value as specified * by Microchip. Different PICs have different sized ID words. The * ID word is returned in the least significant bits of ID with unused * upper bits set to 0. * * An ID value of 0 indicates that the chip ID could not be determined * or that no chip was plugged into the target socket. * * The target chip may be in any state when this routine is called. * The algorithm selections are irrelevant when this routine is called. * * The target chip will be off (no power, no programming voltage) when * this routine returns. The Vdd voltage selections will be set to * default values. The RESET algorithm will be selected appropriately * for the target chip when a valid ID is returned. } module picprg_id; define picprg_id; %include '/cognivision_links/dsee_libs/pics/picprg2.ins.pas'; procedure picprg_id ( {get the hard coded ID of the = target chip} in out pr: picprg_t; {library use state, returned = invalid} out id: picprg_chipid_t; {returned chip ID in low bits, 0 = =3D none} out stat: sys_err_t); {completion status} val_param; var i: sys_int_machine_t; {scratch integer and loop = counter} i32: sys_int_conv32_t; {scratch 32 bit integer} resp: boolean; {a response was received from the = target chip} label leave; { *************************************************************************= * * * Local subroutine CHECK_16 (RESP, STAT) * * Check for target chip responds to normal PIC16 programming commands. * RESP will set returned TRUE if it does and FALSE if it does not. * The target chip will be reset according to the current reset = algorithm * before an attempt is made to communicate with it. The target chip * will be left partway thru a programming command and should be reset * before further attempts are made to communicate with it. } procedure check_16 ( {check for response to normal = PIC16 prog} out resp: boolean; {TRUE iff received a response = from the chip} out stat: sys_err_t); {completion status} val_param; begin picprg_reset (pr, stat); {reset the target chip} if sys_error(stat) then return; picprg_cmdw_send (pr, 6, 2#000100, stat); {READ DATA FROM PROGRAM = MEMORY} if sys_error(stat) then return; picprg_cmdw_clkh (pr, stat); {do clock pulse for dummy start = bit} if sys_error(stat) then return; picprg_cmdw_clkl (pr, stat); if sys_error(stat) then return; picprg_cmdw_clkh (pr, stat); {raise clock for first real data = bit} if sys_error(stat) then return; picprg_cmdw_tdrive (pr, resp, stat); {check for target driving data = line} if sys_error(stat) then return; end; { *************************************************************************= * * * Local subroutine CHECK_18 (RESP, STAT) * * Check for target chip responds to normal PIC18 programming commands. * RESP will set returned TRUE if it does and FALSE if it does not. * The target chip will be reset according to the current reset = algorithm * before an attempt is made to communicate with it. The target chip * will be left partway thru a programming command and should be reset * before further attempts are made to communicate with it. } procedure check_18 ( {check for response to normal = PIC18 prog} out resp: boolean; {TRUE iff received a response = from the chip} out stat: sys_err_t); {completion status} val_param; begin picprg_reset (pr, stat); {reset the target chip} if sys_error(stat) then return; picprg_cmdw_send (pr, 4, 2#0010, stat); {SHIFT OUT TABLAT REGISTER} if sys_error(stat) then return; picprg_cmdw_send (pr, 8, 0, stat); {do 8 dummy write data clock = cycles} if sys_error(stat) then return; picprg_cmdw_tdrive (pr, resp, stat); {check for target driving data = line} if sys_error(stat) then return; if resp then begin {got response where not expected = ?} resp :=3D false; {indicate no response} return; end; picprg_cmdw_clkh (pr, stat); {raise clock for first read data = bit} if sys_error(stat) then return; picprg_cmdw_tdrive (pr, resp, stat); {check for target driving data = line} if sys_error(stat) then return; end; { *************************************************************************= * * * Local subroutine GETID_16 (ID, STAT) * * Get the chip ID using the normal PIC16 command set and assuming the * current reset algorithm selection is appropriate. * * These chips have the ID mapped to program memory address 2000h. } procedure getid_16 ( {try get ID using PIC16 prog = commands} out id: picprg_chipid_t; {returned chip ID in low bits, 0 = =3D none} out stat: sys_err_t); {completion status} val_param; begin picprg_reset (pr, stat); {reset the target chip} if sys_error(stat) then return; picprg_cmdw_send (pr, 6, 2#000000, stat); {LOAD CONFIGURATION, set adr = to 2000h} if sys_error(stat) then return; picprg_cmdw_send (pr, 16, 0, stat); {dummy data for LOAD = CONFIGURATION} if sys_error(stat) then return; for i :=3D 1 to 6 do begin {once for each address = increment} picprg_cmdw_send (pr, 6, 2#000110, stat); {INCREMENT ADDRESS} if sys_error(stat) then return; end; picprg_cmdw_send (pr, 6, 2#000100, stat); {READ DATA FROM PROGRAM = MEMORY} if sys_error(stat) then return; picprg_cmdw_recv (pr, 16, i32, stat); {read ID word at 2006h} if sys_error(stat) then return; id :=3D rshft(i32, 1) & 16#3FFF; {mask in the valid ID bits} end; { *************************************************************************= * * * Local subroutine GETID_18 (ID, STAT) * * Get the chip ID using the normal PIC18 command set and assuming the * current reset algorithm selection is appropriate. * * These chips have the ID mapped to program memory address 3FFFFEh. } procedure getid_18 ( {try get ID using PIC18 prog = commands} out id: picprg_chipid_t; {returned chip ID in low bits, 0 = =3D none} out stat: sys_err_t); {completion status} val_param; var i1, i2: sys_int_machine_t; {scratch integer} begin picprg_reset (pr, stat); {reset the target chip} if sys_error(stat) then return; picprg_18_setadr (pr, 16#3FFFFE, stat); {set next address to read = from} if sys_error(stat) then return; picprg_18_read (pr, 2#1001, 0, i1, stat); {read first byte and = increment adr} if sys_error(stat) then return; picprg_18_read (pr, 2#1001, 0, i2, stat); {read second byte and = increment adr} if sys_error(stat) then return; id :=3D i1 ! lshft(i2, 8); end; { *************************************************************************= * * * Start of main routine. } begin id :=3D 0; {init to valid ID not found} picprg_cmdw_vddvals (pr, 4.5, 5.0, 5.5, stat); {reset to use default = Vdd values} if sys_error(stat) then return; { * See if the chip responds to power up with Vpp before Vdd. Only some * PIC16 do this, like the 16F628. Most don't care or want it the = other * way around. We test for response by trying a PIC16 read data from * program memory command. This command should cause the target chip * to drive the data line, which we test for. } picprg_cmdw_idreset (pr, picprg_reset_62x_k, stat); {set Vpp before = Vdd reset} if sys_error(stat) then return; check_16 (resp, stat); {check for response to PIC16 prog = commands} if sys_error(stat) then return; if resp then begin {a response was received from the = chip ?} getid_16 (id, stat); {try to read the chip ID} if sys_error(stat) then return; if id <> 0 then goto leave; {got it ?} end; { * This chip did not respond. This leaves one of 3 possibilities: * * 1 - No chip is plugged in. * * 2 - The chip requires Vdd before Vpp powerup. * * 3 - The chip does not use the 16xxx programming command set. * * Case 1 will eventually be assumed if all attempts to communicate = with * the chip fail. We will now distinguish between cases 2 and 3 by = trying * the Vdd before Vpp powerup method. } picprg_cmdw_idreset (pr, picprg_reset_18f_k, stat); {set Vdd before = Vpp reset} if sys_error(stat) then return; check_16 (resp, stat); {check for response to PIC16 prog = commands} if sys_error(stat) then return; if resp then begin {a response was received from the = chip ?} getid_16 (id, stat); {try to read the chip ID} if sys_error(stat) then return; goto leave; {return with the ID} end; { * This target chip has not reponded to the normal PIC16 programming = commands * with both reset methods. Now try PIC18 programming command set. } check_18 (resp, stat); {check for response to PIC18 prog = commands} if sys_error(stat) then return; if resp then begin {the proper response was received = ?} getid_18 (id, stat); {get the chip ID using PIC18 = method} if sys_error(stat) then return; goto leave; {return with the ID} end; { * Common exit point. Make sure the target chip is powered down. } leave: picprg_cmdw_off (pr, stat); {turn off power to the target = chip} if sys_error(stat) then return; end; ------=_NextPart_000_004B_01C27A6C.4A63B420-- ***************************************************************** Embed Inc, embedded system specialists in Littleton Massachusetts (978) 742-9014, http://www.embedinc.com -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu