blob: e0fa141da27561fa6027774b10e87808b65fe775 [file] [log] [blame]
// Software CIC
// https://blog.y2kb.com/posts/pdm-mic-spi-cic/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include "cic.h"
void initializeCicFilterStruct(uint8_t CicFilterOrder, uint32_t CicFilterDecimation, struct CicFilter_t* st)
{
if (CicFilterOrder == 0)
{
printf("Order of CIC filter must be over 0\r\n");
return;
}
if(CicFilterDecimation == 0)
{
printf("Decimation of CIC filter must be over 0\r\n");
return;
}
st->order = CicFilterOrder;
st->decimation = CicFilterDecimation;
st->out_i = (int32_t*) malloc(sizeof(int32_t) * st->order);
st->out_c = (int32_t*) malloc(sizeof(int32_t) * st->order);
st->z1_c = (int32_t*) malloc(sizeof(int32_t) * st->order);
if ((st->out_i == NULL) || (st->out_c == NULL) || (st->z1_c == NULL))
{
printf("CicFilterStruct malloc error\r\n");
return;
}
resetCicFilterStruct(st);
}
void resetCicFilterStruct(struct CicFilter_t* st)
{
if(st == NULL)
return;
for(uint8_t i = 0; i < st->order; i++)
{
*(st->out_i + i) = 0;
*(st->out_c + i) = 0;
*(st->z1_c + i) = 0;
}
}
void executeCicFilter(uint8_t* pInBit, uint32_t pInBit_Num, int32_t* pOut_int32, struct CicFilter_t* st)
{
//uint8_t Bout = st->order * (uint8_t)(ceil(log2f(st->decimation))) + 1;
int32_t in_bit;
uint8_t in_Byte;
uint32_t Bit_i, Decimation_count;
uint8_t i;
for(Bit_i = 0, Decimation_count = st->decimation - 1; Bit_i < pInBit_Num; ++Bit_i, --Decimation_count)
{
in_Byte = *(pInBit + (Bit_i >> 3) );
if( (in_Byte >> (Bit_i & 0x07)) & 0x01 ) // First bit is [b0]
in_bit = 1;
else
in_bit = -1;
// Integrator (No need to consider saturation.
// ref : http://d.hatena.ne.jp/suikan+blackfin/20060611/1149996053 (Japanese) )
*(st->out_i) += in_bit;
for (i = 1; i < st->order; ++i)
{
*(st->out_i + i) += *(st->out_i + i - 1);
}
// Decimation
if(Decimation_count == 0)
{
Decimation_count = st->decimation;
// Comb filter
*(st->out_c) = *(st->out_i + st->order - 1) - *(st->z1_c);
*(st->z1_c) = *(st->out_i + st->order - 1);
for (i = 1; i < st->order; ++i)
{
*(st->out_c + i) = *(st->out_c + i - 1) - *(st->z1_c + i);
*(st->z1_c + i) = *(st->out_c + i - 1);
}
*(pOut_int32 + Bit_i / st->decimation) = *(st->out_c + st->order - 1);
}
}
}
void finalizeCicFilterStruct(struct CicFilter_t* st)
{
if (st == NULL)
return;
st->order = 0;
st->decimation = 0;
free(st->out_i);
free(st->out_c);
free(st->z1_c);
}