From caed09f4db0fd329d0167ddf18be8fa429d68e33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Wed, 24 Mar 2021 00:46:30 +0100 Subject: [PATCH] application: add command to set/show target voltage --- application.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/application.c b/application.c index f896592..a42fe6b 100644 --- a/application.c +++ b/application.c @@ -11,6 +11,7 @@ #include // string utilities #include // date/time utilities #include // utilities to check chars +#include // rounding utilities /* STM32 (including CM3) libraries */ #include // Cortex M3 utilities @@ -88,6 +89,30 @@ size_t putc(char c) return length; // return number of characters printed } +/** print float with fixed precision + * @param[in] fpu float to print + * @param[in] precision number of digits after comma to print + * @note %f is used to force scientific notation + */ +static void print_fpu(double fpu, uint8_t precision) +{ + uint32_t multiplier = 1; + for (uint8_t i = 0; i < precision; i++) { + multiplier *= 10; + } + double to_print = round(fpu * multiplier); + printf("%d.", (int32_t)to_print / multiplier); + char decimal[32]; + snprintf(decimal, LENGTH(decimal), "%u", abs(to_print) % multiplier); + if (strlen(decimal) > precision) { + decimal[precision] = 0; + } + for (uint8_t i = strlen(decimal); i < precision; i++) { + putc('0'); + } + puts(decimal); +} + /** get RCC from corresponding port * @param[in] port port address * @return RCC address corresponding to port @@ -179,6 +204,47 @@ static void mux_select(int8_t channel) // menu commands +/** measure and print target voltage + * @param[in] argument 0 to no provide power, 3 to provide 3.3V + */ +static void command_target_voltage(void* argument) +{ + (void)argument; // we won't use the argument + + // set voltage + if (argument) { // if argument is provided + const uint8_t voltage = *(uint32_t*)argument; // get target voltage + switch (voltage) { + case 0: + gpio_set(GPIO_PORT(TARGET_3V_PIN), GPIO_PIN(TARGET_3V_PIN)); // disable 3V output + break; + case 3: + gpio_clear(GPIO_PORT(TARGET_3V_PIN), GPIO_PIN(TARGET_3V_PIN)); // enable 3V output + break; + default: + puts("unknown voltage to set\n"); + break; + } + sleep_us(100); // wait a bit for voltage to settle + } + + // show voltage output + if (!gpio_get(GPIO_PORT(TARGET_3V_PIN), GPIO_PIN(TARGET_3V_PIN))) { + puts("target voltage set to 3.3 V\n"); + } else { + puts("target voltage externally provided\n"); + } + + float* voltages = measure_voltages(); // measure voltages + puts("target voltage: "); + print_fpu(voltages[1], 2); + puts(" V"); + if (voltages[1] < 1.0) { + puts(" (warning: target voltage seems not connected)"); + } + putc('\n'); +} + /** display available commands * @param[in] argument no argument required */ @@ -383,7 +449,7 @@ static const struct menu_command_t menu_commands[] = { .command_handler = &command_help, }, { - .shortcut = 'v', + .shortcut = 'V', .name = "version", .command_description = "show software and hardware version", .argument = MENU_ARGUMENT_NONE, @@ -430,6 +496,14 @@ static const struct menu_command_t menu_commands[] = { .argument_description = NULL, .command_handler = &command_bootloader, }, + { + .shortcut = 'v', + .name = "voltage", + .command_description = "set/measure target voltage", + .argument = MENU_ARGUMENT_UNSIGNED, + .argument_description = "[0|3|5]", + .command_handler = &command_target_voltage, + }, }; static void command_help(void* argument)