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

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

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

Jump to solution
875 Views
abdullahkahrama
Contributor IV

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

Labels (1)
0 Kudos
1 Solution
484 Views
abdullahkahrama
Contributor IV

Hello Yong,

I have just solved my problem. Actually, yes, some of the problem was because of "FTRME_BASE_PTR" which is 0x40020000. However, it should have been 0x40020005. Also, I have deleted some sections of the arm_startup file to save some code space and it seems like I have messed something up. It is now working Smiley Happy

Seems like removing following from __arm_start.c keeps the flash routine from working:

//    zero-fill the .bss section

zero_fill_bss();

#if SUPPORT_ROM_TO_RAM

if (__S_romp != 0L)

    __copy_rom_sections_to_ram();

#endif

View solution in original post

0 Kudos
2 Replies
484 Views
Rick_Li
NXP Employee
NXP Employee

Hi Abdullah Kahraman,

the problem on your side should be caused by the statement "fnRAM_code((volatile unsigned char *) FTMRE_BASE_PTR );".

When calling a function by using the function pointer, the value of function pointer should be added by 1 before calling.

suppose the address of a function in RAM is 0x1000, then, when calling this function pointer, the function pointer should point to address 0x1001.


I hope it helps!

485 Views
abdullahkahrama
Contributor IV

Hello Yong,

I have just solved my problem. Actually, yes, some of the problem was because of "FTRME_BASE_PTR" which is 0x40020000. However, it should have been 0x40020005. Also, I have deleted some sections of the arm_startup file to save some code space and it seems like I have messed something up. It is now working Smiley Happy

Seems like removing following from __arm_start.c keeps the flash routine from working:

//    zero-fill the .bss section

zero_fill_bss();

#if SUPPORT_ROM_TO_RAM

if (__S_romp != 0L)

    __copy_rom_sections_to_ram();

#endif

0 Kudos