I have updated the prm file and code some. This was done using Codewarrior for HC08 5.0 Eval version.
a - There is no need for a special ROM section for the programming code.
b - I have made a DATA_ROM section that is 256 bytes in size or Four 64-byte rows.
c - I have updated the programming functions as I suggested in the previous post.
d - There is no a function to ERASE 64-byte rows in FLASH.
e - The code for Programming and Erasing FLASH is loaded into RAM only as needed.
f - Only one Array is Required in RAM for both the Program and Erase functions.
Functions that I feel need to be included.
a - ProgramFlashWord(char * Address, unsigned int Number), this would be used for storing integers.
b - ProgramFlashLong(char *Address, unsigned long Number), should be obvious.
c - A function that can use two 64 byte sections to store data to be programmed and verify the operation was succesful on Reset.
New prm file
Code:
/* This is a linker parameter file for the GT8 */NAMES END /* CodeWarrior will pass all the needed files to the linker by command line. But here you may add your own files too. */SEGMENTS /* Here all RAM/ROM areas of the device are listed. Used in PLACEMENT below. */ ROM = READ_ONLY 0xE000 TO 0xFCFF; ROMDATA = READ_ONLY 0xFD00 TO 0xFDFF; Z_RAM = READ_WRITE 0x0040 TO 0x00FF; RAM = READ_WRITE 0x0151 TO 0x023F; RAM2 = READ_WRITE 0x0100 TO 0x0150;ENDPLACEMENT /* Here all predefined and user segments are placed into the SEGMENTS defined above. */ DEFAULT_RAM INTO RAM; DEFAULT_ROM, ROM_VAR, STRINGS INTO ROM; _DATA_ZEROPAGE, MY_ZEROPAGE INTO Z_RAM; /* Copy section for Flash programming function */ /* Code must be ran from RAM whill programming Flash */ FLASH_RAM INTO RAM2; /* 256 bytes of Non-volatile data section in FLASH */ /* There are four 64 byte rows in this section */ DATA_ROM INTO ROMDATA; END/* Define the system STACK size */STACKSIZE 0x50/* Reset vector: this is the default entry point for an application. */VECTOR 0 _Startup/* Items in this section will be included during linking */ENTRIESTestArrayEND
Now for the new code. Please excuse the fact that I have not broken this up into multiple files.
Code:
#include <hidef.h> /* for EnableInterrupts macro */#include "derivative.h" /* include peripheral declarations *//* Define FLASH programming error codes */#define ERROR_FLASH_ERASE 1#define ERROR_FLASH_ADDRESS 2#define ERROR_FLASH_WRITE 3/* Define ProgramFlashByte ID */#define PFB_ID 0x01#define PFB_ID_ADDRESS 0x0100#define PFB_SIZE 0x3C#define PFB_SIZE_ADDRESS 0x0101/* Define EraseFlashRow ID */#define EFR_ID 0x02#define EFR_ID_ADDRESS 0x0100#define EFR_SIZE 0x32#define EFR_SIZE_ADDRESS 0x0101/* Define block protect register location */#define BLOCK_PROTECT_REGISTER 0xFF7E;/* ProgramFlashByte function type define */typedef void (*PFB)(char*, char); /* Declare and initialize ProgramFlashByte */const PFB ProgramFlashByte = (PFB)0x0102;/* EraseFlashRow function type define */typedef void (*EFR)(char*); /* Declare and initialize ProgramFlashByte */const EFR EraseFlashBytes = (EFR)0x0102;/* This segment is declared in the prm linker placement file *//* Segment address is 0x0100 to 0x0150 */#pragma DATA_SEG FLASH_RAM/* Declare array to copy ProgramFlash function into */unsigned char FlashRoutine[0x50];#pragma DATA_SEG DEFAULT/* Non-Volatile data array in FLASH */#pragma CONST_SEG DATA_ROMconst int TestArray[5] = {0,1,2,3,4};#pragma CONST_SEG DEFAULT/* This function will be copied to RAM as needed *//* Bus frequency MUST be at minimum 1 Mhz! for HC08GT8(16) *//* Delay timing is for bus speed of 2.457600Mhz maximum */void ProgramFlash(char *Address, char c){ /* Programming step 1, set PGM bit */ FLCR = 1; /* Programming step 2, Read block protect register */ asm{ lda BLOCK_PROTECT_REGISTER; }; /* Programming step 3, Write any data to address */ *(char*)Address = c; /* Programming step 4, Wait for minimum 10us */ asm{ ldx #10; Loop1: dbnzx Loop1; } /* Programming step 5, Set HVEN bit */ FLCR = 9; /* Programming step 6, Wait for minimum 5us */ asm{ ldx #5; Loop2: dbnzx Loop2; } /* Programming step 7, Write data to address */ *(char*)Address = c; /* Programming step 8, Wait for minimum 30us */ asm{ ldx #30; Loop3: dbnzx Loop3; } /* Programming step 9, Clear PGM bit */ FLCR = 8; /* Programming step 10, Wait for minimum 5us */ asm{ ldx #5; Loop4: dbnzx Loop4; } /* Programming step 12, Clear HVEN bit */ FLCR = 0; /* Programming step 13, Wait for 1us */ asm{ nop; nop; };}/* This function will be copied to RAM as needed *//* Bus frequency MUST be at minimum 1 Mhz! for HC08GT8(16) *//* Delay timing is for bus speed of 2.457600Mhz maximum */void EraseFlash(char *Address){ /* Row Erase step 1, Set ERASE bit */ FLCR = 2; /* Row Erase step 2, Read Flash Block protect register */ asm{ lda BLOCK_PROTECT_REGISTER; }; /* Row Erase step 3, Write to ROW address for ERASE */ *(char*)Address = 0; /* Row Erase step 4, Wait for minimum 10us */ asm{ ldx #10; Loop1: dbnzx Loop1; } /* Row Erase step 5, Set HVEN bit */ FLCR = 10; /* Row Erase step 6, Wait for minimum 1ms */ asm{ ldx #100; Loop2: dbnzx Loop2; } /* Programming step 7, Clear ERASE bit */ FLCR = 8; /* Programming step 8,Wait for minimum 5us */ asm{ ldx #5; Loop4: dbnzx Loop4; } /* Programming step 9, Clear HVEN bit */ FLCR = 0; /* Programming step 10, Wait for 1us */ asm{ nop; nop; };}/* Function prototype(s) *//* WriteFlashByte */char WriteFlashByte(char *Address, char c);/* EraseFlashRow */char EraseFlashRow(char *Address);/* Cpu_Initialize */void Cpu_Initialize(void);/* main() function */void main(void) { /* Local variables */ char Error; /* Initialize cpu */ Cpu_Initialize(); /* Write "Test" data to FLASH */ Error = WriteFlashByte((char*)0xFDF0, 'T'); Error = WriteFlashByte((char*)0xFDF1, 'e'); Error = WriteFlashByte((char*)0xFDF2, 's'); Error = WriteFlashByte((char*)0xFDF3, 't'); /* Erase FLASH row, 64 bytes */ Error = EraseFlashRow((char*)0xFDF3); /* Write "Test2" data to FLASH */ Error = WriteFlashByte((char*)0xFDF0, 'T'); Error = WriteFlashByte((char*)0xFDF1, 'e'); Error = WriteFlashByte((char*)0xFDF2, 's'); Error = WriteFlashByte((char*)0xFDF3, 't'); Error = WriteFlashByte((char*)0xFDF4, '2'); /* Loop forever */ for(;;) { }}/* WriteFlashByte */char WriteFlashByte(char *Address, char c) { /* Turn OFF non-standard pointer conversion warning */ #pragma MESSAGE DISABLE C1805 /* Pointer to ProgramFlash function in FLASH */ char *Ptr = (char *)ProgramFlash; /* Used as index during code move from FLASH to RAM */ int Index; /* Storage for CCR */ unsigned char CCR_Byte; /* Verify byte at Address is erased */ if(*(char*)Address != 0xFF) { /* Return error not erased */ return ERROR_FLASH_ERASE; } /* Get a copy of the CCR */ asm{ tpa; sta CCR_Byte; }; /* Diasable interrupts now */ DisableInterrupts; /* Mask off the interrupt bit */ CCR_Byte &= 0x08; /* Check to see if ProgramFlash is present in RAM */ if(*(char*)PFB_ID_ADDRESS != PFB_ID || *(char*)PFB_SIZE_ADDRESS != PFB_SIZE) { /* Set PFB ID and SIZE */ FlashRoutine[0] = PFB_ID; FlashRoutine[1] = PFB_SIZE; /* Copy ProgramFlashFunction to RAM */ for(Index=2; Index<0x50; Index++){ FlashRoutine[Index] = Ptr[Index-2]; } } /* Write the char(byte) to FLASH */ ProgramFlashByte(Address, c); /* Restore interrupts— */ if(!CCR_Byte) EnableInterrupts; /* Verify write to FLASH */ if(*(char*)Address != c) /* Return write error */ return ERROR_FLASH_WRITE; /* Return success */ return FALSE;} /* EraseFlashRow */char EraseFlashRow(char *Address) { /* Pointer to ProgramFlash function in FLASH */ char *Ptr = (char *)EraseFlash; /* Used as index during code move from FLASH to RAM */ int Index; /* Storage for CCR */ unsigned char CCR_Byte; /* Is row already erased– */ /* TODO */ /* Get a copy of the CCR */ asm{ tpa; sta CCR_Byte; }; /* Diasable interrupts now */ DisableInterrupts; /* Mask off the interrupt bit */ CCR_Byte &= 0x08; /* Check to see if EraseFlash is present in RAM */ if(*(char*)EFR_ID_ADDRESS != EFR_ID || *(char*)EFR_SIZE_ADDRESS != EFR_SIZE) { /* Set PFB ID and SIZE */ FlashRoutine[0] = EFR_ID; FlashRoutine[1] = EFR_SIZE; /* Copy ProgramFlashFunction to RAM */ for(Index=2; Index<0x50; Index++){ FlashRoutine[Index] = Ptr[Index-2]; } } /* Write the char(byte) to FLASH */ EraseFlashBytes(Address); /* Restore interrupts˜ */ if(!CCR_Byte) EnableInterrupts; /* Verify erase was successful */ /* TODO */ /* Return success */ return FALSE;} /* Initialize cpu registers and internal clock */void Cpu_Initialize(void) { /* CONFIG1: COPRS=0,LVISTOP=0,LVIRSTD=1,LVIPWRD=0,LVI5OR3=1,SSREC=0,STOP=0,COPD=1 */ CONFIG1 = 41; /* CONFIG2: Unused=0,Unused=0,EXTXTALEN=0,EXTSLOW=0,EXTCLKEN=0,Unused=0,OSCENINSTOP=0,Unused=0 */ CONFIG2 = 0; /* ICG multiplier factor, 9.830400Mhz internal clock, 2.457600Mhz bus */ /* 307.2Khz * 32 */ ICGMR = 32; /* Has the osc trim been set™ */ if(*(byte*)0xFF80 != 0xFF) ICGTR = *(byte*)0xFF80; /* Wait for internal oscillator stabilization */ while(!ICGCR_ICGS); }