2 * Copyright (C) 2012-2015 Czech Technical University in Prague
4 * Created on: 28.2.2013
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.
17 * Commands for port controlling
18 * - Printing list of available ports (not yet available)
19 * - Setting/getting port value*
33 #include <drv/endian.h>
34 #include "cmdproc_utils.h"
36 #define MIN(a, b) ((a) < (b) ? (a) : (b))
38 int cmd_do_port_list(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
42 rpp_sci_printf("List of all defined ports with its type. Those names can be used by portval command.\r\n");
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" };
49 if (port->set == port_spi_set)
50 snprintf(note, sizeof(note), "SPI, %s", port->cfg.spi.chip);
52 rpp_sci_printf("%-10s %s %dx%db%s%s%s\r\n",
54 rw[(port->set ? 1 : 0) | (port->get ? 2 : 0)],
55 port->numchn, port->bpch,
63 static const struct port_desc *port_from_name(const char *port_name)
67 for (i = 0; i < ARRAY_SIZE(port_desc); i++)
68 if (strcmp(port_name, port_desc[i].name) == 0)
74 * @brief Read values from specified port
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
81 int cmd_do_port_val(cmd_io_t *cmd_io, const struct cmd_des *des, char *param[])
87 if (sscanf(param[1], "%31s ", portName) != 1)
88 return -CMDERR_BADPAR;
90 const struct port_desc *port = port_from_name(portName);
92 return -CMDERR_BADPAR;
94 if (param[2] != NULL) { // More parameters = set values
96 return -CMDERR_WRPERM;
101 ret = sscanf(param[2], "%i", &value);
102 if (ret == EOF || ret == 0)
103 return -CMDERR_BADPAR;
105 ret = port->set(port, &value, sizeof(value));
107 return -CMDERR_WRPERM;
108 return cmd_opchar_replong(cmd_io, param, value, 0, 16);
114 assert(port->numchn <= ARRAY_SIZE(value));
116 for (i = 0; i < port->numchn; i++) {
117 ret = sscanf(param[2], "%hi%n", &value[i], &n);
118 if (ret == EOF || ret == 0)
120 value[i] = cpu_to_be16(value[i]);
124 ret = port->set(port, &value, port->numchn * 2);
126 return -CMDERR_WRPERM;
127 if (port->numchn == 1)
128 return cmd_opchar_replong(cmd_io, param, be16_to_cpu(value[0]), 0, 16);
130 for (i = 0; i < port->numchn; i++)
131 rpp_sci_printf("%#x ", be16_to_cpu(value[i]));
132 rpp_sci_printf("\n");
138 ret = sscanf(param[2], "%i", &value);
139 if (ret == EOF || ret == 0 || (value & 0xff000000))
140 return -CMDERR_BADPAR;
142 char v[3] = { (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
144 ret = port->set(port, &v, sizeof(v));
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);
152 ret = sscanf(param[2], "%i", &value);
153 if (ret == EOF || ret == 0)
154 return -CMDERR_BADPAR;
156 char v[4] = { (value >> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, (value >> 0) & 0xff };
158 ret = port->set(port, &v, sizeof(v));
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);
165 rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
166 return -CMDERR_NODEV;
168 } else { /* Get values from port */
170 return -CMDERR_RDPERM;
172 /* Workaround for cmd_opchar_replong() to work */
173 param[2] = param[0] + strlen(param[0]);
175 switch (port->bpch) {
178 ret = port->get(port, &value, sizeof(value));
180 return -CMDERR_RDPERM;
181 return cmd_opchar_replong(cmd_io, param, value, 0, 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));
189 return -CMDERR_RDPERM;
191 if (port->numchn == 1)
192 return cmd_opchar_replong(cmd_io, param, values[0], 0, 16);
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");
202 rpp_sci_printf("Unsupported bits-per-channel value: %d\n", port->bpch);
203 return -CMDERR_NODEV;
206 #pragma diag_remark 112
207 return 0; //warning #112-D: statement is unreachable
208 #pragma diag_warning 112
213 /** Command descriptor for read values from port command */
214 cmd_des_t const cmd_des_port_val = {
216 "portval*","Read or write values from or to the port",
217 "### Command syntax ###\n"
219 " portval<NAME> <VAL> [<VAL> ...]\n"
223 "- `<NAME>` is a string specifying the name of the port\n"
224 "- `<VAL>` is decimal, hexdecimal (0x) or octal (0) number\n"
226 "### Description ###\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"
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"
237 "The get variant returns the value read from the port.\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"
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"
245 "Port names and interface type can be obtained with the portlist\n"
250 " --> portvalGIOB 0x3A\n"
251 " portvalGIOB=0x3a\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
259 /** Command descriptor for port list printout */
260 cmd_des_t const cmd_des_port_list = {
262 "portlist","Print a list of all port names",
263 "### Command syntax ###\n"
267 "### Description ###\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"
276 " List of all defined ports with its type. Those names can be used by portval command.\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
290 /** List of commands for port, defined as external */
291 cmd_des_t const *cmd_list_port[] = {