123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569 |
- /*
- v1.2
-
-
- this program use old code used in another experiment
-
- "int" is used for the ADC and DAC data although it should be unsigned,
- it should be not a problem at all as this data are limited to 12bits...
- */
- #include<ADuC7020.h>
- #include<stdlib.h>
- #include<stdio.h>
- #include<string.h>
- void My_IRQ_Handler(void);
- short i = 0;
- unsigned char Byte_addr = 0;
- int first = 1;
- int i2c_cnt = 0;
- #define BIGDAT_SZ 256
- unsigned short BigDat[BIGDAT_SZ];
- char text[512];
- unsigned short Vout[4];
- unsigned short Vlearn;
- double Vin,Vin_gnd;
- unsigned short start, stop,start_gnd,stop_gnd,start2,stop2,Vset,wf_len, step_max,N;
- unsigned short int FEE_addr;
- unsigned char transf,enab_gnd,busy,remote_trigg;
- unsigned int trigg_cnt,v_cnt,wf_cnt;
- unsigned short test;
- unsigned short probe;
- float Gain;
- //char format = 0;
- unsigned char* pbuff;
- unsigned char* plist[256];
- unsigned char ERROR;
- unsigned int status, uiTest, uiTest1, uiTest2;
- unsigned short ucVerifyTest = 0;
- #pragma pack(1)
- struct Test
- {
- char AA;
- int BB;
- char CC;
- };
- void delay (int length)
- {
- while (length >=0)
- length--;
- }
- // conversion of the read value into it corresponding 12bits integer
- int ADCtoDAT(unsigned long ADC)
- {
- return (ADC&0xFFF0000)>>16;
- }
- unsigned long DATtoADC(int DAT)
- {
- unsigned long ADC;
- ADC=DAT;
- return ADC<<16;
- }
- unsigned long DATtoDAC(unsigned short DAT)
- {
- unsigned int ADC;
- ADC=DAT;
- return ADC<<16;
- }
- int Read_Digital(int n)
- {
- return ((GP0DAT&0x000000FF)>>n)&0x1;
- }
- void Write_Digital(int n, int state)
- {
- if(state==1)
- GP2DAT=(0x00000001<<(n+16))|GP2DAT;
- else
- GP2DAT=~((0x00000001<<(n+16))|(~GP2DAT));
- }
- void ADCpoweron(int time)
- {
- ADCCON = 0x620; // power-on the ADC
- while (time >=0) // wait for ADC to be fully powered on
- time--;
- }
- void get_DACs(void)
- {
- Vout[0]=DAC0DAT>>16;
- Vout[1]=DAC1DAT>>16;
- Vout[2]=DAC2DAT>>16;
- Vout[3]=DAC3DAT>>16;
- }
- void set_DACs(void)
- {
- DAC0DAT=DATtoDAC(Vout[0]);
- DAC1DAT=DATtoDAC(Vout[1]);
- DAC2DAT=DATtoDAC(Vout[2]);
- DAC3DAT=DATtoDAC(Vout[3]);
- }
- void protect_page(unsigned int addr){
- FEEADR = 0x1234; // Key
- FEEDAT = 0x1234; // Key
- FEEPRO = addr;
- FEEMOD = 0x48;
- FEECON = 0x0C;
- status = FEESTA&0x03;
- while (!(status)) status = FEESTA&0x03;
- if ((status&0x02)==0x02) //ERROR = 1;
- return; // return
- }
- unsigned short load(unsigned short int addr){
- FEEADR = addr;
- FEECON = 0x01; // single read command
- status = FEESTA;
- probe = status;
- while ((status&0x04)==0x04) status = FEESTA;
- if ((status&0x02)==0x02){
- return 66;
- // ERROR = 1;
- }
- return (FEEDAT);
- }
- void save(unsigned short int addr, unsigned short data){
-
- //FEEMOD = 0x8;
-
- FEEADR = addr; // set data address
- FEEDAT = data; // set data value
- FEECON = 0x02; // single Write command
- status = FEESTA;
- probe = status;
- while ((status&0x04)==0x04) status = FEESTA;
- if ((status&0x02)==0x02) ERROR = 0;
- //FEEMOD = 0x0;
- //protect_page(0xBFFFFFFF);
- return;
- }
- void erase_page(unsigned short int addr){
- FEEADR = addr; // set data address
- FEECON = 0x05; // erase page command
- status = FEESTA;
- probe = status;
- while ((status&0x04)==0x04) status = FEESTA;
- if ((status&0x02)==0x02) ERROR = 0;
- return;
- }
- void init(void)
- {
- test = load(FEE_addr);
- }
- void erase(void)
- {
- erase_page(FEE_addr); // erase page 120
- }
- void update(void)
- {
- save(FEE_addr, test);
-
- //protect_page(0xBFFFFFFF); // protect pages
- }
- void lock_StabPulse_i2c(void)
- {
- // define variables
- unsigned int cnt_N;
- double sum,sum_gnd;
- unsigned short Vout2;
- //double Vin,Vin_gnd;
- //int Vmean;
- int step = 100;
- short armed; // this is used to detect the trigger :
- // when the trigger input is low armed is set to 1
- // when a measurement start it is set to 0
- short valid_data;
- int k;
- unsigned short Data[256];
- //unsigned int tmp_dat[256];
- POWKEY1 = 0x01;
- POWCON = 0x00; // 41.78MHz
- POWKEY2 = 0xF4;
-
- //GP1CON = 0x00000000; // IO initialization
- //GP1DAT = 0xFF000000; // set P1.n as digital output
-
- GP0CON = 0x00000000; // IO initialization
- //GP0DAT = 0x00000000; // set P0.n as digital input
- // ADC&DAC setting
- ADCpoweron(20000); // power on ADC
- REFCON = 0x01; // internal 2.5V reference
- DAC0CON = 0x12; // AGND-ARef range 0x12 2.5V
- DAC1CON = 0x12; // AGND-ARef range 0x12 2.5V
- DAC2CON = 0x12; // AGND-ARef range 0x12 2.5V
- DAC3CON = 0x12; // AGND-ARef range 0x12 2.5V
- ADCCP = 0x03; // conversion on ADC0
- ADCCON = 0x3E4; // continuous conversion
- // IO setting
- GP2CON = 0x00000000; // IO initialization
- GP2DAT = 0xFF000000; // set P2.n as digital output
- GP0CON = 0x00000000; // IO initialization
- GP0DAT = 0x00000000; // set P0.n as digital input
-
-
- FEEMOD = 0x8;
- delay(20);
- FEE_addr = 0xF000;
- //init();
- //FEEPRO = 0x40000000;
- //test=0;
- // locking parameters initialization
- // cnt = 0; //
- N = 10; // number of measume,ts for averaging
- Vin = 0; // initialize the voltage of first step
- Vin_gnd = 0;
- // Vmean = 2000;
- start = 20;
- stop = 30;
- start_gnd = 0;
- stop_gnd = 10;
- wf_len = 200;
- Vset = 200;
- Vlearn = 2000;
- step = 50;
- step_max = 100;
- Gain = 1;
- // I2C on P1.0 and P1.1
- GP1CON = 0x22;
- IRQ = My_IRQ_Handler;
- IRQEN = 0x200; // I2C0 Slave Interupt
-
- I2C0CFG = 0x04001;
- // Slave ID
- I2C0ID0 = (0x50 + (((GP0DAT&0x000000FF)>>5)&0x1)+(((GP0DAT&0x000000FF)>>7)&0x1)*2)<<1;
- I2C0STX = 0x00;
- I2C0STX = 0x00;
- // assignation of the different pointers for the I2C exchange of data
- for (k=0;k<16;k++){
- plist[k] = (unsigned char*)(BigDat+k*16);
- plist[k+50] = (unsigned char*)(text+k*32);
- }
-
- for(i=0;i<BIGDAT_SZ;i++)
- BigDat[i]=0;
- sprintf(text,"pulse stabilization v1.2 => %s\ncompiled: %s\nbecause we can!",__func__,__DATE__);
-
- for (k=0;k<4;k++){
- plist[100+k] = (unsigned char*)(Vout+k);
- }
- // 104 to execute the function get_DACs
- // 105 to execute the function set_DACs
-
- plist[110] = (unsigned char*)&Vlearn;
- plist[111] = (unsigned char*)&Vin;
- plist[112] = (unsigned char*)&Vin_gnd;
- plist[113] = (unsigned char*)&wf_cnt;
- plist[114] = (unsigned char*)&v_cnt;
- plist[115] = (unsigned char*)&remote_trigg;
- plist[120] = (unsigned char*)&I2C0ID0;
- plist[121] = (unsigned char*)&ADCCP;
- plist[122] = (unsigned char*)&transf;
- plist[123] = (unsigned char*)&wf_len;
- plist[124] = (unsigned char*)&trigg_cnt;
- plist[125] = (unsigned char*)&Vset;
- plist[126] = (unsigned char*)&N;
- plist[127] = (unsigned char*)&start;
- plist[128] = (unsigned char*)&stop;
- plist[129] = (unsigned char*)&start2;
- plist[130] = (unsigned char*)&stop2;
- plist[131] = (unsigned char*)&start_gnd;
- plist[132] = (unsigned char*)&stop_gnd;
- plist[133] = (unsigned char*)&enab_gnd;
- plist[134] = (unsigned char*)&Gain;
- plist[135] = (unsigned char*)&step_max;
- plist[141] = (unsigned char*)&test;
- plist[142] = (unsigned char*)&probe;
-
- plist[140] = (unsigned char*)&FEE_addr;
-
-
- DAC0DAT = DATtoADC(10);
- DAC1DAT = DATtoADC(20);
- DAC2DAT = DATtoADC(2000);
- DAC3DAT = DATtoADC(40);
-
- Vset=0;
- Vout[3] = 111;
- set_DACs();
- transf = 0;
- trigg_cnt = 0;
- wf_cnt = 0;
- v_cnt = 0;
- cnt_N = 0;
- enab_gnd = 0;
- remote_trigg = 0;
- valid_data=0;
- // main loop for the locking
- while(1){
-
- // trigg in is on p0.3 => we check that it is low first (rising edge detection)
- if((((GP0DAT&0x000000FF)>>3)&0x1)==0){
- armed = 1;
- }
- // now p0.3 is high => this is our rising edge
- if(((((GP0DAT&0x000000FF)>>3)&0x1)==1 && armed==1) || remote_trigg){
-
- armed = 0;
- //busy = 0;
- //*** aquisition of the waveform ***
- /*for(k=0;k<wf_len;k++){
- while(!ADCSTA){} // wait for the end of ADC conversion
- tmp_dat[k]= ADCDAT; // read voltage from ADC0
- }
- for(k=0;k<wf_len;k++){
- Data[k]= (tmp_dat[k]&0xFFF0000)>>16; // read voltage from ADC0
-
- }*/
- for(k=0;k<wf_len;k++){
- while(!ADCSTA){} // wait for the end of ADC conversion
- Data[k]= (unsigned short)(ADCDAT >> 16); // read voltage from ADC0
- }
-
- trigg_cnt++;
- if(busy==0){ // supposed to guaranty that no i2c transfer has been performed during the wf acquisition
- //*** copy for the i2c ***
- memcpy(BigDat,Data,256*sizeof(short));
- wf_cnt++;
-
- cnt_N++;
-
- //sum of the data
- for(k=start;k<stop;k++){
- sum += Data[k];
- //cnt++;
- }
- for(k=start_gnd;k<stop_gnd;k++){
- sum_gnd += Data[k];
- //cnt_gnd++;
- }
- if(cnt_N>=N){
- Vin = sum/(cnt_N*(stop-start)); // calculate average value
- Vin_gnd = sum_gnd/(cnt_N*(stop_gnd-start_gnd)); // calculate average value
- valid_data = 1;
- v_cnt++;
- sum = 0; // initialization of the measurement
- sum_gnd = 0;
- cnt_N = 0;
- }
- }
- else busy = 0;
-
- //*** feedback *** (mode is on pin p0.6)
- // LOCK MODE
- if((((GP0DAT&0x000000FF)>>6)&0x1)==1){
- if(valid_data==1){
- valid_data=0;
- cnt_N=0;
- //cnt_gnd=0;
- step = (Vset-Vin+Vin_gnd*enab_gnd)*Gain;
- if (step>step_max)
- step = step_max;
- else if (step<-step_max)
- step = -step_max;
- Vout2 = Vout2 + step;
- if(Vout2>4095){
- Write_Digital(0,1);
- Vout2 = 4090;
- }
- else{
- Write_Digital(0,0);
- }
- }
- }
- // LEARN MODE
- // we set the outputs to the average voltage
- // and save the current input level as the set point of the next locking enable
- else{
- if(valid_data==1){
- valid_data=0;
- Vset = Vin-Vin_gnd*enab_gnd;
- cnt_N=0;
- }
- Vout2 = Vlearn;
- }
- //this line could also be inserted in the if conditions and thus not set every loops
- DAC2DAT = DATtoADC(Vout2); // output voltage
- }
-
- }
- }
- int main(void)
- {
-
- lock_StabPulse_i2c();
- return 0;
- }
- /*************************************************/
- /*************************************************/
- /************ IRQ Service Routine *************/
- /*************************************************/
- /*************************************************/
- void My_IRQ_Handler()
- {
- int status = I2C0SSTA;
- busy = 1;
-
- // Slave Recieve
- if ((status & 0x08)==0x08) // Slave Recieve IRQ
- {
- if(first==1){
- first=0;
- Byte_addr=I2C0SRX;
- I2C0FSTA|= 1 << 8;
- i2c_cnt = 0;
- if(Byte_addr==122)
- transf = 1;
- if(Byte_addr==104){
- // get_DACs();
- init();
- }
- if(Byte_addr==105){
- // set_DACs();
- update();
- }
- if(Byte_addr==106)
- erase();
- Write_Digital(2,0);
- pbuff = plist[Byte_addr];
- I2C0STX = pbuff[0];
-
- }
- else {
- pbuff[i2c_cnt] = I2C0SRX;
- i2c_cnt++;
- }
- }
-
- // Slave Transmit
- else if ((status & 0x04)==0x04) // Slave Transmit IRQ
- {
- i2c_cnt ++;
- I2C0STX = pbuff[i2c_cnt];
- I2C0ADR = 0xA1;
- //if(Byte_addr>=110 && Byte_addr<=113 && i2c_cnt==1)
- //set_DACs();
- }
-
- else if((status & 0x0400)==0x0400) //
- {
- first = 1;
- //Write_Digital(2,1);
- }
-
- busy=1;
- }
|