/***********************************************************************/
/* */
/* FILE :sh_zenka_hilbert.c */
/* DATE :Tue, Feb 03, 2004 */
/* DESCRIPTION :Main Program */
/* CPU TYPE :SH7047 */
/* */
/* This file is generated by Renesas Project Generator (Ver.3.0). */
/* */
/***********************************************************************/


#ifdef __cplusplus
//#include <ios> // Remove the comment when you use ios
//int ios_base::Init::init_cnt; // Remove the comment when you use ios
#endif
#ifdef __cplusplus
extern "C" {
#endif
void abort(void);
#ifdef __cplusplus
}
#endif

#include "7047s.h"
#include <machine.h>

void InitSH(void)
{
PFC.PECRL1.WORD=0;
PFC.PECRL2.WORD=0;
PFC.PEIORL.WORD=0xFFFF;//PE I/O 書き出しモード

PFC.PACRL2.WORD=0;
PFC.PAIORL.WORD=0xFFFF;

PFC.PBCR1.BIT.PB5MD=0; //PB=出力
PFC.PBCR2.BIT.PB5MD=0;
PFC.PBCR1.WORD=0;

PFC.PBIOR.BIT.B5=1;
PFC.PBIOR.WORD=0XFFFF;
PFC.PDIORL.WORD=0xFFFF;


MST.CR2.BIT._AD0=0; // この設定がないと、AD変換器が動かない
AD0.ADCR.BIT.ADST=0;
AD0.ADCR.BYTE=0;
AD0.ADCSR.BYTE=0;
AD0.ADCR.BIT.CKS=0x3;
AD0.ADCR.BIT.ADST=1; //start AD
}





#define N 41

short fir[N]={


// 次数=40 タップ数=41 Q15
// サンプリング= 32KHz
// 帯域端周波数 = 0.5 KHz


-581,-1293,234,-842,2,-958,-30,-1205,-32,-1547,
-29,-2025,-24,-2749,-19,-4004,-12,-6852,-7,-20827,
0,20827,7,6852,12,4004,19,2749,24,2025,
29,1547,32,1205,30,958,-2,842,-234,1293,
581

// 次数=80 タップ数=81 Q15
// サンプリング= 19.8KHz
// 帯域端周波数 = 0.2 KHz

/*
-389,-478,140,-314,29,-293,-6,-321,-16,-367,
-19,-424,-20,-490,-20,-567,-19,-656,-18,-760,
-17,-883,-16,-1032,-15,-1216,-13,-1452,-12,-1766,
-10,-2210,-8,-2896,-6,-4112,-4,-6917,-2,-20849,
0,20849,2,6917,4,4112,6,2896,8,2210,
10,1766,12,1452,13,1216,15,1032,16,883,
17,760,18,656,19,567,20,490,20,424,
19,367,16,321,6,293,-29,314,-140,478,
389*/
};


short data_up[N]={0};
short data_low[N]={0};

short sin_up[N]={0};
short sin_low[N]={0};
short data=0;
short out=0;
short moto_data=0;
short real_y=0;
short imag_y=0;

int output=0;
int data_chukan=0;


unsigned char i=0;

#pragma inline(kakunou)
void kakunou(unsigned char j,short data3,unsigned char k)
{
data_up[k-1-j]=data3; //下から格納する
data_low[k-1-j]=data3; //同じ
}
#pragma inline(sin_kakunou)
void sin_kakunou(unsigned char j,short data3,unsigned char k)
{
sin_up[k-1-j]=data3;
sin_low[k-1-j]=data3;
}



// a1=2cos(2*PI*6000/94523)*2^14

short sinw=8149/100 ;//Q15 a1=sinw 1KHz sampling 25KHz
short sinw_deltaw=0;
short const1_cosd=4118; //Q17 b0=1-cosd 1KHz sampling 25KHz
short* p_sinw;
short* p_sinw_deltaw;
short* p_const1_cosd;


//-----------------

#pragma inline_asm(zenka)

short zenka(short* a,short* b,short* c) //r4=a=1-cosd, r5=b=sinw, r6=c=sin(w-deltaw)
{

mov.w @r4,r1 //r1=@r4=1-cosd
mov.w @r5,r0 //r0=@r5=sinw
mov.w @r6,r7 //@r7=0=sin(w-deltaw)

mov r0,r2 //r2=sinw
muls r1,r0 //(1-cosd)*sinw --to MACL 2^32
shll16 r0 // r0*2^16 sinw 2^31
shll r0 // r0*2 sinw 2^32
sts MACL,r1//積をr1に移す r1=(1-cosd)*sinw
//r0=sinw(2^32)
sub r1,r0 //r0=sinw-(1-cosd)*sinw=cosd*sinw 2^32
shlr16 r0 //上の結果をシフト 2^32--2^16=2^16 = 2*(cosd*sinw) 2^15
exts.w r0,r1 //r1=r0この結果を、符号拡張してr1に保存
sub r7,r1 //2cosd*sinw-sin(w-deltaw)
mov.w r2,@r6//r6=new sin(w-deltaw)
mov.w r1,@r5 //r15=new sinw
mov.l r1,r0 //output=r0
}

int main(void)
{
// INTC.IPRG.BIT._AD01=0xC;//AD0 priority=12
// set_imask(0);
InitSH();
i=0;
// sinw=8149/100 ;//Q15 a1=sinw 1KHz sampling 25KHz
sinw=8149/20 ;
sinw_deltaw=0;
const1_cosd=4118; //Q17 b0=1-cosd 1KHz sampling 25KHz

p_sinw=&sinw;
p_sinw_deltaw=&sinw_deltaw;
p_const1_cosd=&const1_cosd;


while(1)
{
PE.DRL.BIT.B12=1; //DA変換器用タイミング

if (AD0.ADCSR.BIT.ADF)
{

AD0.ADCSR.BIT.ADF=0;
AD0.ADCR.BIT.ADST=0;
data=AD0.ADDR0.WORD;

data -=0x82C0;//無入力時のAD0の値
data=data>>6;//上位10ビットが有効

//AD変換の結果をhilbert変換器に通す---------------------------------------------------------------------
kakunou(i,data,N);
data_chukan=macw( (data_up+N-1-i),fir,N);

data=data_chukan>>15;

moto_data=data_up[N-1-i+(N-1)/2];//N-1-iから40ポイント前の点=中点

moto_data = moto_data*47/50; //振幅のスケーリング。 小数点にすると、極端に遅くなるので注意!


//sin波形の、漸化式による発生

out=zenka(p_const1_cosd,p_sinw,p_sinw_deltaw);

sin_kakunou(i,out,N); //一旦、配列に格納する

//作成したsin波を、hilbert変換器に通し、虚部を求める

data_chukan=macw( (sin_up+N-1-i),fir,N);

imag_y=data_chukan>>15;


real_y=sin_up[N-1-i+(N-1)/2]*7/10;//N-1-iから40ポイント前の点=中点

output=moto_data*real_y - data*imag_y;
output=output>>12;
output +=400;


/* if(i%2)output=moto_data;
else output=data;
output +=0x200;*/


/* if(i%2)output=real_y;
else output=imag_y;
output=output>>3;
output +=400;*/


PE.DRL.WORD =output;

i++;
if( i==N) i=0;

AD0.ADCR.BIT.ADST=1;
}

PE.DRL.BIT.B12=0; //DA変換器用タイミング
}
return 1;
}

void abort(void)
{

}