QD4 writing flash

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

QD4 writing flash

Jump to solution
6,792 Views
sauliuz
Contributor I
Hello,

I want to write a byte into non-volatile memory as a calibration constant. As I understood I need a hole flash page for that (safty reasons dicussed in other threads). So I wrote small procedure. And it does not work...

first I reserve that page in the flash:
Code:
unsigned char FLASH_MAS[512] @0xF800;    // rezervuojam page'a flasho rashymui

 
unsigned char FLASH_MAS[512] @0xF800;    // rezervuojam page'a flasho rashymui

write procedure:
Code:
void WriteToFlash(byte data) {  byte z=0;  FCDIV = 39;      // set flash clock , my bus is 8 MHz so 39   for (i=0;i<50;i++);  // wait a bit, just in case    if (!FSTAT_FACCERR) {    FLASH_MAS[0] = data;     // set flash page adress of interest    FCMD = 0x40;            FSTAT_FCBEF=1;       // erase it  if (FSTAT_FPVIOL || FSTAT_FACCERR); // error  else while (!FSTAT_FCCF); // ok, wait for completion  }   StartTX(0x07);  while(SensorState==sTX);   if (!FSTAT_FACCERR) {    FLASH_MAS[0] = data; // put my data to cerain address    FCMD = 0x20;    FSTAT_FCBEF=1;      // write that data  if (FSTAT_FPVIOL || FSTAT_FACCERR); // error  else while (!FSTAT_FCCF); // ok, wait for write completion  }}

 
where is my mistake?

Saulius
Labels (1)
0 Kudos
1 Solution
1,497 Views
bigmac
Specialist III

Hello, and welcome to the forum.

 

The likely reason for the linker error is that you have not defined the ToCopyToStack segment within the PRM file for the project.  This is the location of the code that will eventually be pushed to the stack, and executed from there. The size of this segment will need to closely match the size of the RAM based function, otherwise an excessive amount of the stack will be required if the segment is made too large.

 

Keep in mind that there is a total of 256 bytes only for the QD4 device.  To maximize the available stack it is better to explicitly allocate as many of your global variables as possible to zeropage RAM, otherwise the allocation will be to default RAM in page 1.

 

An alternative method to the direct use of the stack for the RAM based function is to use a fixed location in RAM for the function (usually at the bottom of the stack segment).  The size of the function using this method is only a few bytes.  The attached code demonstrates this method for the QG8 device, and should be readily adaptable to the QD4.  Maybe only the PRM file would differ.

 

Regards,

Mac

 

S08_Flash_A2.zip

 

Message Edited by t.dowe on 2009-09-02 03:16 PM

View solution in original post

0 Kudos
18 Replies
1,497 Views
celsoken
Contributor V
Ake is right, Saulius. Search for DoOnStack procedure in FS web site. It is a stack-oriented set of flash programming functions. Another observation is that the FS S08 flash protection mechanisms normally protect from a starting address till the end ($FFFF), so we usually place this data in the beginning blocks, in your case, $F000 for the QD4.

I hope it helps. Cheers,

Celso
0 Kudos
1,497 Views
sauliuz
Contributor I
Hello,

Thank you for tips. So I tried to do procedure according your recomendations with running in RAM and here is what I have done.

First reserve one page flash area:
Code:
const unsigned char FLASH_MAS[512] @0xF800 = 0x55;

 Flash page erase and write procedure:
Code:
#pragma CODE_SEG ToCopyToStack // routine in ram void MyStackFunction (byte CMD) { FCMD = CMD;          // write command (erase or write) FSTAT_FCBEF=1;       // start execution asm(nop);            // wait for completion asm(nop); asm(nop); asm(nop);}#pragma CODE_SEG DEFAULT  void WriteToFlash(byte data) {  DisableInterrupts;  FCDIV = 39;   // initialize clcok  FSTAT = 0;    // clear errors  asm(nop);     // just in case  asm (lda #$55   );  // add some data to accumulator  asm (ldhx #$F800);  // put address of the page to erase in H:X  asm (sta 0,x    );  // write accumulator to that address  MyStackFunction (0x40);    for (i=0;i<255;i++);  // just in case... wait   FSTAT = 0;          // clear errors  asm(nop);           // just in case  asm (lda data   );  // add some data to accumulator  asm (ldhx #$F800);  // put address of the page to erase in H:X  asm (sta 0,x    );  // write accumulator to that address  MyStackFunction (0x20);    for (i=0;i<255;i++);  // just in case wait  EnableInterrupts;}

 I call function at main initialization (on test purposes):
Code:
 ... StartTX(0x33);               // send "hello" message through ~rs232 while(SensorState == sTX);   // wait till finished sending  WriteToFlash(0x10);          // write 0x10 to 0xF800 address  COMMAND_CONSTANT = FLASH_MAS[0]; //take constant from 0xF800 (which is FLASH_MAS[0])

for(;;) {
...

 
Problem: when I monitor memory area F800 with Real Time Debugger, and go through my procedure with Single steps (F11) everything seems to work well. Flash page is first erased then new value at 0xF800 is written, which I can access by FLASH_MAS[0]. But if I try to start microntroller normaly (F5) it just hanges and stops. Stuck on this problem.

Saulius




0 Kudos
1,500 Views
PaoloSubiaco
Contributor I
Hi  Sauliuz.
Have you solved the flash problem with QD4 S08 device?
I'm interested about your routines, if available, because I've strange troubles flashing the device.
Thank you in advance! Paolo
0 Kudos
1,500 Views
sauliuz
Contributor I
Actually no. Still struggling with it. I realized that there is something wrong in my RAM code. Latest achievments:
Code:
extern char __SEG_START_ToCopyToStack[];extern char __SEG_SIZE_ToCopyToStack[];typedef char(* my_funtype)(char, char);#pragma CODE_SEG ToCopyToStack // sukasi steke viskas void MyStackFunction (char CMD, char data) {  // PROBABLY SOMETHING WRONG HERE asm {   lda data       ldhx #$F800    sta ,x       } FCMD = CMD; FSTAT_FCBEF = 1; asm { nop nop nop nop } FSTAT_FCBEF = 0; asm { nop nop nop nop }}#pragma CODE_SEG DEFAULTchar CopyToStackandExecute(char data) {  /* this function will copy the function 'MyStackFunction' to stack and execute it */  char res;   #define RAM_BUF_SIZE 40 /* enough to keep 'MyStackFunction' */  char ramBuf[RAM_BUF_SIZE];  char counter;  char *srcPtr;  if (sizeof(ramBuf) < (size_t)__SEG_SIZE_ToCopyToStack) {  return 0;  }  srcPtr = (char *)__SEG_START_ToCopyToStack;  for(counter=0; counter<(char)__SEG_SIZE_ToCopyToStack; counter++) {  ramBuf[counter] = *srcPtr++;}/* call it! *///for (i=0;i<255;i++);StartTX(0x81);while(SensorState==sTX);res = ((my_funtype)ramBuf)(0x40, data); /* I don't receive 0x82 (processor resets) hence here program hangsasm (nop);asm (nop);asm (nop);StartTX(0x82);while(SensorState==sTX);res = ((my_funtype)ramBuf)(0x20, data);asm (nop);asm (nop);asm (nop);StartTX(0x83);while(SensorState==sTX);//for (i=0;i<255;i++);return res;}

 Some advanced C and some assembley involved here. Since I am not expert in those two it might be that mistake is simple. I just don't see it.
Out of Real-Time debugger I can see that flash page is erased, but not written. Immediately after erase (or during it) processor hangs and watchdog resets it (that is my guess).

Saulius

0 Kudos
1,500 Views
PaoloSubiaco
Contributor I
Hi Sauliuz.
I don't know if your routines are right, but I've found a mistake on Freescale include files:
both mc9s08qd4.inc and mc9s08qd4.h says that mPageErase has the same value of mMassErase!!

mMassErase:         equ     65
;mPageErase:         equ     65   FREESCALE BUG IN INCLUDE FILES FOR QD4 device
mPageErase:         equ     64

What happen is that each time you try to erase a page of memory, you erase the entire device which stop working.
Below are the two files and an example of how to call the functions inside.

File flash.asm
Code:
; flash.asm file        XDEF flashPDIS        XDEF flashPEN        XDEF flashErasePage        XDEF flashWrite        INCLUDE "mc9s08qd4.inc"MY_ZEROPAGE:  SECTION  SHORTSTAT  DS.B 1  ;Flash STATUS interl useADRS  DS.W 1  ;Address to program.ADRR  DS.W 1  ;Data-to-program address.LEN   DS.B 1  ;Data-to-program lengthSTACK DS.W 1  ;Stack pointer backup.DEFAULT_ROM:  SECTIONflashErasePage:    sthx  ADRS ;Argument load.    lda   #(mFSTAT_FPVIOL+mFSTAT_FACCERR) ;mask    sta   FSTAT         ;abort any command and clear errors    mov    #EraseSubSize, STAT  ;length of flash erase routine to STAT    tsx    sthx  STACK    ldhx   #EraseSubEnd-1     ;point at last byte to move to stack    bra   DoOnStack       ;execute prog code from stack RAMEndErase:    rts;*******************************************************************************************flashWrite:    sthx  ADRR  ;Load Source Address from H:X    sta   LEN   ;Load Length from A    beq   EndWrite    lda 4,SP    ;Load Dest from SP.    sta ADRS+1    lda 3,SP    sta ADRS    lda   #(mFSTAT_FPVIOL+mFSTAT_FACCERR) ;mask    sta   FSTAT         ;abort any command and clear errors    mov    #ProgSubSize, STAT  ;length of flash prog routine to STAT    tsx    sthx  STACK    ldhx   #ProgSubEnd-1    ;point at last byte to move to stack    bra   DoOnStackEndWrite:    rts;    bra   DoOnStack       ;execute prog code from stack RAM    ; fallthru to this routine;*******************************************************************************************DoOnStack:    lda   ,x         ;read from flash    psha           ;move onto stack    aix   #-1       ;next byte to move    dbnz  STAT, DoOnStack    tsx           ;point to sub on stack    jmp   ,x         ;execute the sub on the stack (will return on it's own);*******************************************************************************************EraseSub:    ldhx   ADRS       ;get flash address    sta   0,x       ;write to flash; latch addr and data    lda   #mPageErase   ;get flash command    sta   FCMD       ;write the flash command    lda   #mFSTAT_FCBEF     ;mask to initiate command    sta   FSTAT       ;[pwpp] register command    nop           ;[p] want min 4~ from w cycle to rChkDoneErase:    lda   FSTAT       ;[prpp] so FCCF is valid    lsla           ;FCCF now in MSB    bpl   ChkDoneErase   ;loop if FCCF = 0    ldhx  STACK    txs    rts         ;refer status back to PCEraseSubEnd:EraseSubSize: equ (*-EraseSub);*******************************************************************************************ProgSub:    lda   FSTAT       ;check FCBEF    and   #mFSTAT_FCBEF     ;mask it    beq    ProgSub      ;loop if not empty    ldhx  ADRR    lda    0,x    aix    #1    sthx  ADRR    ldhx   ADRS       ;get flash address    sta   0,x       ;write to flash; latch addr and data    aix    #1    sthx  ADRS    lda   #mBurstProg   ;get flash command    sta   FCMD       ;write the flash command    lda   #mFSTAT_FCBEF     ;mask to initiate command    sta   FSTAT       ;[pwpp] register commandComCMD:               ;Missing from Original AN2295    lda   FSTAT    and   #mFSTAT_FCCF      ;Loop if FCCF not set.    beq   ComCMD    dbnz  LEN,ProgSub    ;all bytes in a row—ChkDoneProg:    lda   FSTAT       ;[prpp] so FCCF is valid    lsla           ;FCCF now in MSB    bpl   ChkDoneProg   ;loop if FCCF = 0    ldhx  STACK    txs    rtsProgSubEnd:ProgSubSize: equ (*-ProgSub);*******************************************************************************************flashPDIS:            lda FPROT            and #$7F            sta FPROT            rtsflashPEN:            lda FPROT            ora #$80            sta FPROT            sta NVPROT            rts


File flash.h
Code:
// flash.h/*Erase_Page and Write_Flash routines from AN2295*//*FlashInit routine from Motorola's Standard Software SGF Driver v3.0*/#define BUS_CLK 4000000 //Programed bus speed in Hz#if (BUS_CLK/200000)>64  #define FLASH_CLK 0x40|(BUS_CLK/(8*200000)-1)#else  #define FLASH_CLK BUS_CLK/200000#endif/*Erase_PageParameter: unsigned char *dest - Any address in the page to be erased*/void flashErasePage(uchar *far dest);/*Write_FlashParameter: unsigned char *dest - First address to be programed.           length - Number of data bytes to be written.           unsigned char *source - Pointer to the Address containing the first data byte.*/void flashWrite(uchar *far dest,uchar length,uchar *far source);/*Flash_InitParameter: unsigned char FBusDiv - Value to program to the FCDIV register.usage: Flash_Init(FLASH_CLK);*/// flashInit: be sure to have programmed the correct value of BUS_CLKvoid flashInit(void) {  // Clear FACCERR and FPVIOL  if (FSTAT&(FSTAT_FACCERR_MASK|FSTAT_FPVIOL_MASK)) {    FSTAT|=(FSTAT_FACCERR_MASK|FSTAT_FPVIOL_MASK);  }  do {    FCDIV=FLASH_CLK;  } while (FSTAT_FCBEF==0);}void flashPDIS(void);void flashPEN(void);#endif

Example how to call these routines:
Code:
// main.c file#include "flash.h"#define EEDATA_ADDR 0xfc00struct { /*something*/ } eedata; // data which should be stored                                  // into flash at address 0xfc00void main(void) {  // Initalize peripherals  flashInit();  // Initialize Flash divisor for in-application programming    // Write data into memory at address 0xfc00  DisableInterrupts;  flashErasePage((uchar *far)EEDATA_ADDR);  flashWrite((uchar *far)EEDATA_ADDR,sizeof(eedata),(uchar *far)&eedata);  EnableInterrupts;}

 

 





0 Kudos
1,500 Views
sauliuz
Contributor I
Hi Paolo,

I checked my mc9s08qd4.h and it seems that it is ok:
/* Flash commands */
#define mBlank                                5
#define mByteProg                          32
#define mBurstProg                        37
#define mMassErase                      65
#define mPageErase                      64

By the way, I checked your code and when calling to
  flashErasePage((uchar *far)EEDATA_ADDR);
  flashWrite((uchar *far)EEDATA_ADDR,sizeof(eedata),(uchar *far)&eedata);

I get lots of errors, like "illegal cast operation", "type mismatch" and so on...

Is this code working for you? And are you testing it on QD4?

0 Kudos
1,500 Views
sauliuz
Contributor I
Hurray!

here is the code that does work for me (mistake was so silly). Maybe someone will use it. Function in RAM is 37 bytes big (if you make it smaller please post it).

Code:
extern char __SEG_START_ToCopyToStack[];extern char __SEG_SIZE_ToCopyToStack[];typedef char(* my_funtype)(unsigned char, unsigned char);#pragma CODE_SEG ToCopyToStack // sukasi steke viskas void MyStackFunction (unsigned char CMD, unsigned char data) { asm {   lda data       ldhx #$F800 // my writing/erasing location   sta ,x       } FCMD = CMD; FSTAT = 0x80;//_FCBEF = 1; asm { nop nop nop nop } FSTAT = 0; while (!FSTAT_FCCF);}#pragma CODE_SEG DEFAULTchar CopyToStackandExecute(char data) {  /* this function will copy the function 'MyStackFunction' to stack and execute it */  char res; /* return value of 'MyStackFunction' */  #define RAM_BUF_SIZE 37 /* enough to keep 'MyStackFunction' */  char ramBuf[RAM_BUF_SIZE];  char counter;  char *srcPtr;  if (sizeof(ramBuf) < (size_t)__SEG_SIZE_ToCopyToStack) {  /* our buffer is too small to keep the function! */  return 0; /* failure */  }  srcPtr = (unsigned char *)__SEG_START_ToCopyToStack;  for(counter=0; counter<(unsigned char)__SEG_SIZE_ToCopyToStack; counter++) {  ramBuf[counter] = *srcPtr++;}/* call it! */res = ((my_funtype)ramBuf)(0x40, data);// eraseres = ((my_funtype)ramBuf)(0x20, data);// write byte datareturn res;}

 call it from main:
Code:
   FCDIV = 39;   FSTAT = 0;   CopyToStackandExecute(0x10);

Saulius
0 Kudos
1,500 Views
fat_wombat
Contributor III

Hello All:

 

when I try to compile the code of Sauliuz (on CodeWarrior6.2.), I get this message every time:

 

L4024: No information available for segment ToCopyToStack

 

Where's my mistake?

 

Just to mention, my microcontroller is a S9S08QD2.

 

 I have no problems in self-erasing and - writing to flash when I use the pre-made CodeBean IFsh from Proc Experts. My only problem is, that the functions in this bean are HUGE, eating almost 1kB of flash (another 0.5kb required for the page to be erased, so there are only 0.5kB for the code itself :smileysad:

 

Therefore I am looking for small and compact functions, allowing the µC to self-program...

 

Any hints?

0 Kudos
1,498 Views
bigmac
Specialist III

Hello, and welcome to the forum.

 

The likely reason for the linker error is that you have not defined the ToCopyToStack segment within the PRM file for the project.  This is the location of the code that will eventually be pushed to the stack, and executed from there. The size of this segment will need to closely match the size of the RAM based function, otherwise an excessive amount of the stack will be required if the segment is made too large.

 

Keep in mind that there is a total of 256 bytes only for the QD4 device.  To maximize the available stack it is better to explicitly allocate as many of your global variables as possible to zeropage RAM, otherwise the allocation will be to default RAM in page 1.

 

An alternative method to the direct use of the stack for the RAM based function is to use a fixed location in RAM for the function (usually at the bottom of the stack segment).  The size of the function using this method is only a few bytes.  The attached code demonstrates this method for the QG8 device, and should be readily adaptable to the QD4.  Maybe only the PRM file would differ.

 

Regards,

Mac

 

S08_Flash_A2.zip

 

Message Edited by t.dowe on 2009-09-02 03:16 PM
0 Kudos
1,500 Views
fat_wombat
Contributor III

Hello BigMac,

 

as always, you've just solved my problem ;-))) Thank you very much indeed for your help, my code is working now!

 

I've read all about this topic on the forum earlier and I have been trying to adapt your QC8 routines to my application for a while . And yes, it is working now, after your explanation concerning the allocation of variables on the stack :-) Below is my .prm file for the QD2 (the QD2 has only 128 bytes RAM). I am still not quite sure if I really need 30 bytes for the SSTACK, but it is working now well.

 

The biggest advantage to me is, that your routine saves me some 450 bytes FLASH, compared to the readily available code beans (IFsh) from Processor Experts (which I got from this forum, too).

 

This  is a huge improvement to me, since the QD has only 2kB FLASH, 0.5kB must be reserved for the page to be erased/written to and there's very little left for the actual code. Now I feel confident to finish my tasks even with this small µC.

 

(ups, I'm sorry, the code formatting tool here is not working for copy/paste snippets :smileywink:

 

/**************************************************************************************************

.prm file for S9S08QD2 with EEPROM emulation routines

**************************************************************************************************/

 

NAMES

END

SECTIONS
    SSTACK                   =  READ_WRITE   0x0080 TO 0x00B0;   // software stack is 30 bytes wide
    Z_RAM                    =  READ_WRITE   0x00B0 TO 0x00FF;

    FLASH_TO_RAM             =  READ_ONLY    0xFA00 TO 0xFA0F    RELOCATE_TO 0x0080; //here resides the eeprom emulation routine
    ROM                      =  READ_ONLY    0xFA0F TO 0xFFA9;
    PAGE_TO_BE_ERASED        =  READ_WRITE   0xF800 TO 0xF9FF;   //reserve the page to be erased before eeprom emulation
END

PLACEMENT
    DEFAULT_ROM, ROM_VAR, STRINGS       INTO  ROM;
   
    DEFAULT_RAM,                        // non-zero page variables
    _DATA_ZEROPAGE,                     // zero page variables
    MY_ZEROPAGE                         INTO  Z_RAM;
   
    FLASH_ROUTINE                        INTO  FLASH_TO_RAM;   //the eeprom emulation routine will be copied here
END

 


//INIT _EntryPoint                       // The entry point of the application. This function is generated into the CPU module.

STACKSIZE 0x0030                       // Size of the system stack. Value can be changed on the "Build options" tab

 

0 Kudos
1,500 Views
bigmac
Specialist III

Hello,

 

With the use of STACKSIZE parameter, the stack may not be placed within the SSTACK segment, but may occupy decimal 48 bytes (not 30 bytes) immediately above your global variables, within DEFAULT_RAM. This may be problematic with the very small amount of RAM available (all within page 0). Check the project map file for the actual placement of the variables and the stack. To ensure the stack is placed within SSTACK, the STACKTOP parameter might be used in lieu of STACKSIZE.

 

However, with the position of SSTACK immediately above the MCU registers, if the stack should overflow, this will over-write the register settings, a situation that may be very difficult to debug. If global variables were to be over-written instead, the debug situation may be a little easier. I would therefore suggest placing the stack above DEFAULT_RAM.

 

You might also make use of the ROM1 segment for the code that is transfered to RAM - a minor saving of flash.

 

The following PRM arrangement may be more suitable.

 

/* Linker parameter file for mc9s08qd2 */
NAMES END

SEGMENTS
Z_RAM = READ_WRITE 0x0080 TO 0x00BF;
SSTACK = READ_WRITE 0x00C0 TO 0x00FF;

ROM = READ_ONLY 0xFA00 TO 0xFFA9;
ROM1 = READ_ONLY 0xFFC0 TO 0xFFCF RELOCATE_TO 0x00C0;
END

PLACEMENT
DEFAULT_RAM,
_DATA_ZEROPAGE, MY_ZEROPAGE INTO Z_RAM;

_PRESTART, /* startup code */
STARTUP, /* startup data structures */
ROM_VAR, /* constant variables */
STRINGS, /* string literals */
VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */
DEFAULT_ROM,
COPY /* copy down information */
INTO ROM;
FLASH_ROUTINE INTO ROM1;
/* Pass option -OnB=b to compiler */
END

STACKTOP 0x00FF

 

The QD2 device is not really suited to C programming because of its very limited resources. Better coding efficiency would be achieved using assembler.

 

Regards,

Mac

Message Edited by bigmac on 2009-08-26 12:41 PM
0 Kudos
1,500 Views
CompilerGuru
NXP Employee
NXP Employee
Just wanted to comment on the use of STACKTOP/STACKSIZE and SSTACK as segment name.
 

The reason why the linker does not place the stack into the SSTACK segment with STACK_SIZE is the at all the linker predefined names are defined as section names (used before the INTO clause in th placement), not as segment names. Therefore the unused SSTACK segment entry is mostly ignored by the linker (may be used for memory overlap reporting).

 

Using a predefined linker section name as segment name confuses me, I would recommend not to do that and instead use another name like SSTACK_SEGMENT. When the SSTACK section is placed explicitely into the SSTAC_SEGMENT the STACKTOP entry should not be used anymore.

 

 

SEGMENTS
  SSTACK_SEGMENT = NO_INIT 0x00C0 TO 0x00FF;
  ...
END

PLACEMENT
  SSTACK INTO SSTACK_SEGMENT;
  ...

 

When placing SSTACK fully into a segment neither STACKTOP nor STACKSIZE are needed.

 

Daniel

 

BTW: The SSTACK_SEGMENT should be NO_INIT qualified. Using READ_WRITE means to initialize the objects allocated in there by the startup code, but the startup code is using the stack to do that.

The reason why it does not crash with READ_WRITE anyway is that the linker explicitely ignores READ_WRITE in the segment for the SSTACK section, using NO_INIT makes this explicit.

 

0 Kudos
1,500 Views
Eak
Contributor I

Hello.

 

I also need to write a few bytes to the flash using a QD4 microcontroller. I am using the recommeded solution posted from BigMac, and I was able to understand the code. I am also aware that I need to erase the flash before writing, etc. But for sure am I doing something wrong.

 

The problem I has was with the CopyInRAM function, from the file S08_Flash.c:

 

extern char __SEG_START_FLASH_ROUTINE[];
extern char __SEG_SIZE_FLASH_ROUTINE[];

(...)

#define Start_data   __SEG_START_FLASH_ROUTINE#define Size_data    __SEG_SIZE_FLASH_ROUTINEvoid CopyInRAM(void){   char *srcPtr, *dstPtr;   int count;   srcPtr = (char *)Start_data;   dstPtr = (char *)(void *)&Flash_Cmd;   for (count = 0; count < (int)Size_data; count++) {      *dstPtr = *srcPtr;      dstPtr++;      srcPtr++;   }}

 

The srcPtr and dstPtr seems unitialized and the copy is not working as expected. The Start_Data and Size_Data may be the cause of the probem, however I can see the FLASH_ROUTINE correctly defined in the "map" file.

 

I edited the PRM linker file with the advertizements from other posts, as recommended by FSL moderators.

 

 

NAMESENDSECTIONS    Z_RAM        =  READ_WRITE   0x0060 TO 0x00DF;    FAR_RAM      =  READ_WRITE   0x0100 TO 0x015F;    SSTACK_SEG   =  NO_INIT      0x00E0 TO 0x00FF;    ROM          =  READ_ONLY    0xF000 TO 0xFBFF;    FLASH_SECTOR =  READ_ONLY    0xFC00 TO 0xFDFF;    FLASH_FUNCT  =  READ_ONLY    0xFE00 TO 0xFE1F;ENDPLACEMENT    SSTACK                         INTO  SSTACK_SEG;    DEFAULT_RAM                    INTO  Z_RAM;    DEFAULT_ROM, ROM_VAR, STRINGS  INTO  ROM;    _DATA_ZEROPAGE, MY_ZEROPAGE    INTO  Z_RAM;    MY_FAR_DATA                    INTO  FAR_RAM;    FLASH_ROUTINE                  INTO  FLASH_FUNCT;ENDINIT _EntryPoint

 

 

Please, can someone help me to find the issue? I am still unable to write the flash using BigMac code.

 

 

0 Kudos
1,500 Views
Eak
Contributor I

I found one mistake, but code still do not work. In the PRM file we must use the RELOCATE so in the run-time the function can be executed from the correct address at RAM.

 

Unfortunately the code warrior seems to ignore the extern char statements and the copy to ram does not work. Ouch.

 

FLASH_FUNCT  =  READ_ONLY    0xFE00 TO 0xFE1F  RELOCATE_TO 0x00E0;
0 Kudos
1,500 Views
fat_wombat
Contributor III

Hello bigmac,

 

thank you for your advice!

 

One would rarely find such helping forum users like you!

 

The prm file you suggested is much more sofisticated than mine and after spending couple of days, thinking waht it actually does, I am really grateful that you have posted it. I wouldn't have be able to gather so much detail by myself.

 

Just one last question - do you think, that I need to specify the ROM page to be erased (by the ROM writing routine) like this:

 

 

PAGE_TO_BE_ERASED        =  READ_WRITE   0xF800 TO 0xF9FF;   //reserve the page to be erased

 

or is it an obsolete thing to do?

 

You are right about the assembler and QD2, but I don't really have the time for learning the FSL assembler and I guess after this short trip into the beautiful FSL world I shall return back to reallity spending my whole time with the NEC V850 creatures (being unfortunately much cheaper in industrial quantities than FSL).

0 Kudos
1,500 Views
bigmac
Specialist III

Hello,


fat.wombat wrote:

Just one last question - do you think, that I need to specify the ROM page to be erased (by the ROM writing routine) like this:

 

PAGE_TO_BE_ERASED        =  READ_WRITE   0xF800 TO 0xF9FF;   //reserve the page to be erased

 

or is it an obsolete thing to do?

 


Firstly, this segment should be READ_ONLY rather than READ_WRITE, since it is a page of flash memory.  Its inclusion will do no harm, and may be useful for documentation purposes.

 

Whether it is actually necessary would depend on the actions required by the linker in allocating variables to the segment.  If absolute addresses are handled by the code for both programming and reading the page, and no variables are used, the definition is probably not essential.  Of course, the ROM segment must always exclude this flash page.

 

Regards,

Mac

0 Kudos
1,500 Views
bigmac
Specialist III
Hello,
 
A further comment about the code presented by Paolo -
 
You may wish to consider re-sequencing the flash.asm code so that the sub-routines EraseSub and ProgSub
occur first, followed by the sub-routines flashErasePage and flashWrite.  This will likely prevent assembler
warnings because the labels EraseSubSize,  ProgSubSize, etc. are referenced before they have been defined.
 
Regards,
Mac
 
0 Kudos
1,500 Views
Ake
Contributor II
Hi,
As the 9S08 does not have any onboard ROM that can store useful routines, you will have to provide them yourself, and as the address/data bus connected to the Flash EPROM has to be quite during the erasure/programming, you need to put the code somewhere else.
The only place left to put it is in the RAM.
There are two ways to do it, either you set aside a buffer where you can store the erasure/programming code, or you can assign a buffer on the stack.
So to program eg a byte in the Flash EPROM, first copy the programming routine to the RAM or stack. Then call the routine with the address and data as parameters.
 
What I can see from your code, I am not too good at C, you have no moving around with your routines.
So that is what you will have to add.
 
Sorry, I have not written it for the 9S08QD4 yet.
 
Regards,
Ake
0 Kudos