CMSIS FIR filter aplication for real signal

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

CMSIS FIR filter aplication for real signal

2,313 Views
romanrumian
Contributor I

Hello,

how signal samples should be gathered (what data structure and how DMA channel should be set up)  in let's say Kinets K22 in order to use them for FIR library function ?

I cannot find an example for real-time, continuous signal filtering.

Regards

Roman

0 Kudos
3 Replies

1,256 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Roman,

I see that you use DMA to transfer data from ADC to memory, when the predefined number of data has been transferred, the DMA complete interrupt will be triggered, in the DMA ISR, you can do the digital filtering.

Obviously, you should do digital filtering with multiple input data. In the case, for example, you input data temp[100], you just need redefine the BLOCKSIZE parameter, it is okay. As you said that "FIR block filtering function needs input data buffer having the length equal to block_length+number_of_fir_coefficients", the buffer you referred to is the FirState[], which is defined as  int16_t FirState[TAPNUMBER+BLOCKSIZE];

Hope it can help you.

This is the snippet of FIR code with multiple data inputs:

#define FRAC16(x) 32768*x

#define TAPNUMBER 20

#define BLOCKSIZE 100

int16_t lpFilterCoefficent[TAPNUMBER]=

{

FRAC16(4.45556640625000e-003),

FRAC16(1.44042968750000e-002),

FRAC16(2.54516601562500e-002),

FRAC16(3.69873046875000e-002),

FRAC16(4.84619140625000e-002),

FRAC16(5.92041015625000e-002),

FRAC16(6.86950683593750e-002),

FRAC16(7.63244628906250e-002),

FRAC16(8.16650390625000e-002),

FRAC16(8.44116210937500e-002),

FRAC16(8.44116210937500e-002),

FRAC16(8.16650390625000e-002),

FRAC16(7.63244628906250e-002),

FRAC16(6.86950683593750e-002),

FRAC16(5.92041015625000e-002),

FRAC16(4.84619140625000e-002),

FRAC16(3.69873046875000e-002),

FRAC16(2.54516601562500e-002),

FRAC16(1.44042968750000e-002),

FRAC16(4.45556640625000e-003)

};

const arm_fir_instance_q15 sFirStru;

int16_t FirState[TAPNUMBER+BLOCKSIZE];

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */

int main(void)

/*lint -restore Enable MISRA rule (6.3) checking. */

{

    int16_t temp0,offset,scale;

  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

    //OSA_Init();

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                    ***/

  /* Write your code here */

  /* For example: for(;;) { } */

  __asm("nop");

  arm_fir_init_q15(&sFirStru,TAPNUMBER,&lpFilterCoefficent[0],&FirState[0],BLOCKSIZE);

...........................

}

void ADC_ISR(void)

{

int16_t temp[100],temp1[100];

    __asm("nop");

/* Write your code here ... */

    temp=(int16_t)var0[index]; //ADC sample here

#ifdef DIGITALFILTER

    arm_fir_fast_q15(&sFirStru,&temp[0][,&temp1[0],BLOCKSIZE);

#endif

}

Hope it acn help you.

BR

XiangJun Rong

0 Kudos

1,256 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Roman,

As you know the SDK provide CMSIS library, before you develop the FIR code based on K22, I suggest you install the Kinetis tools for example KDS tools and KSDK tools from the wbsite:

K40_100 |Kinetis K40 100 MHz MCUs|Freescale

after you install the the KDS and KSDK tools, you can find out the directory:

D:\Freescale\KSDK_1.2.0\platform\CMSIS\DSP_Lib\Source\FilteringFunctions

we provide the FIR source code.

This is the architacture of FIR filtering in real world, the Kinetis has on-chip SAR ADC, you can use PDB to trigger ADC so that you can sample an analog signal with a fixed cycle time, I suggest you use interrupt mode for the ADC conversion, after the ADC conversion is over, an ADC interrupt is triggered by ADC, in the ISR of ADC conversion, you can read the ADC sample and filter it.

You have to use the other tools to design a digital filter so that you can get the FIR coefficients based on filter type and pass-band.

Before you use the CMSIS library, you have to compile the platform library. we provide Q16/Q32/float data type digital filtering the CMSIS lib.

This is the snippet of FIR code:

#define FRAC16(x) 32768*x

#define TAPNUMBER 20

#define BLOCKSIZE 1

int16_t lpFilterCoefficent[TAPNUMBER]=

{

FRAC16(4.45556640625000e-003),

FRAC16(1.44042968750000e-002),

FRAC16(2.54516601562500e-002),

FRAC16(3.69873046875000e-002),

FRAC16(4.84619140625000e-002),

FRAC16(5.92041015625000e-002),

FRAC16(6.86950683593750e-002),

FRAC16(7.63244628906250e-002),

FRAC16(8.16650390625000e-002),

FRAC16(8.44116210937500e-002),

FRAC16(8.44116210937500e-002),

FRAC16(8.16650390625000e-002),

FRAC16(7.63244628906250e-002),

FRAC16(6.86950683593750e-002),

FRAC16(5.92041015625000e-002),

FRAC16(4.84619140625000e-002),

FRAC16(3.69873046875000e-002),

FRAC16(2.54516601562500e-002),

FRAC16(1.44042968750000e-002),

FRAC16(4.45556640625000e-003)

};

const arm_fir_instance_q15 sFirStru;

int16_t FirState[TAPNUMBER+BLOCKSIZE];

/*lint -save  -e970 Disable MISRA rule (6.3) checking. */

int main(void)

/*lint -restore Enable MISRA rule (6.3) checking. */

{

    int16_t temp0,offset,scale;

  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

    //OSA_Init();

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                    ***/

  /* Write your code here */

  /* For example: for(;;) { } */

  __asm("nop");

  arm_fir_init_q15(&sFirStru,TAPNUMBER,&lpFilterCoefficent[0],&FirState[0],BLOCKSIZE);

...........................

}

void ADC_ISR(void)

{

int16_t temp,temp1;

    __asm("nop");

/* Write your code here ... */

    temp=(int16_t)var0[index]; //ADC sample here

#ifdef DIGITALFILTER

    arm_fir_fast_q15(&sFirStru,&temp,&temp1,1);

#endif

}

Hope it acn help you.

BR

XiangJun Rong

0 Kudos

1,256 Views
romanrumian
Contributor I

Dear XiangJun Rong,

many thanks for your detailed answer, but it still did not solved my main problem: the way we can gather input signal samples using DMA in a data structure compatible with CMSIS FIR functions.

I am experienced Digital Signal Processors programmer (DSP56300 family in assembler, and AD SHARC in C), so I have already analysed CMSIS DSP library code.

FIR block filtering function needs input data buffer having the length equal to block_length+number_of_fir_coefficients. During the output block calculations we have to prepare new, next buffer of input data which must have, at the beginning, continuation from old buffer (overlap, last n=number_of_fir_coefficients samples-1), and new samples should be added starting from n-th position in this new buffer. So, the question is: how to program DMA for this task, because we don't want to loose CPU time for other task than FIR filtering.

So we have to do two transfers for every new input buffer:

1. Copy of overlap samples from the end of old (current) buffer to new one.

2. Gathering the block_length number of new samples in new buffer.

Kind regards

Roman

0 Kudos