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