]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - source/commands.c
cbc56a3436a8b48b32aa5c7af6f78f518ac8516d
[pes-rpp/rpp-test-sw.git] / source / commands.c
1 /** @file commands.c
2 *   @brief Command definitions file
3 *   @date 31.July.2012
4 *
5 *  Command is defined by its function. The function and others parameters are stored as list element.
6 *  All commands represented as elements are stored in lists connected into one main list.
7 */
8
9 /* Include files */
10 #include "cmd_proc.h"
11 #include "sys_common.h"
12 #include "cmdio_tisci.h"
13 #include "string.h"
14 #include "stdio.h"
15 #include "can.h"
16 #include "adc.h"
17 #include "dmm.h"
18 #include "din.h"
19 #include "mout.h"
20 #include "hout.h"
21 #include "vbat.h"
22 #include "lin.h"
23
24 /** @brief Count of AD channels in ADC1
25 */
26 #define ADC1_CHANNEL_COUNT      12
27 /** @brief Count of AD channels in HOUT port
28 */
29 #define HOUT_IFBK_CHANNEL_COUNT         6
30
31 /** @brief List in which commands are stored */
32 cmd_des_t const **cmd_list;
33 /** @brief Semaphore blocking task when it waits for interrupt signaling message receive */
34 xSemaphoreHandle canMsgReceived;
35 xSemaphoreHandle canMsgSent;
36 xSemaphoreHandle linMsgReceived;
37 xSemaphoreHandle linIDReceived;
38 /** @brief Semaphore blocking task when it waits for interrupt signaling end of the conversion */
39 xSemaphoreHandle adcDataConverted;
40 /** @brief Data structure containing converted data from ADC */
41 ADCData_t adcData;
42
43 /** @brief Set of port adresses for each din pin
44  *
45  * Defined in din.c */
46 extern gioPORT_t * dinPorts[8];
47 /** @brief Set of port adresses for each mout pin
48  *
49  * Defined in mout.c */
50 extern gioPORT_t * moutPorts[12];
51 /** @brief Set of port adresses for each hout pin
52  *
53  * Defined in hout.c */
54 extern gioPORT_t * houtPorts[12];
55
56 /** @brief Set of bit indexes for each din pin
57  *
58  * Each element stores index of a bit in register assigned to din pin.
59  * Defined in din.c */
60 extern uint8_t dinBits[8];
61 /** @brief Set of bit indexes for each mout pin
62  *
63  * Each element stores index of a bit in register assigned to mout pin.
64  * Defined in din.c */
65 extern uint8_t moutBits[12];
66 /** @brief Set of bit indexes for each hout pin
67  *
68  * Each element stores index of a bit in register assigned to hout pin.
69  * Defined in din.c */
70 extern uint8_t houtBits[12];
71 /** @brief Set of bit indexes for each v_bat pin
72  *
73  * Each element stores index of a bit in register assigned to v_bat pin.
74  * Defined in vbat.c */
75 extern uint8_t vbatBits[4];
76
77 canBASE_t* canDst;
78 canBASE_t* canSrc;
79 uint32_t canMsgBox;
80
81
82 /* ------------------------------
83  * User defined command functions
84  * ------------------------------
85  */
86
87 int cmd_do_lin_loop_back(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
88         uint8_t txData[8] = {'L', 'I', 'N', ' ', 'T', 'E', 'S', 'T'};
89         uint8_t rxData[8];
90         uint8_t txID = 0xAC;
91         uint8_t rxID = 0;
92
93         linEnableLoopback(linREG, Digital);
94         linEnableNotification(linREG, LIN_RX_INT|LIN_ID_INT);
95         linIDReceived = xSemaphoreCreateCounting(1, 0);
96         linMsgReceived = xSemaphoreCreateCounting(1, 0);
97
98         linSetLength(linREG, 8);
99         linSendHeader(linREG, txID);
100         while(!linIsTxReady(linREG)) ;
101         xSemaphoreTake(linIDReceived, portMAX_DELAY);
102         rxID = linGetIdentifier(linREG);
103         if (rxID == txID) {
104                 linSend(linREG, txData);
105                 while(!linIsTxReady(linREG)) ;
106                 xSemaphoreTake(linMsgReceived, portMAX_DELAY);
107                 linGetData(linREG, rxData);
108                 uint8_t errCnt = 0;
109                 uint8_t i;
110                 for (i = 0; i < 8; i++) {
111                         if (txData[i] != rxData[i]) errCnt++;
112                 }
113
114                 if (!errCnt) {
115                         print((uint8_t *)"OK");
116                 }
117                 else {
118                         print((uint8_t *)"Transmittion errors: ");
119                         char errBuf[2];
120                         i2str(errBuf, errCnt, 1, 10);
121                         print((uint8_t *)errBuf);
122                         print((uint8_t *)"\r\n");
123                 }
124         }
125         else {
126                 print((uint8_t *)"FAILED: Sent and Received ID does not match.\r\n");
127         }
128         linDisableLoopback(linREG);
129         vSemaphoreDelete(linIDReceived);
130         vSemaphoreDelete(linMsgReceived);
131
132         return 0;
133 }
134
135
136 int cmd_do_vbat_set(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
137         vbatSetBit(NULL, vbatBits[0], 1);
138         print((uint8_t *)"V_BAT_EN set.");
139         return 0;
140 }
141
142 int cmd_do_vbat_clr(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
143         vbatSetBit(NULL, vbatBits[0], 0);
144         print((uint8_t *)"V_BAT_EN cleared.");
145         return 0;
146 }
147 int cmd_do_vbat_get(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
148         uint32_t value = vbatGetBit(vbatBits[0]);
149         if (value) {
150                 print((uint8_t *)"1\r\n");
151         }
152         else {
153                 print((uint8_t *)"0\r\n");
154         }
155         return 0;
156 }
157
158 /**     Tests the capacity of connected SDRAM
159  * @param[in]   cmd_io  Pointer to IO stack
160  * @param[in]   des             Pointer to command descriptor
161  * @param[in]   param   Parameters of command
162  * @return      0 when OK or error code
163  */
164 int cmd_do_test_ram(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
165         volatile uint32_t* addrPtr = (uint32_t*)0x80000000U;
166         volatile uint32_t* endAddr = (uint32_t*)0x87FFFFFFU;
167         uint32_t pattern = 0x55555555U;
168         uint32_t cnt = 0;
169         uint32_t errCnt = 0;
170         uint32_t readVal = 0;
171
172         while (addrPtr <= endAddr) {
173                         *addrPtr = pattern;
174                         pattern += 0x55555555U;
175                         addrPtr++;
176         }
177
178         addrPtr = (uint32_t *)0x80000000U;
179         pattern = 0x55555555U;
180         while (addrPtr <= endAddr) {
181                 readVal = *addrPtr;
182                 if (pattern == readVal) cnt++;
183                 else if(errCnt++ <= 10) {
184                         print((uint8_t *)"Error at 0x");
185                         char numBuf[10];
186                         i2str(numBuf, (long)addrPtr, 1, 16);
187                         print((uint8_t *)numBuf);
188                         print((uint8_t *)"\r\n");
189                 }
190                 else break;
191                 pattern += 0x55555555U;
192                 addrPtr++;
193         }
194
195         cnt /= (sizeof(uint32_t)*1000000);
196         if (cnt == 0) {
197                 print((uint8_t*)"SDRAM not connected.\r\n");
198         }
199         else {
200                 char numBuf[10];
201                 i2str(numBuf, cnt, 1, 10);
202                 print((uint8_t*)"SDRAM installed: ");
203                 print((uint8_t*)numBuf);
204                 print((uint8_t*)" MB\r\n");
205         }
206
207         return 0;
208 }
209
210 /**     Reads values from MOUT_EN pins and prints them
211  * @param[in]   cmd_io  Pointer to IO stack
212  * @param[in]   des             Pointer to command descriptor
213  * @param[in]   param   Parameters of command
214  * @return      0 when OK or error code
215  */
216 int cmd_do_read_mout_values(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
217         print((uint8_t *)"\r\nValues from MOUT_EN:");
218         uint32_t portVal = moutGetPort();
219         print((uint8_t *)"\r\npin\t|\tvalue");
220         uint8_t i;
221         for (i = 6, portVal = portVal>>6; i < 12; i++, portVal = portVal>>1) {
222                 uint8_t bit = portVal&1;
223                 char numBuf[2];
224                 i2str(numBuf, i-5, 1, 10);
225                 print((uint8_t *)"\r\n");
226                 print((uint8_t *)numBuf);
227                 print((uint8_t *)"\t|\t");
228                 if (bit) {
229                         print((uint8_t *)"1");
230                 }
231                 else {
232                         print((uint8_t *)"0");
233                 }
234         }
235         return 0;
236 }
237
238 /**     Reads values from DIN pins and prints them
239  * @param[in]   cmd_io  Pointer to IO stack
240  * @param[in]   des             Pointer to command descriptor
241  * @param[in]   param   Parameters of command
242  * @return      0 when OK or error code
243  */
244 int cmd_do_read_din_values(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
245         print((uint8_t *)"\r\nValues from DIN:");
246         uint32_t portVal = dinGetPort();
247         print((uint8_t *)"\r\npin\t|\tvalue");
248         uint8_t i;
249         for (i = 0; i < 8; i++,portVal = portVal>>1) {
250                 uint8_t bit = portVal&1;
251                 print((uint8_t *)"\r\n");
252                 char numBuf[1];
253                 i2str(numBuf, i+8, 1, 10);
254                 print((uint8_t *)numBuf);
255                 print((uint8_t *)"\t|\t");
256                 if (bit) {
257                         print((uint8_t *)"1");
258                 }
259                 else {
260                         print((uint8_t *)"0");
261                 }
262         }
263         return 0;
264 }
265
266 /**     Reads values from HOUT_DIAG pins and prints them
267  * @param[in]   cmd_io  Pointer to IO stack
268  * @param[in]   des             Pointer to command descriptor
269  * @param[in]   param   Parameters of command
270  * @return      0 when OK or error code
271  */
272 int cmd_do_read_hout_diag_values(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
273         print((uint8_t *)"\r\nValues from HOUT_DIAG:");
274         uint32_t portVal = houtGetPort();
275         print((uint8_t *)"\r\npin\t|\tvalue");
276         uint8_t i;
277         for (i = 0, portVal = portVal>>6; i < 6; i++,portVal = portVal>>1) {
278                 uint8_t bit = portVal&1;
279                 print((uint8_t *)"\r\n");
280                 char numBuf[1];
281                 i2str(numBuf, i+1, 1, 10);
282                 print((uint8_t *)numBuf);
283                 print((uint8_t *)"\t|\t");
284                 if (bit) {
285                         print((uint8_t *)"1");
286                 }
287                 else {
288                         print((uint8_t *)"0");
289                 }
290         }
291         return 0;
292 }
293
294 /**     Reads values from ADC and stores them to ADCData structure defined as global.
295  * ADCData structure must be defined properly before this function is called.
296  * @param[in]   adc             Pointer to ADC base register
297  * @param[in]   group   ADC group selector
298  * @return      0 when OK or error code
299  */
300 int read_adc(adcBASE_t* adc, uint32_t group) {
301         if (adcData.adc_data == NULL) {
302                 return 1;
303         }
304         adcDataConverted = xSemaphoreCreateCounting(1, 0);
305         adcEnableNotification(adc, group);
306     adcCalibration(adc);
307     adcMidPointCalibration(adc);
308
309         adcStartConversion(adc, group);
310         xSemaphoreTake(adcDataConverted, portMAX_DELAY);
311
312     if (adcData.flags & BAD_CHANNELS_COUNT) {
313         print((uint8_t *)"\r\nERROR: Bad count of channels was read! Can not proceed.");
314         adcData.flags &= ~BAD_CHANNELS_COUNT;
315         adcDisableNotification(adc, group);
316         vSemaphoreDelete(canMsgReceived);
317         return 1;
318     }
319     if (adcData.flags & MEM_OVERRUN) {
320         print((uint8_t *)"\r\nWARNING: ADC Memory overrun detected. Values can be imprecise.");
321         adcData.flags &= ~MEM_OVERRUN;
322     }
323         adcDisableNotification(adc, group);
324         vSemaphoreDelete(canMsgReceived);
325     return 0;
326 }
327
328 /**     Reads values from HOUT_IFBK pins (subset of ADC)
329  * @param[in]   cmd_io  Pointer to IO stack
330  * @param[in]   des             Pointer to command descriptor
331  * @param[in]   param   Parameters of command
332  * @return      0 when OK or error code
333  */
334 int cmd_do_read_hout_ifbk_values(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
335 {
336         char numBuf[4];                                 // Buffer used for i2str conversion
337     uint32_t i;                                         // Cycle control variable
338
339     // ADCData structure initialization
340     adcData_t adc_data_origin[HOUT_IFBK_CHANNEL_COUNT];
341     adcData.adc_data = adc_data_origin;
342     adcData.ch_count = HOUT_IFBK_CHANNEL_COUNT;
343
344     print((uint8_t *)"\r\nRead HOUT_IFBK values.");
345     if (read_adc(adcREG2, adcGROUP1) == 1)
346         return 1;
347     /* conversion results */
348     for (i = 0; i < adcData.ch_count; i++) {
349         print((uint8_t *)"\r\nHOUT: ");
350         i2str(numBuf, adcData.adc_data[i].id-1, 1, 10);
351         print((uint8_t *)numBuf);
352         print((uint8_t *)"\tvalue: ");
353         i2str(numBuf, adcData.adc_data[i].value, 1, 10);
354         print((uint8_t *)numBuf);
355         print((uint8_t *)" 0x");
356         i2str(numBuf, adcData.adc_data[i].value, 1, 16);
357         print((uint8_t *)numBuf);
358     }
359     adcData.adc_data = NULL;
360     return 0;
361 }
362
363 /**     Reads values from ADC1 pins
364  * @param[in]   cmd_io  Pointer to IO stack
365  * @param[in]   des             Pointer to command descriptor
366  * @param[in]   param   Parameters of command
367  * @return      0 when OK or error code
368  */
369 int cmd_do_read_adc1_values(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
370 {
371         char numBuf[4];                                 // Buffer used for i2str conversion
372     uint32_t i;                                         // Cycle control variable
373
374     /* ADCData structure initialization */
375     adcData_t adc_data_origin[ADC1_CHANNEL_COUNT];
376     adcData.adc_data = adc_data_origin;
377     adcData.ch_count = ADC1_CHANNEL_COUNT;
378
379     print((uint8_t *)"\r\nADC1 values:");
380     if (read_adc(adcREG1, adcGROUP1) == 1)
381         return 1;
382
383     /* conversion results :                                       */
384     for (i = 0; i < adcData.ch_count; i++) {
385         print((uint8_t *)"\r\nChannel: ");
386         i2str(numBuf, adcData.adc_data[i].id, 1, 10);
387         print((uint8_t *)numBuf);
388         print((uint8_t *)"\tvalue: ");
389         i2str(numBuf, adcData.adc_data[i].value, 1, 10);
390         print((uint8_t *)numBuf);
391         print((uint8_t *)" 0x");
392         i2str(numBuf, adcData.adc_data[i].value, 1, 16);
393         print((uint8_t *)numBuf);
394     }
395     adcData.adc_data = NULL;
396     return 0;
397 }
398
399 /**     Read values general command function. According the suffix switch to appropriate reading procedure.
400  * @param[in]   cmd_io  Pointer to IO stack
401  * @param[in]   des             Pointer to command descriptor
402  * @param[in]   param   Parameters of command
403  * @return      0 when OK or error code
404  */
405 int cmd_do_read_values(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
406         uint32_t suffix = 0;
407         int ret;
408         char* token = NULL;
409         if ((token = strtok(param[1], " ")) == NULL) {
410                 print((uint8_t *)"ERROR: No suffix!");
411                 return 1;
412         }
413
414         if (!strcmp(token, "ADC1"))
415                 suffix = 1;
416         else if (!strcmp(token, "DIN"))
417                 suffix = 2;
418         else if (!strcmp(token, "MOUTE"))
419                 suffix = 3;
420         else if (!strcmp(token, "HOUTD"))
421                 suffix = 4;
422         else if (!strcmp(token, "HOUTF"))
423                 suffix = 5;
424         else {
425                 print((uint8_t *)"ERROR: Wrong suffix!");
426                 return 1;
427         }
428         switch(suffix) {
429         case 1:
430                 ret = cmd_do_read_adc1_values(cmd_io, des, param);
431                 break;
432         case 2:
433                 ret = cmd_do_read_din_values(cmd_io, des, param);
434                 break;
435         case 3:
436                 ret = cmd_do_read_mout_values(cmd_io, des, param);
437                 break;
438         case 4:
439                 ret = cmd_do_read_hout_diag_values(cmd_io, des, param);
440                 break;
441         case 5:
442                 ret = cmd_do_read_hout_ifbk_values(cmd_io, des, param);
443                 break;
444         default:
445                 ret = 1;
446         }
447
448         return ret;
449 }
450
451 /**     Set value general command function. According the suffix sets given bit to given value to appropriate port pin.
452  * @param[in]   cmd_io  Pointer to IO stack
453  * @param[in]   des             Pointer to command descriptor
454  * @param[in]   param   Parameters of command
455  * @return      0 when OK or error code
456  */
457 int cmd_do_set_pin(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
458         void (*setBit)(gioPORT_t *, uint32_t, uint32_t) = NULL;
459         gioPORT_t * port = NULL;
460         char* token = NULL;
461         uint32_t pin;
462         uint32_t bit;
463         uint32_t value;
464         uint32_t suffix = 0;
465
466         // Get suffix
467         if ((token = strtok(param[1], " ")) == NULL) {
468                 print((uint8_t *)"ERROR: No suffix!");
469                 return 1;
470         }
471         if (!strcmp(token, "MOUTI"))
472                 suffix = 1;
473         else if (!strcmp(token, "HOUTI")) {
474                 suffix = 2;
475         }
476         else if (!strcmp(token, "VBAT")) {
477                 suffix = 3;
478         }
479
480         else {
481                 print((uint8_t *)"ERROR: Wrong suffix!");
482                 return 1;
483         }
484         // Get index of the bit
485         if ((token = strtok(param[2], " ")) == NULL) {
486                 print((uint8_t *)"ERROR: Parameter 1 expected.");
487                 return 1;
488         }
489         if (EOF == sscanf(token, "%d", &pin)){
490                 print((uint8_t *)"ERROR: unsigned number expected as param 1!");
491                 return 1;
492         }
493         // Get value
494         if ((token = strtok(NULL, " ")) == NULL) {
495                 print((uint8_t *)"ERROR: Parameter 2 expected.");
496                 return 1;
497         }
498         if (EOF == sscanf(token, "%d", &value)){
499                 print((uint8_t *)"ERROR: unsigned number expected as param 2!");
500                 return 1;
501         }
502         if ((token = strtok(NULL, " ")) != NULL) {
503                 print((uint8_t *)"ERROR: More than 2 parameters detected!");
504                 return 1;
505         }
506
507         switch(suffix) {
508         case 1 :        // MOUTI
509                 setBit=&gioSetBit;
510                 if (pin < 1 || pin > 6) {
511                         print((uint8_t *)"ERROR: 1st parameter out of range <1;6>!");
512                         return 1;
513                 }
514                 if (value != 1 && value != 0) {
515                         print((uint8_t *)"ERROR: 2nd parameter out of range <0;1>!");
516                         return 1;
517                 }
518                 port = moutPorts[pin-1];
519                 bit = moutBits[pin-1];
520                 break;
521         case 2 :        // HOUTI
522                 setBit=&gioSetBit;
523                 if (pin < 1 || pin > 6) {
524                         print((uint8_t *)"ERROR: 1st parameter out of range <1;6>!");
525                         return 1;
526                 }
527                 if (value != 1 && value != 0) {
528                         print((uint8_t *)"ERROR: 2nd parameter out of range <0;1>!");
529                         return 1;
530                 }
531                 port = houtPorts[pin-1];
532                 bit = houtBits[pin-1];
533                 break;
534         case 3 :        // VBAT
535                 setBit=&vbatSetBitAndDir;
536                 if (pin < 1 || pin > 3) {
537                         print((uint8_t *)"ERROR: 1st parameter out of range <1;3>!");
538                         return 1;
539                 }
540                 if (value != 1 && value != 0) {
541                         print((uint8_t *)"ERROR: 2nd parameter out of range <0;1>!");
542                         return 1;
543                 }
544                 port = NULL;
545                 bit = vbatBits[pin];
546                 break;
547         }
548         setBit(port, bit, value);
549         print((uint8_t *)"Bit has been set.");
550         return 0;
551 }
552
553 /**     Get value general command function. According the suffix gets given bit of appropriate port pin.
554  * @param[in]   cmd_io  Pointer to IO stack
555  * @param[in]   des             Pointer to command descriptor
556  * @param[in]   param   Parameters of command
557  * @return      0 when OK or error code
558  */
559 int cmd_do_get_pin(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[]) {
560         char* token = NULL;
561         char numBuf[4];
562         uint32_t value;
563         uint32_t pin;
564         uint32_t suffix = 100;
565         // Get suffix
566         if ((token = strtok(param[1], " ")) == NULL) {
567                 print((uint8_t *)"ERROR: No suffix!");
568                 return 1;
569         }
570         if (!strcmp(token, "ADC1"))
571                 suffix = 1;
572         else if (!strcmp(token, "DIN"))
573                 suffix = 2;
574         else if (!strcmp(token, "MOUTE"))
575                 suffix = 3;
576         else if (!strcmp(token, "HOUTD"))
577                 suffix = 4;
578         else if (!strcmp(token, "HOUTF"))
579                 suffix = 5;
580         else if (!strcmp(token, "VBAT"))
581                 suffix = 6;
582         else {
583                 print((uint8_t *)"ERROR: Wrong suffix!");
584                 return 1;
585         }
586         // Get pin
587         if ((token = strtok(param[2], " ")) == NULL) {
588                 print((uint8_t *)"ERROR: Parameter 1 expected.");
589                 return 1;
590         }
591         if (EOF == sscanf(token, "%d", &pin)){
592                 print((uint8_t *)"ERROR: unsigned number expected as param 1!");
593                 return 1;
594         }
595         if ((token = strtok(NULL, " ")) != NULL) {
596                 print((uint8_t *)"ERROR: More than 1 parameters detected!");
597                 return 1;
598         }
599
600         switch(suffix) {
601         case 1 :        // ADC1
602         {
603                 if (pin > 11) {
604                         print((uint8_t *)"ERROR: 1st parameter out of range <0;11>!");
605                         return 1;
606                 }
607
608                 adcData_t adc_data_origin[ADC1_CHANNEL_COUNT];
609             adcData.adc_data = adc_data_origin;
610             adcData.ch_count = ADC1_CHANNEL_COUNT;
611             if (read_adc(adcREG1, adcGROUP1) == 1)
612                 return 1;
613             value = adcData.adc_data[pin].value;
614             adcData.adc_data = NULL;
615                 break;
616         }
617         case 2 :        // DIN
618                 pin -= 7;
619                 if (pin < 1  || pin > 8) {
620                         print((uint8_t *)"ERROR: 1st parameter out of range <8;15>!");
621                         return 1;
622                 }
623                 value = gioGetBit(dinPorts[pin-1], dinBits[pin-1]);
624                 break;
625         case 3 :        // MOUTE
626                 if (pin < 1 || pin > 6) {
627                         print((uint8_t *)"ERROR: 1st parameter out of range <1;6>!");
628                         return 1;
629                 }
630                 value = gioGetBit(moutPorts[pin-1], moutBits[pin-1]);
631                 break;
632         case 4 :        // HOUTD
633                 if (pin < 1 || pin > 6) {
634                         print((uint8_t *)"ERROR: 1st parameter out of range <1;6>!");
635                         return 1;
636                 }
637                 value = gioGetBit(houtPorts[pin-1], houtBits[pin-1]);
638                 break;
639         case 5 :        // HOUTF
640         {
641                 if (pin < 1 || pin > 6) {
642                         print((uint8_t *)"ERROR: 1st parameter out of range <1;6>!");
643                         return 1;
644                 }
645                 adcData_t adc_data_origin[HOUT_IFBK_CHANNEL_COUNT];
646             adcData.adc_data = adc_data_origin;
647             adcData.ch_count = HOUT_IFBK_CHANNEL_COUNT;
648             if (read_adc(adcREG2, adcGROUP1) == 1)
649                 return 1;
650             value = adcData.adc_data[pin].value;
651             adcData.adc_data = NULL;
652                 break;
653         }
654         case 6 :        // VBAT
655         {
656                 if (pin < 1 || pin > 3) {
657                         print((uint8_t *)"ERROR: 1st parameter out of range <1;3>!");
658                         return 1;
659                 }
660                 value = vbatGetBit(vbatBits[pin]);
661                 break;
662         }
663         }
664         i2str(numBuf, value, 1, 10);
665         print((uint8_t *)numBuf);
666         return 0;
667 }
668
669 /**     Runs test of ADC1. Test each channel if it is shorted to REFLO or REFHI
670  * @param[in]   cmd_io  Pointer to IO stack
671  * @param[in]   des             Pointer to command descriptor
672  * @param[in]   param   Parameters of command
673  * @return      0 when OK or error code
674  */
675 int cmd_do_test_adc1_connection(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
676 {
677         uint32_t Vn[ADC1_CHANNEL_COUNT];        // Nominal value, converted from ADC
678         uint32_t Vu[ADC1_CHANNEL_COUNT];        // Upper bound
679         uint32_t Vd[ADC1_CHANNEL_COUNT];        // Lower bound
680         uint32_t* Vptr;                                         // Pointer to value (used in cycle)
681         uint8_t j;                                                      // Cycle control variable
682         uint32_t i;                                                     // Cycle control variable
683         char numBuf[2];                                         // Buffer used for i2str conversion
684
685         // Initialize ADCData structure
686     adcData_t adc_data_origin[ADC1_CHANNEL_COUNT];
687     adcData.adc_data = adc_data_origin;
688     adcData.ch_count = ADC1_CHANNEL_COUNT;
689
690     print((uint8_t *)"\r\nTesting ADC1 connection.");
691
692     // Read and store Nominal voltage, Lowest voltage Highest voltage in that order
693     for (j = 0; j < 3; j++) {
694         // Choose voltage
695                 switch(j) {
696                         case    0:
697                                 adcREG1->CALCR = 0;
698                                 Vptr = &Vn[0];
699                                 break;
700                         case    1:
701                                 adcREG1->CALCR |= (1 << 24);
702                                 Vptr = &Vd[0];
703
704                                 break;
705                         case    2:
706                                 adcREG1->CALCR |= (1 << 8);
707                                 Vptr = &Vu[0];
708                                 break;
709                 }
710                 // Read
711             if (read_adc(adcREG2, adcGROUP1) == 1)
712                 return 1;
713             // Store
714                 for (i = 0; i < ADC1_CHANNEL_COUNT; i++) {
715                         Vptr[i] = adcData.adc_data[i].value;
716                 }
717         }
718
719         print((uint8_t *)"\r\n|\tChannel\t|\tStatus");
720         for (i = 0; i < ADC1_CHANNEL_COUNT; i++) {
721                 i2str(numBuf, i, 2, 10);
722                 print((uint8_t *)"\r\n|\t");
723                 print((uint8_t *)numBuf);
724                 print((uint8_t *)"\t|\t");
725
726                 if(Vu[i] <= Vd[i]) {
727                         if (Vn[i] == 0) {
728                                 print((uint8_t *)"shorted with REFLO");
729                         }
730                         else {
731                                 print((uint8_t *)"shorted with REFHI");
732                         }
733                 }
734                 else {
735                         print((uint8_t *)"GOOD");
736                 }
737         }
738     adcREG1->CALCR = 0;
739         adcData.adc_data = NULL;
740         return 0;
741 }
742
743
744 /**     Runs test of CAN loopback. Send message from CAN1 and receive it on CAN2.
745  * @param[in]   cmd_io  Pointer to IO stack
746  * @param[in]   des             Pointer to command descriptor
747  * @param[in]   param   Parameters of command
748  * @return      0 when OK or error code
749  */
750 int cmd_do_test_can_loopback(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
751 {
752         uint32_t can[2];
753         canBASE_t *canBases[3] = {canREG1, canREG2, canREG3};
754         uint32_t canMailBoxes[3] = {canMESSAGE_BOX1, canMESSAGE_BOX2, canMESSAGE_BOX3};
755         char* token = NULL;
756         uint32_t txTimeOutCnt = 0;
757         uint32_t rxTimeOutCnt = 0;
758         uint32_t messagesTransmitted = 0;
759         uint32_t messagesReceived = 0;
760         uint32_t i;
761         uint8_t tx_data[8] = {'T', 'E', 'S', 'T', ' ', 'C', 'A', 'N'};
762         uint8_t rx_data[8] = {0, 0, 0, 0, 0, 0, 0, 0 };
763
764         dmmREG->PC5 = (1<<(11+2)); // CAN_NSTB
765         vTaskDelay(50/portTICK_RATE_MS);
766         dmmREG->PC5 = (1<<(13+2)); // CAN_EN
767         vTaskDelay(50/portTICK_RATE_MS);
768         dmmREG->PC4 = (1<<(11+2)); // CAN_NSTB
769         vTaskDelay(50/portTICK_RATE_MS);
770         dmmREG->PC4 = (1<<(13+2)); // CAN_EN
771         vTaskDelay(50/portTICK_RATE_MS);
772
773         // Get can ID 1
774         if ((token = strtok(param[1], " ")) == NULL) {
775
776                 print((uint8_t *)"ERROR: Parameter 1 expected.");
777                 return 1;
778         }
779         if (EOF == sscanf(token, "%d", &can[0])){
780                 print((uint8_t *)"ERROR: unsigned number expected as param 1!");
781                 return 1;
782         }
783         // Get can ID 2
784         if ((token = strtok(NULL, " ")) == NULL) {
785                 print((uint8_t *)"ERROR: Parameter 2 expected.");
786                 return 1;
787         }
788         if (EOF == sscanf(token, "%d", &can[1])){
789                 print((uint8_t *)"ERROR: unsigned number expected as param 2!");
790                 return 1;
791         }
792         if ((token = strtok(NULL, " ")) != NULL) {
793                 print((uint8_t *)"ERROR: More than 2 parameters detected!");
794                 return 1;
795         }
796         if (can[0] == can[1]) {
797                 print((uint8_t *)"ERROR: Destination equals source!);");
798                 return 1;
799         }
800         if (can[0] < 1 | can[1] > 3) {
801                 print((uint8_t *)"Parameter out of range <1;3>!");
802                 return 1;
803         }
804         canSrc = canBases[can[0]-1];
805         canDst = canBases[can[1]-1];
806         canMsgBox = canMailBoxes[can[0]-1];
807         canMsgReceived = xSemaphoreCreateCounting(1, 0);
808         canMsgSent = xSemaphoreCreateCounting(1, 0);
809
810         print((uint8_t *)"\r\nTesting CAN loopback\r\n");
811         canInit();
812         i = canSrc->ES; // Reset error flag
813         i = canDst->ES; // Reset error flag
814         canEnableErrorNotification(canDst);
815         canEnableErrorNotification(canSrc);
816
817         for (i = 0; i < 100; i++) {             // Send 100 times the message
818                 if (canGetErrorLevel(canSrc) != canLEVEL_ACTIVE) {
819                         print((uint8_t*)"TX: CAN is not active.\r\n");
820                         break;
821                 }
822                 canTransmit(canSrc, canMsgBox, tx_data);
823                 if (xSemaphoreTake(canMsgSent, 100/portTICK_RATE_MS) == pdFALSE) {
824                         txTimeOutCnt++;
825                 }
826                 else {
827                         if (canGetErrorLevel(canSrc) & canLEVEL_BUS_OFF) {
828                                 print((uint8_t *)"TX: CAN bus is off.\r\n");
829                                 break;
830                         }
831                         else if (canGetErrorLevel(canSrc) & canLEVEL_PASSIVE) {
832                                 print((uint8_t *)"TX: CAN bus in passive mode.\r\n");
833                                 continue;
834                         }
835                         else if (canGetErrorLevel(canSrc) & canLEVEL_WARNING) {
836                                 print((uint8_t *)"TX: CAN bus error counter warning.\r\n");
837                                 continue;
838                         }
839                         else {
840                                 messagesTransmitted++;
841                                 if (xSemaphoreTake(canMsgReceived, 100/portTICK_RATE_MS) == pdFALSE) {
842                                         rxTimeOutCnt++;
843                                 }
844                                 else {
845                                         if (canGetData(canDst, canMsgBox, rx_data))
846                                                 messagesReceived++;
847
848                                         if (canGetErrorLevel(canDst) & canLEVEL_BUS_OFF) {
849                                                 print((uint8_t *)"RX: CAN bus is off.\r\n");
850                                                 break;
851                                         }
852                                         else if (canGetErrorLevel(canDst) & canLEVEL_PASSIVE) {
853                                                 print((uint8_t *)"RX: CAN bus in passive mode.\r\n");
854                                                 continue;
855                                         }
856                                         else if (canGetErrorLevel(canDst) & canLEVEL_WARNING) {
857                                                 print((uint8_t *)"RX: CAN bus error counter reached warning level.\r\n");
858                                                 continue;
859                                         }
860                                 }
861                         }
862                 }
863         }
864         print((uint8_t *)"Messages transmitted: ");
865         char errBuf[10];
866         i2str(errBuf, messagesTransmitted, 1, 10);
867         print((uint8_t *)errBuf);
868         print((uint8_t *)"/100\r\n");
869
870         print((uint8_t *)"Messages received: ");
871         i2str(errBuf, messagesReceived, 1, 10);
872         print((uint8_t *)errBuf);
873         print((uint8_t *)"/100\r\n");
874
875         print((uint8_t *)"TX timeouts: ");
876         i2str(errBuf, txTimeOutCnt, 1, 10);
877         print((uint8_t *)errBuf);
878         print((uint8_t *)"\r\n");
879
880         print((uint8_t *)"RX timeouts: ");
881         i2str(errBuf, rxTimeOutCnt, 1, 10);
882         print((uint8_t *)errBuf);
883         print((uint8_t *)"\r\n");
884
885         print((uint8_t *)"TX error counter: ");
886         uint32_t errCnt = canSrc->EERC & 0xFFU;
887         i2str(errBuf, errCnt, 1, 10);
888         print((uint8_t *)errBuf);
889         print((uint8_t *)"\r\n");
890
891         print((uint8_t *)"RX error counter: ");
892         errCnt = canSrc->EERC & 0xFF00U;
893         i2str(errBuf, errCnt, 1, 10);
894         print((uint8_t *)errBuf);
895         print((uint8_t *)"\r\n");
896
897         //dmmREG->PC3 &= ~(1<<(11+2));
898         //dmmREG->PC3 &= ~(1<<(13+2));
899
900         canDisableErrorNotification(canDst);
901         canDisableErrorNotification(canSrc);
902         vSemaphoreDelete(canMsgReceived);
903         vSemaphoreDelete(canMsgSent);
904         return 0;
905 }
906
907 /**     Runs test of HOUT. Test, weather HOUT is in fault state, which means that HOUT_DIAG is shorted to ground
908  * @param[in]   cmd_io  Pointer to IO stack
909  * @param[in]   des             Pointer to command descriptor
910  * @param[in]   param   Parameters of command
911  * @return      0 when OK or error code
912  */
913 int cmd_do_test_hout_fault(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
914 {
915         print((uint8_t *)"Testing fault state of HOUT port:");
916         uint8_t i;
917         for (i = 0; i < 6; i++) {
918                 HOUTSetBit(houtPorts[i], houtBits[i], 1);
919                 vTaskDelay(100/portTICK_RATE_MS);
920                 if (HOUTGetBit(houtPorts[i+6], houtBits[i+6]) == 1) {
921                         print((uint8_t *)"\r\nOK");
922                 }
923                 else {
924                         print((uint8_t *)"\r\nFAIL");
925                 }
926                 HOUTSetBit(houtPorts[i], houtBits[i], 0);
927         }
928         return 0;
929 }
930
931 /**     Runs test of MOUT. Test, weather MOUT is in fault state, which means that MOUT_EN is shorted to ground
932  * @param[in]   cmd_io  Pointer to IO stack
933  * @param[in]   des             Pointer to command descriptor
934  * @param[in]   param   Parameters of command
935  * @return      0 when OK or error code
936  */
937 int cmd_do_test_mout_fault(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
938 {
939         print((uint8_t *)"Testing fault state of MOUT port:");
940         uint8_t i;
941         for (i = 0; i < 6; i++) {
942                 MOUTSetBit(moutPorts[i], moutBits[i], 1);
943                 vTaskDelay(100/portTICK_RATE_MS);
944                 if (MOUTGetBit(moutPorts[i+6], moutBits[i+6]) == 1) {
945                         print((uint8_t *)"\r\nOK");
946                 }
947                 else {
948                         print((uint8_t *)"\r\nFAIL");
949                 }
950                 MOUTSetBit(moutPorts[i], moutBits[i], 0);
951         }
952         return 0;
953 }
954
955 /* ------------------------------
956  * User defined command variables
957  * ------------------------------
958  */
959
960 /* -------------------
961  * Command definitions
962  * -------------------
963  */
964
965 cmd_des_t const cmd_des_lin_loop_back={
966     0, 0,
967     "LINLOOPBACK","Test digital loopback on LIN",
968     cmd_do_lin_loop_back, (void *)&cmd_list
969 };
970
971 cmd_des_t const cmd_des_vbat_set={
972     0, 0,
973     "VBATSET","Set V_BAT_EN.",
974     cmd_do_vbat_set, (void *)&cmd_list
975 };
976
977 cmd_des_t const cmd_des_vbat_clr={
978             0, 0,
979             "VBATCLR","Clear V_BAT_EN.",
980             cmd_do_vbat_clr, (void *)&cmd_list
981         };
982
983 /** @brief command descriptor for test SDRAM */
984 cmd_des_t const cmd_des_vbat_get={
985     0, 0,
986     "VBATGET","Get value from V_BAT_EN.",
987     cmd_do_vbat_get, (void *)&cmd_list
988 };
989
990 /** @brief command descriptor for test SDRAM */
991 cmd_des_t const cmd_des_test_sdram={
992     0, 0,
993     "TESTSDRAM","Test if SDRAM module is connected and if it is, measure capacity",
994     cmd_do_test_ram, (void *)&cmd_list
995 };
996 /** @brief command descriptor for get value of pin command */
997 cmd_des_t const cmd_des_get_pin={
998     0, 0,
999     "GETPIN*","Get value of pin at port given as suffix\r\n\t"
1000                         "-suffix ADC1 pin<0;11>  - read value from ADC1[pin]\r\n\t"
1001                         "-suffix DIN pin<8;15>   - read values from DIN[pin]\r\n\t"
1002                         "-suffix HOUTD pin<1;6> - read values from HOUT_DIAG[pin]\r\n\t"
1003                         "-suffix HOUTF pin<1;6> - read values from HOUT_IFBK[pin]\r\n\t"
1004                         "-suffix MOUTE pin<1;6> - read values from MOUT_EN[pin]\r\n\t"
1005                 "-suffix VBAT pin<1;3> - reads values from V_BAT_[pin]_EN.",
1006     cmd_do_get_pin, (void *)&cmd_list
1007 };
1008 /** @brief command descriptor for set value to pin command */
1009 cmd_des_t const cmd_des_set_pin={
1010     0, 0,
1011     "SETPIN*","Set value to pin at port given as suffix\r\n\t"
1012                         "-suffix: MOUTI pin<1;6> value <0;1> - MOUT[pin]_IN <- value\r\n\t"
1013                         "-suffix: HOUTI pin<1;6> value <0;1> - HOUT[pin]_IN <- value\r\n\t"
1014                         "-suffix: VBAT id<1;3> value <0;1> - V_BAT_[id]_EN <- value\r\n\t\t"
1015                                         "iff value = 1 then V_Bat is set as an input and value to log 1\r\n\t\t"
1016                                         "iff value = 0 than V_Bat is set as an output and value to log 0",
1017     cmd_do_set_pin, (void *)&cmd_list
1018 };
1019 /** @brief command descriptor for read values from port command */
1020 cmd_des_t const cmd_des_read={
1021     0, 0,
1022     "READVAL*","Read values from port\r\n\t"
1023                         "-suffix ADC1  - read values from ADC1\r\n\t"
1024                         "-suffix DIN   - read values from DIN\r\n\t"
1025                                 "-suffix HOUTD - read values from HOUT_DIAG\r\n\t"
1026                         "-suffix HOUTF - read values from HOUT_IFBK\r\n\t"
1027                         "-suffix MOUTE - read values from MOUT_EN",
1028     cmd_do_read_values, (void *)&cmd_list
1029 };
1030 /** @brief command descriptor for test ADC connection command */
1031 cmd_des_t const cmd_des_test_adc_connetion={
1032     0, 0,
1033     "ADCCON","Test fitness of each ADC channel connection",
1034     cmd_do_test_adc1_connection, (void *)&cmd_list
1035 };
1036 /** @brief command descriptor for test CAN loopback command */
1037 cmd_des_t const cmd_des_test_can_loopback={
1038     0, 0,
1039     "CANLOOPBACK","CANLOOPBACK src<1;3> dest<1;3> Test CAN loopback between src and dest.",
1040     cmd_do_test_can_loopback, (void *)&cmd_list
1041 };
1042 /** @brief command descriptor for test mout fault state command */
1043 cmd_des_t const cmd_des_test_mout_fail={
1044     0, 0,
1045     "MOUTFAIL","Test if some MOUT port is in fault state",
1046     cmd_do_test_mout_fault, (void *)&cmd_list
1047 };
1048 /** @brief command descriptor for test hout fault state command */
1049 cmd_des_t const cmd_des_test_hout_fail={
1050     0, 0,
1051     "HOUTFAIL","Test if some HOUT port is in fault state",
1052     cmd_do_test_hout_fault, (void *)&cmd_list
1053 };
1054 /** @brief command descriptor for show help command */
1055 cmd_des_t const cmd_des_help={
1056     0, 0,
1057     "HELP","prints help for commands\r\n",
1058     cmd_do_help, (void *)&cmd_list
1059 };
1060
1061 /*  ------------------------
1062  *  Command lists definitons
1063  *  ------------------------
1064  */
1065 /** @brief Main list of commands */
1066 cmd_des_t const *cmd_list_main[]={
1067   &cmd_des_help,
1068   &cmd_des_lin_loop_back,
1069   &cmd_des_get_pin,
1070   &cmd_des_read,
1071   &cmd_des_set_pin,
1072   &cmd_des_vbat_clr,
1073   &cmd_des_vbat_get,
1074   &cmd_des_vbat_set,
1075   &cmd_des_test_adc_connetion,
1076   &cmd_des_test_can_loopback,
1077   &cmd_des_test_hout_fail,
1078   &cmd_des_test_mout_fail,
1079   &cmd_des_test_sdram,
1080   NULL
1081 };
1082
1083 /** @brief pointer to the main list */
1084 cmd_des_t const **cmd_list = cmd_list_main;