This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Flash mirror mode

Other Parts Discussed in Thread: TM4C1294KCPDT, TM4C1294NCPDT

Has anyone used flash mirror mode on the TM4C129? My understanding is that enabling it will translate reads of the lower half of flash into reads of the upper half, and possibly vice versa, but writes and erasures won't be affected. Instead, I'm seeing the entire lower half reading as erased and attempting to read the upper half results in a hard fault.

// TM4C1294KCPDT with 512 KB of flash
// Flash: 0x00000000 to 0x0007FFFF, upper half at 0x00040000
// This code runs from RAM

volatile uint32_t oldLower, oldUpper, oldFlashConf, newFlashConf, newLower, newUpper;
ROM_IntMasterDisable();

// Read first word of lower and upper halfs of flash
oldLower = HWREG(0x00000000); // 0x20000200
oldUpper = HWREG(0x00040000); // 0xCCCCCCCC

// Enable flash mirror mode
oldFlashConf = HWREG(FLASH_CONF); // 0x00000000
HWREGBITW(FLASH_CONF + 3, 6)= 1;
newFlashConf = HWREG(FLASH_CONF); // 0x40000000

// Read first word of lower half of flash
newLower = HWREG(0x00000000); // 0xFFFFFFFF (expected 0xCCCCCCCC)

// Try to read first word of upper half of flash
asm volatile(" BKPT #0");
newUpper = HWREG(0x00040000); // Hard fault (expected 0x20000200)

  • Hello BB_,

    I have forwarded this post to my colleague, who might have already tried this.

    Thanks,
    Sai
  • Hello BB_

    TM4C1294KCPDT has 512KB of Flash which means that the Mirror Mode is not available on this device. Only 1MB flash devices have the 4 banks which allow for mirror mode.

    Regards
    Amit
  • Thanks for your prompt reply.

    According to the datasheet it does have 4 banks: "The Flash memory is configured as four banks of 8 K x 128 bits (4 * 128 KB total) which are two-way interleaved."

    If mirror mode is indeed not supported on this part, then the datasheet and the FMM bit in the Flash Peripheral Properties (FLASHPP) register are incorrect.
  • Hello BB_,

    Are you executing the program out of SRAM?

    I would need to double check the implementation of Mirror Mode on the 512K parts.

    Regards
    Amit
  • Yes, I have that code in a ramfunc and confirmed that it actually is located in SRAM. It's at 0x20000200 in the minimal example I've attached, which is pretty much just the code above plus main, the vector table, and linker command file.)

    #include <stdint.h>
    #include <stdbool.h>
    #include "driverlib/rom.h"
    #include "driverlib/flash.h"
    #include "inc/hw_types.h"
    #include "inc/hw_flash.h"
    
    #pragma CODE_SECTION(test, ".TI.ramfunc")
    void test(void)
    {
        volatile uint32_t oldLower, oldUpper, oldFlashConf, newFlashConf, newLower, newUpper;
        ROM_IntMasterDisable();
    
        // Read first word of lower and upper halfs of flash
        oldLower = HWREG(0x00000000); // 0x20000200
        oldUpper = HWREG(0x00040000); // 0xCCCCCCCC
    
        // Enable flash mirror mode
        oldFlashConf = HWREG(FLASH_CONF); // 0x00000000
        HWREGBITW(FLASH_CONF + 3, 6)= 1;
        newFlashConf = HWREG(FLASH_CONF); // 0x40000000
    
        // Read first word of lower half of flash
        newLower = HWREG(0x00000000); // 0xFFFFFFFF
    
        // Try to read first word of upper half of flash
        asm volatile(" BKPT #0");
        newUpper = HWREG(0x00040000); // Hard fault
    }
    
    int main(void)
    {
        test();
    }
    

    //*****************************************************************************
    //
    // Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2011-2014 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Software License Agreement
    //
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    //
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // External declarations for the interrupt handlers used by the application.
    //
    //*****************************************************************************
    
    
    //*****************************************************************************
    //
    // The vector table.  Note that the proper constructs must be placed on this to
    // ensure that it ends up at physical address 0x0000.0000 or at the start of
    // the program if located at a start address other than 0.
    //
    //*****************************************************************************
    #pragma DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
        IntDefaultHandler,                      // GPIO Port A
        IntDefaultHandler,                      // GPIO Port B
        IntDefaultHandler,                      // GPIO Port C
        IntDefaultHandler,                      // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,                      // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
        IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
        IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        IntDefaultHandler,                      // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
        IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        IntDefaultHandler,                      // I2C6 Master and Slave
        IntDefaultHandler,                      // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        IntDefaultHandler,                      // I2C8 Master and Slave
        IntDefaultHandler,                      // I2C9 Master and Slave
        IntDefaultHandler,                      // GPIO Port T
        IntDefaultHandler,                      // Fan 1
        0,                                      // Reserved
    };
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor first starts execution
    // following a reset event.  Only the absolutely necessary set is performed,
    // after which the application supplied entry() routine is called.  Any fancy
    // actions (such as making decisions based on the reset cause register, and
    // resetting the bits in that register) are left solely in the hands of the
    // application.
    //
    //*****************************************************************************
    void
    ResetISR(void)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a NMI.  This
    // simply enters an infinite loop, preserving the system state for examination
    // by a debugger.
    //
    //*****************************************************************************
    static void
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives a fault
    // interrupt. This saves context and then enters an infinite loop, preserving
    // the system state for examination by a debugger.
    //
    //*****************************************************************************
    static void
    FaultISR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // This is the code that gets called when the processor receives an unexpected
    // interrupt.  This simply enters an infinite loop, preserving the system state
    // for examination by a debugger.
    //
    //*****************************************************************************
    static void
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    

    /******************************************************************************
     *
     * Default Linker Command file for the Texas Instruments TM4C1294KCPDT
     *
     * This is derived from revision 15071 of the TivaWare Library.
     *
     *****************************************************************************/
    
    --retain=*(.intvecs)
    
    MEMORY
    {
        FLASH_A(RX) : origin = 0x00000000, length = 0x00040000, fill=0xAAAAAAAA
        FLASH_B(R)  : origin = 0x00040000, length = 0x00040000, fill=0xCCCCCCCC
        SRAM (RWX)  : origin = 0x20000000, length = 0x00040000, fill=0xEEEEEEEE
    }
    
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* --heap_size=0                                                             */
    /* --stack_size=256                                                          */
    /* --library=rtsv7M4_T_le_eabi.lib                                           */
    
    /* Section allocation in memory */
    
    SECTIONS
    {
        .intvecs:   > 0x00000000
        .text   :   > FLASH_A
        .const  :   > FLASH_A
        .binit  :   > FLASH_A
        .cinit  :   > FLASH_A
        .pinit  :   > FLASH_A
        .init_array : > FLASH_A
        .TI.ramfunc : > FLASH_A, run=SRAM, table(BINIT)
    
        .vtable :   > 0x20000000
        .data   :   > SRAM
        .bss    :   > SRAM
        .sysmem :   > SRAM
        .stack  :   > SRAM
    }
    
    __STACK_TOP = __stack + 512;
    

  • Hello BB_

    I can confirm that it is a bug in the 512KB parts. The Mirror Mode cannot be used. The only WA would be to replace the part with a 1MB part. The only pin compatible and feature compatible part is TM4C1294NCPDT

    Regards
    Amit