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.

FIR16 aligned to 0x100



Hello dear friends!

I am using FIR16 filter from fixed point dsp library (fir.h, fir16.asm - V1.20.00.00).

In description FIXEDPT-SW-LIB-UG-V1.20.00.00 have note:

1. The delay buffer is assigned to a section, “firldb”, which should be aligned to 256 word boundary in the data memory (RAM) for the FIR16 module. The FIR16_Alt module does not require any alignment

2. The coefficients are placed in a section, “firfilt”, that can be placed anywhere in the data memory (RAM).

I create coefficients from MatLab, and generate .h file with this coefficients.

Do I understand correctly, if I use reorder function, I can not align the filter coefficient in the memory?

if((FIR_ORDER & 0x01) == 0){
revCoeff[FIR_ORDER_REV-1] = 0;
}
// Reorder the coefficients
for(i = 0; i < FIR_ORDER + 2; i = i + 2){
revCoeff[FIR_ORDER_REV-i-1] = coeff[i/2+FIR_ORDER_REV/2];
revCoeff[FIR_ORDER_REV-i-2] = coeff[i/2];
}

I only align the dbuffer in memory?

firldb align(0x100) > RAMM0,  PAGE = 0

Because in .cmd file from example (F28335_FIXPT_FIR_lnk.cmd) specified:

