]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_port.c
d00048699ea615a327360a5c02c3645f56f48c03
[pes-rpp/rpp-test-sw.git] / rpp-test-sw / commands / cmd_port.c
1 /*
2  * Copyright (C) 2012-2015 Czech Technical University in Prague
3  *
4  * Created on: 28.2.2013
5  *
6  * Authors:
7  *     - Michal Horn
8  *
9  * This document contains proprietary information belonging to Czech
10  * Technical University in Prague. Passing on and copying of this
11  * document, and communication of its contents is not permitted
12  * without prior written authorization.
13  *
14  * File : cmd_port.c
15  *
16  * Abstract:
17  *           Commands for port controlling
18  *          - Printing list of available ports (not yet available)
19  *          - Setting/getting port value*
20  */
21
22 #include "cmd_port.h"
23 #include "stdio.h"
24 #include "string.h"
25
26 #ifndef DOCGEN
27
28 #include "rpp/rpp.h"
29 #include "drv/port.h"
30 #ifdef TARGET_HAS_SPI
31 #include "drv/spi.h"
32 #endif
33 #include <drv/endian.h>
34 #include "cmdproc_utils.h"
35
36 #define MIN(a, b) ((a) < (b) ? (a) : (b))
37
38 int cmd_do_port_list(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
39 {
40         uint32_t i;
41
42         rpp_sci_printf("List of all defined ports with its type. Those names can be used by portval command.\r\n");
43
44         for (i = 0; i < ARRAY_SIZE(port_desc); i++) {
45                 const struct port_desc *port = &port_desc[i];
46                 const char *rw[4] = { "N/A", "WO", "RO", "RW" };
47                 char note[30] = "";
48 #ifdef TARGET_HAS_SPI
49                 if (port->set == port_spi_set)
50                         snprintf(note, sizeof(note), "SPI, %s", port->cfg.spi.chip);
51 #endif
52                 rpp_sci_printf("%-10s %s %dx%db%s%s%s\r\n",
53                                            port->name,
54                                            rw[(port->set ? 1 : 0) | (port->get ? 2 : 0)],
55                                            port->numchn, port->bpch,
56                                            *note ? " (": "",
57                                            note,
58                                            *note ? ")" : "");
59         }
60         return 1;
61 }
62
63 static const struct port_desc *port_from_name(const char *port_name)
64 {
65         uint32_t i;
66
67         for (i = 0; i < ARRAY_SIZE(port_desc); i++)
68                 if (strcmp(port_name, port_desc[i].name) == 0)
69                         return &port_desc[i];
70         return NULL;
71 }
72
73 /**
74  * @brief       Read values from specified port
75  *
76  * @param[in]   cmd_io  Pointer to IO stack
77  * @param[in]   des             Pointer to command descriptor
78  * @param[in]   param   Parameters of command
79  * @return      0 when OK or error code
80  */
81 int cmd_do_port_val(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
82 {
83         int32_t ret;
84         int i;
85         char portName[32];
86
87         if (sscanf(param[1], "%31s ", portName) != 1)
88                 return -CMDERR_BADPAR;
89
90         const struct port_desc *port = port_from_name(portName);
91         if (!port)
92                 return -CMDERR_BADPAR;
93
94         if (param[2] != NULL) { // More parameters = set values
95                 if (!port->set)
96                         return -CMDERR_WRPERM;
97
98                 switch (port->bpch) {
99                 case 1: {
100                         uint32_t value;
101                         ret = sscanf(param[2], "%i", &value);
102                         if (ret == EOF || ret == 0)
103                                 return -CMDERR_BADPAR;
104
105                         ret = port->set(port, &value, sizeof(value));
106                         if (ret == FAILURE)
107                                 return -CMDERR_WRPERM;
108                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
109                 }
110                 case 16: {
111                         uint16_t value[8];
112                         int i, n;
113                         char *p = param[2];
114                         assert(port->numchn <= ARRAY_SIZE(value));
115
116                         for (i = 0; i < port->numchn; i++) {
117                                 ret = sscanf(param[2], "%hi%n", &value[i], &n);
118                                 if (ret == EOF || ret == 0)
119                                         break;
120                                 value[i] = cpu_to_be16(value[i]);
121                                 p += n;
122                         }
123
124                         ret = port->set(port, &value, port->numchn * 2);
125                         if (ret == FAILURE)
126                                 return -CMDERR_WRPERM;
127                         if (port->numchn == 1)
128                                 return cmd_opchar_replong(cmd_io, param, be16_to_cpu(value[0]), 0, 16);
129                         else {
130                                 for (i = 0; i < port->numchn; i++)
131                                         rpp_sci_printf("%#x ", be16_to_cpu(value[i]));
132                                 rpp_sci_printf("\n");
133                                 return 0;
134                         }
135                 }
136                 case 24: {
137                         uint32_t value;
138                         ret = sscanf(param[2], "%i", &value);
139                         if (ret == EOF || ret == 0 || (value & 0xff000000))
140                                 return -CMDERR_BADPAR;
141
142                         char v[3] = { (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
143
144                         ret = port->set(port, &v, sizeof(v));
145                         if (ret == FAILURE)
146                                 return -CMDERR_WRPERM;
147                         value = v[0] << 16 | v[1] << 8 | v[2];
148                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
149                 }
150                 case 32: {
151                         uint32_t value;
152                         ret = sscanf(param[2], "%i", &value);
153                         if (ret == EOF || ret == 0)
154                                 return -CMDERR_BADPAR;
155
156                         char v[4] = { (value >> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
157
158                         ret = port->set(port, &v, sizeof(v));
159                         if (ret == FAILURE)
160                                 return -CMDERR_WRPERM;
161                         value = v[0] << 24 | v[1] << 16 | v[2] << 8 | v[3];
162                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
163                 }
164                 default:
165                         rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
166                         return -CMDERR_NODEV;
167                 }
168         } else { /* Get values from port */
169                 if (!port->get)
170                         return -CMDERR_RDPERM;
171
172                 /* Workaround for cmd_opchar_replong() to work */
173                 param[2] = param[0] + strlen(param[0]);
174
175                 switch (port->bpch) {
176                 case 1: {
177                         uint32_t value = 0;
178                         ret = port->get(port, &value, sizeof(value));
179                         if (ret == FAILURE)
180                                 return -CMDERR_RDPERM;
181                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
182                 }
183                 case 16: {
184                         uint16_t values[16] = {0};
185                         if (port->numchn > ARRAY_SIZE(values))
186                                 return -CMDERR_BADCFG;
187                         ret = port->get(port, &values, sizeof(values));
188                         if (ret == FAILURE)
189                                 return -CMDERR_RDPERM;
190
191                         if (port->numchn == 1)
192                                 return cmd_opchar_replong(cmd_io, param, values[0], 0, 16);
193                         else {
194                                 rpp_sci_printf("%*s=", param[2] - param[0], param[0]);
195                                 for (i = 0; i < port->numchn; i++)
196                                         rpp_sci_printf(" %hx", values[i]);
197                                 rpp_sci_printf("\n");
198                                 return 0;
199                         }
200                 }
201                 default:
202                         rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
203                         return -CMDERR_NODEV;
204                 }
205         }
206 #pragma diag_remark 112
207         return 0; //warning #112-D: statement is unreachable
208 #pragma diag_warning 112
209 }
210
211 #endif  /* DOCGEN */
212
213 /** Command descriptor for read values from port command */
214 cmd_des_t const cmd_des_port_val = {
215         0, 0,
216         "portval*","Read or write values from or to the port",
217         "### Command syntax ###\n"
218         "\n"
219         "     portval<NAME> <VAL> [<VAL> ...]\n"
220         "     portval<NAME>\n"
221         "where\n"
222         "\n"
223         "- `<NAME>` is a string specifying the name of the port\n"
224         "- `<VAL>` is decimal, hexdecimal (0x) or octal (0) number\n"
225         "\n"
226         "### Description ###\n"
227         "\n"
228         "This command sets (when VAL is present) or gets (without VAL) values\n"
229         "of all channels of the specified port. For digital IO ports (1 bit per\n"
230         "channel), the least significant bit of the VAL corresponds to the\n"
231         "first pin, the second bit to the second pin, etc.\n"
232         "\n"
233         "The set variant of the command returns a value that depends on the\n"
234         "port type. For digital IO, this is the value set, for SPI ports this\n"
235         "is the SPI response.\n"
236         "\n"
237         "The get variant returns the value read from the port.\n"
238         "\n"
239         "If the port represents an SPI device, then it is write only and the\n"
240         "argument is interpreted as a message sent to the device.\n"
241         "\n"
242         "If the port is represents the ADC interface of the MCU, it is read\n"
243         "only and returns values for each ADC pin.\n"
244         "\n"
245         "Port names and interface type can be obtained with the portlist\n"
246         "command.\n"
247         "\n"
248         "### Example ###\n"
249         "\n"
250         "     --> portvalGIOB 0x3A\n"
251         "     portvalGIOB=0x3a\n"
252         "     --> portvalGIOB\n"
253         "     portvalGIOB=0x3a\n"
254         "     --> portvalADCCND 0x4100 0x4100 0x4100 0x4100 0x4100 0x4100\n"
255         "     0xffff 0xffff 0xffff 0xffff 0xffff 0xffff\n",
256         CMD_HANDLER(cmd_do_port_val), (void *)&cmd_list_port
257 };
258
259 /** Command descriptor for port list printout */
260 cmd_des_t const cmd_des_port_list = {
261         0, 0,
262         "portlist","Print a list of all port names",
263         "### Command syntax ###\n"
264         "\n"
265         "     portlist\n"
266         "\n"
267         "### Description ###\n"
268         "\n"
269         "This command prints the list of all defined ports accessible via the\n"
270         "portval command. Each line contains port name, read/write type, number\n"
271         "of channels and width of the channel in bits.\n"
272         "\n"
273         "### Example ###\n"
274         "\n"
275         "     --> portlist\n"
276         "     List of all defined ports with its type. Those names can be used by portval command.\n"
277         "     GIOA       RW 8x1b\n"
278         "     GIOB       RW 8x1b\n"
279         "     NHET1      RW 30x1b\n"
280         "     ADC        RO 24x16b\n"
281         "     THERM1     WO 1x16b (SPI, MCP6S93)\n"
282         "     THERM2     WO 1x16b (SPI, MCP6S93)\n"
283         "     ADCCND     WO 6x16b (SPI, MCP6S93)\n"
284         "     PWR        WO 1x16b (SPI, TPS65381)\n"
285         "     SENSUP     WO 1x16b (SPI, MCP6S93)\n"
286         "     DACLBK     WO 1x16b (SPI, MCP6S93)\n",
287         CMD_HANDLER(cmd_do_port_list), (void *)&cmd_list_port
288 };
289
290 /** List of commands for port, defined as external */
291 cmd_des_t const *cmd_list_port[] = {
292         &cmd_des_port_val,
293         &cmd_des_port_list,
294         NULL
295 };