diff --git a/application.c b/application.c index be44b12..fab11db 100644 --- a/application.c +++ b/application.c @@ -54,6 +54,7 @@ static uint32_t boot_time = 0; #define TARGET_CHANNEL 1 /**< PA1/ADC1_IN1 used to measure target voltage */ const uint8_t adc_channels[] = {ADC_CHANNEL17, ADC_CHANNEL(TARGET_CHANNEL)}; /**< voltages to convert (channel 17 = internal voltage reference) */ #define TARGET_EN PA5 /**< pin to provide target voltage to LV side of voltage shifter (pulling them high through 10 kO) */ +#define TARGET_RST PA6 /**< pin to reset target */ #define TARGET_5V PA7 /**< pin to provide 5 V on target voltage (controlling gate of pMOS, externally pulled up) */ #define TARGET_3V PB0 /**< pin to provide 3.3 V on target voltage (controlling gate of pMOS, externally pulled up) */ @@ -225,6 +226,60 @@ static void command_target_voltage(void* argument) putc('\n'); } +/** configure or reset target + * @param[in] argument 1 to assert reset, 0 to release reset, ODL to set reset pin to open-drain active low, ODH to set reset pin to open-drain active high, PPL to set reset pin to push-pull active low, PPH to set reset pin to push-pull active high + */ +static void command_target_reset(void* argument) +{ + (void)argument; // we won't use the argument + static bool active_low = true; // if the reset is active low or high + + // set reset mode + if (argument) { // if argument is provided + if (0 == strcmp("0", argument)) { // release reset + if (active_low) { + gpio_set(GPIO_PORT(TARGET_RST), GPIO_PIN(TARGET_RST)); + } else { + gpio_clear(GPIO_PORT(TARGET_RST), GPIO_PIN(TARGET_RST)); + } + } else if (0 == strcmp("1", argument)) { // assert reset + if (active_low) { + gpio_clear(GPIO_PORT(TARGET_RST), GPIO_PIN(TARGET_RST)); + } else { + gpio_set(GPIO_PORT(TARGET_RST), GPIO_PIN(TARGET_RST)); + } + } else if (0 == strcmp("ODL", argument)) { // set reset to open-drain active low + active_low = true; // remember we are active low + gpio_set_output_options(GPIO_PORT(TARGET_RST), GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_RST)); // set output as open-drain + } else if (0 == strcmp("ODH", argument)) { // set reset to open-drain active hig + active_low = false; // remember we are active high + gpio_set_output_options(GPIO_PORT(TARGET_RST), GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_RST)); // set output as open-drain + } else if (0 == strcmp("PPL", argument)) { // set reset to push-pull active low + active_low = true; // remember we are active low + gpio_set_output_options(GPIO_PORT(TARGET_RST), GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_RST)); // set output as push-pull + } else if (0 == strcmp("PPH", argument)) { // set reset to push-pull active high + active_low = false; // remember we are active high + gpio_set_output_options(GPIO_PORT(TARGET_RST), GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_RST)); // set output as push-pull + } + } + + const bool open_drain = (GPIO_OTYPER(GPIO_PORT(TARGET_RST)) & GPIO_PIN(TARGET_RST)); // if the output is configured as open drain (else it's push-pull) + printf("reset pin set to %s active %s\n", open_drain ? "open-drain" : "push-pull", active_low ? "low" : "high"); + if (gpio_get(GPIO_PORT(TARGET_RST), GPIO_PIN(TARGET_RST))) { + if (active_low) { + puts("reset released\n"); + } else { + puts("reset asserted\n"); + } + } else { + if (active_low) { + puts("reset asserted\n"); + } else { + puts("reset released\n"); + } + } +} + /** scan for SWD interface on channels * @param[in] argument not used */ @@ -679,8 +734,8 @@ static const struct menu_command_t menu_commands[] = { .command_handler = &command_uptime, }, { - .shortcut = 'r', - .name = "reset", + .shortcut = 'R', + .name = "board_reset", .command_description = "reset board", .argument = MENU_ARGUMENT_NONE, .argument_description = NULL, @@ -726,6 +781,14 @@ static const struct menu_command_t menu_commands[] = { .argument_description = "[0|3|5]", .command_handler = &command_target_voltage, }, + { + .shortcut = 'r', + .name = "reset", + .command_description = "configure/reset target board", + .argument = MENU_ARGUMENT_STRING, + .argument_description = "[0|1|ODL|ODH|PPL|PPH]", + .command_handler = &command_target_reset, + }, { .shortcut = 'c', .name = "start", @@ -888,6 +951,10 @@ void main(void) gpio_set(GPIO_PORT(TARGET_5V), GPIO_PIN(TARGET_5V)); // ensure we do not enable pMOS to provide voltage gpio_set_output_options(GPIO_PORT(TARGET_5V), GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_5V)); // set output as open-drain gpio_mode_setup(GPIO_PORT(TARGET_5V), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(TARGET_5V)); // configure pin as output + rcc_periph_clock_enable(GPIO_RCC(TARGET_RST)); // enable clock for port domain + gpio_set(GPIO_PORT(TARGET_RST), GPIO_PIN(TARGET_RST)); // ensure reset is not pulled low + gpio_set_output_options(GPIO_PORT(TARGET_RST), GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_RST)); // set output as open-drain + gpio_mode_setup(GPIO_PORT(TARGET_RST), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(TARGET_RST)); // configure pin as output puts("OK\n"); puts("setup signal pins: ");