/* 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 #include #include #include 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 char transf,enab_gnd,busy,remote_trigg; unsigned int trigg_cnt,v_cnt,wf_cnt; float Gain; //char format = 0; unsigned char* pbuff; unsigned char* plist[256]; 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 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 // 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 %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; 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>16; // read voltage from ADC0 }*/ for(k=0;k> 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=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(); if(Byte_addr==105) set_DACs(); 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; }