void Write_Command(uchar index,uint fcmd,uint addr)
{
FCCOBIX = index;
FCCOB = (fcmd<<8) | addr;
}
Write_Command(0x00,Program_Dflash,0x10);
Write_Command(0x01,0x00,des_addr); //0X00
Write_Command(0x02,0x00,1);
Write_Command(0x03,0x00,2);
Write_Command(0x04,0x00,3);
Write_Command(0x05,0x00,4);
I use this program to write the data in the data flash area(the global address is 0x10_0000),but I can not write the read out program so I couldnot read the data I just write,which engieer can help me or write down the read out program! Thanks!
Solved! Go to Solution.
Ok. The problem is solved now. Applying appropriate global address to the memory controller solves this issue.
Thanks kef for clearing doubts.
-- NKG
Hi,
You can read the data from D-flash using one of the below shown example methods.
case1: data = *(uint8_t* __eptr)(0x0800);
(or)
case2: data = *(uint8_t* __far)(0x100000);
both case1 and case2 will store the same value to the variable 'data'. But the only difference among them is 'how you are accessing the D-flash memory location'.
Case1 is accessing the D-flash memory using logical address.
Case2 is accessing the D-flash memory using global address.
i.e. the logical address 0x0800 (of D-flash) is same as global address 0x100000.
Freescale provides an executable file called ‘ hcs12xadrmap.exe ’ which shows the relation between logical and global address of HCS12(x) family. . It can be found in the following path of your computer.
C:\Program Files\Freescale\Codewarrior for HC12 V4.6\Prog
hope this helps
nandu
You just the expert, the way you suggest was very uses full ,than you very much!
Dear All,
I'm using S12P micro in my one of project. I'm using D_Flash for const variables storing. I've written following code
sCHAR flashCommand(void)
{
volatile uCHAR i;
// Check whethere previous command is still executing
while(!FLAG_COMMAND_COMPLETE);
// if there is any error then clear it
if((!FLASH_STATUS_REG1) || (!FLASH_STATUS_REG2))
{
FLASH_STATUS_REG1 = 0x30; // Clear ACCERR and FPVIOL
FLASH_STATUS_REG2 = 0x03; // Clear bit Errors
}
for(i=0; i<=indexCommandArray; i++)
{
FCCOBIX = i;
FCCOB = flashCommandArray[i];
}
FSTAT = 0x80; // Launch the command
asm nop;
asm nop;
asm nop;
asm nop;
asm nop;
asm nop;
while(!FLAG_COMMAND_COMPLETE);
return ERR_OK;
}
/****************************************************************************/
#pragma DATA_SEG DFLASH_DATA
uINT __far testString = 0x1234;
#pragma DATA_SEG DEFAULT
The DFlash is defined as,
DFLASH_00 = READ_ONLY 0x010400 TO 0x0113FF;
And calling the function by,
applyFlashCommand((uLONG) testString, 100, PROGRAM_D_FLASH);
when I execute above function, I got ACCERR everytime. As per ref manual the ACCERR will come when,
Set if CCOBIX[2:0] < 010 at command launch -- Confirmed
Set if CCOBIX[2:0] > 101 at command launch -- Confirmed
Set if command not available in current mode (see Table 13-27) - Confirmed
Set if an invalid global address [17:0] is supplied -- NOT Confirmed
Set if a misaligned word address is supplied (global address [0] != 0) -- NOT Confirmed
Set if the requested group of words breaches the end of the D-Flash block - Confirmed
Plz throw some light over this issue. I also confused that the DFlash address is logical or global(physical).
-- Thanks and Regards,
N. K. Gavali
I wonder why are you using nonstandard bit and registers names in your code.
This piece of code isn't the root of problem, but it is wrong. Code assumes FSTAT==0 when errors flags are not active. At least CCIF is usually set.
if((!FLASH_STATUS_REG1) || (!FLASH_STATUS_REG2))
{
FLASH_STATUS_REG1 = 0x30; // Clear ACCERR and FPVIOL
FLASH_STATUS_REG2 = 0x03; // Clear bit Errors
}
This is not enough. Different flash commands require different COBIX value. You didn't provide all relevant code, but indexCommandArray must be different for different commands.
Since DFLASH addresses specified in PRM are DPAGE-paged, you need to add __DPAGE_SEG here
#pragma DATA_SEG __DPAGE_SEG DFLASH_DATA
.....
#pragma DATA_SEG DEFAULT
Please note also that flash controller wants not DPAGE- or PPAGE-page paged addresses, but global addresses. You need to convert addresses of you DFLASH_DATA variables.
Thanks kef,
Plz explain me the relation between logical and global address for Dflash for perticularly S12P. for S12X CPU it depends on EPAGE. but here no EPAGE available so, how can I calculate the global address for DFlash (as given in prm file above).
// re-calculate the address
address = ((uINT)globalAddress); // I think I'm wrong here to calculate the global address
indexCommandArray = 0;
flashCommandArray[0] = commandAndHiByte; // The Command_Byte + HI_Byte_GLOBAL_Add
indexCommandArray = 1;
flashCommandArray[1] = address; // 16 bit Global Add
indexCommandArray = 2;
flashCommandArray[2] = data; // 16 bit data
// Here I want to skip other 3 words and want to write single word.
flashCommand(); // Code is explained as in previous
-- Thanks and Regards,
N. K. Gavali
First of all sorry for bad advice. Your allocation is OK, provided far keyword is used.
#pragma DATA_SEG DFLASH_DATA
int __far var;
#pragma DATA_SEG DEFAULT
But looking at memory maps in PDF and at CW default PRM file for S12P, I don't understand why this PRM specifies such weird DFLASH addresses. 0x010400 to 0x0113FF. Page 0x01 must be PPAGE. Why then out-of-PPAGE window offsets?
I don't have S12P to try, but I would edit PRM to make DFLASH nonpaged 0x0400 to 0x13FF and remove __far keyword from variable definitions.
To answer your question regarding global address for DLFASH. Look at S12P memory map in figure 1-2. CPU local address of DFLASH 0x0400 translates to global address 0x0_4400. So you need to add 0x4000 to CPU local address to get global address:
#pragma DATA_SEG DFLASH_DATA
int var;
#pragma DATA_SEG DEFAULT
gloal_address = (uLONG)&var + 0x4000;
Thanks kef
Yes after reading comparisions of S12X and S12P, I understand the D flash global addressing. It is same as the Pflash global address but only till 17 bit. i,.e. 4bit PPAGE + 13bit Local Dflash Address.
The address 0x10400 and 0x1113F for Dflash range is generated by Device Initialization. If I understand it clearly, one can easily know that PPAGE = 0x01 and rest is 16 bit local address.
I will also chcek it by placing the flashCommand() routine into RAM area.
I have checked with address 0x4400 once with same routine but that time also I've faced ACCERR by the memory controller.
Perhaps I was doing the memory access by wrong sequence i,e. it might be like this,
First ERASE_VERIFY_D_FLASH_SECTION (0x11) or ERASE_D_FLASH_SECTOR(0x12) command should be given to memory controller with valid starting address then PROGRAM_D_FLASH should be given.
is that logic correct? or if any other way to do it? please guide.
-- Thanks and Regards,
NKG
Ok. The problem is solved now. Applying appropriate global address to the memory controller solves this issue.
Thanks kef for clearing doubts.
-- NKG
What exactly do you want to do? Just read the flash back?
You have a couple of ways - either use global addressing in assembler, or use the EPAGE register and read from the EEPROM window. Check the datasheet.
James
thank you I use the local address with the EPAGE ,I read out the value .