#define Page_Erase PGM[2]=0x40; temp = ((unsigned char(*)(unsigned int, unsigned char))(PGM)) #define Program_Byte PGM[2]=0x20; temp = ((unsigned char(*)(unsigned int, unsigned char))(PGM)) //Array of opcode instructions of the Erase/Program function in the HCS08 family// A = data, X = Address. volatile unsigned char PGM[35] = { 0xF7, // STA ,X Save the data byte into the address. 0xA6,0x00, // LDA cmd (Filled in before calling)0xC7,0x18,0x26, // STA _FCMD0x45,0x18,0x25, // LDHX @_FSTAT0xF6, // LDA ,X0xAA,0x80, // ORA #$800xF7, // STA ,X0x9D,0x9D,0x9D,0x9D, // NOP, NOP,NOP,NOP0xC6,0x18,0x25, // LDA _FSTAT0xA5,0x30, // BIT #$300x27,0x03, // BEQ *+5 (Label1)0xa6,0xff, // RTS 0x81, // Label1: 0xC6,0x18,0x25, // LDA _FSTAT 0xa5,0x40, // BIT #$40 0x27,0xF9, // BEQ *-5 (Label) 0x81, // RTS }; byte FlashErasePage(word page) { volatile unsigned char temp ; byte im; asm TPA; // get the flags asm STA im // save them asm SEI // clear the im bit if (FSTAT&0x30){ //Check to see if FACCERR or FPVIOL is set FSTAT = FSTAT | 0x30; //write a 1 to clear } temp = Page_Erase(page,0); asm LDA im // get the flags back asm TAP // restore the im bit. return temp; } byte FlashProgramByte(word address, byte data) { volatile unsigned char temp; byte im; asm TPA; asm STA im asm SEI if (FSTAT&0x30){ //Check to see if FACCERR or FPVIOL is set FSTAT = FSTAT | 0x30; //write a 1 to clear } temp = Program_Byte(address, data); asm LDA im asm TAP return temp; }
Message Edited by JimDon on 2008-02-25 01:24 AM
Added p/n to subject.
include "mc9s08qg4.inc"cmd: EQU 0; dummyPGM_SEC: SECTION XDEF PGMPGM: STA ,X ; Save the data byte into the address. LDA #cmd ;(Filled in before calling) LDHX #FSTAT STA FCMD-FSTAT,X ; FCMD LDA ,X ORA #$80 STA ,X NOP NOP NOP NOP LDA ,X ; FSTAT BIT #$30 BEQ Label1 LDA #-1 ; needed? RTSLabel1: LDA ,X ; FSTAT BIT #$40 BEQ Label1 RTS
STA ,X NOP LDA #$30 BIT ,X ; FSTAT And, is there a reason (bug workaround, compatibility, etc.) for this: LDA ,X ORA #$80 STA ,X instead of this shorter version? (AFAIK, the remaining FSTAT bits are indifferent at this stage): LDA #$80 STA ,X I still find this version to use less RAM.
#define Page_Erase PGM[2]=0x40; ((void(*)(unsigned int, unsigned char))(PGM)) #define Program_Byte PGM[2]=0x20; ((void(*)(unsigned int, unsigned char))(PGM)) //Array of opcode instructions of the Erase/Program function in the HCS08 family // A = data, X = Address. volatile unsigned char PGM[18] = { 0xF7, // STA ,X Save the data byte into the address. 0xA6,0x00, // LDA cmd 0xC7,0x18,0x26, // STA _FCMD 0xA6,0x80, // LDA FCBEF bit 0xc7,0x18,0x25, // sta FSTAT 0x44, // lsra - one byte - longer delay than nop 0xc5,0x18,0x25, // Bit fstat 0x27,0xfb, // BEQ *-3 0x81 // RTS }; byte FlashErasePage(word page) { byte im; asm TPA // get that flags asm STA im // save the flags asm SEI // kill IM bit if (FSTAT&0x30){ //Check to see if FACCERR is set FSTAT = FSTAT | 0x30; //write a 1 to FACCERR to clear } Page_Erase(page,0); asm LDA im // put the im bit bak asm TAP if (FSTAT&0x30){ //check to see if FACCERR or FVIOL are set return 0xFF; //if so, error. } return 0; } byte FlashProgramByte(word address, byte data) { byte im; asm TPA asm STA im asm SEI if (FSTAT&0x30){ FSTAT = FSTAT | 0x30; } Program_Byte(address, data); asm LDA im asm TAP if (FSTAT&0x30){ //check to see if FACCERR or FVIOL are set return 0xFF; //if so, error. } return 0; }
bigmac wrote:Why bother testing FSTAT - simply clear the flags. If they are already clear, nothing will happen.
0xF7, // STA ,X Save the data byte into the address. 0xA6,0x00, // LDA cmd 0xC7,0x18,0x26, // STA _FCMD 0xA6,0x80, // LDA FCBEF bit