AnsweredAssumed Answered

Erasing a flash sector puts directs CPU into "unhandled interrupt code" section

Question asked by Abdullah Kahraman on Dec 22, 2014
Latest reply on Dec 25, 2014 by Abdullah Kahraman

Hello,

 

I have asked the question in this link before.

 

I am working with a MKE04Z8VFK4. Below code worked before, when there were no optimizations. However, now that my flash is about to be used, I have to optimize to fit all of my code in.

 

I am trying to erase a flash sector however, in the debugger, the CPU goes into the function for "unhandled interrupt code". Below is my code and optimization settings.

 

opt.png

 

 

#define PROG_WORD_SIZE   30
#define CAST_POINTER_ARITHMETIC   unsigned long



void __attribute__((optimize("O0"))) FLASH_erase(void)
{
    static void (*fnRAM_code)(volatile unsigned char *) = 0;
    static unsigned short fnFlashRoutine[] =
    { 0x2180, 0x7001, 0x7801, 0x0609, 0xd5fc, 0x4770 };

    if (!fnRAM_code)
    { // the first time this is used it will load the program to SRAM
        int i = 0;
        unsigned char *ptrThumb2 = (unsigned char *) fnFlashRoutine;
        static unsigned short usProgSpace[PROG_WORD_SIZE]; // make space for the routine on stack (this will have an even boundary)

        ptrThumb2 = (unsigned char *) (((CAST_POINTER_ARITHMETIC) ptrThumb2)
                & ~0x1); // thumb 2 address

        while (i < PROG_WORD_SIZE)
        { // copy program to SRAM
            usProgSpace[i++] = *(unsigned short *) ptrThumb2;
            ptrThumb2 += sizeof(unsigned short);
        }

        ptrThumb2 = (unsigned char *) usProgSpace;
        ptrThumb2++; // create a thumb 2 call
        fnRAM_code = (void (*)(volatile unsigned char *)) (ptrThumb2);
    }

    // Read FCLKDIV register
    if (FTMRE_FCLKDIV != 0x17)
    {
        // If FCLKDIV register not correct,
        // Wait for any flash command in progress.
        while ((FTMRE_FSTAT & FTMRE_FSTAT_CCIF_MASK) == 0x00)
            ;
        // Write FLCKDIV register
        FTMRE_FCLKDIV = FTMRE_FCLKDIV_FDIV(0x17);
    }
    else
    {
        // If FCLKDIV register is correct,
        // Wait for any flash command in progress.
        while ((FTMRE_FSTAT & FTMRE_FSTAT_CCIF_MASK) == 0x00)
            ;
    }
    // Access Error and or Protection Violation Check
    if (((FTMRE_FSTAT & FTMRE_FSTAT_ACCERR_MASK) == 1)
            || ((FTMRE_FSTAT & FTMRE_FSTAT_FPVIOL_MASK) == 1))
    {
        // Write: FSTAT register: Clear ACCERR and FPVIOL
        FTMRE_FSTAT = 0x30;
    }

    // Write to FCCOBIX register to identify specific command parameter to load
    FTMRE_FCCOBIX = 0x00;
    // Write to FCCOB register to load required command parameter
    FTMRE_FCCOBHI = 0x0A; // Erase flash block command code
    FTMRE_FCCOBLO = 0x00; // Global address [23:16] to identify flash block

    FTMRE_FCCOBIX = 0x01;
    FTMRE_FCCOBHI = 0x1F; // Global address [15:0] of longwords location to be programmed
    FTMRE_FCCOBLO = 0xE0; // Global address [1:0] must be 0x00

    // Write: FSTAT register to launch command
    //FTMRE_FSTAT = 0x80;
    fnRAM_code((volatile unsigned char *) FTMRE_BASE_PTR ); // execute the command from SRAM
}



 

Here are the last steps before crash. It crashes after it processes "blx r3".

 

asm.png

Outcomes