AnsweredAssumed Answered

MPC5643L FlashErase IVOR1Trap using C90FL library

Question asked by Jonah Ryan-Davis on Aug 25, 2017
Latest reply on Sep 15, 2017 by Jonah Ryan-Davis

I'm using the C90FL C_array library that I downloaded from this page:

MPC564xL|32-bit MCU|Chassis-Safety|NXP 

The link for  "MPC56xx C90FL JDP Standard Software Driver for Single-Module Flash (REV 1.0.3)"

 

FlashInit, SetLock, and FlashWrite seem to work fine.

I'm having trouble using FlashErase.

I'm trying to erase all of the sections of main flash from 0x00030000 and after.

 

 

First I tried calling like this:

 

FlashErase(&ssdConfig, FALSE, 0xFFFFFFE0U, 0xFFFFFFFFU, 0xFFFFFFFFU, NULL_CALLBACK);

Which successfully erases flash, but leads to an IVOR1Trap on this address:

Where MCSR = 0x00090010 (MAV = 1, IF = 1, BUS_IRERR = 1)

Since it's a C array, I don't have very many ways to debug, so this is the last breakpoint I can set in the assembly:

What's very weird, is that if I set this breakpoint and step through, I eventually make it to this address:

If I then run the application, there is no exception, no issues.

 

However, if I set a breakpoint directly at the se_lwz instruction, there is an IVOR1Trap and the breakpoint is never hit.

 

 

So then I tried calling it like this:

void callback(void)
{
   
}
FlashErase(&ssdConfig, FALSE, 0xFFFFFFE0U, 0xFFFFFFFFU, 0xFFFFFFFFU, callback);

(with optimization off)

Which also successfully erases flash, but still leads to an IVOR1 trap on a different address:

With the same MCSR 0x00090010

 

This has similar but slightly different behavior. This is the last breakpoint I can set:

If I step through after this, it calls my callback

And makes it to the next instruction (which is the address causing the exception):

If I run from here, everything works fine!

 

However, if I set a breakpoint on the se_b instruction, there is an IVOR1Trap and the breakpoint is never hit.

ALSO, if I set a breakpoint from the callback itself, it's never hit, same issue.

 

 

Some more info

Below is a simplified version of my source

 

Here's what's being passed into the FlashErase call:

I can verify that the callback is being passed in correctly with the address 0x00020f94

From the map file:

00000f94 000002 00020f94 00001bd4 2 callback main.o

I also can verify the C_array is being called from the right address of 0x00022c08

From the map file:

000000a8 000114 00022c08 00003848 4 FlashErase_C FlashErase.o 

 

FlashErase.c

const unsigned long FlashErase_C[] = 
{
     
    0x182106D0, 0x00801AC1, 0x0908DD01, 0x013F014E, 0x015D016C,
    0x017B030A, 0xC08F52F8, 0x00001AE7, 0xC8142A07, 0xE6047320,
    0x0300E85D, 0x480977C6, 0x063F2A16, 0xE61E52DF, 0x00042C06,
    0xC57F18E7, 0xB0204076, 0x46D62C05, 0xC67F18E7, 0xB0204075,
    0x46C56D05, 0x4456016D, 0x2C07C76F, 0x18C6B020, 0x406746B7,
    0x017BC07F, 0xD4D7C06F, 0xD5B6E804, 0xC37F1AC7, 0x80E07FA7,
    0xDB782A07, 0xE60577C7, 0x063F2A07, 0xE60577C7, 0x063F2A17,
    0xE22CC078, 0x65D774E7, 0x049FD078, 0xC06867D6, 0xE6222C07,
    0x54F60000, 0xC06865F6, 0x74C6049F, 0xD068C078, 0x6757E207,
    0x181AACFF, 0xE6FB00BA, 0x0007E8F8, 0xC07870C7, 0x7FFE4667,
    0xD078C078, 0x6767E203, 0x73200500, 0xC07870C7, 0x7FFB4667,
    0xD078E803, 0x73200300, 0xC97F2A07, 0xE6070193, 0x1800D000,
    0x00001800, 0xD0000193, 0x1AC10808, 0xCD010090, 0x18218030,
    0x0004564C, 0x454D5043, 0x39304645, 0x313130FF
};
/* Total Data Size = 276 bytes */

 

