calibration.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. #include <string.h>
  2. #include "LabArm.h"
  3. uint8_t MenuMode;
  4. typedef struct
  5. {
  6. uint32_t Adc;
  7. int16_t Dac; /* 1 - 4095 */
  8. int16_t Out; /* 1 - 9999 */
  9. int8_t DotPosition; /* 0,1,2,3,4 */
  10. int8_t Ok; /* Fiilled flag */
  11. int16_t Res;
  12. }Calibration_t;
  13. Calibration_t VMax;
  14. Calibration_t VMin;
  15. Calibration_t IMax;
  16. Calibration_t IMin;
  17. static Calibration_t* Cur;
  18. static char* Text;
  19. __IO static uint32_t* CurDac;
  20. uint8_t Contrast;
  21. MenuFunction_t AfterContrast;
  22. void ContrastMenu(void)
  23. {
  24. if (Event == EV_FUNC_FIRST)
  25. {
  26. // Contrast = CurrentSettings.VoltageDAC>>12;
  27. LcdBlank(); /* Clear screen */
  28. LcdChr(Y_POSITION*1 + X_POSITION * 0 + 14, "Contrast");
  29. LcdChr(Y_POSITION*4 + X_POSITION * 0 + 14, "Press");
  30. LcdChr(Y_POSITION*5 + X_POSITION * 0 + 14, "to exit");
  31. goto redraw;
  32. }
  33. if ( (Event & EV_MASK) == EV_KEY_PRESSED )
  34. {
  35. switch (Event & KEY_MASK)
  36. {
  37. case KEY_UP:
  38. if ( Contrast < 15 )
  39. Contrast++;
  40. break;
  41. case KEY_DOWN:
  42. if ( Contrast > 0 )
  43. Contrast--;
  44. break;
  45. case KEY_ENTER:
  46. LcdContrast ( Contrast*3+42 );
  47. CurrentFunc(AfterContrast);
  48. return;
  49. }
  50. redraw:
  51. LcdContrast ( Contrast*3+42 );
  52. {
  53. char Buf[2];
  54. uint8_t Counter = Contrast;
  55. Buf[0] = Counter/10 + '0';
  56. Counter = Counter%10;
  57. Buf[1] = Counter + '0';
  58. LcdChr(BIG_UP+Y_POSITION*2 + X_POSITION * 2 + 2, Buf);
  59. LcdChr(BIG_DOWN+Y_POSITION*3 + X_POSITION * 2 + 2, Buf);
  60. }
  61. }
  62. }
  63. static float Offset(float YMax, float YMin, float XMax, float XMin)
  64. {
  65. return (YMin*XMax - YMax*XMin)/(XMax-XMin);
  66. }
  67. static void CalibrationToConfig(Config_t* Config)
  68. {
  69. int i;
  70. Config->V.ADCRamp = ((float)(VMax.Out - VMin.Out))/(VMax.Adc-VMin.Adc);
  71. Config->V.ADCOffset = Offset(VMax.Out, VMin.Out, VMax.Adc, VMin.Adc);
  72. Config->I.ADCRamp = ((float)(IMax.Out - IMin.Out))/(IMax.Adc-IMin.Adc);
  73. Config->I.ADCOffset = Offset(IMax.Out, IMin.Out, IMax.Adc, IMin.Adc);
  74. Config->V.DACRamp = ((float)(VMax.Out - VMin.Out))/(VMax.Dac-VMin.Dac);
  75. Config->V.DACOffset = Offset(VMax.Out, VMin.Out, VMax.Dac, VMin.Dac);
  76. Config->I.DACRamp = ((float)(IMax.Out - IMin.Out))/(IMax.Dac-IMin.Dac);
  77. Config->I.DACOffset = Offset(IMax.Out,IMin.Out,IMax.Dac, IMin.Dac);
  78. Config->V.DotPosition = VMax.DotPosition;
  79. Config->I.DotPosition = IMax.DotPosition;
  80. /* Check menu correctness */
  81. for (i=0; i<12; i++)
  82. {
  83. UserMenu_t* Menu = &CurrentConfig.Menu[i];
  84. if ( (Menu->IVFlag == MENU_I_FLAG && IMax.DotPosition != Menu->DotPosition ) ||
  85. (Menu->IVFlag == MENU_V_FLAG && VMax.DotPosition != Menu->DotPosition ) ) /* Dot position was changed */
  86. {
  87. memset(Menu, 0xFF, sizeof(*Menu)); /* Clear the menu */
  88. }
  89. }
  90. }
  91. void OutValue(uint8_t Y, uint8_t X, uint16_t Num, uint8_t DotPosition, uint8_t SelectPos)
  92. {
  93. int i;
  94. int Div = 1000;
  95. uint8_t DisplayFlag = 0;
  96. for(i=0; i<4; i++)
  97. {
  98. char Chr;
  99. uint32_t Light = 0;
  100. if (i == DotPosition )
  101. {
  102. LcdChr ( Y_POSITION*(Y)+X_POSITION*X+1, " " );
  103. LcdChr ( Y_POSITION*(Y+1)+X_POSITION*X+1, "." );
  104. X=X+1;
  105. DisplayFlag++;
  106. }
  107. if ( DisplayFlag == 0 && i == (DotPosition - 1))
  108. {
  109. DisplayFlag++;
  110. }
  111. Chr = Num / Div;
  112. if ( DisplayFlag == 0 && Chr == 0)
  113. Chr = ' ';
  114. else
  115. {
  116. DisplayFlag = 1;
  117. Chr = Chr + '0';
  118. }
  119. if (i == SelectPos)
  120. {
  121. Light = INVERSE;
  122. }
  123. LcdChr (Light + Y_POSITION*Y+X_POSITION*X+BIG_UP+1, &Chr );
  124. LcdChr (Light + Y_POSITION*(Y+1)+X_POSITION*X+BIG_DOWN+1, &Chr );
  125. X = X + 2;
  126. Num = Num % Div;
  127. Div = Div / 10;
  128. }
  129. if ( DotPosition == 4)
  130. {
  131. LcdChr ( Y_POSITION*(Y)+X_POSITION*X+1, " " );
  132. LcdChr ( Y_POSITION*(Y+1)+X_POSITION*X+1, " " );
  133. }
  134. }
  135. void OutValueSmall(uint8_t Y, uint8_t X, uint16_t Num, uint8_t DotPosition, uint8_t InverseFlag)
  136. {
  137. int i;
  138. int Div = 1000;
  139. uint32_t Light = InverseFlag?INVERSE:0;
  140. uint8_t DisplayFlag=0;
  141. for(i=0; i<4; i++)
  142. {
  143. char Chr;
  144. if (i == DotPosition)
  145. {
  146. DisplayFlag = 1;
  147. LcdChr ( Light + Y_POSITION*(Y)+X_POSITION*X+1, "." );
  148. X=X+1;
  149. DisplayFlag++;
  150. }
  151. if ( DisplayFlag == 0 && i == (DotPosition - 1))
  152. {
  153. DisplayFlag++;
  154. }
  155. Chr = Num / Div;
  156. if ( DisplayFlag == 0 && Chr == 0)
  157. Chr = ' ';
  158. else
  159. {
  160. DisplayFlag = 1;
  161. Chr = Chr + '0';
  162. }
  163. LcdChr (Light + Y_POSITION*Y+X_POSITION*X+1, &Chr );
  164. X = X + 1;
  165. Num = Num % Div;
  166. Div = Div / 10;
  167. }
  168. if ( DotPosition == 4)
  169. {
  170. LcdChr ( Y_POSITION*(Y)+X_POSITION*X+1, " " );
  171. }
  172. }
  173. void CalibrationMenuInternal(void);
  174. void SaveMenu(void)
  175. {
  176. if (Event == EV_FUNC_FIRST)
  177. {
  178. MenuMode = 0;
  179. LcdBlank(); /* Clear screen */
  180. goto redraw;
  181. }
  182. if ( (Event & EV_MASK) == EV_KEY_PRESSED )
  183. {
  184. switch (Event & KEY_MASK)
  185. {
  186. case KEY_UP:
  187. if ( MenuMode == 0 )
  188. MenuMode = 1;
  189. break;
  190. case KEY_DOWN:
  191. if ( MenuMode != 0 )
  192. MenuMode = 0;
  193. break;
  194. case KEY_ENTER:
  195. if (MenuMode != 0)
  196. {
  197. SaveConfig();
  198. }
  199. CurrentFunc(StartFunction);
  200. return;
  201. }
  202. }
  203. else
  204. return;
  205. redraw:
  206. LcdChr(X_POSITION*0+Y_POSITION*1+14 + (0==MenuMode)*INVERSE, "Save to memory");
  207. LcdChr(X_POSITION*0+Y_POSITION*2+14 + (1==MenuMode)*INVERSE, "Save to flash");
  208. }
  209. void SetDac(void);
  210. void SelectDot(void)
  211. {
  212. if (Event == EV_FUNC_FIRST)
  213. {
  214. LcdBlank(); /* Clear screen */
  215. goto redraw;
  216. }
  217. if ( (Event & EV_MASK) == EV_KEY_PRESSED )
  218. {
  219. switch (Event & KEY_MASK)
  220. {
  221. case KEY_UP:
  222. Cur->DotPosition++;
  223. if (Cur->DotPosition>4)
  224. Cur->DotPosition = 4;
  225. goto redraw;
  226. case KEY_DOWN:
  227. Cur->DotPosition--;
  228. if (Cur->DotPosition<0)
  229. Cur->DotPosition = 0;
  230. goto redraw;
  231. case KEY_ENTER:
  232. CurrentFunc(SetDac);
  233. }
  234. }
  235. return;
  236. redraw:
  237. LcdChr(X_POSITION*0+Y_POSITION*1+14, Text);
  238. LcdChr(X_POSITION*0+Y_POSITION*2+14, "Set Dot");
  239. OutValue(3, 1, Cur->Out, Cur->DotPosition, 0xFF);
  240. }
  241. int16_t IncrementMul;
  242. int8_t ChangeNumberFlag;
  243. void SetOut(void)
  244. {
  245. if (Event == EV_FUNC_FIRST)
  246. {
  247. LcdBlank(); /* Clear screen */
  248. MenuMode = 0;
  249. IncrementMul = 1000;
  250. ChangeNumberFlag = 0;
  251. LcdChr(X_POSITION*0+Y_POSITION*1+14, Text);
  252. LcdChr(X_POSITION*0+Y_POSITION*2+14, "Set Out");
  253. LcdChr(X_POSITION*0+Y_POSITION*5+14, "Longkey to end");
  254. goto redraw;
  255. }
  256. if ( (Event & EV_MASK) == EV_KEY_PRESSED )
  257. {
  258. switch (Event & KEY_MASK)
  259. {
  260. case KEY_UP:
  261. if ( ChangeNumberFlag )
  262. {
  263. Cur->Out += IncrementMul;
  264. goto redraw;
  265. }
  266. else
  267. {
  268. if ( MenuMode < 3 )
  269. {
  270. IncrementMul /= 10;
  271. MenuMode++;
  272. goto redraw;
  273. }
  274. }
  275. return;
  276. case KEY_DOWN:
  277. if ( ChangeNumberFlag )
  278. {
  279. Cur->Out -= IncrementMul;
  280. goto redraw;
  281. }
  282. else
  283. {
  284. if ( MenuMode > 0 )
  285. {
  286. IncrementMul *= 10;
  287. MenuMode--;
  288. goto redraw;
  289. }
  290. }
  291. return;
  292. case KEY_ENTER:
  293. if ( ChangeNumberFlag == 0 )
  294. ChangeNumberFlag = 1;
  295. else
  296. ChangeNumberFlag = 0;
  297. return;
  298. }
  299. }
  300. if ( (Event & EV_MASK) == EV_KEY_LONG )
  301. {
  302. Cur->Ok = 1;
  303. CurrentFunc(CalibrationMenuInternal);
  304. }
  305. return;
  306. redraw:
  307. OutValue(3, 1, Cur->Out, Cur->DotPosition, MenuMode);
  308. }
  309. void WaitMeasure(void)
  310. {
  311. if (Event == EV_FUNC_FIRST)
  312. {
  313. LcdBlank(); /* Clear screen */
  314. LcdChr(X_POSITION*0+Y_POSITION*3+14, "Please wait");
  315. MenuMode = 0;
  316. return;
  317. }
  318. if ( (Event & EV_MASK) == EV_KEY_PRESSED &&
  319. (Event & KEY_MASK) == KEY_ADC ) /* End of conversion */
  320. {
  321. if (MenuMode == 2)
  322. {
  323. CurrentFunc(SetOut);
  324. if ( Cur == &VMax || Cur == &VMin )
  325. Cur->Adc = ADCVoltage;
  326. else
  327. Cur->Adc = ADCCurrent;
  328. }
  329. MenuMode++;
  330. }
  331. }
  332. void SetDac(void)
  333. {
  334. if (Event == EV_FUNC_FIRST)
  335. {
  336. LcdBlank(); /* Clear screen */
  337. LcdChr(X_POSITION*0+Y_POSITION*1+14, Text);
  338. LcdChr(X_POSITION*0+Y_POSITION*2+14, "Set Out");
  339. EncCounter = Cur->Dac;
  340. goto redraw;
  341. }
  342. if ( (Event & EV_MASK) == EV_KEY_PRESSED )
  343. {
  344. switch (Event & KEY_MASK)
  345. {
  346. case KEY_UP:
  347. case KEY_DOWN:
  348. Cur->Dac = EncCounter;
  349. goto redraw;
  350. case KEY_ENTER:
  351. CurrentFunc(WaitMeasure);
  352. }
  353. }
  354. return;
  355. redraw:
  356. OutValue(3, 1, Cur->Dac, 4, 0xFF);
  357. *CurDac = Cur->Dac;
  358. OutValueSmall(5,0, EncStep, 4, 0);
  359. }
  360. void CalibrationMenu(void)
  361. {
  362. /* Init The calibration */
  363. VMax.Ok = 0;
  364. VMin.Ok = 0;
  365. IMax.Ok = 0;
  366. IMin.Ok = 0;
  367. CurrentFunc(CalibrationMenuInternal);
  368. }
  369. void CalibrationMenuInternal(void)
  370. {
  371. if (Event == EV_FUNC_FIRST)
  372. {
  373. MenuMode = 0;
  374. LcdBlank(); /* Clear screen */
  375. goto redraw;
  376. }
  377. if ( (Event & EV_MASK) == EV_KEY_PRESSED )
  378. {
  379. switch (Event & KEY_MASK)
  380. {
  381. case KEY_DOWN:
  382. if ( MenuMode == 0 )
  383. MenuMode = 4;
  384. else
  385. MenuMode = MenuMode - 1;
  386. goto redraw;
  387. case KEY_UP:
  388. if ( MenuMode == 4 )
  389. MenuMode = 0;
  390. else
  391. MenuMode = MenuMode + 1;
  392. goto redraw;
  393. case KEY_ENTER:
  394. switch(MenuMode)
  395. {
  396. case 0:
  397. Cur = &VMax;
  398. Text = "Max Voltage";
  399. Cur->Dac = 3700;
  400. Cur->Out = 5555;
  401. Cur->DotPosition = 2;
  402. CurDac = &DAC_V;
  403. CurrentFunc(SelectDot);
  404. return;
  405. case 1:
  406. if (VMax.Ok == 0 ) /* The max value has not been set */
  407. return;
  408. Cur = &VMin;
  409. Text = "Min Voltage";
  410. Cur->Dac = 350;
  411. Cur->Out = 555;
  412. Cur->DotPosition = VMax.DotPosition;
  413. CurDac = &DAC_V;
  414. CurrentFunc(SetDac);
  415. return;
  416. case 2:
  417. Cur = &IMax;
  418. Text = "Max Current";
  419. Cur->Dac = 3700;
  420. Cur->Out = 5555;
  421. Cur->DotPosition = 2;
  422. CurDac = &DAC_I;
  423. DAC_V = 2000; /* Set intermidiate voltage value !!! */
  424. CurrentFunc(SelectDot);
  425. return;
  426. case 3:
  427. if (IMax.Ok == 0 ) /* The max value has not been set */
  428. return;
  429. Cur = &IMin;
  430. Text = "Min Current";
  431. Cur->Dac = 350;
  432. Cur->Out = 555;
  433. Cur->DotPosition = IMax.DotPosition;
  434. CurDac = &DAC_I;
  435. CurrentFunc(SetDac);
  436. return;
  437. default:
  438. if ( VMax.Ok && VMin.Ok && IMax.Ok && IMin.Ok )
  439. {
  440. CalibrationToConfig(&CurrentConfig);
  441. CurrentFunc(SaveMenu);
  442. }
  443. return;
  444. }
  445. }
  446. }
  447. return;
  448. redraw:
  449. LcdChr(X_POSITION*0+Y_POSITION*1+14 + (0==MenuMode)*INVERSE, "Max Voltage");
  450. LcdChr(X_POSITION*0+Y_POSITION*2+14 + (1==MenuMode)*INVERSE, "Min Voltage");
  451. LcdChr(X_POSITION*0+Y_POSITION*3+14 + (2==MenuMode)*INVERSE, "Max Current");
  452. LcdChr(X_POSITION*0+Y_POSITION*4+14 + (3==MenuMode)*INVERSE, "Min Current");
  453. if ( VMax.Ok && VMin.Ok && IMax.Ok && IMin.Ok )
  454. {
  455. LcdChr(X_POSITION*0+Y_POSITION*5+14 + (4==MenuMode)*INVERSE, "Ok");
  456. }
  457. else
  458. {
  459. LcdChr(X_POSITION*0+Y_POSITION*5+14 + (4==MenuMode)*INVERSE, "");
  460. }
  461. }