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.

MSP430FR5994: Odd LEA RAM issue.

Part Number: MSP430FR5994

Hi,

 I'm trying to use the LEA on an MSP430FR5994 to compute a FIR filter with a reasonably large number of coefficients.

I can't seem to find any documentation on quite what the 'tapLength' member of fir_params is supposed to do, but following the filter_ex1_fir_q15.c example I have:

#define FIR_LENGTH (128)

DSPLIB_DATA(FILTER_COEFFS_AUD,4)

_q15 FILTER_COEFFS_AUD[FIR_LENGTH] = { .. }

DSPLIB_DATA(result,4)

_q15 result[FIR_LENGTH+48];

DSPLIB_DATA(fir_data_buffer,MSP_ALIGN_FOR_Q15(FIR_LENGTH))

_q15 fir_data_buffer[2*FIR_LENGTH];

static int qq = 0;

msp_fir_q15_params fir_params;

fir_params.length = FIR_LENGTH;

fir_params.tapLength = 128;

fir_params.coeffs = FILTER_COEFFS_AUD;

fir_params.enableCircularBuffer = true;

memset( result, qq, 20 * sizeof(_q15));

status = msp_fir_q15( &fir_params, &fir_data_buffer[2*FIR_LENGTH - 128], &result[24] )

if (memcmp( result, qq, 20 * sizeof(_q15))  {

 /* Complain */

}

++qq;

 Now, status is always OK.

 And by and large this code works. But every so often, it will trigger the memcmp() and complain.

 When I look closer, the CPU reads 0x80 from one of the guard bytes rather than the expected value (qq).

 The debugger reads qq.

 So, something weird is happening to memory accesses just after msp_fir_q15().

The question is - what have I done wrong? And if I have done something wrong, why does it only "sometimes" happen?

It looks kind of like the situation described in TRM S10.2.2 , but I don't believe this chip has a DTC.

I've tried disabling interrupts around the whole block, in case it is an interrupt corrupting memory behind my back and this has no effect.

I've tried replacing the LEA call with some token manual code that does the appropriate number of multiplications, and that seems to work fine.

I am running at 16MHz , but running from either the DCO or the HF XTAL does the same thing and I was under the impression that a 16MHz MCLK was  legal in this situation?

My MSP430FR5994 advertises itself as a Rev C.

A __delay_cycles(1000) after the msp_fir_q15() call seems to make it happen more quickly (but that could be statistical noise).

Any help gratefully accepted .. 

(for the curious, my stack is immedately below result - and obviously this causes apparent stack corruption and, seemingly, a branch through zero if it is affected)

 

  • Hi Richard,

    Can you please provide a complete example C program including the coefficients and main you're using as well as the version of CCS/IAR and DSPlib you're using? A couple of things just looking through the code you provided:

    1. You use a different macro to align the data, your code calls MSP_ALIGN_FOR_Q15 when it should use MSP_ALIGN_FIR_Q15 which is provided by DSPLib and calculates the correct alignment
    2. Your memcmp syntax is incorrect, the first two arguments should be pointers but you're passing qq (an int) as the second pointer which will produce undefined results (qq is initialized to 0 so the first memcmp call will actually compare the results array with whatever is stored at address 0)
    3. The 'tapLength' parameter is the length of coefficients and is different from the length of the FIR
    4. Since you are using the circular buffer feature I'd recommend taking a look at the section in the DSPLib users guide (link)

    Regards,

    Brent Peterson

  • Hi Brent,

     Many thanks for the quick reply and sorry for the somewhat shoddy example code!

     

     1. Apologies - typo when copying. 

     2. You're quite right - again, sorry. Trying to summarise an explicit compare loop whilst short of time and failing massively; apologies.

     3. tapLength - yeah. The documentation says that, but I'm not sure what it means - presumably this is a way to specify only the non-zero coefficients in the filter, but I'm not all that clear on how this works - is it just that the first tapLength taps are specified and the rest are understood to be 0 ? Or something more complex? Any chance you could point me to the doc I've clearly missed? (in this particular case, the coefficients are to be set later by my client so I can't guarantee that any of them will be 0, though the filter will likely be symmetric)

     4. Thanks! Have done so - turns out it doesn't matter if you turn circular buffers off, so whilst I think I understand how to do this, it doesn't seem to be relevant.

    I think a colleague of mine has spotted the issue - though I will check - seems that in DSPLib 1.20.03.01 with MSP_DISABLE_LPM0 off, msp_lea_invokeCommand() issues __bis_SR_register(GIE+LPM0_bits) and then assumes that when it returns, the LEA is done. If another interrupt occurs before the LEA is done, our RTOS comes out of LPM0 (since it wants to run now), and we wake early and run (at least) msp_lea_freeMemory(), which seems to confuse the LEA - we could theoretically re-enter the LEA operation, which I am guessing would be bad.

    Changing this to:

     while (!msp_lea_cfg) { __bis_SR_register(GIE+LPM0_bits); } 

    seems to solve the problem for me. We'll investigate and I'll attempt to produce a canned test case once I've made sufficient progress to have a bit of time to do so, and update this post if we find this isn't the case for the benefit of the search engine.

    Sorry to have bothered and thanks again for the rapid response!

**Attention** This is a public forum