Help! Writting to S12XEP100 flash using registers

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

Help! Writting to S12XEP100 flash using registers

Jump to solution
1,571 Views
mroczeks
Contributor IV

Hi All,

 

I am trying to do a simple excersise of writing some example data into specific memory location (flash) of S12XEP100 MCU (onboard DEMO9S12XEP100 kit).

I read MC9S12XEP100RMV1 and S12XCPUV2 documents quite thoroughly and everything seems to be very clear to me.

Anyway I am not able to make that excersise working OK.

 

I suppose the reason lays somewhere in compiler / linker / IDE which I am not too familiar with for now.

There is a .prm file which I somewhat understand (at lest think so).

Then there are datapage.c and Start12.c files which I can hardly follow.

 

Please, find the main routine listed below.

I believe the entire project (with datapage.c and Start12.c files) will be very helpful for investigation so I add it as attachment.

 

void main(void) {
 
  DisableInterrupts;

  /* 1. configure mcu clock: Fosc = 4MHz >> Fbus = 8MHz */
  _SYNR.Byte = 0x03;
  _REFDV.Byte = 0x40;
  _POSTDIV.Byte = 0x01;
 
  /* 2. wait for PLL to lock */
  while(!_CRGFLG.Bits.LOCK) {
  }
 
  /* 3. select PLL as clock source */
  _CLKSEL.Bits.PLLSEL = 1;
 
  /* flash procedure tests: */

  /* 4. clear the illegal address reset flag */
  CRGFLG_ILAF = 1;        
 
  /* 5. initialise the memory controller prior to any  */
  /* commands being launched or EEE data access     */
  while(!FSTAT_CCIF) {
  }
 
  /* 6. load the clock divider before any flash command. Assumes 4MHz XTAL */
  FCLKDIV = 3;   
    
    /* 7. wait for ready state */      
  while(!FSTAT_CCIF) {
  }

  /* 8. no protection */
  FPROT = 0xFF;

  /* 9. wait for ready state */  
  while(!FSTAT_CCIF) {
  }
 
  /* 10. clear flash error flags */
  FSTAT = ( FSTAT_FPVIOL_MASK | FSTAT_ACCERR_MASK );
 
  /* 11. erase sector 0x7F_5000: */
    FCCOBIX = 0;      /* index for command and global address */
    FCCOBHI = 0x0A;   /* command - 0x0A = erase sector */
  FCCOBLO = 0x7F;   /* global address */

    FCCOBIX = 1;      /* index for "local" address */
  FCCOB = 0x5000;   /* "local" address */
 
  /* 12. launch command execution */
  FSTAT_CCIF = FSTAT_CCIF_MASK;

  /* 13. wait for ready state */
  while(!FSTAT_CCIF) {
  }
 
 
  /* 14. program sector 0x7F_5000: */
  FCCOBIX = 0;
    FCCOBHI = 0x06;
  FCCOBLO = 0x7F;

    FCCOBIX = 1;
  FCCOB = 0x5000;
  /* data word 1 */
  FCCOBIX = 2;
  FCCOB = 0x1234;
  /* data word 2 */
  FCCOBIX = 3;
  FCCOB = 0x5678;
  /* data word 3 */
  FCCOBIX = 4;
  FCCOB = 0x9ABC;
  /* data word 4 */
  FCCOBIX = 5;
  FCCOB = 0xDEF0;
 
  /* 15. launch command execution */
  FSTAT_CCIF = FSTAT_CCIF_MASK;

  /* 16. wait for ready state */
  while(!FSTAT_CCIF) {
  }
 
  /* flash tests completed */

 

 

  for(;:smileywink:
  {
    //while(_CAN0RFLG.Bits.RXF == 0) { }
    
  }
  for(;:smileywink: {} /* wait forever */
  /* please make sure that you never leave this function */
}

 

Please help! After feeling so inspired I feel quite desperate now :/


Labels (1)
0 Kudos
1 Solution
663 Views
mroczeks
Contributor IV

Thanks for the answer DPB!

 

Actually replacing 'FSTAT_CCIF_MASK' define with explicit value (0x80) didn't help in my case for some reason... :/

It compiled into BCLR instruction as well.

 

Anyway trying to set that CCIF bit in a different way was a good idea.

I replaced entire lines 'FSTAT_CCIF = FSTAT_CCIF_MASK;' with more "direct" expression: '_FSTAT.Bits.CCIF = 1;'

It worked OK this way :smileyhappy:

 

You were correct with memory address - I changed it to 0x74_5000.

 

Several thoughts after solving my case...

1. It seems quite confusing that those macro defines didn't work.

 

2. Translating that macro to BCLR command is quite a strange behaviour. BCLR clears a bit instead of setting it... That translation looks like a compiler error a bit :/ Same goes for "...= 0x80 ".

 

3. _FSTAT.Bits.CCIF = 1 line is compiled into BSET instruction... Which is a proper procedure to launch flash command as MC9S12XEP100RMV1 paper, chapter 29.4.1.2.1 says that clearing of the CCIF command completion FLAG (flag, not the bit) in the FSTAT register is done by writing 1 to CCIF ( "(...)writting 1 clears the CCIF to 0(...)" ).

 

4. The TrueTimeSimulator & RealTimeDebugger doesn't seem to become my favourite debugger... Refreshing of memory overview does not work so you can't observe memory content changes as you progress with the code execution... You have to close it and run debug again (without flashing the chip again this time) to see updated memory content :/

 

5. It is probably best to trace code execution and check for corresponding assembly instructions to make sure everything is going OK (like that BSET is executed, not BCLR command).

 

Thanks again!

View solution in original post

0 Kudos
6 Replies
663 Views
DPB
NXP Employee
NXP Employee

Hello

 

The lines..    

FSTAT_CCIF = FSTAT_CCIF_MASK;       are compiled into BCLR commands, which do not work for flag clearing.

I swapped them for a hardwired FSTAT = 0x80; 

 

Then ensuring that the flash block which is being programmed/erased is not the same flash block that the code is running from and the code successfully programs the flash. I used flash location 0x74_5000 because the code was running from 0x7F_C000 (same block as 0x7f_5000) in my project environment.

 

DPB

0 Kudos
664 Views
mroczeks
Contributor IV

Thanks for the answer DPB!

 

Actually replacing 'FSTAT_CCIF_MASK' define with explicit value (0x80) didn't help in my case for some reason... :/

It compiled into BCLR instruction as well.

 

Anyway trying to set that CCIF bit in a different way was a good idea.

I replaced entire lines 'FSTAT_CCIF = FSTAT_CCIF_MASK;' with more "direct" expression: '_FSTAT.Bits.CCIF = 1;'

It worked OK this way :smileyhappy:

 

You were correct with memory address - I changed it to 0x74_5000.

 

Several thoughts after solving my case...

1. It seems quite confusing that those macro defines didn't work.

 

2. Translating that macro to BCLR command is quite a strange behaviour. BCLR clears a bit instead of setting it... That translation looks like a compiler error a bit :/ Same goes for "...= 0x80 ".

 

3. _FSTAT.Bits.CCIF = 1 line is compiled into BSET instruction... Which is a proper procedure to launch flash command as MC9S12XEP100RMV1 paper, chapter 29.4.1.2.1 says that clearing of the CCIF command completion FLAG (flag, not the bit) in the FSTAT register is done by writing 1 to CCIF ( "(...)writting 1 clears the CCIF to 0(...)" ).

 

4. The TrueTimeSimulator & RealTimeDebugger doesn't seem to become my favourite debugger... Refreshing of memory overview does not work so you can't observe memory content changes as you progress with the code execution... You have to close it and run debug again (without flashing the chip again this time) to see updated memory content :/

 

5. It is probably best to trace code execution and check for corresponding assembly instructions to make sure everything is going OK (like that BSET is executed, not BCLR command).

 

Thanks again!

0 Kudos
663 Views
CompilerGuru
NXP Employee
NXP Employee

I replaced entire lines 'FSTAT_CCIF = FSTAT_CCIF_MASK;' with more "direct" expression: '_FSTAT.Bits.CCIF = 1;'

 

> 2. Translating that macro to BCLR command is quite a strange behaviour. BCLR clears a bit instead of setting it...

> That translation looks like a compiler error a bit :/ Same goes for "...= 0x80 ".

 

What "FSTAT_CCIF = FSTAT_CCIF_MASK" does is to assign 0x80 to a single bit bitfield. Obviously this wont fit, and therefore what this means is to execute _FSTAT.Bits.CCIF = (0x80 & 1), or in other words clear _FSTAT.Bits.CCIF.

 

In the end, the macros for single bit access and the macros for the masks of the bits in the register should not be used together. Either use the bit access macros and 0/1 as values or use the _MASK macros and the byte name of the register.

 

As far as the refreshing in hiwave goes, not sure which target connection you are using but typically there is a memory configuration dialog which let you configure if flash should be cached or not.

 

Daniel

 

0 Kudos
663 Views
mroczeks
Contributor IV

Hi!

 

Now I see... It was my mistake all the time :/

I mixed up byte access with bit access...

 

My target connection is SofTec HCS12. I am able to set up periodical mode inside memory window (like for every 1s) but it does not work... Anyway that's not the main topic here.

 

Thanks again, everything is clear for me now :smileyhappy:

0 Kudos
663 Views
CompilerGuru
NXP Employee
NXP Employee

I know it's not the main topic here, anyway.

That by default HIWAVE is not reloading flash content (again) came up in other threads, for example in this one:

 

https://community.freescale.com/message/49575#49575

 

Did not use SofTec for a while, it might be different on a per connection basis though. 

 

Daniel

0 Kudos
663 Views
mroczeks
Contributor IV

Thanks!

 

The "off topic" link solved my issue with CodeWarrior IDE... :smileywink:

0 Kudos