#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations */word wTemp = 0; //General usage wordbyte bTemp = 0; //General usage bytevoid InitFlashRoutine(void); // match number of bytes above.void FlashInit(void);byte FlashErasePage(word page); byte FlashProgramByte(word address, byte data);const unsigned char ROM_PGM[7] = { 0xf7, // sta ,X FSTAT 0x44, // lsra - delay and convert to FCCF bit0xf5, // Bit X ,fstat0xf5, // Bit X ,fstat0x27,0xfd, // BEQ *-10x81 // RTS}; volatile unsigned char PGM[7] = { 0xf7, // sta ,X FSTAT 0x44, // lsra - delay and convert to FCCF bit0xf5, // Bit X ,fstat0xf5, // Bit X ,fstat0x27,0xfd, // BEQ *-10x81 // RTS}; void main(void) { PTBDD_PTBDD2 = 1; //Pin used for debug PTBD_PTBD2 = 0; //LED1 on on first power up PTBDD_PTBDD3 = 1; //Pin used for debug PTBD_PTBD3 = 1; //LED2 off //Setup bus to run at 19.925Mhz//ICSC1 remains default (Internal reference with FLL enabled)//ICSSC setting, 39.85Mhz//DRST = 01 = Mid range//DMX32 = 1 = Accurate internal xtal//Internal reference selected//Output of FLL Selected ICSSC = 0b01110000; ICSC2 = 0b00000000; //Bus div 1//Not sure how this is suppose to be done now as there is no FLL lock... Just created a about a short delay to be sure// while(!ICGS1_LOCK) __RESET_WATCHDOG(); //Wait for lock before allowing software to startup//Loop for wTemp*2^8 wTemp = 1000; bTemp = 0; while(--wTemp){ while(++bTemp) __RESET_WATCHDOG(); //Wait at least some time for the clock to stablise, really should be 1mS } PTBD_PTBD2 = 1; //LED off once running EnableInterrupts; /* enable interrupts */ /* include your code here */ InitFlashRoutine(); //Ensure RAM is loaded correctly FlashErasePage(0x8000); FlashProgramByte(0x8000, 0xCC); if((*((byte *)0x8000)) == 0xCC) PTBD_PTBD3 = 0; //LED on if programming success for(;;) { __RESET_WATCHDOG(); /* feeds the dog */ } /* loop forever */ /* please make sure that you never leave main */}void InitFlashRoutine(void) // match number of bytes above. { PGM[0] = ROM_PGM[0]; PGM[1] = ROM_PGM[1]; PGM[2] = ROM_PGM[2]; PGM[3] = ROM_PGM[3]; PGM[4] = ROM_PGM[4]; PGM[5] = ROM_PGM[5]; PGM[6] = ROM_PGM[6]; }// - - - - - - - - - - - - -//This must be setup based on the clock settings#define initFCDIV 0b01001101 //FLASH clock divider (setup for 20Mhz Bus)// ||||||||// |||||||+-DIV0 \// ||||||+--DIV1 |// |||||+---DIV2 >-- divide by (12+1)// ||||+----DIV3 | BUSCLK/(8*12)~=(192.3Khz)// |||+-----DIV4 |// ||+------DIV5 /// |+-------PRDIV8 -- divide (prescale) by 8// +--------DIVLD --- read-only statusvoid FlashInit(void){ while(FSTAT_FACCERR) FSTAT_FACCERR = 1; //Make sure error is cleared before setting up the divider if(!FCDIV_FDIVLD) FCDIV = initFCDIV; //set fFCLK = about 200kHz (if not already setup i.e. on warm boot) FPROT_FPOPEN = 1; //No flash protection FPROT_FPS = 1; //No flash protection}// - - - - - - - - - - - - -byte FlashErasePage(word page) { asm { TPA ; Get status to A PSHA ; Save current status SEI ; Disable interrupts LDA #0x30 STA FSTAT ; Clear FACCERR & FPVIOL flags LDHX page STA ,X ; Save the data LDA #$40 ; Erase command STA FCMD LDA #FSTAT_FCBEF_MASK LDHX @FSTAT JSR PGM PULA ; Restore previous status TAP } return (FSTAT & 0x30); }byte FlashProgramByte(word address, byte data) { asm{ TPA PSHA ; Save current status SEI ; Disable interrupts LDA #0x30 STA FSTAT ; Clear FACCERR & FPVIOL flags LDHX address LDA data STA ,X ; Save the data LDA #$20 ; Burn command STA FCMD LDA #FSTAT_FCBEF_MASK LDHX @FSTAT JSR PGM PULA ; Restore previous status TAP } return (FSTAT & 0x30); }
Carl,
you init FPROT register this way:
FPROT_FPOPEN = 1; //No flash protection
FPROT_FPS = 1; //No flash protection
This way you are write protecting 126kB of flash. Is it what you want?
Flash routines from your first thread message (PGM and two Flashxxx routines) are working OK for me on QE128.