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.

CCS/MSP432P401R: MSP432P401R: Flash memory

Part Number: MSP432P401R

Tool/software: Code Composer Studio

Dear all,

I need to register a "1Bit" 0 or 1 information in a non-volatile memory location.

Is there a memory location that can be written in Run Time and after a re-energization, the saved value is not "Reset"?

I tried to follow some examples the "Resource Explorer" but without success.

Any help is appreciated.

Best regards,

Will A.D.

  • Hi WIll,

    Is this the example you tried?

     

    /* --COPYRIGHT--,BSD
     * Copyright (c) 2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 Flash Controller - Programming Calibration Data
     *
     * Description: This example shows the use of the the Flash Controller APIs
     * to erase and program simulated calibration data to a specific area in memory.
     * Data in this example is programmed to user area of memory. The "fake"
     * calibration data is stored in a RAM array and set using the memset function,
     * however in a real application this buffer would be filled out using a serial
     * interface such as I2C.
     *
     *                MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST               |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *            |                  |
     *
     ******************************************************************************/
    /* DriverLib Includes */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    
    #define CALIBRATION_START 0x0003F000
    
    /* Statics */
    uint8_t simulatedCalibrationData[4096];
    
    int main(void)
    {
        /* Since this program has a huge buffer that simulates the calibration data,
         * halting the watch dog is done in the reset ISR to avoid a watchdog 
         * timeout during the zero 
         */
    
        /* Setting our MCLK to 48MHz for faster programming */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
        FlashCtl_setWaitState(FLASH_BANK0, 1);
        FlashCtl_setWaitState(FLASH_BANK1, 1);
        MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
    
        /* Initializing our buffer to a pattern of 0xA5 */
        memset(simulatedCalibrationData, 0xA5, 4096);
        
        //![FlashCtl Program]
        /* Unprotecting Info Bank 0, Sector 0  */
        MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
    
        /* Trying to erase the sector. Within this function, the API will
            automatically try to erase the maximum number of tries. If it fails,
             trap in an infinite loop */
        if(!MAP_FlashCtl_eraseSector(CALIBRATION_START))
            while(1);
    
        /* Trying to program the memory. Within this function, the API will 
            automatically try to program the maximum number of tries. If it fails,
            trap inside an infinite loop */
        if(!MAP_FlashCtl_programMemory(simulatedCalibrationData,
                (void*) CALIBRATION_START, 4096))
                    while(1);
    
        /* Setting the sector back to protected  */
        MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR31);
        //![FlashCtl Program]
    
        /* Going to LPM3 when not in use */
        while (1)
        {
            MAP_PCM_gotoLPM3();
        }
    }
    
    

  • Hello Dennis,

    Yes I was using this example and the "flash_mass_erase" for these tests.

    Between my posting and now, I was able to write to the flash memory (in a specific location), and I am triggering an LED proving that the saved value is correct.

    Thank you very much for your help.

    Below is the code I used, I know it could be much better, but I will not dedicate time to it now, it was just to acquire practical knowledge.

    /* DriverLib Includes */
    #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
    /* Standard Includes */
    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    //#define BANK1_S30 0x3E000
    #pragma RETAIN(memory)
    #pragma NOINIT(memory)
    #pragma LOCATION(memory, 0x3E000)
    volatile unsigned int memory[32];
    /* Statics */
    uint32_t freq[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
    int control = 0;
    int main(void)
    {
        /* Setting our MCLK to 48MHz for faster programming */
        MAP_PCM_setCoreVoltageLevel(PCM_VCORE1);
        FlashCtl_setWaitState(FLASH_BANK0, 1);
        FlashCtl_setWaitState(FLASH_BANK1, 1);
        MAP_CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_48);
        /* Enable DMA interrupt */
        MAP_DMA_assignInterrupt(INT_DMA_INT1, 1);
        MAP_DMA_clearInterruptFlag(DMA_CH1_EUSCIB0RX0 & 0x0F);
        /* Configuring P1.0 as output and P1.1 (switch) as input */
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
        MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
        /* Configuring P1.1 as an input and enabling interrupts */
        MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
        MAP_Interrupt_enableInterrupt(INT_PORT1);
        /* Enabling SRAM Bank Retention */
        MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);
        /* Enabling MASTER interrupts */
        MAP_Interrupt_enableMaster();
    
        while (1)
        {
            if(memory[0] == 1)
            {
                if(memory[1] == 2)
                {
                    if(memory[2] == 3)
                    {
                        if(memory[3] == 4)
                        {
                            if(memory[4] == 5)
                            {
                                if(memory[5] == 6)
                                {
                                    if(memory[6] == 7)
                                    {
                                        if(memory[7] == 8)
                                        {
                                            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, GPIO_PIN0);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, GPIO_PIN0);
            }
        }
    }
    
    /* GPIO ISR */
    void PORT1_IRQHandler(void)
    {
        uint32_t status;
        status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
        /* Toggling the output on the LED */
        if(status & GPIO_PIN1)
        {
            if (control == 0)
            {
                /* Initializing our buffer*/
                freq[0] = 0x01;
                freq[1] = 0x02;
                freq[2] = 0x03;
                freq[3] = 0x04;
                freq[4] = 0x05;
                freq[5] = 0x06;
                freq[6] = 0x07;
                freq[7] = 0x08;
                /* Unprotecting User Bank 1, Sectors 30 and 31  */
                MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1, FLASH_SECTOR30 | FLASH_SECTOR31);
                /* Trying a mass erase. Since we unprotected User Bank 1*/
                MAP_FlashCtl_performMassErase();
                /* Trying to program the filler data*/
                MAP_FlashCtl_programMemory (freq, (void*) memory, 32);
                /* Setting  sector 31 back to protected  */
                MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR30 | FLASH_SECTOR31);
                control = 1;
            }
            else
            {
                /* Initializing our buffer to a pattern of 0xA5 */
                memset(freq, 0x00, 32);
                /* Unprotecting User Bank 1, Sectors 30 and 31  */
                MAP_FlashCtl_unprotectSector(FLASH_MAIN_MEMORY_SPACE_BANK1, FLASH_SECTOR30 | FLASH_SECTOR31);
                /* Trying a mass erase. Since we unprotected User Bank 1*/
                MAP_FlashCtl_performMassErase();
                /* Trying to program the filler data*/
                MAP_FlashCtl_programMemory (freq, (void*) memory, 32);
                /* Setting  sector 31 back to protected  */
                MAP_FlashCtl_protectSector(FLASH_MAIN_MEMORY_SPACE_BANK1,FLASH_SECTOR30 | FLASH_SECTOR31);
                control = 0;
            }
        }
    }

    Anyway if anyone has anything to add, I would be grateful.

    Thanks.