2 * Copyright (C) 2012-2015 Czech Technical University in Prague
4 * Created on: 28.2.2013
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
33 * Commands for port controlling
34 * - Printing list of available ports (not yet available)
35 * - Setting/getting port value*
49 #include <drv/endian.h>
50 #include "cmdproc_utils.h"
52 #define MIN(a, b) ((a) < (b) ? (a) : (b))
54 int cmd_do_port_list(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
58 rpp_sci_printf("List of all defined ports with its type. Those names can be used by portval command.\r\n");
60 for (i = 0; i < ARRAY_SIZE(port_desc); i++) {
61 const struct port_desc *port = &port_desc[i];
62 const char *rw[4] = { "N/A", "WO", "RO", "RW" };
65 if (port->set == port_spi_set)
66 snprintf(note, sizeof(note), "SPI, %s", port->cfg.spi.chip);
68 rpp_sci_printf("%-10s %s %dx%db%s%s%s\r\n",
70 rw[(port->set ? 1 : 0) | (port->get ? 2 : 0)],
71 port->numchn, port->bpch,
79 static const struct port_desc *port_from_name(const char *port_name)
83 for (i = 0; i < ARRAY_SIZE(port_desc); i++)
84 if (strcmp(port_name, port_desc[i].name) == 0)
90 * @brief Read values from specified port
92 * @param[in] cmd_io Pointer to IO stack
93 * @param[in] des Pointer to command descriptor
94 * @param[in] param Parameters of command
95 * @return 0 when OK or error code
97 int cmd_do_port_val(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
103 if (sscanf(param[1], "%31s ", portName) != 1)
104 return -CMDERR_BADPAR;
106 const struct port_desc *port = port_from_name(portName);
108 return -CMDERR_BADPAR;
110 if (param[2] != NULL) { // More parameters = set values
112 return -CMDERR_WRPERM;
114 switch (port->bpch) {
117 ret = sscanf(param[2], "%i", &value);
118 if (ret == EOF || ret == 0)
119 return -CMDERR_BADPAR;
121 ret = port->set(port, &value, sizeof(value));
123 return -CMDERR_WRPERM;
124 return cmd_opchar_replong(cmd_io, param, value, 0, 16);
130 assert(port->numchn <= ARRAY_SIZE(value));
132 for (i = 0; i < port->numchn; i++) {
133 ret = sscanf(param[2], "%hi%n", &value[i], &n);
134 if (ret == EOF || ret == 0)
136 value[i] = cpu_to_be16(value[i]);
140 ret = port->set(port, &value, port->numchn * 2);
142 return -CMDERR_WRPERM;
143 if (port->numchn == 1)
144 return cmd_opchar_replong(cmd_io, param, be16_to_cpu(value[0]), 0, 16);
146 for (i = 0; i < port->numchn; i++)
147 rpp_sci_printf("%#x ", be16_to_cpu(value[i]));
148 rpp_sci_printf("\n");
154 ret = sscanf(param[2], "%i", &value);
155 if (ret == EOF || ret == 0 || (value & 0xff000000))
156 return -CMDERR_BADPAR;
158 char v[3] = { (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
160 ret = port->set(port, &v, sizeof(v));
162 return -CMDERR_WRPERM;
163 value = v[0] << 16 | v[1] << 8 | v[2];
164 return cmd_opchar_replong(cmd_io, param, value, 0, 16);
168 ret = sscanf(param[2], "%i", &value);
169 if (ret == EOF || ret == 0)
170 return -CMDERR_BADPAR;
172 char v[4] = { (value >> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
174 ret = port->set(port, &v, sizeof(v));
176 return -CMDERR_WRPERM;
177 value = v[0] << 24 | v[1] << 16 | v[2] << 8 | v[3];
178 return cmd_opchar_replong(cmd_io, param, value, 0, 16);
181 rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
182 return -CMDERR_NODEV;
184 } else { /* Get values from port */
186 return -CMDERR_RDPERM;
188 /* Workaround for cmd_opchar_replong() to work */
189 param[2] = param[0] + strlen(param[0]);
191 switch (port->bpch) {
194 ret = port->get(port, &value, sizeof(value));
196 return -CMDERR_RDPERM;
197 return cmd_opchar_replong(cmd_io, param, value, 0, 16);
200 uint16_t values[16] = {0};
201 if (port->numchn > ARRAY_SIZE(values))
202 return -CMDERR_BADCFG;
203 ret = port->get(port, &values, sizeof(values));
205 return -CMDERR_RDPERM;
207 if (port->numchn == 1)
208 return cmd_opchar_replong(cmd_io, param, values[0], 0, 16);
210 rpp_sci_printf("%*s=", param[2] - param[0], param[0]);
211 for (i = 0; i < port->numchn; i++)
212 rpp_sci_printf(" %hx", values[i]);
213 rpp_sci_printf("\n");
218 rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
219 return -CMDERR_NODEV;
222 #pragma diag_remark 112
223 return 0; //warning #112-D: statement is unreachable
224 #pragma diag_warning 112
229 /** Command descriptor for read values from port command */
230 cmd_des_t const cmd_des_port_val = {
232 "portval*","Read or write values from or to the port",
233 "### Command syntax ###\n"
235 " portval<NAME> <VAL> [<VAL> ...]\n"
239 "- `<NAME>` is a string specifying the name of the port\n"
240 "- `<VAL>` is decimal, hexdecimal (0x) or octal (0) number\n"
242 "### Description ###\n"
244 "This command sets (when VAL is present) or gets (without VAL) values\n"
245 "of all channels of the specified port. For digital IO ports (1 bit per\n"
246 "channel), the least significant bit of the VAL corresponds to the\n"
247 "first pin, the second bit to the second pin, etc.\n"
249 "The set variant of the command returns a value that depends on the\n"
250 "port type. For digital IO, this is the value set, for SPI ports this\n"
251 "is the SPI response.\n"
253 "The get variant returns the value read from the port.\n"
255 "If the port represents an SPI device, then it is write only and the\n"
256 "argument is interpreted as a message sent to the device.\n"
258 "If the port is represents the ADC interface of the MCU, it is read\n"
259 "only and returns values for each ADC pin.\n"
261 "Port names and interface type can be obtained with the portlist\n"
266 " --> portvalGIOB 0x3A\n"
267 " portvalGIOB=0x3a\n"
269 " portvalGIOB=0x3a\n"
270 " --> portvalADCCND 0x4100 0x4100 0x4100 0x4100 0x4100 0x4100\n"
271 " 0xffff 0xffff 0xffff 0xffff 0xffff 0xffff\n",
272 CMD_HANDLER(cmd_do_port_val), (void *)&cmd_list_port
275 /** Command descriptor for port list printout */
276 cmd_des_t const cmd_des_port_list = {
278 "portlist","Print a list of all port names",
279 "### Command syntax ###\n"
283 "### Description ###\n"
285 "This command prints the list of all defined ports accessible via the\n"
286 "portval command. Each line contains port name, read/write type, number\n"
287 "of channels and width of the channel in bits.\n"
292 " List of all defined ports with its type. Those names can be used by portval command.\n"
297 " THERM1 WO 1x16b (SPI, MCP6S93)\n"
298 " THERM2 WO 1x16b (SPI, MCP6S93)\n"
299 " ADCCND WO 6x16b (SPI, MCP6S93)\n"
300 " PWR WO 1x16b (SPI, TPS65381)\n"
301 " SENSUP WO 1x16b (SPI, MCP6S93)\n"
302 " DACLBK WO 1x16b (SPI, MCP6S93)\n",
303 CMD_HANDLER(cmd_do_port_list), (void *)&cmd_list_port
306 /** List of commands for port, defined as external */
307 cmd_des_t const *cmd_list_port[] = {