This is a multi-part message in MIME format. ------=_NextPart_000_0038_01C32931.83DA8B60 Content-Type: text/plain; charset="Windows-1252" Content-Transfer-Encoding: 7bit > Still no joy. We erase then program config then the program. The > program is there when checked on the promate but the config is blank. I just checked my notes and didn't see any bug relating to this. The only notes about the 16F87x was that the bulk erase doesn't actually do an erase unless the protection bits are reset from 0 to 1. To completely erase the chip, I first write 0 to all the config bits, then do a bulk erase. However, this doesn't sound like it's relevant to your problem. I have attached the relevant snippets of code that handles setting the address and writing to a 16F87x in my programmer. This code runs on a 16F628. Maybe you'll spot something you are doing differently. -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics ------=_NextPart_000_0038_01C32931.83DA8B60 Content-Type: application/octet-stream; name="prg_16f.aspic" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="prg_16f.aspic" ; ;*********************************************************************** ; ; Local subroutine SET_ADR ; ; Set the internal target chip address to match the desired address. ; The desired address is in TADR and the current address internal ; to the target chip is TADRI. The PIC16 chips only implement a 14 ; bit address space, so the routines in this module only use the ; low 2 bytes of TADR and TADRI. ; locsub set_adr, regf0 | regf1 ; ; Perform a reset if the current target address is unknown. A reset ; unconditionally sets the target address to 0. ; dbankif gbankadr btfss flag_tadrkn ;the target address is known ? goto sa_reset ;no, reset the target chip to force known = address ; ; Perform a reset if the current address is greater than the desired ; address. This resets the current address to 0, and is the only way ; of decreasing the program counter. ; dbankif gbankadr movf tadri+1, w ;get current address high byte subwf tadr+1, w ;compare to desired address high byte skip_wle ;not definitely past desired address ? goto sa_reset ;definitely past desired address, do the = reset skip_z ;high byte compare inconclusive ? goto sa_dreset ;definitely before desired address, skip = the reset movf tadri+0, w ;get current address low byte subwf tadr+0, w ;compare to desired address low byte skip_wgt ;past desired address, need to do reset ? goto sa_dreset ;no, skip the reset ; ; The current address is greater than the desired address. Reset ; the target chip, which also resets the current address to zero. ; sa_reset gcall op_reset ;reset the target, curr address becomes 0 wait ;wait for the reset to complete dbankif gbankadr sa_dreset dbankis gbankadr ;skip here to avoid doing a reset ; ; The current target chip address is less than or equal to the desired ; address. ; ; Now check for the current address is in the low half of memory and = the ; desired address in the upper half. The program counter can't just = be ; incremented from 1FFFh to 2000h. The LOAD CONFIGURATION command is ; required to switch the program counter to 2000h. ; dbankif gbankadr btfss tadr+1, 5 ;desired address is in high half of adr = space ? goto sa_dhhalf ;no, skip switching to high half btfsc tadri+1, 5 ;current address is in low half of adr = space ? goto sa_dhhalf ;no, skip switching to high half dbankif gbankadr loadk16 tadri, h'2000' ;update our copy of internal chip = address clrf reg0 ;pass LOAD CONFIGURATION opcode gcall sert_send6 ;send the command clrf reg1 ;pass data word to send after the command gcall sert_send14ss ;send REG1,REG0 as data word sa_dhhalf unbank ;skip to here to avoid switching to high = addresses ; ; The current address is less than or equal to the desired address, ; and is in the same half of the address space. ; ; Now increment the current address until it matches the desired = address. ; dbankif gbankadr sa_loopinc ;back here after each address increment movf tadri+0, w ;get current address low byte xorwf tadr+0, w ;compare to desired address low byte skip_z ;low bytes match, need to check high bytes = ? goto sa_doinc ;addresses don't match, do an increment movf tadri+1, w ;get current address high byte xorwf tadr+1, w ;compare to desired address high byte skip_nz ;addresses don't match ? goto sa_doneinc ;current address =3D desired address, all = done ; ; The current and desired addresses don't match. Increment ; the current address. ; sa_doinc movlw b'000110' ;pass INCREMENT ADDRESS opcode movwf reg0 gcall sert_send6 ;send it dbankif gbankadr incf tadri+0 ;increment low byte of current address skip_nz ;no carry into upper byte ? incf tadri+1 ;propagate the carry goto sa_loopinc ;back to compare addresses after the = increment sa_doneinc dbankis gbankadr ;done incrementing current address to match = desired leaverest ; ;*********************************************************************** ; ; Subroutine F16_WRITE ; ; Write the data in REG1,REG0 to the target chip at address TADR. ; ; This version is for generic 16Fxxx targets. It will work for the ; 12F6xx targets if FLAG_OP1 is set. ; glbsub f16_write, regf2 movf reg0, w ;save original REG0 value in REG2 movwf reg2 mcall set_adr ;make sure target chip is at the desired = address dbankif gbankadr movlw b'000010' ;get LOAD DATA FOR PROGRAM MEMORY command btfsc flag_spdata ;really are in program memory space ? movlw b'000011' ;get LOAD DATA FOR DATA MEMORY command movwf reg0 gcall sert_send6 ;send the command movf reg2, w ;restore the original data in REG0 movwf reg0 gcall sert_send14ss ;send the data word dbankif gbankadr movlw b'011000' ;get 16F87x command BEGIN PROGRAM ONLY = CYCLE btfsc flag_op1 ;really is for 16F87x? movlw b'001000' ;get 12F6xx command BEGIN PROGRAMMING movwf reg0 gcall sert_send6 dbankif gbankadr movf tprog, w ;get timer 2 ticks to wait for program = cycle done intr_off ;temp disable interrupts movwf cntwait+0 ;set the wait time clrf cntwait+1 bcf flag_done ;indicate a wait interval is in progress intr_on ;re-enable interrupts writing ;indicate the target chip is being written = to movf reg2, w ;restore the original data in REG0 movwf reg0 leaverest end ------=_NextPart_000_0038_01C32931.83DA8B60--