Allow H7 targets to specify an ADC device for each channel and a default

ADC device in case of resource re-mapping conflict.

This allows a single ADC device to be used for all channels, which can
free up DMA channels.

For the H7 this makes much more sense because the TEMP and VREF channels
are ALWAYS on ADC3, so using ADC3 for other pins is optimal.

The previous behaviour was to use the first instance for that supported
the pin.  This behavour is only used when the configured default DMA
device does not support the pin.

e.g.

```

possible.

```

The above config would no-longer use ADC1 for anything, as ADC2 and ADC3
can satisfy all the ADC requirements.
This commit is contained in:
Dominic Clifton 2020-08-09 16:58:07 +02:00
parent 474fddd08a
commit ea69db0400
3 changed files with 55 additions and 14 deletions

View File

@ -281,18 +281,22 @@ void adcInit(const adcConfig_t *config)
if (config->vbat.enabled) {
adcOperatingConfig[ADC_BATTERY].tag = config->vbat.ioTag;
adcOperatingConfig[ADC_BATTERY].adcDevice = config->vbat.device;
}
if (config->rssi.enabled) {
adcOperatingConfig[ADC_RSSI].tag = config->rssi.ioTag; //RSSI_ADC_CHANNEL;
adcOperatingConfig[ADC_RSSI].adcDevice = config->rssi.device;
}
if (config->external1.enabled) {
adcOperatingConfig[ADC_EXTERNAL1].tag = config->external1.ioTag; //EXTERNAL1_ADC_CHANNEL;
adcOperatingConfig[ADC_EXTERNAL1].adcDevice = config->external1.device;
}
if (config->current.enabled) {
adcOperatingConfig[ADC_CURRENT].tag = config->current.ioTag; //CURRENT_METER_ADC_CHANNEL;
adcOperatingConfig[ADC_CURRENT].adcDevice = config->current.device;
}
#ifdef USE_ADC_INTERNAL
@ -331,24 +335,30 @@ void adcInit(const adcConfig_t *config)
// Found a tag map entry for this input pin
// Find an ADC device that can handle this input pin
for (dev = 0; dev < ADCDEV_COUNT; dev++) {
if (!adcDevice[dev].ADCx
bool useConfiguredDevice = (dev != ADCINVALID) && (adcTagMap[map].devices & (1 << dev));
if (!useConfiguredDevice) {
// If the ADC was configured to use a specific device, but that device was not active, then try and find another active instance that works for the pin.
for (dev = 0; dev < ADCDEV_COUNT; dev++) {
if (!adcDevice[dev].ADCx
#ifndef USE_DMA_SPEC
|| !adcDevice[dev].dmaResource
|| !adcDevice[dev].dmaResource
#endif
) {
// Instance not activated
) {
// Instance not activated
continue;
}
if (adcTagMap[map].devices & (1 << dev)) {
// Found an activated ADC instance for this input pin
break;
}
}
if (dev == ADCDEV_COUNT) {
// No valid device found, go next channel.
continue;
}
if (adcTagMap[map].devices & (1 << dev)) {
// Found an activated ADC instance for this input pin
break;
}
}
if (dev == ADCDEV_COUNT) {
// No valid device found, go next channel.
continue;
}
}

View File

@ -58,21 +58,49 @@ void pgResetFn_adcConfig(adcConfig_t *adcConfig)
#ifdef VBAT_ADC_PIN
adcConfig->vbat.enabled = true;
adcConfig->vbat.ioTag = IO_TAG(VBAT_ADC_PIN);
#if defined(STM32H7)
#ifdef VBAT_ADC_INSTANCE
adcConfig->vbat.device = ADC_DEV_TO_CFG(adcDeviceByInstance(VBAT_ADC_INSTANCE));
#else
adcConfig->vbat.device = adcConfig->device;
#endif
#endif
#endif
#ifdef EXTERNAL1_ADC_PIN
adcConfig->external1.enabled = true;
adcConfig->external1.ioTag = IO_TAG(EXTERNAL1_ADC_PIN);
#if defined(STM32H7)
#ifdef EXTERNAL1_ADC_INSTANCE
adcConfig->external1.device = ADC_DEV_TO_CFG(adcDeviceByInstance(EXTERNAL1_ADC_INSTANCE));
#else
adcConfig->external1.device = adcConfig->device;
#endif
#endif
#endif
#ifdef CURRENT_METER_ADC_PIN
adcConfig->current.enabled = true;
adcConfig->current.ioTag = IO_TAG(CURRENT_METER_ADC_PIN);
#if defined(STM32H7)
#ifdef CURRENT_METER_ADC_INSTANCE
adcConfig->current.device = ADC_DEV_TO_CFG(adcDeviceByInstance(CURRENT_METER_ADC_INSTANCE));
#else
adcConfig->current.device = adcConfig->device;
#endif
#endif
#endif
#ifdef RSSI_ADC_PIN
adcConfig->rssi.enabled = true;
adcConfig->rssi.ioTag = IO_TAG(RSSI_ADC_PIN);
#if defined(STM32H7)
#ifdef RSSI_ADC_INSTANCE
adcConfig->rssi.device = ADC_DEV_TO_CFG(adcDeviceByInstance(RSSI_ADC_INSTANCE));
#else
adcConfig->rssi.device = adcConfig->device;
#endif
#endif
#endif
adcConfig->vrefIntCalibration = 0;

View File

@ -31,6 +31,9 @@
typedef struct adcChannelConfig_t {
bool enabled;
ioTag_t ioTag;
#if defined(STM32H7)
int8_t device; // ADCDevice
#endif
} adcChannelConfig_t;
typedef struct adcConfig_s {