1
0

Demov1p0.C 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /*
  2. v1.0
  3. "int" is used for the ADC and DAC data although it should be unsigned,
  4. it should be not a problem at all as this data are limited to 12bits...
  5. */
  6. #include<ADuC7020.h>
  7. #include<stdlib.h>
  8. #include<stdio.h>
  9. #include<string.h>
  10. void My_IRQ_Handler(void);
  11. short i = 0;
  12. unsigned char Byte_addr = 0;
  13. int first = 1;
  14. int i2c_cnt = 0;
  15. #define BIGDAT_SZ 256
  16. unsigned short BigDat[BIGDAT_SZ];
  17. char text[512];
  18. unsigned short Vout[4];
  19. unsigned short start, stop,start_gnd,stop_gnd,start2,stop2,Vset,wf_len, step_max,N;
  20. unsigned char transf,enab_gnd;
  21. unsigned int trigg_cnt;
  22. float Gain;
  23. //char format = 0;
  24. unsigned char* pbuff;
  25. unsigned char* plist[256];
  26. void delay (int length)
  27. {
  28. while (length >=0)
  29. length--;
  30. }
  31. // conversion of the read value into it corresponding 12bits integer
  32. int ADCtoDAT(unsigned long ADC)
  33. {
  34. return (ADC&0xFFF0000)>>16;
  35. }
  36. unsigned long DATtoADC(int DAT)
  37. {
  38. unsigned long ADC;
  39. ADC=DAT;
  40. return ADC<<16;
  41. }
  42. unsigned long DATtoDAC(unsigned short DAT)
  43. {
  44. unsigned int ADC;
  45. ADC=DAT;
  46. return ADC<<16;
  47. }
  48. int Read_Digital(int n)
  49. {
  50. return ((GP0DAT&0x000000FF)>>n)&0x1;
  51. }
  52. void Write_Digital(int n, int state)
  53. {
  54. if(state==1)
  55. GP2DAT=(0x00000001<<(n+16))|GP2DAT;
  56. else
  57. GP2DAT=~((0x00000001<<(n+16))|(~GP2DAT));
  58. }
  59. void ADCpoweron(int time)
  60. {
  61. ADCCON = 0x620; // power-on the ADC
  62. while (time >=0) // wait for ADC to be fully powered on
  63. time--;
  64. }
  65. void get_DACs(void)
  66. {
  67. Vout[0]=DAC0DAT>>16;
  68. Vout[1]=DAC1DAT>>16;
  69. Vout[2]=DAC2DAT>>16;
  70. Vout[3]=DAC3DAT>>16;
  71. }
  72. void set_DACs(void)
  73. {
  74. DAC0DAT=DATtoDAC(Vout[0]);
  75. DAC1DAT=DATtoDAC(Vout[1]);
  76. DAC2DAT=DATtoDAC(Vout[2]);
  77. DAC3DAT=DATtoDAC(Vout[3]);
  78. }
  79. void lock_StabPulse_i2c(void)
  80. {
  81. // define variables
  82. unsigned int cnt_N, tg_cnt;
  83. double sum,sum_gnd;
  84. unsigned short Vout2;
  85. double Vin,Vin_gnd;
  86. int Vmean;
  87. int step = 100;
  88. short armed; // this is used to detect the trigger :
  89. // when the trigger input is low armed is set to 1
  90. // when a measurement start it is set to 0
  91. int k;
  92. unsigned short Data[256];
  93. POWKEY1 = 0x01;
  94. POWCON = 0x00; // 41.78MHz
  95. POWKEY2 = 0xF4;
  96. //GP1CON = 0x00000000; // IO initialization
  97. //GP1DAT = 0xFF000000; // set P1.n as digital output
  98. GP0CON = 0x00000000; // IO initialization
  99. //GP0DAT = 0x00000000; // set P0.n as digital input
  100. // ADC&DAC setting
  101. ADCpoweron(20000); // power on ADC
  102. REFCON = 0x01; // internal 2.5V reference
  103. DAC0CON = 0x12; // AGND-ARef range 0x12 2.5V
  104. DAC1CON = 0x12; // AGND-ARef range 0x12 2.5V
  105. DAC2CON = 0x12; // AGND-ARef range 0x12 2.5V
  106. DAC3CON = 0x12; // AGND-ARef range 0x12 2.5V
  107. ADCCP = 0x03; // conversion on ADC0
  108. ADCCON = 0x3E4; // continuous conversion
  109. // IO setting
  110. GP2CON = 0x00000000; // IO initialization
  111. GP2DAT = 0xFF000000; // set P2.n as digital output
  112. GP0CON = 0x00000000; // IO initialization
  113. GP0DAT = 0x00000000; // set P0.n as digital input
  114. // locking parameters initialization
  115. // cnt = 0; //
  116. N = 50; // number of measume,ts for averaging
  117. Vin = 0; // initialize the voltage of first step
  118. Vmean = 2000;
  119. start = 20;
  120. stop = 30;
  121. start_gnd = 0;
  122. stop_gnd = 10;
  123. wf_len = 256;
  124. Vset = 10;
  125. step = 50;
  126. step_max = 100;
  127. Gain = 1;
  128. // I2C on P1.0 and P1.1
  129. GP1CON = 0x22;
  130. IRQ = My_IRQ_Handler;
  131. IRQEN = 0x200; // I2C0 Slave Interupt
  132. I2C0CFG = 0x04001;
  133. // Slave ID
  134. I2C0ID0 = (0x50 + (((GP0DAT&0x000000FF)>>5)&0x1)+(((GP0DAT&0x000000FF)>>7)&0x1)*2)<<1;
  135. I2C0STX = 0x00;
  136. I2C0STX = 0x00;
  137. // assignation of the different pointers for the I2C exchange of data
  138. for (k=0;k<16;k++){
  139. plist[k] = (unsigned char*)(BigDat+k*16);
  140. plist[k+50] = (unsigned char*)(text+k*32);
  141. }
  142. for(i=0;i<BIGDAT_SZ;i++)
  143. BigDat[i]=0;
  144. sprintf(text,"pulse stabilization => %s\ncompiled: %s\nbecause we can!",__func__,__DATE__);
  145. for (k=0;k<4;k++){
  146. plist[100+k] = (unsigned char*)(Vout+k);
  147. }
  148. // 104
  149. // 105
  150. plist[120] = (unsigned char*)&I2C0ID0;
  151. plist[121] = (unsigned char*)&ADCCP;
  152. plist[122] = (unsigned char*)&transf;
  153. plist[123] = (unsigned char*)&wf_len;
  154. plist[124] = (unsigned char*)&trigg_cnt;
  155. plist[125] = (unsigned char*)&Vset;
  156. plist[126] = (unsigned char*)&N;
  157. plist[127] = (unsigned char*)&start;
  158. plist[128] = (unsigned char*)&stop;
  159. plist[129] = (unsigned char*)&start2;
  160. plist[130] = (unsigned char*)&stop2;
  161. plist[131] = (unsigned char*)&start_gnd;
  162. plist[132] = (unsigned char*)&stop_gnd;
  163. plist[133] = (unsigned char*)&enab_gnd;
  164. plist[134] = (unsigned char*)&Gain;
  165. plist[135] = (unsigned char*)&step_max;
  166. DAC0DAT = DATtoADC(10);
  167. DAC1DAT = DATtoADC(20);
  168. DAC2DAT = DATtoADC(2000);
  169. DAC3DAT = DATtoADC(40);
  170. Vset=0;
  171. Vout[3] = 111;
  172. set_DACs();
  173. transf = 0;
  174. trigg_cnt = 0;
  175. tg_cnt = 0;
  176. cnt_N = 0;
  177. enab_gnd = 0;
  178. // main loop for the locking
  179. while(1){
  180. // trigg in is on p0.3 => we check that it is low first (rising edge detection)
  181. if((((GP0DAT&0x000000FF)>>3)&0x1)==0){
  182. armed = 1;
  183. }
  184. // now p0.3 is high => this is our rising edge
  185. if((((GP0DAT&0x000000FF)>>3)&0x1)==1 && armed==1){
  186. armed = 0;
  187. //*** aquisition of the waveform ***
  188. for(k=0;k<wf_len;k++){
  189. while(!ADCSTA){} // wait for the end of ADC conversion
  190. Data[k]= (ADCDAT&0xFFF0000)>>16; // read voltage from ADC0
  191. }
  192. tg_cnt++;
  193. //*** copy for the i2c ***
  194. while(transf==1){} // we make sure that the data are not changed during the transfer
  195. memcpy(BigDat,Data,256*sizeof(short));
  196. trigg_cnt = tg_cnt;
  197. if (cnt_N==0){
  198. sum = 0; // initialization of the measurement
  199. sum_gnd = 0;
  200. }
  201. cnt_N++;
  202. //sum of the data
  203. for(k=start;k<stop;k++){
  204. sum += Data[k];
  205. //cnt++;
  206. }
  207. for(k=start_gnd;k<stop_gnd;k++){
  208. sum_gnd += Data[k];
  209. //cnt_gnd++;
  210. }
  211. if(cnt_N>=N){
  212. Vin = sum/(cnt_N*(stop-start)); // calculate average value
  213. Vin_gnd = sum_gnd/(cnt_N*(stop_gnd-start_gnd)); // calculate average value
  214. }
  215. //*** feedback *** (mode is on pin p0.6)
  216. // LOCK MODE
  217. if((((GP0DAT&0x000000FF)>>6)&0x1)==1){
  218. if(cnt_N>=N){
  219. cnt_N=0;
  220. //cnt_gnd=0;
  221. step = (Vset-Vin+Vin_gnd*enab_gnd)*Gain;
  222. if (step>step_max)
  223. step = step_max;
  224. else if (step<-step_max)
  225. step = -step_max;
  226. Vout2 = Vout2 + step;
  227. if(Vout2>4095){
  228. Write_Digital(0,1);
  229. Vout2 = 4090;
  230. }
  231. else{
  232. Write_Digital(0,0);
  233. }
  234. }
  235. }
  236. // LEARN MODE
  237. // we set the outputs to the average voltage
  238. // and save the current input level as the set point of the next locking enable
  239. else{
  240. if(cnt_N>=N){
  241. Vset = Vin-Vin_gnd*enab_gnd;
  242. cnt_N=0;
  243. }
  244. Vout2 = Vmean;
  245. }
  246. //this line could also be inserted in the if conditions and thus not set every loops
  247. DAC2DAT = DATtoADC(Vout2); // output voltage
  248. }
  249. }
  250. }
  251. int main(void)
  252. {
  253. lock_StabPulse_i2c();
  254. return 0;
  255. }
  256. /*************************************************/
  257. /*************************************************/
  258. /************ IRQ Service Routine *************/
  259. /*************************************************/
  260. /*************************************************/
  261. void My_IRQ_Handler()
  262. {
  263. int status = I2C0SSTA;
  264. // Slave Recieve
  265. if ((status & 0x08)==0x08) // Slave Recieve IRQ
  266. {
  267. if(first==1){
  268. first=0;
  269. Byte_addr=I2C0SRX;
  270. I2C0FSTA|= 1 << 8;
  271. i2c_cnt = 0;
  272. if(Byte_addr==122)
  273. transf = 1;
  274. if(Byte_addr==104)
  275. get_DACs();
  276. if(Byte_addr==105)
  277. set_DACs();
  278. Write_Digital(2,0);
  279. pbuff = plist[Byte_addr];
  280. I2C0STX = pbuff[0];
  281. }
  282. else {
  283. pbuff[i2c_cnt] = I2C0SRX;
  284. i2c_cnt++;
  285. }
  286. }
  287. // Slave Transmit
  288. else if ((status & 0x04)==0x04) // Slave Transmit IRQ
  289. {
  290. i2c_cnt ++;
  291. I2C0STX = pbuff[i2c_cnt];
  292. I2C0ADR = 0xA1;
  293. //if(Byte_addr>=110 && Byte_addr<=113 && i2c_cnt==1)
  294. //set_DACs();
  295. }
  296. else if((status & 0x0400)==0x0400) //
  297. {
  298. first = 1;
  299. //Write_Digital(2,1);
  300. }
  301. // either we transfer a waveform or some parameters
  302. // and when it is done we should put back transf = 0
  303. /*if((i2c_cnt>31 && Byte_addr==15) || (i2c_cnt>1 && Byte_addr>15)){
  304. Write_Digital(2,1);
  305. transf = 0;
  306. } */
  307. /*if(i2c_cnt>31 && Byte_addr==15){
  308. Write_Digital(2,1);
  309. transf = 0;
  310. }*/
  311. }