Can FLASH be set as Read/Write?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Can FLASH be set as Read/Write?

3,000 Views
ThomasG
Contributor I
 
I am using the MC9S12XDP512 part and am wondering if I can set portions of the paged FLASH to be READ_WRITE instead of READ_ONLY.  I have a large configuration table that I need to store that may have to be occasionally changed so I would like to store it in FLASH instead of RAM.  If anyone knows the answer or has done something like this before, I would appreciate the help.
 
Thanks,
 
Thomas
Labels (1)
Tags (1)
0 Kudos
3 Replies

445 Views
ThomasG
Contributor I

Thank you for the replies.  I think this answers my basic question and can get me going with what I need to do.

 

-Thomas

0 Kudos

445 Views
Technoman64
Contributor III

I have used FLASH on the HCS(X) devices to store lookup tables. Here is the code I used to erase and program the FLASH sectors (1024 bytes).

This first part shows I accessed and checked each value in a FLASH table. If any of the parameters are out of spec it programs the table to a DEFAULT setting.

The second section shows how to setup your GLOBAL segment to place the tables.

The third setion is the code to erase and program the FLASH.

Not sure if this is the best way to do it but it worked for me.

Be sure to #define the OSC_SPEED so the proper FLASH timing can be set. Look at the last function in this code.

Code:

#include "FlashCtrl.h"#pragma DATA_SEG DATATABLE_DATA#pragma CODE_SEG DATATABLE_CODE/* Check data tables */void CheckDataTables(void) { /* Local variables */ BYTE Flag; WORD i;  /* Check Nitrous table */ for(i = 0; i < NITROUS_TABLE_SIZE; i++) {  /* Check each table entry */  if(NitrousTable[SetupIndex][i] < NITROUS_PERCENT_MIN || NitrousTable[SetupIndex][i] > NITROUS_PERCENT_MAX){   /* Erase table sector */   Flag = Flash_EraseSector((INT16 *__far)&NitrousTable[SetupIndex][0]);   /* Write factory data */   for(i = 0; i < NITROUS_TABLE_SIZE; i++){    Flag = Flash_WriteWord((INT16 *__far)&NitrousTable[SetupIndex][i], NitrousTableDefault[i]);   }   /* Break loop */   break;  } }  /* Check Fuel table */ for(i = 0; i < FUEL_TABLE_SIZE; i++) {  /* Check each table entry */  if(FuelTable[SetupIndex][i] < FUEL_PERCENT_MIN || FuelTable[SetupIndex][i] > FUEL_PERCENT_MAX){   /* Erase table sector */   Flag = Flash_EraseSector((INT16 *__far)&FuelTable[SetupIndex][0]);   /* Write factory data */   for(i = 0; i < FUEL_TABLE_SIZE; i++){    Flag = Flash_WriteWord((INT16 *__far)&FuelTable[SetupIndex][i], FuelTableDefault[i]);   }   /* Break loop */   break;  } }}#pragma CODE_SEG DEFAULT#pragma DATA_SEG DEFAULT/* This SEGMENT(TABLE_ROM) must be declared as PAGED_FLASH in prm file */#pragma CONST_SEG __GPAGE_SEG TABLE_ROM/* Nitrous Table */const WORD NitrousTable[SETUP_MAX][512];/* Fuel Table */const WORD FuelTable[SETUP_MAX][512];#pragma CONST_SEG __GPAGE_SEG DEFAULTTABLE_ROM/* FLASH data table address range */#define TABLE_ADDRESS_LOW  0x780000#define TABLE_ADDRESS_HIGH  0x787FFF#pragma DATA_SEG FlashCtrl_DATA                                            #pragma CODE_SEG FlashCtrl_CODE                     /* Flash_WriteWord */BYTE Flash_WriteWord(WORD *__far WriteAddress, WORD Data){ /* Check range of WriteAddress */ if(WriteAddress < (WORD *__far)TABLE_ADDRESS_LOW || WriteAddress > (WORD *__far)TABLE_ADDRESS_HIGH)  return FALSE;  /* Has the FLASH divider clock been set— */ if(!FCLKDIV_FDIVLD)  FlashCtrl_Init();  /* Check command flag */ if(!FSTAT_CBEIF)  return FALSE;  /* Clear flags */ FSTAT = 48;    /* Array address and program data */   WriteAddress[0] = Data;    /* Word program command */ FCMD = 32;    /* Clear flag command buffer empty */    FSTAT = 128;     /* Is protection violation or acces error detected– */   if ((FSTAT_PVIOL == 1)||(FSTAT_ACCERR == 1))     return FALSE;      /* Wait to buffer empty */ while(FSTAT_CBEIF == 0); /* Wait to command complete */ while(FSTAT_CCIF == 0); /* Was write successful˜ */ if(WriteAddress[0] != Data)  return FALSE;  /* Return success */  return TRUE;}/* Flash_EraseSector */BYTE Flash_EraseSector(WORD *__far EraseAddress){ /* Check range of EraseAddress */ if(EraseAddress < (WORD *__far)TABLE_ADDRESS_LOW || EraseAddress > (WORD *__far)TABLE_ADDRESS_HIGH)  return FALSE;  /* Has the FLASH divider clock been set™ */ if(!FCLKDIV_FDIVLD)  FlashCtrl_Init();  /* Check command flag */ if(!FSTAT_CBEIF)  return FALSE;  /* Clear flags */ FSTAT = 48;  /* Write to erase address */ EraseAddress[0] = 0x10;   /* Initiate Sector Erase commamd */ FCMD = 64; /* Clear flag command buffer empty */ FSTAT = 128;        /* Is protection violation or access error detected ? */ if ((FSTAT_PVIOL == 1)||(FSTAT_ACCERR == 1))     /* If yes then error */     return FALSE;        /* Wait to buffer empty */   while(FSTAT_CBEIF == 0); /* Wait to command complete */ while(FSTAT_CCIF == 0);  /* Return success */ return TRUE;}/* FlashCtrl_Init */void FlashCtrl_Init(void){#if OSC_SPEED == 4000000 /* 4mhz clock */ FCLKDIV = 20;                        #elif OSC_SPEED == 8000000 /* 8mhz clock */ FCLKDIV = 40;#elif OSC_SPEED == 10000000 /* 10mhz clock */ FCLKDIV = 50;#endif}#pragma DATA_SEG DEFAULT                                            #pragma CODE_SEG DEFAULT                    


 

0 Kudos

445 Views
J2MEJediMaster
Specialist I
Check out the follow thread in the 8-bit Microcontroller Forum. It has a discussion about how to program Flash to store variables:

http://forums.freescale.com/freescale/board/message?board.id=8BITCOMM&message.id=1084 target=_blank

It may not be exactly what you're looking for, but it will probably give you some ideas.

---Tom
0 Kudos