diff --git a/application.c b/application.c index 5e0add9..4fff7ce 100644 --- a/application.c +++ b/application.c @@ -54,6 +54,8 @@ 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_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) */ #define CHANNEL_NUMBERS 16 /**< number of target signals */ static const uint32_t channel_ports[] = {GPIO_PORT(PB12), GPIO_PORT(PB13), GPIO_PORT(PB14), GPIO_PORT(PB15), GPIO_PORT(PA8), GPIO_PORT(PA9), GPIO_PORT(PA10), GPIO_PORT(PA15), GPIO_PORT(PB3), GPIO_PORT(PB4), GPIO_PORT(PB5), GPIO_PORT(PB6), GPIO_PORT(PB7), GPIO_PORT(PB8), GPIO_PORT(PB9), GPIO_PORT(PB10)}; /**< GPIO ports for signal pin */ @@ -173,20 +175,51 @@ static void print_idcode(uint32_t idcode) // menu commands /** measure and print target voltage - * @param[in] argument not used + * @param[in] argument 0 to no provide power, 3 to provide 3.3V, 5 to provide 5V */ static void command_target_voltage(void* argument) { (void)argument; // we won't use the argument gpio_set(GPIO_PORT(TARGET_EN), GPIO_PIN(TARGET_EN)); // ensure the level shifters pulling up the signals are not enabled + + // 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_5V), GPIO_PIN(TARGET_5V)); // disable 5V output + gpio_set(GPIO_PORT(TARGET_3V), GPIO_PIN(TARGET_3V)); // disable 3V output + break; + case 3: + gpio_set(GPIO_PORT(TARGET_5V), GPIO_PIN(TARGET_5V)); // disable 5V output + gpio_clear(GPIO_PORT(TARGET_3V), GPIO_PIN(TARGET_3V)); // enable 3V output + break; + case 5: + gpio_clear(GPIO_PORT(TARGET_5V), GPIO_PIN(TARGET_5V)); // enable 5V output + gpio_set(GPIO_PORT(TARGET_3V), GPIO_PIN(TARGET_3V)); // disable 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_5V), GPIO_PIN(TARGET_5V))) { + puts("target voltage set to 5 V\n"); + } else if (!gpio_get(GPIO_PORT(TARGET_3V), GPIO_PIN(TARGET_3V))) { + 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] > 3.25) { - puts(" (warning: signal voltage may exceed 3.30 V limit)"); - } else if (voltages[1] < 1.0) { + if (voltages[1] < 1.0) { puts(" (warning: target voltage seems not connected)"); } putc('\n'); @@ -683,9 +716,9 @@ static const struct menu_command_t menu_commands[] = { { .shortcut = 'v', .name = "voltage", - .command_description = "measure target voltage", - .argument = MENU_ARGUMENT_NONE, - .argument_description = NULL, + .command_description = "set/measure target voltage", + .argument = MENU_ARGUMENT_UNSIGNED, + .argument_description = "[0|3|5]", .command_handler = &command_target_voltage, }, { @@ -842,6 +875,14 @@ void main(void) gpio_set(GPIO_PORT(TARGET_EN), GPIO_PIN(TARGET_EN)); // ensure we do not enable pMOS to power level shifters gpio_set_output_options(GPIO_PORT(TARGET_EN), GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_EN)); // set output as open-drain gpio_mode_setup(GPIO_PORT(TARGET_EN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(TARGET_EN)); // configure pin as output + rcc_periph_clock_enable(GPIO_RCC(TARGET_3V)); // enable clock for port domain + gpio_set(GPIO_PORT(TARGET_3V), GPIO_PIN(TARGET_3V)); // ensure we do not enable pMOS to provide voltage + gpio_set_output_options(GPIO_PORT(TARGET_3V), GPIO_OTYPE_OD, GPIO_OSPEED_2MHZ, GPIO_PIN(TARGET_3V)); // set output as open-drain + gpio_mode_setup(GPIO_PORT(TARGET_3V), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(TARGET_3V)); // configure pin as output + rcc_periph_clock_enable(GPIO_RCC(TARGET_5V)); // enable clock for port domain + 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 puts("OK\n"); puts("setup signal pins: ");