]> rtime.felk.cvut.cz Git - pes-rpp/rpp-test-sw.git/blob - rpp-test-sw/commands/cmd_port.c
471b2c6679dffd437a1af1df8b71387e2e954f99
[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                         ret = port->set(port, &value, sizeof(value));
115                         if (ret == FAILURE)
116                                 return -CMDERR_WRPERM;
117                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
118                 }
119                 case 24: {
120                         uint32_t value;
121                         ret = sscanf(param[2], "%i", &value);
122                         if (ret == EOF || ret == 0 || (value & 0xff000000))
123                                 return -CMDERR_BADPAR;
124
125                         char v[3] = { (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
126
127                         ret = port->set(port, &v, sizeof(v));
128                         if (ret == FAILURE)
129                                 return -CMDERR_WRPERM;
130                         value = v[0] << 16 | v[1] << 8 | v[2];
131                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
132                 }
133                 case 32: {
134                         uint32_t value;
135                         ret = sscanf(param[2], "%i", &value);
136                         if (ret == EOF || ret == 0)
137                                 return -CMDERR_BADPAR;
138
139                         char v[4] = { (value >> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
140
141                         ret = port->set(port, &v, sizeof(v));
142                         if (ret == FAILURE)
143                                 return -CMDERR_WRPERM;
144                         value = v[0] << 24 | v[1] << 16 | v[2] << 8 | v[3];
145                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
146                 }
147                 default:
148                         rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
149                         return -CMDERR_NODEV;
150                 }
151         } else { /* Get values from port */
152                 if (!port->get)
153                         return -CMDERR_RDPERM;
154
155                 /* Workaround for cmd_opchar_replong() to work */
156                 param[2] = param[0] + strlen(param[0]);
157
158                 switch (port->bpch) {
159                 case 1: {
160                         uint32_t value = 0;
161                         ret = port->get(port, &value, sizeof(value));
162                         if (ret == FAILURE)
163                                 return -CMDERR_RDPERM;
164                         return cmd_opchar_replong(cmd_io, param, value, 0, 16);
165                 }
166                 case 16: {
167                         uint16_t values[16] = {0};
168                         if (port->numchn > ARRAY_SIZE(values))
169                                 return -CMDERR_BADCFG;
170                         ret = port->get(port, &values, sizeof(values));
171                         if (ret == FAILURE)
172                                 return -CMDERR_RDPERM;
173
174                         if (port->numchn == 1)
175                                 return cmd_opchar_replong(cmd_io, param, values[0], 0, 16);
176                         else {
177                                 rpp_sci_printf("%*s=", param[2] - param[0], param[0]);
178                                 for (i = 0; i < port->numchn; i++)
179                                         rpp_sci_printf(" %hx", values[i]);
180                                 rpp_sci_printf("\n");
181                                 return 0;
182                         }
183                 }
184                 default:
185                         rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
186                         return -CMDERR_NODEV;
187                 }
188         }
189         return 0;
190 }
191
192 #endif  /* DOCGEN */
193
194 /** Command descriptor for read values from port command */
195 cmd_des_t const cmd_des_port_val = {
196         0, 0,
197         "portval*","Read or write values from or to the port",
198         "### Command syntax ###\n"
199         "\n"
200         "     portval<NAME> <VAL> [<VAL> ...]\n"
201         "     portval<NAME>\n"
202         "where\n"
203         "\n"
204         "- `<NAME>` is a string specifying the name of the port\n"
205         "- `<VAL>` is decimal, hexdecimal (0x) or octal (0) number\n"
206         "\n"
207         "### Description ###\n"
208         "\n"
209         "This command sets (when VAL is present) or gets (without VAL) values\n"
210         "of all channels of the specified port. For digital IO ports (1 bit per\n"
211         "channel), the least significant bit of the VAL corresponds to the\n"
212         "first pin, the second bit to the second pin, etc.\n"
213         "\n"
214         "The set variant of the command returns a value that depends on the\n"
215         "port type. For digital IO, this is the value set, for SPI ports this\n"
216         "is the SPI response.\n"
217         "\n"
218         "The get variant returns the value read from the port.\n"
219         "\n"
220         "If the port represents an SPI interface of the MCU, then it is write\n"
221         "only and the argument is interpreted as a command for the port\n"
222         "controller.\n"
223         "\n"
224         "If the port is represents the ADC interface of the MCU, it is read\n"
225         "only and returns values for each ADC pin.\n"
226         "\n"
227         "Port names and interface type can be obtained with the portlist\n"
228         "command.\n"
229         "\n"
230         "### Example ###\n"
231         "\n"
232         "     --> portvalGIOB 0x3A\n"
233         "     portvalGIOB=0x3a\n"
234         "     --> portvalGIOB\n"
235         "     portvalGIOB=0x3a\n"
236         "This pair of commands sets:\nGIOB"
237         "GIOB=0\n"
238         "GIOB=1\n"
239         "GIOB=0\n"
240         "GIOB=1\n"
241         "GIOB=1\n"
242         "GIOB=1\n"
243         "Which is shown in getter output\n",
244         CMD_HANDLER(cmd_do_port_val), (void *)&cmd_list_port
245 };
246
247 /** Command descriptor for port list printout */
248 cmd_des_t const cmd_des_port_list = {
249         0, 0,
250         "portlist","Print a list of all port names",
251         "### Command syntax ###\n"
252         "\n"
253         "     portlist\n"
254         "\n"
255         "### Description ###\n"
256         "\n"
257         "This command prints the list of all defined ports accessible via the\n"
258         "portval command. Each line contains port name, read/write type, number\n"
259         "of channels and width of the channel in bits.\n"
260         "\n"
261         "### Example ###\n"
262         "\n"
263         "     --> portlist\n"
264         "     List of all defined ports with its type. Those names can be used by portval command.\n"
265         "     GIOA      RW 8x1b\n"
266         "     GIOB      RW 8x1b\n"
267         "     NHET      RW 30x1b\n"
268         "     ADC       RO 16x12b\n",
269         CMD_HANDLER(cmd_do_port_list), (void *)&cmd_list_port
270 };
271
272 /** List of commands for port, defined as external */
273 cmd_des_t const *cmd_list_port[] = {
274         &cmd_des_port_val,
275         &cmd_des_port_list,
276         NULL
277 };