AnsweredAssumed Answered

Need help with ADSP-21469 decimation using FIR accelerator

Question asked by more10 on Jul 9, 2013
Latest reply on Jul 16, 2013 by more10

I have been struggling for a couple of days to get the FIR accelerator working, and have run out of ideas.

 

I have modified the "21469 AD1939 C Block-Based Talkthru 48 or 96 kHz" example.

 

Sample rate is 96 kHz. Block size is 512.

 

I have set up the FIR for 2 channels (left and right). 256 taps, decimation factor 4 and output buffer size is 128. The input circular buffers are 767 (256 - 1 + 4 * 128 ) bytes. Coefficients are stored backwards. Input buffer and output buffer are stored with the oldest value first.

 

On first iteration I start writing input buffer at position 255. I use the circindex function to update the index into the input buffer.

 

The intrerrupt is set up to interrupt when all channels are done, and this seems to work. After first iteration the FIR accelerator is started by toggling pFIRCTL1, and this seems to work also.

 

The FIR output (each value is written 4 times) is written to headphone channels. I hear only a 187 hz (96kHz/512) rumble.

 

Does the __builtin_conv_RtoF function generate the correct float format for the FIR?

 

Mårten

 

#define TAPS 256
#define WINDOW 128
#define DECIMATION 4
extern float FIR_CF_buff[TAPS];
extern float FIR_IP_buff1[TAPS - 1 + WINDOW * DECIMATION];
extern float FIR_IP_buff2[TAPS - 1 + WINDOW * DECIMATION];
extern float FIR_OP_buff1[WINDOW];
extern float FIR_OP_buff2[WINDOW];

 

int FIR_TCB_CH2[13]={
                                        0,                                                                                 // CP                     = Chain pointer register
                                        TAPS,                                                                      // CC/CL           = Coefficient buffer length register
                                        1,                                                                                // CM                      = Coefficient modifier register
                                        (int)FIR_CF_buff,                               // CI              = Cofficient index register
                                        (int)FIR_OP_buff2,                                        // OB              = Ouput data base register
                                        WINDOW,                                                                      // OL/OC            = Output buffer length register
                                        1,                                                                                // OM                     = Output modifier register
                                        (int)FIR_OP_buff2,                                        // OI                      = Output data index register
                                        (int)FIR_IP_buff2,                                        // IB                     = Input data base register
                                        TAPS - 1 + WINDOW * DECIMATION,          // IL/IC             = Input buffer length register
                                        1,                                                                                // IM                     = Input buffer modifier register
                                        (int)FIR_IP_buff2,                                        // II                     = Input data index register
                                        TAPS - 1|(WINDOW<<14)|FIR_RATIO4|FIR_SRCEN                              // FIRCTL2
                              };

int FIR_TCB_CH1[13]={
                                        (int)FIR_TCB_CH2+12,                               // CP                     = Chain pointer register
                                        TAPS,                                                                      // CC/CL           = Coefficient buffer length register
                                        1,                                                                                // CM                      = Coefficient modifier register
                                        (int)FIR_CF_buff,                               // CI              = Cofficient index register
                                        (int)FIR_OP_buff1,                                         // CI              = Cofficient index register
                                        WINDOW,                                                                      // OL/OC            = Output buffer length register
                                        1,                                                                                // OM                     = Output modifier register
                                        (int)FIR_OP_buff1,                                        // OI                      = Output data index register
                                        (int)FIR_IP_buff1,                                        // IB                     = Input data base register
                                        TAPS - 1 + WINDOW * DECIMATION,          // IL/IC             = Input buffer length register
                                        1,                                                                                // IM                     = Input buffer modifier register
                                        (int)FIR_IP_buff1,                                        // II                     = Input data index register
                                        TAPS - 1
                                        |(WINDOW<<14)
                                        |FIR_RATIO4
                                        |FIR_SRCEN                              // FIRCTL2
                              };

void Init_FIR()
{
          int temp;
          FIR_TCB_CH2[0]=(int)FIR_TCB_CH1+12;
          //Mapping the FIR DMA interrupt
          temp=*pPICR0;
          temp&=~(P0I0|P0I1|P0I2|P0I3|P0I4);
          temp|=P0I0|P0I1|P0I3|P0I4;
          *pPICR0=temp;
          //Selecting the FIR Accelerator
          temp=*pPMCTL1;
          temp&=~(BIT_17|BIT_18);
          temp|=FIRACCSEL;
          *pPMCTL1=temp;
          //PMCTL1 effect latency
                    asm("nop;nop;nop;nop;");
                    //Initializing the chain pointer register
          *pCPFIR=(int)FIR_TCB_CH1+12-0x80000;
          //Now Enabling the FIR Accelerator
          *pFIRCTL1=FIR_EN|FIR_DMAEN|FIR_CH2|FIR_RND0;
}

Outcomes