]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_gpio.c
2 * (C) Copyright 2014 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0
8 #include "print-utils.h"
9 #include "getopt-min.h"
15 static uint_fast8_t pinnames_get(char *pin_names
[GPIO_MAX
+1])
17 static const FLASH
char delim1
[] = {":= "};
18 static const FLASH
char delim2
[] = {", "};
19 uint_fast8_t width
= 0;
23 memset(pin_names
, 0, (GPIO_MAX
+1) * sizeof(char *));
25 /* TODO: enters endless loop on wrong parameters */
27 lp
= getenv_str(PSTR(ENV_PINALIAS
));
29 pin_names
[GPIO_MAX
] = strdup(lp
);
30 if (pin_names
[GPIO_MAX
] != NULL
) {
31 char *ptr
= strtok_P(pin_names
[GPIO_MAX
], delim1
);
33 if (((i
= strtoul(ptr
, &lp
, 10)) < GPIO_MAX
) &&
35 (ptr
= strtok_P(NULL
, delim2
)) != NULL
) {
37 ptr
= strtok_P(NULL
, delim1
);
41 for (i
= 0; i
< GPIO_MAX
; i
++)
42 if (strlen(pin_names
[i
]) > width
)
43 width
= strlen(pin_names
[i
]);
50 static size_t xstrlen(char *s
)
58 static const FLASH
char * const FLASH pinconf_str
[] = {
66 static const FLASH
char * const FLASH pinlevel_str
[] = {
72 static void print_pin(uint8_t pin
, uint_fast8_t multi
, char *pin_names
[], uint_fast8_t pn_width
)
75 const FLASH
char *levelp
;
78 pinconf
= gpio_config_get(pin
);
79 if (pinconf
== OUTPUT_TIMER
) {
80 div
= gpio_clockdiv_get(pin
);
81 levelp
= pinlevel_str
[2];
83 levelp
= pinlevel_str
[gpio_read(pin
)];
86 printf_P(PSTR("%3d "), pin
);
88 printf_P(PSTR("%s "), pin_names
[pin
]);
89 print_blanks(pn_width
- xstrlen(pin_names
[pin
]));
91 my_puts_P(pinconf_str
[pinconf
]);
92 print_blanks(7 - strlen_P(pinconf_str
[pinconf
]));
94 print_blanks(5 - strlen_P(levelp
));
95 if (pinconf
== OUTPUT_TIMER
)
96 printf_P(PSTR("%8ld %8ld"),
99 printf_P(PSTR("%d: \"%s\", "), pin
, pin_names
[pin
] ? pin_names
[pin
] : 0);
100 my_puts_P(pinconf_str
[pinconf
]);
101 my_puts_P(PSTR(", "));
104 if (pinconf
== OUTPUT_TIMER
)
105 printf_P(PSTR("divide by %ld (%ldHz)"),
108 my_puts_P(PSTR("\n"));
111 static int_fast8_t pinarg_insert(uint8_t pin
, uint_fast8_t count
, uint_fast8_t pinarg
[])
118 for (pos
= 0; pos
< count
; pos
++) {
119 if (pin
== pinarg
[pos
])
121 if (pin
< pinarg
[pos
])
124 for (uint_fast8_t i
= count
-1; i
== pos
; i
--)
125 pinarg
[i
+1] = pinarg
[i
];
131 static uint_fast8_t pinarg_get(char * arg
, uint_fast8_t pinarg
[])
136 uint_fast8_t count
= 0;
139 pin1
= strtoul(arg
, &endp
, 10);
140 if (endp
!= arg
&& *endp
== '-') {
142 uint_fast8_t pin2
= (int) strtoul(arg
, &endp
, 10);
144 for (; pin1
< pin2
; pin1
++)
145 if ((rc
= pinarg_insert(pin1
, count
, pinarg
)) >= 0)
153 if ((*endp
== ',' || *endp
== '\0') &&
154 (rc
= pinarg_insert(pin1
, count
, pinarg
)) >= 0) {
168 command_ret_t
do_gpio(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char *const argv
[])
170 uint_fast8_t printheader
= 1;
171 uint_fast8_t pinarg
[GPIO_MAX
];
172 uint_fast8_t pinargc
;
175 while ((opt
= getopt(argc
, argv
, PSTR("s"))) != -1) {
181 return CMD_RET_USAGE
;
185 /* remaining arguments */
189 /* print config of all pins */
190 for (pinargc
= 0; pinargc
< GPIO_MAX
; pinargc
++)
191 pinarg
[pinargc
] = pinargc
;
194 pinargc
= pinarg_get(argv
[optind
++], pinarg
);
196 return CMD_RET_USAGE
;
203 /* no more args, print pin config */
205 char *pin_names
[GPIO_MAX
+ 1];
206 uint_fast8_t pin_names_width
= pinnames_get(pin_names
);
209 print_pin(pinarg
[0], 0, pin_names
, pin_names_width
);
212 if (pin_names_width
> 0) {
213 if ( strlen("Name") > pin_names_width
)
214 pin_names_width
= strlen("Name");
215 char s
[pin_names_width
+1];
216 memset(s
, ' ', pin_names_width
);
217 s
[pin_names_width
] = '\0';
218 strncpy_P(s
, PSTR("Name"), 4);
219 printf_P(PSTR("Pin %s Config Level Divider Frequency/Hz\n"),s
);
220 memset(s
, '-', pin_names_width
);
221 printf_P(PSTR("----%s-----------------------------------\n"), s
);
223 printf_P(PSTR("Pin Config Level Divider Frequency/Hz\n"
224 "--------------------------------------\n"));
226 for (uint_fast8_t i
= 0; i
< pinargc
; i
++)
227 print_pin(pinarg
[i
], 1, pin_names
, pin_names_width
);
229 if (pin_names
[GPIO_MAX
] != NULL
)
230 free(pin_names
[GPIO_MAX
]);
231 return CMD_RET_SUCCESS
;
234 /* arguments must be in pairs: pins conf */
236 return CMD_RET_USAGE
;
240 gpiomode_t mode
= NONE
;
242 unsigned long value
= 0;
245 switch (toupper(argv
[optind
][0])) {
261 value
= strtoul(argv
[optind
], &endp
, 10);
271 if (*endp
&& strcmp_P(endp
, PSTR("Hz")) == 0) {
277 printf_P(PSTR("invalid parameter: '%s'\n"), argv
[optind
]);
278 return CMD_RET_USAGE
;
282 printf_P(PSTR("invalid value: %lu \n"));
283 return CMD_RET_USAGE
;
287 if (value
> F_CPU
/ 2) {
288 printf_P(PSTR("Max frequency is: %luHz\n"), F_CPU
/2);
289 return CMD_RET_USAGE
;
298 return CMD_RET_USAGE
;
300 for (uint_fast8_t i
= 0; i
< pinargc
; i
++) {
303 gpio_write(pinarg
[i
], level
);
307 gpio_config(pinarg
[i
], mode
);
310 if (gpio_clockdiv_set(pinarg
[i
], value
) < 0) {
311 printf_P(PSTR("Setting pin %d to %lu failed.\n"),
321 pinargc
= pinarg_get(argv
[optind
++], pinarg
);
325 return CMD_RET_SUCCESS
;