Hello Tony,
I was originally thinking that the flag clearing required read-modify-write, as with many other flags. However, on checking with the data sheet, these flags only require a write to clear them. This is explicitly stated within the description for each flag.
FSTAT = 0x30; // This should work if flags are set, and have no effect if flags are clear.
JimD,
With the interrupt control process within the erase and program functions, I see that you are creating a local variable (on the stack), and then writing to it using inline assembly. Probably better to directly push the value on the stack. So your functions might look like this.
byte FlashErasePage( word page)
{
volatile byte temp;
asm {
TPA
PSHA // Save current status
SEI // Disable interrupts
}
FSTAT = 0x30; // Clear FACCERR & FPVIOL flags
temp = Page_Erase( page, 0);
asm {
PULA // Restore previous status
TAP
}
return temp;
}
byte FlashProgramByte( word address, byte data)
{
volatile byte temp;
asm {
TPA
PSHA ; Save current status
SEI ; Disable interrupts
}
FSTAT = 0x30; // Clear FACCERR & FPVIOL flags
temp = Program_Byte(address, data);
asm {
PULA ; Restore previous status
TAP
}
return temp;
}
However, since assembly is being used, why not stick entirely with assembly, and also avoid the need for the complex incantations within the macros - well I find them complex. The following might be a possibility.
byte FlashErasePage( word page)
{
volatile byte temp;
asm {
TPA
PSHA ; Save current status
SEI ; Disable interrupts
LDA #0x30
STA FSTAT ; Clear FACCERR & FPVIOL flags
LDA #0x40 ; ERASE command
STA PGM:2
LDHX page
JSR PGM ; Execute RAM routine
STA temp ; Return value
PULA ; Restore previous status
TAP
}
return temp;
}
byte FlashProgramByte( word address, byte data)
{
volatile byte temp;
asm {
TPA
PSHA ; Save current status
SEI ; Disable interrupts
LDA #0x30
STA FSTAT ; Clear FACCERR & FPVIOL flags
LDA #0x20 ; PROGRAM command
STA PGM:2
LDHX address
LDA data
JSR PGM ; Execute RAM routine
STA temp ; Return value
PULA ; Restore previous status
TAP
}
return temp;
}
Finally, on the subject of "padding" delays, a benign, single byte instruction is TST ,X. This provides a delay of 3 cycles for the 9S08.
Probably not relevant here, but a very simple way to generate much longer delays using 4 bytes -
lda #<delay_value>
dbnza * ; 4 cycles per loop
Regards,
Mac
Message Edited by bigmac on
2008-02-26 07:28 AM