firldb align(0x100) > RAML1, PAGE = 0
firfilt : > RAML1, PAGE = 0
#if defined(RAM)
coefffilt align(0x100)> RAML2, PAGE = 0
#elif defined(FLASH)
coefffilt align(0x100)> FLASHA, PAGE = 0
#endif //RAM

  • Hi Potapov,

    You do not need to align the coefficient array in memory, only the delay line buffer. The delay line buffer is accessed using the circular addressing mode of the C28x, so it needs to be aligned to a 2N boundary (N being the size of the buffer). The coefficients array are accessed using the indirect addressing mode so it needn't be aligned.

    I will put in a ticket to remove alignment for coefffilt from the linker command file.
  • Vishal, thanks for your answer.

    I am using F2808.

    I have tried to use this library and have some problem:
    when I use inly RAM memory to debuging - it`s ok.
    but when I use FLASH and RAM memory to work - processor freezes (maybe going to ILLEGAL_ISR).

    This is my init. code...

    /* ===== FIR16 Filter initialization ===== */
    /* Define the Delay buffer for the N order filter and place it in "firldb" section */
    #pragma DATA_SECTION(dbuffer_DC, "firldb");
    int32_t			dbuffer_DC[(FIR_ORDER_DC+3)/2];
    const int16_t	COEFF_FIR16_DC[FIR_ORDER_DC+2];
    int16_t			revCoeff_DC[FIR_ORDER_DC+2];
    FIR16 			FIR16_DC;
    
    #pragma DATA_SECTION(dbuffer_AC, "firldb");
    int32_t			dbuffer_AC[(FIR_ORDER_AC+3)/2];
    const int16_t	COEFF_FIR16_AC[FIR_ORDER_AC+2];
    int16_t			revCoeff_AC[FIR_ORDER_AC+2];
    FIR16 			FIR16_AC;
    
    void InitFIR16 (void)
    {
    	Uint i;
    
    	// DC
    	FIR16 FIR16_DC=FIR16_DEFAULTS;
    
    	if((FIR_ORDER_DC & 0x01) == 0)
    	{
    		revCoeff_DC[FIR_ORDER_REV_DC-1] = 0;
    	}
    	// Reorder the coefficients
    	for(i = 0; i < FIR_ORDER_DC + 2; i = i + 2)
    	{
    		revCoeff_DC[FIR_ORDER_REV_DC-i-1] = COEFF_FIR16_DC[(i>>1)+(FIR_ORDER_REV_DC/2)];
    		revCoeff_DC[FIR_ORDER_REV_DC-i-2] = COEFF_FIR16_DC[(i>>1)];
    	}
    	// Initialize FIR16 object
    	FIR16_DC.order=FIR_ORDER_DC;
    	FIR16_DC.dbuffer_ptr=&dbuffer_DC[0];
    	FIR16_DC.coeff_ptr=(int32_t *)&revCoeff_DC[0];
    	FIR16_DC.init(&FIR16_DC);
    
    	// AC
    	FIR16 FIR16_AC=FIR16_DEFAULTS;
    
    	if((FIR_ORDER_AC & 0x01) == 0)
    	{
    		revCoeff_AC[FIR_ORDER_REV_AC-1] = 0;
    	}
    	// Reorder the coefficients
    	for(i = 0; i < FIR_ORDER_AC + 2; i = i + 2)
    	{
    		revCoeff_AC[FIR_ORDER_REV_AC-i-1] = COEFF_FIR16_AC[(i>>1)+(FIR_ORDER_REV_AC/2)];
    		revCoeff_AC[FIR_ORDER_REV_AC-i-2] = COEFF_FIR16_AC[(i>>1)];
    	}
    	// Initialize FIR16 object
    	FIR16_AC.order=FIR_ORDER_AC;
    	FIR16_AC.dbuffer_ptr=&dbuffer_AC[0];
    	FIR16_AC.coeff_ptr=(int32_t *)&revCoeff_AC[0];
    	FIR16_AC.init(&FIR16_AC);
    }
    // -------------------------------------- //// -------------------------------------- //
    
    

    And this is my linker .cmd...

    PAGE 0:    /* Program Memory */

    RAML0       : origin = 0x008000, length = 0x001900

    ...

    PAGE 1 :   /* Data Memory */

    RAML1       : origin = 0x009700, length = 0x000700

    ...

    ramfuncs : LOAD = FLASHD, 
    RUN = RAML0, 
    LOAD_START(_RamfuncsLoadStart),
    LOAD_END(_RamfuncsLoadEnd),
    RUN_START(_RamfuncsRunStart),
    PAGE = 0

    ...

    firldb align(0x100) > RAML1,     PAGE = 1

    ...

    I changed location PAGE 0/1 and RAM L/M 0/1 for firldb, it also  do not work.

    Also in fir16.asm I specified, that FIR16 calculation doing in RAM memory:

    .sect "ramfuncs"

    _FIR16_calc:

    ...

    but if I remove .sect "ramfuncs" it also do not work.

    What I do wrong?

  • When the execution goes to illegal_isr its because the c28x tries to execute some garbage opcode. Its trying to execute something that is not code. I would single step through each line of the C code and see where the execution goes to illegal_isr.

    The FIR code should be able to run out of Flash.
  • Dear Vishal.

    I debug this code in FLASH, and...

    ... I am going to calculation FIR16_DC, and...

    ...jumping to here. It is infinite loop (from 0x000724 to 0x00072C)

    What is this location? I never specify this addresses.

  • Hmm, so it looks like XAR7 contains the value 0x722 just before LCR (the call to the FIR routine). So two things to check for
    1. check the value of FIR16_DC.calc - it should hold the address of the FIR routine. go to that location in the disassembly window and make sure the FIR code is there
    2. MOVL XAR7, @0x2a is acutally loading the value at address (DP*0x40 + 0x2a) i.e. the data page pointer times 64 words plus the offset. This address should correspond to the location of the object element FIR16_DC.calc. So make sure the DP pointer is pointing to the correct page, ifs it not then this instruction is loading the value at the wrong address.

    If you find that point #2 is the problem then my follow up question would be - do you have DP load optimization turned on? if yes then does turning it off fix your problem? if it does then please let me know as this might be a compiler issue.
  • Vishal,

    Yes, you was right. I have the wrong address, because I specify FIR16 FIR16_DC=FIR16_DEFAULTS; in initialization function (look at the my second message). When I specify it in header - it all ok.

    But then I have a new problem =)

    Do I understand correctly: if I want to use several filters (I want to use 5 filters) I should specify separate memory aligned sections? Because if I specify several dbuffer in one section - the filters is working not correctly (the point address of dbuffer is damaged). When I specify separate aligned sections for each filter - it work ok.

    I am using Filter order = 50. I look at disassembly and on memory browser - filter is not used all 0x100 memory, but when I decrease this memory - I have a similar error (the point address of dbuffer is damaged).

  • Potapov Viacheslav said:
    if I want to use several filters (I want to use 5 filters) I should specify separate memory aligned sections? Because if I specify several dbuffer in one section - the filters is working not correctly (the point address of dbuffer is damaged). When I specify separate aligned sections for each filter - it work ok.

    Each filter must have its own object and delay line buffer (each aligned to a 0x100 boundary). 

    Potapov Viacheslav said:
    I am using Filter order = 50. I look at disassembly and on memory browser - filter is not used all 0x100 memory, but when I decrease this memory - I have a similar error (the point address of dbuffer is damaged)

    The fillter can be upto order 127 (128 taps). You can assign a dbuffer array of 51 dwords but you need to make sure the alignment is set to 0x100 word boundary. The reason for this is the code uses the c28x circular addressing mode will zeros out the lower 8 bits of the address pointer when it hits the programmed end address of the delay line buffer.