0
$\begingroup$

Question: Are the Least Mean Squares (LMS) coefficient update equations and step size being handled correctly?

Some background information: This algorithm is implemented on the ezdsp5535 on which uses Texas Instruments TMS320c5535 DSP. The code is being compiled using Code Composer Studio version 4 (CCSV4) (note that I cannot upgrade to a newer version).The interrupt service routine is triggered when the transmit and/or receive registers are full or empty. I2S connects the Audio Codec to the DSP. Note that the I2S has been configure for I/O data word lengths of 32 bits.

Purpose of algorithm: The LMS is implemented for offline system identification. A white noise signal will be input into the DSK to determine the coefficients for the secondary path transfer function. this will occur in an interrupt service routine following a procedure similar to what is listed here (7-39 to 7-41).

The code below also used and modified some the basic functions that came with dsp and CCSV4.

    interrupt void I2S_LMS()
    {
    //-------------------------------------------Variable Initializations
   Int16 LeftIn=0;                          // LEFT input sample "reference signal"
   Int16 RightIn=0;                         // Right input sample "desired signal"
   Int16 LO;                                // LEFT output sample "antinoise signal" 
   Int16 Error=0;                           // error signal
   Int32 LeftOut=0;                         // 32 bit accumulator for 16*16->32 signal out
   Int16 j;                                 // index for for loop
   Int32 muE;                               // 32 bit accumulator for the step times the error 16*16->32
   regs =   HI2s->hwRegs;
    //------------------------------------------Clear flags and disable the transmit and receive interrupts
CSL_FINST(regs->I2SINTMASK, I2S_I2SINTMASK_XMITST, DISABLE); // disables the transmit interrupt
CSL_FINST(regs->I2SINTMASK, I2S_I2SINTMASK_RCVST, DISABLE);  // disables the receive interrupt
IRQ_clear(RCV2_EVENT);                                       // clears the receive interrupt 
IRQ_clear(XMT2_EVENT);                                       // clears the transmit interrupt
CSL_FINSR(CSL_GPIO_REGS->IOOUTDATA2,1,1,0);                  // turns on green LED
    //-------------------------------------------LMS code begins
    I2S_readLeft(&LeftIn);               // Read in left
    I2S_readRight(&RightIn);             // Read in Right       
    LeftIn=(LeftIn<<2);                  // bit shift the input signal
    //++++++++++++++++++++++++++CHECK INPUTS+++++++++++++++++++++++++++
    if((LeftIn>32766 || LeftIn<-32766)==1) //bound check  
    {
        LeftIn = 0;
        CSL_FINSR(CSL_GPIO_REGS->IOOUTDATA1,15,15,0); // Oragnge LED ON
    }
    if((RightIn>32766 || RightIn<-32766)==1) //bound check  
    {
        RightIn = 0;
        CSL_FINSR(CSL_GPIO_REGS->IOOUTDATA1,15,15,0); // Oragnge LED ON
    }
    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    ++TimerCntISR;                       // timer counter
    ++CurrentIndex;                      // index for the LMS equations
    if(CurrentIndex==FilterOrder) CurrentIndex = 0; // when index upper bound reached reset the current index
    InputBuffer[CurrentIndex]=LeftIn;    // store the LeftIn sample into the the InputBuffer
    BufferIndex=CurrentIndex;           
    for(j=0;j<FilterOrder;j++)
    {
        LeftOut+=(Int32)(Int16)CoefficentBuffer[j]*(Int32)(Int16)InputBuffer[BufferIndex]; // compute MAC
        --BufferIndex;                   // decrement the Buffer Index
        if(BufferIndex==-1){BufferIndex=FilterOrder-1;} // Lower bound
    }
    LO=(Int16)(LeftOut>>6);              // scale the output
    Error=RightIn-LO;                    // compute the difference between the primary reference signal and the anti noise signal
    muE=step*Error;                      // compute the step times the Error signal

    for(j=0;j<FilterOrder;j++)
    {
        CoefficentBuffer[j]+=muE*InputBuffer[j]; // update the coefficents in the coefficent buffer
    }

    //++++++++++++++++++++++++++CHECKOUTPUTS+++++++++++++++++++++++++++++++++++
    if((LO>32766 || LO<-32766)==1) //bound check  
    {
        LO = 0;
        CSL_FINSR(CSL_GPIO_REGS->IOOUTDATA2,0,0,0);
        puts("error out");
    }

    if((Error>32766 || Error<-32766)==1) //bound check  
    {
        Error = 0;
        CSL_FINSR(CSL_GPIO_REGS->IOOUTDATA2,0,0,0);
        puts("error error");
    }
    if((muE>32766 || muE<-32766)==1) //bound check  
    {
        muE = 0;
        CSL_FINSR(CSL_GPIO_REGS->IOOUTDATA2,0,0,0);
        puts("error mue");
    }
    if (status==0)
    {
        I2S_writeLeft(Error);
    }
    if (status==1)
    {
        I2S_writeLeft(LO);
    }

CSL_FINSR(CSL_GPIO_REGS->IOOUTDATA2,1,1,1); //LED OFF
CSL_FINST(regs->I2SINTMASK, I2S_I2SINTMASK_RCVST, ENABLE); // enable the receive interrupt.
return;

}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.