application: add multiplex control

This commit is contained in:
King Kévin 2021-03-24 00:42:25 +01:00
parent d55dbc34b2
commit df2dfe0cb4
1 changed files with 63 additions and 0 deletions

View File

@ -54,6 +54,12 @@ static uint32_t boot_time = 0;
#define SIGNAL_CHANNEL 1 /**< PA1/ADC1_IN1 used to measure signal voltage */
const uint8_t adc_channels[] = {ADC_CHANNEL17, ADC_CHANNEL(TARGET_CHANNEL), ADC_CHANNEL(SIGNAL_CHANNEL)}; /**< voltages to convert (channel 17 = internal voltage reference) */
#define MUX_EN_PIN PC15 /**< pin to enable analog multiplexer (active low) */
#define MUX_S0_PIN PA7 /**< pin to set S0 bit of analog multiplexer */
#define MUX_S1_PIN PB0 /**< pin to set S1 bit of analog multiplexer */
#define MUX_S2_PIN PB1 /**< pin to set S2 bit of analog multiplexer */
#define MUX_S3_PIN PB2 /**< pin to set S3 bit of analog multiplexer */
size_t putc(char c)
{
size_t length = 0; // number of characters printed
@ -90,6 +96,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 || (channel > CHANNEL_NUMBERS - 1)) {
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
/** display available commands
@ -465,6 +504,30 @@ void main(void)
// important: do not re-enable backup_domain_write_protect, since this will prevent clearing flags (but RTC registers do not need to be unlocked)
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