
デモプログラムを改造したDSPフィルタ CODEC版(DM330011)
投稿日 2013/04/23
microchip社のdsPIC33F DSCのスターターキットDM330011に付属のデモプログラムを改造してDSPフィルターを作ってみました。
前回はADコンバータとOCPWMを使用したデモプログラムを改造しましたが、今回はCODECを使用したデモプログラムを改造してみました。
このデモプログラムはDCI(Data Converter Interface)を使用したサンプルになっています。DCIはI2SのようなインターフェースをサポートしたCODECを簡単に使えるようにしたインターフェースです。比較的新しいモデルのCPUに搭載されている機能です。
スターターキットのボードにはCPUとしてdsPIC33FJ256GP506が搭載されており、DCIをサポートしています。CODECはWM8510を使用しています。CODECにはさまざまな種類がありますが、大まかに言えば信号をADコンバータでサンプリングし、必要なフィルター処理等を行って、DAコンバータで出力するものです。ディスクリートで組んでも実現できるものですが、ICにパッケージされており便利です。そんなCODECをなるべく簡単に扱えるよう、I2Sなどのインターフェースの細かいタイミングを気にせずに使えるようにするのがDCIの役割です。
前回のADコンバータとOCPWMを使用したデモのような、ADコンバータやOCPWMの細かい設定は不要となります。
DCIの細かいことはまだ勉強不足ですが、DCIのread(信号の入力)とwrite(信号の出力)の間にDSPフィルターを入れればよいので、まずは動くかどうか確認してみました。
フィルタは前回同様650から850Hzの通過帯域をもつFIRバンドパスフィルタです。
やっていることは簡単で、WM8510ReadとWM8510Writeの間にDSPフィルタを入れているだけです。
ソースコード(main.c)
#include "..\h\p33FJ256GP506.h"
#include "..\h\WM8510CodecDrv.h"
#include "..\h\sask.h"
#include "dsp.h"
_FGS(GWRP_OFF & GCP_OFF);
_FOSCSEL(FNOSC_FRC);
_FOSC(FCKSM_CSECMD & OSCIOFNC_ON & POSCMD_NONE);
_FWDT(FWDTEN_OFF);
//DSP Filter Struct
extern FIRStruct bandpass650_850Filter;
//FRAME_SIZE - Size of each audio frame
#define FRAME_SIZE 128
// Allocate memory for buffers and drivers
int codecBuffer[WM8510DRV_DRV_BUFFER_SIZE];
fractional Signal_in[FRAME_SIZE];
fractional Signal_out[FRAME_SIZE];
//Instantiate the drivers structures and create handles.
WM8510Handle codec;
WM8510Handle * codecHandle = &codec;
int main(void)
{
//Configure Oscillator to operate the device at 40MHz.
//Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
//Fosc= 7.37M*40/(2*2)=80Mhz for 7.37M input clock
PLLFBD=41; //M=39
CLKDIVbits.PLLPOST=0; //N1=2
CLKDIVbits.PLLPRE=0; //N2=2
OSCTUN=0;
__builtin_write_OSCCONH(0x01); //Initiate Clock Switch to FRC with PLL
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0b01); //Wait for Clock switch to occur
while(!OSCCONbits.LOCK);
//Intialize the board and the drivers
SASKInit();
WM8510Init(codecHandle,codecBuffer);
//Start Audio input and output function
WM8510Start(codecHandle);
//Configure codec for 8K operation
WM8510SampleRate8KConfig(codecHandle);
//Initialize FIR Filter
FIRDelayInit(&bandpass650_850Filter);
//Main processing loop. Executed for every input and output frame
while(1)
{
//Obtain Audio Samples
while(WM8510IsReadBusy(codecHandle));
WM8510Read(codecHandle,Signal_in,FRAME_SIZE);
//Processing DSP filter
FIR(FRAME_SIZE, &Signal_out[0], &Signal_in[0], &bandpass650_850Filter);
//Wait till the codec is available for a new frame
while(WM8510IsWriteBusy(codecHandle));
//Write the frame to the output
WM8510Write (codecHandle,Signal_out,FRAME_SIZE);
}
}
フィルタの係数ファイルは、前回と同じです。
(JF1VRR)