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.

MSP430FR6989: #10099-D program will not fit into available memory

Part Number: MSP430FR6989

I am trying to flash the transform_ex1_fft_fixed_q15 example from the DSP Library for MSP430 (Library). When I try to flash it, I get the error mentioned in the title. Looking at other threads (Related question), I tried to change both my stack and heap sizes so that the main file would build and I could look at the map file. However, trying stack and heap sizes anywhere from 5 to 1000 (originally 160), did not work. I've tried looking at the memory allocation tab. Failed allocation states "160 out of -1 bytes used (-16000%)", RAM states "2,408 out of 2,408 bytes used (100%)", FRAM states  "110 out of 48,000 bytes used (0%)", and FRAM2 states "4,338 out of 81,912 bytes used (5%)". Available memory ranges are:

RAM    size: 0x800    unused: 0x0    max hole: 0x0

I have also tried using a second MSP430FR6989, but I get the same error. Does anyone know how else I can see what is causing this error, or if my MCU simply doesn't have enough FRAM (128kB)?

  • Hi Samuel,

    Thanks for providing the memory allocation results. If you look at the linker cmd file below, you can see that the .stack section is placed in RAM. Based on the memory allocation results, the RAM section is completely filled which is why the .stack section is not able to fit in memory.

    You can also verify that by looking in the map file in the project Debug folder. As you can see here, the .bss section (for uninitialized global and static variables, specifically variables temp, cycleCount, input, and window) starts at RAM (location 0x1c00) and takes up all 2KB of RAM.

    To resolve this issue, you can move the temp, window, and input variables to FRAM since they take up a lot of space. I've attached a code example below where I used #pragma PERSISTENT to place those variables in .TI.persistent (linker cmd file places in FRAM). Here's a helpful app note that talks about the best practices for working with FRAM, see section 3 Variables.

    /* --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--*/
    //******************************************************************************
    // Real FFT with fixed scaling.
    //
    //! \example transform_ex1_fft_fixed_q15.c
    //! This example demonstrates how to use the msp_fft_fixed_q15 API to transform
    //! a real input data array to the frequency domain using the Q15 fast fourier
    //! transform (FFT) with fixed scaling. The real FFT function is identical to
    //! running a complex FFT with imaginary components set to zero. The result of
    //! the real FFT is a complex vector with half the samples but identical byte
    //! length.
    //!
    // Brent Peterson, Jeremy Friesenhahn
    // Texas Instruments Inc.
    // April 2016
    //******************************************************************************
    #include "msp430.h"
    
    #include <math.h>
    #include <stdint.h>
    #include <stdbool.h>
    
    #include "DSPLib.h"
    
    /* Input signal parameters */
    #define FS                  8192
    #define SAMPLES             256
    #define SIGNAL_FREQUENCY1   200
    #define SIGNAL_AMPLITUDE1   0.6
    #define SIGNAL_FREQUENCY2   2100
    #define SIGNAL_AMPLITUDE2   0.15
    
    /* Hamming window parameters */
    #define HAMMING_ALPHA       0.53836
    #define HAMMING_BETA        0.46164
    
    /* Constants */
    #define PI                  3.1415926536
    
    /* Generated Hamming window function */
    DSPLIB_DATA(window,4)
    /* Declare as persistent to move variable to FRAM */
    #pragma PERSISTENT(window)
    _q15 window[SAMPLES] = {0};
    
    /* Input signal and FFT result */
    DSPLIB_DATA(input,MSP_ALIGN_FFT_Q15(SAMPLES))
    /* Declare as persistent to move variable to FRAM */
    #pragma PERSISTENT(input)
    _q15 input[SAMPLES] = {0};
    
    /* Temporary data array for processing */
    DSPLIB_DATA(temp,4)
    /* Declare as persistent to move variable to FRAM */
    #pragma PERSISTENT(temp)
    _q15 temp[3*SAMPLES/2] = {0};
    
    /* Benchmark cycle counts */
    volatile uint32_t cycleCount;
    
    /* Function prototypes */
    extern void initSignal(void);
    extern void initHamming(void);
    
    void main(void)
    {
        msp_status status;
        msp_mpy_q15_params mpyParams;
        msp_fft_q15_params fftParams;
    
        /* Disable WDT */
        WDTCTL = WDTPW + WDTHOLD;
    
    #ifdef __MSP430_HAS_PMM__
        /* Disable GPIO power-on default high-impedance mode for FRAM devices */
        PM5CTL0 &= ~LOCKLPM5;
    #endif
        
        /* Initialize input signal and Hamming window */
        initSignal();
        initHamming();
    
        /* Multiply input signal by generated Hamming window */
        mpyParams.length = SAMPLES;
        status = msp_mpy_q15(&mpyParams, input, window, input);
        msp_checkStatus(status);
    
        /* Initialize the fft parameter structure. */
        fftParams.length = SAMPLES;
        fftParams.bitReverse = true;
        fftParams.twiddleTable = MAP_msp_cmplx_twiddle_table_2048_q15;
    
        /* Perform real FFT with fixed scaling */
        msp_benchmarkStart(MSP_BENCHMARK_BASE, 16);
        status = MAP_msp_fft_fixed_q15(&fftParams, input);
        cycleCount = msp_benchmarkStop(MSP_BENCHMARK_BASE);
        msp_checkStatus(status);
        
        /* End of program. */
        __no_operation();
    }
    
    void initSignal(void)
    {
        msp_status status;
        msp_add_q15_params addParams;
        msp_sinusoid_q15_params sinParams;
    
        /* Generate Q15 input signal 1 */
        sinParams.length = SAMPLES;
        sinParams.amplitude = _Q15(SIGNAL_AMPLITUDE1);
        sinParams.cosOmega = _Q15(cosf(2*PI*SIGNAL_FREQUENCY1/FS));
        sinParams.sinOmega = _Q15(sinf(2*PI*SIGNAL_FREQUENCY1/FS));
        status = msp_sinusoid_q15(&sinParams, input);
        msp_checkStatus(status);
    
        /* Generate Q15 input signal 2 to temporary array */
        sinParams.length = SAMPLES;
        sinParams.amplitude = _Q15(SIGNAL_AMPLITUDE2);
        sinParams.cosOmega = _Q15(cosf(2*PI*SIGNAL_FREQUENCY2/FS));
        sinParams.sinOmega = _Q15(sinf(2*PI*SIGNAL_FREQUENCY2/FS));
        status = msp_sinusoid_q15(&sinParams, temp);
        msp_checkStatus(status);
    
        /* Add input signals */
        addParams.length = SAMPLES;
        status = msp_add_q15(&addParams, input, temp, input);
        msp_checkStatus(status);
    }
    
    void initHamming(void)
    {
        msp_status status;
        msp_sub_q15_params subParams;
        msp_copy_q15_params copyParams;
        msp_fill_q15_params fillParams;
        msp_sinusoid_q15_params sinParams;
    
        /* Generate sinusoid for cosine function */
        sinParams.length = 3*SAMPLES/2;
        sinParams.amplitude = _Q15(HAMMING_BETA);
        sinParams.cosOmega = _Q15(cosf(2*PI/(SAMPLES-1)));
        sinParams.sinOmega = _Q15(sinf(2*PI/(SAMPLES-1)));
        status = msp_sinusoid_q15(&sinParams, temp);
        msp_checkStatus(status);
    
        /* Shift sinusoid by pi/2 to create cosine function */
        copyParams.length = SAMPLES;
        status = msp_copy_q15(&copyParams, &temp[SAMPLES/4], &temp[0]);
        msp_checkStatus(status);
    
        /* Fill temporary array with alpha constant */
        fillParams.length = SAMPLES;
        fillParams.value = _Q15(HAMMING_ALPHA);
        status = msp_fill_q15(&fillParams, window);
        msp_checkStatus(status);
    
        /* Subtract generated cosine from alpha constant to generate final window */
        subParams.length = SAMPLES;
        status = msp_sub_q15(&subParams, window, temp, window);
        msp_checkStatus(status);
    }
    

    Hope this helps!

    Regards,

    Urica Wang

  • This is the best answer I've ever gotten for a programming question. Thank you so much, this both fixed my problem and helped me understand what I was doing wrong.

**Attention** This is a public forum