main.c

#include "ssd_c90fl.h"

extern unsigned int FlashErase_C[];
pFLASHERASE pFlashErase = (pFLASHERASE)FlashErase_C;

UINT32 FlashErase ( PSSD_CONFIG pSSDConfig,
                BOOL shadowFlag,
                UINT32 lowEnabledBlocks,
                UINT32 midEnabledBlocks,
                UINT32 highEnabledBlocks,
                void (*CallBack)(void)
                )
{
    return pFlashErase(pSSDConfig,
                        shadowFlag,
                        lowEnabledBlocks,
                        midEnabledBlocks,
                        highEnabledBlocks,
                        CallBack
                        );
}


#define C90FL_REG_BASE                 0xC3F88000
#define MAIN_ARRAY_BASE                0x00000000
#define SHADOW_ROW_BASE                0x00F00000
#define SHADOW_ROW_SIZE                0x00004000

#define FLASH_ARRAY_SIZE               0x00100000 /* 1MB */
#define C90FL_PAGE_SIZE                0x10
#define COPY_TO_RAM                    FALSE
#define BUFFER_SIZE_BYTE               0x100

#define FLASH_BIUCR_ADDR               (C90FL_REG_BASE + 0x1C)
#define FLASH_BIUCR_BFEN               0x1
/* Password to unlock space array */
#define FLASH_LMLR_PASSWORD            0xA1A11111   /* Low/Mid address lock enabled password */
#define FLASH_HLR_PASSWORD             0xB2B22222   /* High address lock enabled password */
#define FLASH_SLMLR_PASSWORD           0xC3C33333   /* Secondary low and middle address lock enabled password */

SSD_CONFIG ssdConfig =
{
    C90FL_REG_BASE,         /* C90FL control register base */
    MAIN_ARRAY_BASE,        /* base of main array */
    0,                      /* size of main array */
    SHADOW_ROW_BASE,        /* base of shadow row */
    SHADOW_ROW_SIZE,        /* size of shadow row */
    0,                      /* block number in low address space */
    0,                      /* block number in middle address space */
    0,                      /* block number in high address space */
    C90FL_PAGE_SIZE,        /* page size */
    FALSE                   /* debug mode selection */
};

void callback(void)
{
   
}

FlashInit(&ssdConfig);
SetLock(&ssdConfig, LOCK_SHADOW_PRIMARY, 1, FLASH_LMLR_PASSWORD);
SetLock(&ssdConfig, LOCK_SHADOW_SECONDARY, 1, FLASH_SLMLR_PASSWORD);
SetLock(&ssdConfig, LOCK_LOW_PRIMARY, ~(0xFFFFFFE0U), FLASH_LMLR_PASSWORD);
SetLock(&ssdConfig, LOCK_LOW_SECONDARY, ~(0xFFFFFFE0U), FLASH_SLMLR_PASSWORD);
SetLock(&ssdConfig, LOCK_MID_PRIMARY, ~(0xFFFFFFFFU), FLASH_LMLR_PASSWORD);
SetLock(&ssdConfig, LOCK_MID_SECONDARY, ~(0xFFFFFFFFU), FLASH_SLMLR_PASSWORD);
SetLock(&ssdConfig, LOCK_HIGH, ~(0xFFFFFFFFU), FLASH_HLR_PASSWORD);
FlashErase(&ssdConfig, FALSE, 0xFFFFFFE0U, 0xFFFFFFFFU, 0xFFFFFFFFU, callback);
//FlashErase(&ssdConfig, FALSE, 0xFFFFFFE0U, 0xFFFFFFFFU, 0xFFFFFFFFU, NULL_CALLBACK);

Outcomes