Skip to main content
Visitor II
October 6, 2008
Question

STR912FW44: Data abort after 32k flash boundary (ADR 0x8000 and higher)

  • October 6, 2008
  • 3 replies
  • 880 views
Posted on October 06, 2008 at 12:31

STR912FW44: Data abort after 32k flash boundary (ADR 0x8000 and higher)

    This topic has been closed for replies.

    3 replies

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:56

    Hi guys,

    I am writing a C low level startup sequence for the STR912FW44. After the routine has finished, the code then tries to read flash memory past a 32k ''boundary'' (address 0x8000 and higher), e.g. address 0xa444, and a data abort exception is thrown.

    The STR912FW44 has 512k flash mapped to bank 0 and 32k flash is mapped to bank 1. I am able to successfully program a 41k application into flash.

    Can anyone give me a hint of what I might be missing or doing wrong?

    Thanks!

    Pieter

    Here is my C initialisation code:

    void LowLevelInit(void)

    {

    /* ''Buffered'' is defined in ''91xconf.h'' */

    #ifdef Buffered

    __asm__ __volatile__(

    ''mrc p15, 0, r0, c1, c0, 0 \n\t'' /* Read CP15 c1, Control Register */

    ''orr r0, r0, #0x8 \n\t'' /* Enable BIU write buffer on AMBA AHB */

    ''mcr p15, 0, r0, c1, c0, 0 \n\t'' /* Write CP15 c1, Control Register */

    : : : ''r0'');

    #endif

    /*

    * Set bits 17 (Data TCM order bit) and bit 18 (Instruction TCM order bit)

    * in the Configuration Control Register.

    */

    __asm__ __volatile__(

    ''mov r0, #0x60000 \n\t''

    ''mcr p15, 1, r0, c15, c1, 0 \n\t''

    : : : ''r0'');

    /*

    * Map Flash Bank 0 at address 0x0 and Bank 1 at address 0x80000,

    * when the bank 0 is the boot bank, then enable the Bank 1.

    */

    FMI->BBADR = 0x00000000>>2; /* Set Boot bank base address to 0x00000000 */

    FMI->BBSR = 4; /* Set Boot bank size to 512KB */

    FMI->NBBADR = 0x00080000>>2; /* Set Non boot bank base address to 0x00080000 */

    FMI->NBBSR = 2; /* Set Non boot bank size to 32KB */

    FMI->CR = 0x18; /* Enable Flash Boot Bank and Non Boot Bank */

    /* Enable SRAM */

    SCU->SCR0 = 0x187 | (2 << 3); /* Set System configuration register to 96K SRAM size */

    }

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:56

    Hi pieter,

    Here my init function, which do exactely what you are looking for:

    I m using the Bank0 for startup-program and the bank1 for emulate EEPROM and keep some data. Both work correctly.

    I use the lib. from ST.

    You can take a look also on the other part of the code (commented #if 0), this code works, and don't use the ST lib.

    Regards.

    Damien

    FMI_BankRemapConfig (0x04,0x02,0x00000000, 0x00080000);

    //Arg 1 -> 0x4: Boot bank size 512KBytes.

    //Arg 2 -> 0x2: Non Boot bank size 32KBytes.

    //Arg 3 -> Mapping address boot bank

    //Arg 4 -> Mapping address NON boot bank

    /* Turn ON clock*/

    SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1);

    //never put FMI in reset here, or will crash

    SCU_AHBPeriphClockConfig(__FMI, ENABLE);

    SCU_AHBPeriphReset(__FMI, DISABLE);

    FMI_Config(FMI_READ_WAIT_STATE_2, FMI_WRITE_WAIT_STATE_0, FMI_PWD_ENABLE,FMI_LVD_ENABLE, FMI_FREQ_HIGH);

    #if 0

    //previous code, from the STR912 GCC port from Richard Berry, FreeRTOS corp.

    // For info only

    FMI->BBSR = 4;

    FMI->NBBSR = 2;

    FMI->BBADR = (0 >> 2);

    FMI->NBBADR = (0x80000 >> 2);

    FMI->CR |= 0x18;

    FMI->CR &= FMI_WRITE_WAIT_STATE_0;

    *(vu16 *)FMI_BANK_1 = 0x60;

    /* need 3 read wait states if operating @ 96Mhz */

    *(vu16 *)(FMI_BANK_1 | FMI_READ_WAIT_STATE_3 | FMI_PWD_ENABLE | FMI_LVD_ENABLE | FMI_FREQ_HIGH) = 0x03;

    #endif

    Visitor II
    May 17, 2011
    Posted on May 17, 2011 at 09:56

    Hi Damien,

    Thanks for the help!

    It turns out that if DEBUG is defined in ''91xconf.h'' (or in my Makefile), the peripheral registers are declared as ''extern'' in ''91x_map.h'' and initialised to correct values in the function ''debug()'' in ''91x_lib.c''.

    I did not call ''debug()'' first and my lowlevel C initialisation function accessed random values in stead of correct registers.

    Regards,

    Pieter