Reprogramming flash on MC9S08QE parts

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

Reprogramming flash on MC9S08QE parts

2,630 Views
FreeFromScales
Contributor I

I'm developing a bootloader and running into a problem reprogramming the flash on devices that use PPAGE.  I'm testing on a MC9S08QE128 part.  I can successfully program pages 4 through 7; however, attempts to program pages 0, 1, 2, or 3 result in "random" processor crashes.

 

Note that the same exact code is used to program pages 4-7 as 0-3. It appears that it is the programming cycle that causes the issue.  If I don't call the program routine, I can erase all of pages 0-3.  If in the program routine I force PPAGE to 4, the programming works (but, of course, at address 0x10000 instead of 0x00000).

 

The actual erase and program routines are executing in RAM.  I've verified that PPAGE is always programmed correctly (I divide the address by 16KB).

 

I tried specifically testing each 16KB block from 0 through 3 (rather than trying to program each in order).  This resulted in the same failures; the failures are hard to debug because the part typically resets and the debugger loses control.   

 

My bootloader starts at address 0xF400 and checks that it is not attempted to overwrite itself.

 

I'm not sure where else to look - thoughts and suggestions appreciated.

John

Labels (1)
0 Kudos
8 Replies

575 Views
bigmac
Specialist III

Hello John,

 

Do you disable interrupts prior to running the RAM based code?

Do you service the COP timer from within the RAM based code?  This is important during the erase process.

 

Regards,

Mac

 

0 Kudos

575 Views
tonyp
Senior Contributor II

First of all, I can verify that QE128 programming of any page works just fine.  I've been working with QE128's for many many months without any problems.  So, I'm confident you should look for the problem in your software.

 

Have you verified the actual addresses you attempt to program?  Pages 0-3 are already in the 64K range directly accessible by the CPU.   If you're always programming within the page window ($8000-$BFFF) which I assume is the case since you're changing the PPAGE even for pages below 4 then you should move (offset) all addresses to that range.   For Page 0 you have to add $8000, for Page 1 $4000, etc.  Do you correctly do this?  I suspect the error is in remapping your content to fall within the PPAGE window.  So, without correct remapping you may end up "writing" over various parts of the memory map (including registers) which may cause the "random" crashes you experience.  Just a guess.

Message Edited by tonyp on 2009-07-15 01:15 AM
0 Kudos

575 Views
FreeFromScales
Contributor I

I agree that it must be a software issue - wasn't trying to imply that the Si has issues! Plus I agree that it seems like I'm writing to the wrong address but I don't see the issue.

 

I'll double check the addressing again but this is what I do (I realize the code could be optimized...)

 

unsigned char program(unsigned long address, unsigned short buffer,
                      unsigned short length)
{
    unsigned long ptr = address;
    unsigned short pData = buffer;
   
    // Divide address by 0x4000 to get page number
    PPAGE = (byte)(ptr >> 14); 

    ptr &= (unsigned long)0x3FFF;    // Force 16KB limit
    ptr |= (unsigned long)0x8000;    // Force address to start at paged window address (0x8000)

    [ rest of code here ]

 

}

 

This same algorithm works for address 0x10000 through 0x1FFFF.  Interrupts are off.

 

So for address 0x00000, PPAGE would be 0 and ptr would be 0x8000.  That is the simplest case.  For 0x10000, PPAGE would be 4 and ptr would be 0x8000.  Again, works for 0x10000 and not 0 - my head hurts!

 

 

0 Kudos

575 Views
FreeFromScales
Contributor I

Solved it but don't fully understand why.  There is a timing issue that only shows up when programming the first 64KB and not the 2nd 64KB. 

 

I noticed that sometimes some of the flash was getting programmed at 0x0000. I added this silly delay loop and the problem went away ("result" is 8-bits, on the stack, and starts at 0).

 

    while (length--)
    {
        *ptr = *pData;
        FCMD = FL_CMD_BURST_PROGRAM;
        FSTAT_FCBEF = 1;
        while (--result);          // Silly delay added here

        ptr++;
        pData++;  

        while (!(FSTAT_FCCF));
    }

 

I suspect that FCDIV is not correctly and will look closer at it.

 

 

0 Kudos

575 Views
bigmac
Specialist III

Hello,

 

Does this code execute from RAM?  The Reference manual does seem to be quite ambiguous whether there is only a single flash array present, or whether addresses 0x10000 and beyond are within a second array (with the burst programming command not able to cross this boundary).

 

If you are actually attempting to execute the code from flash, and there happens to be two flash arrays, this might explain your problem.  The issue is when you attempt to program the array in which the code is based. 

 

Additionally, you do seem to be deviating from the burst programming algorithm specified in the reference manual, where the FCBEF flag is tested between bytes, and then a test of the FCCF flag is done for the final byte. In every case, you are waiting the additional period for the FCCF flag. Not sure whether this makes any difference, apart from a longer programming period.

 

Regards,

Mac

 

0 Kudos

575 Views
FreeFromScales
Contributor I

Thanks.  Yes the code is in RAM; I have verified this in the debugger.  When I tried to initially program from flash nothing worked.  So, moving code to RAM did make a difference. 

 

I'm using XMODEM to download the image; after every 128 bytes received, I jump into RAM and commit those bytes to flash and then return to executing in flash to get the next 128 bytes.  Perhaps the internal overhead of switching from RAM to flash to RAM is interferring with the flash programming algorithm.  That all seems logical except that it doesn't crash after 128 bytes;it crashes within the first couple bytes when everything is executing in RAM.  Don't know what all this means!

 

Concerning the departure in code: Originally I had the FCCF check outside but thought to move it inside the loop.  I was concerned that maybe I misunderstood the spec.  Concerning the crash issue, it doesn't make a difference where the FCCF check is.

 

FYI: I checked out FCDIV and setting different values didn't affect anything that I could observe. 

 

 

0 Kudos

575 Views
bigmac
Specialist III

Hello,

 

Traditionally, a small delay (4 cycles) was required between the commencement of the command  FSTAT_FCBEF = 1; and the testing of the FCCF flag.  The requirement of this delay does not seem to be mentioned within the QE128 reference manual.  However, the incrementing of the pointers should easily account for the delay.

 

Since you are waiting for the FCCF flag, there is no time saving benefit in using the burst programming command.  You might try programming as a sequence of single bytes, using the normal program command.  Then prior to looping for the next byte you would test the error flags, and exit the loop if either is set.  This way you can specifically identify whether an error is occurring, and the type of error.  In fact, the wait loop should also be exited if FCCF is set or either of the error flags is set.  This error checking seems to have been omitted within the QE128 data.

 

While the error checking will not solve your problem, it will give insight that an error is occurring, and would provide a more direct indication when you try other changes. 

 

Do you explicitly clear the error flags, just prior to commencing the previously posted code?

 

Regards,

Mac

 

0 Kudos

575 Views
FreeFromScales
Contributor I

I did have the 4 NOPs; they are mentioned in the 32KB part spec (or I read that somewhere).  But then I thought the same as you did - the pointer increments is more than enough time.

 

I can try the none-burst mode but I suspect it won't show anything. I've since learnt that if I single-step through the code, the burst flash works fine. That is, I don't think it will show anything since it doesn't appear to be any specific address that fails; its a matter of overrunning the flash microcode.

 

However, perhaps this problem (whatever it is) only exists while using burst mode - using single-byte mode may just work.  I'll consider this.

 

I do check the error codes just prior to entering into the "while  (length--)" loop.  I've never seen them set (I set a breakpoint and never hit it).

 

Thanks again for all your support!

 

0 Kudos