Author Topic: Flash Clock Setting correction  (Read 15882 times)

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Flash Clock Setting correction
« on: January 26, 2008, 09:16:56 PM »
Hi all M5223X users

Thanks to Leon Y's investigations it has been determined that the setting for the FLASH Clock (state-machine frequency) is not correct in the routine fnConfigFlash() in M5223X.c.

The calculation of the setting uses the oscillator clock where the correct clock value should be (system clock/2).
Since all M5223X projects use 25MHz clock (due to the Ethernet/PHY requirements) a system clock of (60/2MHz == 30MHz) results in a flash clock frequency slightly higher than the correct frequency range.

Before looking at the correction it may be interesting to look at why the error was made and what the implications may be.

The reason for the error is almost certainly due to the fact that the data sheet about the FLASH module is not that specific about this point. It states that the Internal Flash Bus Clock must be divided down to a frequency in the range of 150kHz and 200kHz. Possible Internal Flash Bus Clock frequencies are in the range of >150kHz to <102.4MHz. The Internal Flash Bus Clock was somehow interpreted as being the crystal frequency since example values seemed way off if the PLL output were the Internal Flash Bus Clock frequency. It has now been established that it it is the PLL output clock divided by 2 - this is specified in the data sheet in chapter 21.6 (EZPort) - "The flash controller module runs at the system clock frequency divided by 2". This detail doesn't appear in the FLASH module chapter itself, presumably the source of the misunderstanding.

