From 468f199d22ee6825973088014b74dd9b7e3d6e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Thu, 11 Mar 2021 10:53:02 +0100 Subject: [PATCH] application: add multiplexer control --- application.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/application.c b/application.c index 3446fff..f062e93 100644 --- a/application.c +++ b/application.c @@ -59,6 +59,12 @@ const uint8_t channels[] = {ADC_CHANNEL17, ADC_CHANNEL(TARGET_CHANNEL), ADC_CHAN #define SIGNAL_PU_PIN PA4 /**< pin to pull signal to target voltage (controlling gate of pMOS) */ #define TARGET_EN PA5 /**< pin to provide target voltage to LV side of voltage shifter (pulling them high through 10 kO) */ +#define MUX_EN_PIN PB2 /**< pin to enable analog multiplexer (active low) */ +#define MUX_S0_PIN PA6 /**< pin to set S0 bit of analog multiplexer */ +#define MUX_S1_PIN PA7 /**< pin to set S1 bit of analog multiplexer */ +#define MUX_S2_PIN PB0 /**< pin to set S2 bit of analog multiplexer */ +#define MUX_S3_PIN PB1 /**< pin to set S3 bit of analog multiplexer */ + size_t putc(char c) { size_t length = 0; // number of characters printed @@ -118,6 +124,39 @@ static float* measure_voltages(void) return voltages; } +/** select channel of multiplexer + * @param[in] channel channel to select, or -1 to disable multiplexer + */ +static void mux_select(int8_t channel) +{ + gpio_set(GPIO_PORT(MUX_EN_PIN), GPIO_PIN(MUX_EN_PIN)); // disable multiplexer while we are switching + if (channel < 0 || channel > 15) { + return; // no channel to select + } + // select channel using bit pattern + if (channel & 0x1) { + gpio_set(GPIO_PORT(MUX_S0_PIN), GPIO_PIN(MUX_S0_PIN)); + } else { + gpio_clear(GPIO_PORT(MUX_S0_PIN), GPIO_PIN(MUX_S0_PIN)); + } + if (channel & 0x2) { + gpio_set(GPIO_PORT(MUX_S1_PIN), GPIO_PIN(MUX_S1_PIN)); + } else { + gpio_clear(GPIO_PORT(MUX_S1_PIN), GPIO_PIN(MUX_S1_PIN)); + } + if (channel & 0x4) { + gpio_set(GPIO_PORT(MUX_S2_PIN), GPIO_PIN(MUX_S2_PIN)); + } else { + gpio_clear(GPIO_PORT(MUX_S2_PIN), GPIO_PIN(MUX_S2_PIN)); + } + if (channel & 0x8) { + gpio_set(GPIO_PORT(MUX_S3_PIN), GPIO_PIN(MUX_S3_PIN)); + } else { + gpio_clear(GPIO_PORT(MUX_S3_PIN), GPIO_PIN(MUX_S3_PIN)); + } + gpio_clear(GPIO_PORT(MUX_EN_PIN), GPIO_PIN(MUX_EN_PIN)); // enable multiplexer +} + // menu commands static void command_swd_scan(void* argument) @@ -578,6 +617,30 @@ void main(void) gpio_mode_setup(GPIO_PORT(SIGNAL_PU_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(SIGNAL_PU_PIN)); // configure pin as output puts("OK\n"); + puts("setup analog multiplexer: "); + rcc_periph_clock_enable(GPIO_RCC(MUX_EN_PIN)); // enable clock for port domain + gpio_set(GPIO_PORT(MUX_EN_PIN), GPIO_PIN(MUX_EN_PIN)); // ensure multiplexer is disabled + gpio_set_output_options(GPIO_PORT(MUX_EN_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN(MUX_EN_PIN)); // set output as push-pull to drive correctly + gpio_mode_setup(GPIO_PORT(MUX_EN_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(MUX_EN_PIN)); // configure pin as output + rcc_periph_clock_enable(GPIO_RCC(MUX_S0_PIN)); // enable clock for port domain + gpio_clear(GPIO_PORT(MUX_S0_PIN), GPIO_PIN(MUX_S0_PIN)); // any channel selected is fine + gpio_set_output_options(GPIO_PORT(MUX_S0_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN(MUX_S0_PIN)); // set output as push-pull to drive correctly + gpio_mode_setup(GPIO_PORT(MUX_S0_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(MUX_S0_PIN)); // configure pin as output + rcc_periph_clock_enable(GPIO_RCC(MUX_S1_PIN)); // enable clock for port domain + gpio_clear(GPIO_PORT(MUX_S1_PIN), GPIO_PIN(MUX_S1_PIN)); // any channel selected is fine + gpio_set_output_options(GPIO_PORT(MUX_S1_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN(MUX_S1_PIN)); // set output as push-pull to drive correctly + gpio_mode_setup(GPIO_PORT(MUX_S1_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(MUX_S1_PIN)); // configure pin as output + rcc_periph_clock_enable(GPIO_RCC(MUX_S2_PIN)); // enable clock for port domain + gpio_clear(GPIO_PORT(MUX_S2_PIN), GPIO_PIN(MUX_S2_PIN)); // any channel selected is fine + gpio_set_output_options(GPIO_PORT(MUX_S2_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN(MUX_S2_PIN)); // set output as push-pull to drive correctly + gpio_mode_setup(GPIO_PORT(MUX_S2_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(MUX_S2_PIN)); // configure pin as output + rcc_periph_clock_enable(GPIO_RCC(MUX_S3_PIN)); // enable clock for port domain + gpio_clear(GPIO_PORT(MUX_S3_PIN), GPIO_PIN(MUX_S3_PIN)); // any channel selected is fine + gpio_set_output_options(GPIO_PORT(MUX_S3_PIN), GPIO_OTYPE_PP, GPIO_OSPEED_2MHZ, GPIO_PIN(MUX_S3_PIN)); // set output as push-pull to drive correctly + gpio_mode_setup(GPIO_PORT(MUX_S3_PIN), GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN(MUX_S3_PIN)); // configure pin as output + mux_select(-1); // ensure it is disabled + puts("OK\n"); + puts("setup ADC to measure voltages: "); rcc_periph_clock_enable(RCC_ADC1); // enable clock for ADC domain adc_power_off(ADC1); // switch off ADC while configuring it