--- In 68HC12@y..., Dave Perreault <briggsroad@c...> wrote: > Bruce > > The sector modify command erases two words and writes the first > word. Since the programming registers are buffered, you can give > the the programming command for a write of the second word > without waiting for the sector modify command to complete. They > refer to this as pipelining. You must then wait on the status flag CCIF which indicates the NO commands are pending.. > Thanks Dave I post what I have at the bottom of email.. This code hasn't been tested but illustrates a problem in porting code from some earlier versions (the 'D60) in my case. The code being ported makes pretty extensive use of aligned word manipulations of the EEPROM. With the 'S12 supporting only 4 byte-aligned sector erase (ie 2 lsb in address are don't care), word manipulations of the EEPROM are a little tricky. I now have three routines doing the work of a single routine in the old 'D60 code. (i) writes an arbitrary number of long-word aligned sectors, (ii) writes the first word of a longword aligned sector, and (iii) writes the second word of a longword aligned sector. (ii) & (iii) preserve the other word of the sector. [I hope and trust there was a good engineering reason for not implementing word-length sectors on the 'S12 eeprom.] ****************************************************************************** * WRITE_EEPROM - GENERAL_INIT PURPOSE SUBROUTINE * * - X: source data (RAM/ROM) * * - Y: destination (EEPROM) * * - B: no of _LONGWORDS_ to write * * - interrupts should be disabled * * - A: preserved * * - WRITES MUST BE LONG WORD ALIGNED!! * * - this routine should be less than COP timeout: probably 1 sec * ****************************************************************************** WRITE_EEPROM PSHA JSR COP_SERVICE brclr ECLKDIV,#EDIVLD,EEPROM_exit ;abort if clock divider not set _EEPROM_PROG_LOOP movw 2,x+,2,y+ ; store data to ALIGNED! EEPROM address movb #SEC_MOD,ECMD ; sector modify command (erase 4B, write 2B) movb #CBEIF,ESTAT ; start the command by writing a 1 to CBEIF. ldaa ESTAT ; check to see if there was a problem executing ; the command. bita #PVIOL+ ACCERR ; if either the PVIOL or ACCERR bit is set, bne EEPROM_exit ; return. movw 2,x+,2,y+ ; store data to ALIGNED! EEPROM address movb #PROG,ECMD ; sector modify command (erase 4B, write 2B) movb #CBEIF,ESTAT ; start the command by writing a 1 to CBEIF. ldaa ESTAT ; check to see if there was a problem executing ; the command. bita #PVIOL+ ACCERR ; if either the PVIOL or ACCERR bit is set, bne EEPROM_exit ; return. brclr ESTAT,#CBEIF,* ; wait here till the command buffer is empty. dbne b,_EEPROM_PROG_LOOP ; any more words to program? brclr ESTAT,#CCIF,* EEPROM_exit JSR COP_SERVICE PULA RTS ****************************************************************************** ****************************************************************************** * WRITE_EEPROM_WORD - write first word of long word block * * - preserves second word * * - X: source data (RAM/ROM) * * - Y: destination (EEPROM) * * - interrupts should be disabled * * - A: preserved * * - WRITES MUST BE LONG WORD ALIGNED!! * * - this routine should be less than COP timeout: probably 1 sec * ****************************************************************************** WRITE_EEPROM_WORD PSHA JSR COP_SERVICE brclr ECLKDIV,#EDIVLD,EEPROM_W_exit ;abort if clock divider not set movw 2,y,2,-sp ; save 2nd word in EEPROM sector movw 2,x+,2,y+ ; store data to ALIGNED! EEPROM address movb #SEC_MOD,ECMD ; sector modify command (erase 4B, write 2B) movb #CBEIF,ESTAT ; start the command by writing a 1 to CBEIF. ldaa ESTAT ; check to see if there was a problem executing ; the command. bita #PVIOL+ ACCERR ; if either the PVIOL or ACCERR bit is set, bne EEPROM_W_exit ; return. movw 2,sp+,2,y+ ; restore previous value in 2nd word of sector movb #PROG,ECMD ; sector modify command (erase 4B, write 2B) movb #CBEIF,ESTAT ; start the command by writing a 1 to CBEIF. ldaa ESTAT ; check to see if there was a problem executing ; the command. bita #PVIOL+ ACCERR ; if either the PVIOL or ACCERR bit is set, bne EEPROM_W_exit ; return. brclr ESTAT,#CBEIF,* ; wait here till the command buffer is empty. brclr ESTAT,#CCIF,* EEPROM_W_exit JSR COP_SERVICE PULA RTS ****************************************************************************** ****************************************************************************** * WRITE_EEPROM_WORD_2ND - write second word of long word block * * - preserves first word * * - X: source data (RAM/ROM) * * - Y: destination (EEPROM) * * - interrupts should be disabled * * - A: preserved * * - WRITES MUST BE LONG WORD ALIGNED!! * * - this routine should be less than COP timeout: probably 1 sec * ****************************************************************************** WRITE_EEPROM_WORD_2ND PSHA JSR COP_SERVICE brclr ECLKDIV,#EDIVLD,EEPROM_W2ND_exit ;abort if clock divider not set movw -2,y,-2,y ; store original data in first word; zzz!!! allowed? movb #SEC_MOD,ECMD ; sector modify command (erase 4B, write 2B) movb #CBEIF,ESTAT ; start the command by writing a 1 to CBEIF. ldaa ESTAT ; check to see if there was a problem executing ; the command. bita #PVIOL+ ACCERR ; if either the PVIOL or ACCERR bit is set, bne EEPROM_W_exit ; return. movw 0,x,0,y ; write new word to 2nd word in eeprom sector movb #PROG,ECMD ; sector modify command (erase 4B, write 2B) movb #CBEIF,ESTAT ; start the command by writing a 1 to CBEIF. ldaa ESTAT ; check to see if there was a problem executing ; the command. bita #PVIOL+ ACCERR ; if either the PVIOL or ACCERR bit is set, bne EEPROM_W_exit ; return. brclr ESTAT,#CBEIF,* ; wait here till the command buffer is empty. brclr ESTAT,#CCIF,* EEPROM_W2ND_exit JSR COP_SERVICE PULA RTS ****************************************************************************** |