DemoMem.C 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. /*
  2. v1.2
  3. this program use old code used in another experiment
  4. "int" is used for the ADC and DAC data although it should be unsigned,
  5. it should be not a problem at all as this data are limited to 12bits...
  6. */
  7. #include<ADuC7020.h>
  8. #include<stdlib.h>
  9. #include<stdio.h>
  10. #include<string.h>
  11. void My_IRQ_Handler(void);
  12. short i = 0;
  13. unsigned char Byte_addr = 0;
  14. int first = 1;
  15. int i2c_cnt = 0;
  16. #define BIGDAT_SZ 256
  17. unsigned short BigDat[BIGDAT_SZ];
  18. char text[512];
  19. unsigned short Vout[4];
  20. unsigned short Vlearn;
  21. double Vin,Vin_gnd;
  22. unsigned short start, stop,start_gnd,stop_gnd,start2,stop2,Vset,wf_len, step_max,N;
  23. unsigned short int FEE_addr;
  24. unsigned char transf,enab_gnd,busy,remote_trigg;
  25. unsigned int trigg_cnt,v_cnt,wf_cnt;
  26. unsigned short test;
  27. unsigned short probe;
  28. float Gain;
  29. //char format = 0;
  30. unsigned char* pbuff;
  31. unsigned char* plist[256];
  32. unsigned char ERROR;
  33. unsigned int status, uiTest, uiTest1, uiTest2;
  34. unsigned short ucVerifyTest = 0;
  35. #pragma pack(1)
  36. struct Test
  37. {
  38. char AA;
  39. int BB;
  40. char CC;
  41. };
  42. void delay (int length)
  43. {
  44. while (length >=0)
  45. length--;
  46. }
  47. // conversion of the read value into it corresponding 12bits integer
  48. int ADCtoDAT(unsigned long ADC)
  49. {
  50. return (ADC&0xFFF0000)>>16;
  51. }
  52. unsigned long DATtoADC(int DAT)
  53. {
  54. unsigned long ADC;
  55. ADC=DAT;
  56. return ADC<<16;
  57. }
  58. unsigned long DATtoDAC(unsigned short DAT)
  59. {
  60. unsigned int ADC;
  61. ADC=DAT;
  62. return ADC<<16;
  63. }
  64. int Read_Digital(int n)
  65. {
  66. return ((GP0DAT&0x000000FF)>>n)&0x1;
  67. }
  68. void Write_Digital(int n, int state)
  69. {
  70. if(state==1)
  71. GP2DAT=(0x00000001<<(n+16))|GP2DAT;
  72. else
  73. GP2DAT=~((0x00000001<<(n+16))|(~GP2DAT));
  74. }
  75. void ADCpoweron(int time)
  76. {
  77. ADCCON = 0x620; // power-on the ADC
  78. while (time >=0) // wait for ADC to be fully powered on
  79. time--;
  80. }
  81. void get_DACs(void)
  82. {
  83. Vout[0]=DAC0DAT>>16;
  84. Vout[1]=DAC1DAT>>16;
  85. Vout[2]=DAC2DAT>>16;
  86. Vout[3]=DAC3DAT>>16;
  87. }
  88. void set_DACs(void)
  89. {
  90. DAC0DAT=DATtoDAC(Vout[0]);
  91. DAC1DAT=DATtoDAC(Vout[1]);
  92. DAC2DAT=DATtoDAC(Vout[2]);
  93. DAC3DAT=DATtoDAC(Vout[3]);
  94. }
  95. void protect_page(unsigned int addr){
  96. FEEADR = 0x1234; // Key
  97. FEEDAT = 0x1234; // Key
  98. FEEPRO = addr;
  99. FEEMOD = 0x48;
  100. FEECON = 0x0C;
  101. status = FEESTA&0x03;
  102. while (!(status)) status = FEESTA&0x03;
  103. if ((status&0x02)==0x02) //ERROR = 1;
  104. return; // return
  105. }
  106. unsigned short load(unsigned short int addr){
  107. FEEADR = addr;
  108. FEECON = 0x01; // single read command
  109. status = FEESTA;
  110. probe = status;
  111. while ((status&0x04)==0x04) status = FEESTA;
  112. if ((status&0x02)==0x02){
  113. return 66;
  114. // ERROR = 1;
  115. }
  116. return (FEEDAT);
  117. }
  118. void save(unsigned short int addr, unsigned short data){
  119. //FEEMOD = 0x8;
  120. FEEADR = addr; // set data address
  121. FEEDAT = data; // set data value
  122. FEECON = 0x02; // single Write command
  123. status = FEESTA;
  124. probe = status;
  125. while ((status&0x04)==0x04) status = FEESTA;
  126. if ((status&0x02)==0x02) ERROR = 0;
  127. //FEEMOD = 0x0;
  128. //protect_page(0xBFFFFFFF);
  129. return;
  130. }
  131. void erase_page(unsigned short int addr){
  132. FEEADR = addr; // set data address
  133. FEECON = 0x05; // erase page command
  134. status = FEESTA;
  135. probe = status;
  136. while ((status&0x04)==0x04) status = FEESTA;
  137. if ((status&0x02)==0x02) ERROR = 0;
  138. return;
  139. }
  140. void init(void)
  141. {
  142. test = load(FEE_addr);
  143. }
  144. void erase(void)
  145. {
  146. erase_page(FEE_addr); // erase page 120
  147. }
  148. void update(void)
  149. {
  150. save(FEE_addr, test);
  151. //protect_page(0xBFFFFFFF); // protect pages
  152. }
  153. void lock_StabPulse_i2c(void)
  154. {
  155. // define variables
  156. unsigned int cnt_N;
  157. double sum,sum_gnd;
  158. unsigned short Vout2;
  159. //double Vin,Vin_gnd;
  160. //int Vmean;
  161. int step = 100;
  162. short armed; // this is used to detect the trigger :
  163. // when the trigger input is low armed is set to 1
  164. // when a measurement start it is set to 0
  165. short valid_data;
  166. int k;
  167. unsigned short Data[256];
  168. //unsigned int tmp_dat[256];
  169. POWKEY1 = 0x01;
  170. POWCON = 0x00; // 41.78MHz
  171. POWKEY2 = 0xF4;
  172. //GP1CON = 0x00000000; // IO initialization
  173. //GP1DAT = 0xFF000000; // set P1.n as digital output
  174. GP0CON = 0x00000000; // IO initialization
  175. //GP0DAT = 0x00000000; // set P0.n as digital input
  176. // ADC&DAC setting
  177. ADCpoweron(20000); // power on ADC
  178. REFCON = 0x01; // internal 2.5V reference
  179. DAC0CON = 0x12; // AGND-ARef range 0x12 2.5V
  180. DAC1CON = 0x12; // AGND-ARef range 0x12 2.5V
  181. DAC2CON = 0x12; // AGND-ARef range 0x12 2.5V
  182. DAC3CON = 0x12; // AGND-ARef range 0x12 2.5V
  183. ADCCP = 0x03; // conversion on ADC0
  184. ADCCON = 0x3E4; // continuous conversion
  185. // IO setting
  186. GP2CON = 0x00000000; // IO initialization
  187. GP2DAT = 0xFF000000; // set P2.n as digital output
  188. GP0CON = 0x00000000; // IO initialization
  189. GP0DAT = 0x00000000; // set P0.n as digital input
  190. FEEMOD = 0x8;
  191. delay(20);
  192. FEE_addr = 0xF000;
  193. //init();
  194. //FEEPRO = 0x40000000;
  195. //test=0;
  196. // locking parameters initialization
  197. // cnt = 0; //
  198. N = 10; // number of measume,ts for averaging
  199. Vin = 0; // initialize the voltage of first step
  200. Vin_gnd = 0;
  201. // Vmean = 2000;
  202. start = 20;
  203. stop = 30;
  204. start_gnd = 0;
  205. stop_gnd = 10;
  206. wf_len = 200;
  207. Vset = 200;
  208. Vlearn = 2000;
  209. step = 50;
  210. step_max = 100;
  211. Gain = 1;
  212. // I2C on P1.0 and P1.1
  213. GP1CON = 0x22;
  214. IRQ = My_IRQ_Handler;
  215. IRQEN = 0x200; // I2C0 Slave Interupt
  216. I2C0CFG = 0x04001;
  217. // Slave ID
  218. I2C0ID0 = (0x50 + (((GP0DAT&0x000000FF)>>5)&0x1)+(((GP0DAT&0x000000FF)>>7)&0x1)*2)<<1;
  219. I2C0STX = 0x00;
  220. I2C0STX = 0x00;
  221. // assignation of the different pointers for the I2C exchange of data
  222. for (k=0;k<16;k++){
  223. plist[k] = (unsigned char*)(BigDat+k*16);
  224. plist[k+50] = (unsigned char*)(text+k*32);
  225. }
  226. for(i=0;i<BIGDAT_SZ;i++)
  227. BigDat[i]=0;
  228. sprintf(text,"pulse stabilization v1.2 => %s\ncompiled: %s\nbecause we can!",__func__,__DATE__);
  229. for (k=0;k<4;k++){
  230. plist[100+k] = (unsigned char*)(Vout+k);
  231. }
  232. // 104 to execute the function get_DACs
  233. // 105 to execute the function set_DACs
  234. plist[110] = (unsigned char*)&Vlearn;
  235. plist[111] = (unsigned char*)&Vin;
  236. plist[112] = (unsigned char*)&Vin_gnd;
  237. plist[113] = (unsigned char*)&wf_cnt;
  238. plist[114] = (unsigned char*)&v_cnt;
  239. plist[115] = (unsigned char*)&remote_trigg;
  240. plist[120] = (unsigned char*)&I2C0ID0;
  241. plist[121] = (unsigned char*)&ADCCP;
  242. plist[122] = (unsigned char*)&transf;
  243. plist[123] = (unsigned char*)&wf_len;
  244. plist[124] = (unsigned char*)&trigg_cnt;
  245. plist[125] = (unsigned char*)&Vset;
  246. plist[126] = (unsigned char*)&N;
  247. plist[127] = (unsigned char*)&start;
  248. plist[128] = (unsigned char*)&stop;
  249. plist[129] = (unsigned char*)&start2;
  250. plist[130] = (unsigned char*)&stop2;
  251. plist[131] = (unsigned char*)&start_gnd;
  252. plist[132] = (unsigned char*)&stop_gnd;
  253. plist[133] = (unsigned char*)&enab_gnd;
  254. plist[134] = (unsigned char*)&Gain;
  255. plist[135] = (unsigned char*)&step_max;
  256. plist[141] = (unsigned char*)&test;
  257. plist[142] = (unsigned char*)&probe;
  258. plist[140] = (unsigned char*)&FEE_addr;
  259. DAC0DAT = DATtoADC(10);
  260. DAC1DAT = DATtoADC(20);
  261. DAC2DAT = DATtoADC(2000);
  262. DAC3DAT = DATtoADC(40);
  263. Vset=0;
  264. Vout[3] = 111;
  265. set_DACs();
  266. transf = 0;
  267. trigg_cnt = 0;
  268. wf_cnt = 0;
  269. v_cnt = 0;
  270. cnt_N = 0;
  271. enab_gnd = 0;
  272. remote_trigg = 0;
  273. valid_data=0;
  274. // main loop for the locking
  275. while(1){
  276. // trigg in is on p0.3 => we check that it is low first (rising edge detection)
  277. if((((GP0DAT&0x000000FF)>>3)&0x1)==0){
  278. armed = 1;
  279. }
  280. // now p0.3 is high => this is our rising edge
  281. if(((((GP0DAT&0x000000FF)>>3)&0x1)==1 && armed==1) || remote_trigg){
  282. armed = 0;
  283. //busy = 0;
  284. //*** aquisition of the waveform ***
  285. /*for(k=0;k<wf_len;k++){
  286. while(!ADCSTA){} // wait for the end of ADC conversion
  287. tmp_dat[k]= ADCDAT; // read voltage from ADC0
  288. }
  289. for(k=0;k<wf_len;k++){
  290. Data[k]= (tmp_dat[k]&0xFFF0000)>>16; // read voltage from ADC0
  291. }*/
  292. for(k=0;k<wf_len;k++){
  293. while(!ADCSTA){} // wait for the end of ADC conversion
  294. Data[k]= (unsigned short)(ADCDAT >> 16); // read voltage from ADC0
  295. }
  296. trigg_cnt++;
  297. if(busy==0){ // supposed to guaranty that no i2c transfer has been performed during the wf acquisition
  298. //*** copy for the i2c ***
  299. memcpy(BigDat,Data,256*sizeof(short));
  300. wf_cnt++;
  301. cnt_N++;
  302. //sum of the data
  303. for(k=start;k<stop;k++){
  304. sum += Data[k];
  305. //cnt++;
  306. }
  307. for(k=start_gnd;k<stop_gnd;k++){
  308. sum_gnd += Data[k];
  309. //cnt_gnd++;
  310. }
  311. if(cnt_N>=N){
  312. Vin = sum/(cnt_N*(stop-start)); // calculate average value
  313. Vin_gnd = sum_gnd/(cnt_N*(stop_gnd-start_gnd)); // calculate average value
  314. valid_data = 1;
  315. v_cnt++;
  316. sum = 0; // initialization of the measurement
  317. sum_gnd = 0;
  318. cnt_N = 0;
  319. }
  320. }
  321. else busy = 0;
  322. //*** feedback *** (mode is on pin p0.6)
  323. // LOCK MODE
  324. if((((GP0DAT&0x000000FF)>>6)&0x1)==1){
  325. if(valid_data==1){
  326. valid_data=0;
  327. cnt_N=0;
  328. //cnt_gnd=0;
  329. step = (Vset-Vin+Vin_gnd*enab_gnd)*Gain;
  330. if (step>step_max)
  331. step = step_max;
  332. else if (step<-step_max)
  333. step = -step_max;
  334. Vout2 = Vout2 + step;
  335. if(Vout2>4095){
  336. Write_Digital(0,1);
  337. Vout2 = 4090;
  338. }
  339. else{
  340. Write_Digital(0,0);
  341. }
  342. }
  343. }
  344. // LEARN MODE
  345. // we set the outputs to the average voltage
  346. // and save the current input level as the set point of the next locking enable
  347. else{
  348. if(valid_data==1){
  349. valid_data=0;
  350. Vset = Vin-Vin_gnd*enab_gnd;
  351. cnt_N=0;
  352. }
  353. Vout2 = Vlearn;
  354. }
  355. //this line could also be inserted in the if conditions and thus not set every loops
  356. DAC2DAT = DATtoADC(Vout2); // output voltage
  357. }
  358. }
  359. }
  360. int main(void)
  361. {
  362. lock_StabPulse_i2c();
  363. return 0;
  364. }
  365. /*************************************************/
  366. /*************************************************/
  367. /************ IRQ Service Routine *************/
  368. /*************************************************/
  369. /*************************************************/
  370. void My_IRQ_Handler()
  371. {
  372. int status = I2C0SSTA;
  373. busy = 1;
  374. // Slave Recieve
  375. if ((status & 0x08)==0x08) // Slave Recieve IRQ
  376. {
  377. if(first==1){
  378. first=0;
  379. Byte_addr=I2C0SRX;
  380. I2C0FSTA|= 1 << 8;
  381. i2c_cnt = 0;
  382. if(Byte_addr==122)
  383. transf = 1;
  384. if(Byte_addr==104){
  385. // get_DACs();
  386. init();
  387. }
  388. if(Byte_addr==105){
  389. // set_DACs();
  390. update();
  391. }
  392. if(Byte_addr==106)
  393. erase();
  394. Write_Digital(2,0);
  395. pbuff = plist[Byte_addr];
  396. I2C0STX = pbuff[0];
  397. }
  398. else {
  399. pbuff[i2c_cnt] = I2C0SRX;
  400. i2c_cnt++;
  401. }
  402. }
  403. // Slave Transmit
  404. else if ((status & 0x04)==0x04) // Slave Transmit IRQ
  405. {
  406. i2c_cnt ++;
  407. I2C0STX = pbuff[i2c_cnt];
  408. I2C0ADR = 0xA1;
  409. //if(Byte_addr>=110 && Byte_addr<=113 && i2c_cnt==1)
  410. //set_DACs();
  411. }
  412. else if((status & 0x0400)==0x0400) //
  413. {
  414. first = 1;
  415. //Write_Digital(2,1);
  416. }
  417. busy=1;
  418. }