It turns out that a system running at 60MHz will have a FLASH state-machine clock (FCLK) of 234'375Hz using the original code. This is 17.19% higher than the maximum specified frequency and this means that the timing when programming and deleting FLASH using IAP (in-application-programming) is also 17.19% less that specified. The good news is that there is no known case that this has caused a real problem so it seems as though there must be a bit more tolerance than specified - although it is possible that effects in slight under-programming could only be detected after ageing.
Systems which don't use the typical (maximum) system clock of 60MHz can be classified as follows:
Frequencies between 38.4MHz and 51.2MHz are in tolerance.
Frequencies less that 38.4MHz would cause over-programming which could result, in the worst case, in stress-enduced FLASH damage. [I haven't heard of anyone using the chip at such a slow system frequency - idle mode is also not an issue. However please see the note about the Boot Loader below!]

The following code corrects this and also automatically respects the optimum setting for any possible system speed as suggested by Freescale.

Code: [Select]
#if BUS_CLOCK > (12800000)                                               // divider required above this frequency (required clock is between 150kHz and 200kHz - incorrect value > 200kHz could reduce programming reliability. incorrect value < 150kHz could result in FLASH damage)
    #define FLASH_DIV   ((BUS_CLOCK/200000/8/2) - 1)
    #define FLASH_ROUND (((BUS_CLOCK + ((200000*8*2) - 1))/200000/8/2) - 1)
    #if FLASH_ROUND > FLASH_DIV
        #undef FLASH_DIV 
        #define FLASH_DIV FLASH_ROUND
    #endif
    CFMCLKD = (PRDIV8 | FLASH_DIV);                                      // set the FLASH state machine frequency as close to, but not higher than 200kHz
#else
    #define FLASH_DIV   ((BUS_CLOCK/200000/2) - 1)
    #define FLASH_ROUND (((BUS_CLOCK + ((200000*2) - 1))/200000/2) - 1)
    #if FLASH_ROUND > FLASH_DIV
        #undef FLASH_DIV 
        #define FLASH_DIV FLASH_ROUND
    #endif
    CFMCLKD = FLASH_DIV;                                                 // set the FLASH state machine frequency as close to, but not higher than 200kHz
#endif

Thsi code replaces the following in fnConfigFlash() in M5223X.c.
    // This works for oscillator clocks greater than 12.8Mhz
    CFMCLKD = (PRDIV8 | (unsigned char)((OSCCLK/200000/8)));


I recommend making this change also in M5223X_boot.c if you are using the boot loader. In this case the error is probably causing some stress on the FLASH due to overprogramming since the Boot Software doesn't set up the PLL to operate at 60MHz, instead it leaves it at the oscillator speed (25MHz) - this results in a FCLK of 97'656Hz with the original code. In this case the following 2 lines can be added before the new code above to ensure that the calculation is made with the bus equal to the oscillator value:
#undef  BUS_CLOCK
#define BUS_CLOCK  OSCCLK

I hope that this doesn't cause any inconvenience and that there are no reliability concequences found as a result.

Regards

Mark

« Last Edit: January 26, 2008, 11:52:19 PM by mark »

Offline eduardovra

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Flash Clock Setting correction
« Reply #1 on: January 29, 2008, 08:32:53 PM »
Hi Mark

I have a M52233DEMO board and I'm having some trouble using the fnSaveNewPars() function. Sometimes when I call it my program hangs but sometimes not.
The strange is that, in this situation, the core watchdog of the processor doesn't works, and I have to turn of the equipament to get it working again.
When I look at where the program hangs using the debugger, I get into the function fnFlashNow.

Code: [Select]
static int fnFlashNow(unsigned char ucCommand, unsigned long *ptrWord, unsigned long ulWord)
{
    static unsigned long ulProgSpace[PROG_SIZE/sizeof(unsigned long)];   // SRAM space on long boundary
   
    static void (*fnRAM_code)(void) = 0;

    if (!fnRAM_code) {                                                   // the first time this is used it will load the program to SRAM
    uMemcpy(ulProgSpace, (unsigned char*)fnFlashRoutine, PROG_SIZE);
        fnRAM_code = (void(*)(void))ulProgSpace;
    }


    uDisable_Interrupt();                                                // protect this region from interrupts

#ifdef _WINDOWS                                                          // command sequence - set the word to the address (in the sector)
    if (ucCommand != CMD_SECTOR_ERASE) {
      *ptrWord = ulWord;                                                 // value not important for deletes
    }
#else
    ptrWord += (CFM_FLASH/sizeof(unsigned long));                        // position the write into CFM FLASH (a copy of real FLASH for commands)
    *ptrWord = ulWord;                                                   // value not important for deletes
#endif
    CFMCMD = ucCommand;                                                  // The command

fnRAM_code();                                                       // execute from SRAM

    uEnable_Interrupt();                                                 // safe to accept interrupts again

    return (CFMUSTAT & (ACCERR | PVIOL));                                // if there was an error this will be non-zero
   
}

In this function, I've commented the fnRAM_code() line and then my program runs normaly.
I'm thinking if is it possible that the code get broken from RAM or Flash, or could be another problem ?

Thanks in advance !

Regards

Eduardo Vieira

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Flash Clock Setting correction
« Reply #2 on: January 29, 2008, 09:34:58 PM »
Hi Eduardo

I note that you originally had some difficulties programming the boot loader and the application with your demo board - this may be signalling a problem with the hardware (?).

Watchdog - if the routine were to hang for some reason (like forever loop) I would certainly expect the watchdog to fire as long as it is active (check that it is really active in your project (define CONFIGURE_WATCHDOG in app_hw_m5223x.h) and also that it is not being disabled by pulling IRQ4 low on reset (with active watchdog it is not possible to work properly with the debugger and so this technique allows debugging)). If the watchdog fires, the NMI _sw_wdog_timeout() should immediately command a hardware reset - since the code seems to be looping somewhere I don't expect that this function can somehow be blocked.

Assuming that the code is looping in or around the fnFlashNow() can you see where this function is being called from (is it looping there)? If there were problems with FLASH operations you may be able to see that the return value is not 0 (expected value in CFMUSTAT) - if this is non-zero can you see which bit is being set?

When you comment the function fnRAM_code() no FLASH accesses are made so this does suggest that there is something not operating correctly with the FLASH itself(?).

It may also be interesting to load the reference code to your board (http://www.utasker.com/software/software.html) to see whether you have also unreliability when modifying parameters. As far as I know there have never been any difficulties encountered with this code so it may help to determine whether it is hardware releated or due to the present software version (or compiler?).

I hope that you can find out why this may be.

Regards

Mark

Offline eduardovra

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Flash Clock Setting correction
« Reply #3 on: January 30, 2008, 07:10:38 PM »
Hi Mark

I have checked and it's everything ok with the watchdog. I only disable it when I use the debugger.
When the program hangs, I can see (using the debugger) the sequence of functions calls the cause the trouble, and it's always the same:

  • MyPersonalFuncion()
  • fnSaveNewPars(SAVE_NEW_PARAMETERS)
  • fnDelPar()
  • fnSetParameters()
  • fnEraseFlashSector()
  • fnFlashNow()

Another thing I was thinking about is that I'm using an old version of uTasker (it's date from one year ago, I think it's v1.3 SP1 or SP2). Could this be a problem ?
Another question: Is there any problem in using fnSaveNewPars function a several times consecutively? Because when I do this the program hangs quickly.

Regards

Eduardo Vieira



Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Flash Clock Setting correction
« Reply #4 on: January 30, 2008, 08:40:08 PM »
Hi Eduardo

There have not been any changes in the latest service packs which solve any known problems with the parameters - it is possible to continuously change the parameters (the only restriction is the fact that the FLASH has a limited write/erase life time but this is in the 100'000x range for all modern FLASH so shouldn't be an issue when testing).

The service packs are mainly useful for additional features (and a few bug fixes) so you can look through the release notes to see whether the latest service pack makes sense for your project or not.

I see that it is the delete which seems to hang. If the delete function is continuously called can you find out why ? Is it bebcause it is trying to delete a much larger range that it should? Did you manage to see what the FLASH controller status register was returning?

Regards

Mark

Offline eduardovra

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Flash Clock Setting correction
« Reply #5 on: January 31, 2008, 06:20:48 PM »
Hi Mark

I've seen the value that CFMUSTAT is returning after the program hangs: 0xC0.
My flash granularity is 2k, so the variable ptrSector in the function fnEraseFlashSector could be at maximum 127(??). Because sometimes the value of this variable is set to 255, could this be a problem ?
I was wondering if is there any way I can detect the fault condition and then stop the execution before fnRAM_code() and return an error to the upper level function.

Thank you very much for the help !

Regards

Eduardo


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Flash Clock Setting correction
« Reply #6 on: February 01, 2008, 03:34:45 PM »
Hi Eduardo

The status 0xc0 doesn't indicate an error with the FLASH programming access. It signifies that the command buffer is empty (nothing in operation) and an interrupt flag is set (indicatin last command complete).

ptrSector is a pointer to an address in the sector which is to be deleted and do I would expect values of only 0x18000 (for first parameter block - if not  moved) and 0x18800 (for second parameter block).

I still don't see what thsi error can be - you may like to add a check of valid FLASH range for this pointer to see whether you can trigger on a discrepency.

Regards

Mark






Offline eduardovra

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Flash Clock Setting correction
« Reply #7 on: February 11, 2008, 07:22:31 PM »
Hi Mark

Although I had not discovered the cause of the problem, I've solved it by turning on code optimizations (smaller code) on the CW compiler settings.
I think that there's something related to the size of the object code. With the optimizations enabled, the binary object code generated was about ~50 kb, and with it disabled, the binary generated was almost 85 kb.
However this should not cause any problems, since the size of my program is limited to 96 kb (uTasker default value).
But now, with this change, the program works normally.

Regards

Eduardo

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Flash Clock Setting correction
« Reply #8 on: February 12, 2008, 12:44:13 AM »
Eduardo

The uTasker project is set up to use highest optimisation for size. However it can be quite difficult to debug in CW with this setting and so it is sometimes reduced for debugging purposes - I presume that you did reduce it at one time for this reason(?)

In the routine fnFlashNow() there is a copy of the progamming routine which is put into SRAM for execution. The size of the RAM reserved for this is #define PROG_SIZE  80. This value was set from experience (but using optimisation). I wonder whether the code space is not adequate when not using optimisation? I would however expect a crash of the code were being overwritten or didn't fit into the space, but perhaps this coul dstill be a reason for strange behaviour!

If you reduce optimisation but increase the code space value to, say, 160, does it then operate correctly??

Regards

Mark

Offline eduardovra

  • Newbie
  • *
  • Posts: 11
    • View Profile
Re: Flash Clock Setting correction
« Reply #9 on: February 12, 2008, 01:28:56 PM »
Mark

Yes, I've disabled the optimizations for size for debugging purposes.
With respect to #define PROG_SIZE, I've set it to 160 value, but with no success.
Anothing thing I have noted is that sometimes, after calling the fnFlashNow(), the program calls mcf52235_init() function and then it crashes.

Regards

Eduardo