diff --git a/targets/TARGET_STM/TARGET_STM32H7/analogout_device.c b/targets/TARGET_STM/TARGET_STM32H7/analogout_device.c index f152113022..82dd474f0a 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/analogout_device.c +++ b/targets/TARGET_STM/TARGET_STM32H7/analogout_device.c @@ -23,6 +23,12 @@ #include "stm32h7xx_hal.h" #include "PeripheralPins.h" +// These variables are used for the "free" function +static int channel1_used = 0; +#if defined(DAC_CHANNEL_2) +static int channel2_used = 0; +#endif + void analogout_init(dac_t *obj, PinName pin) { DAC_ChannelConfTypeDef sConfig = {0}; @@ -55,6 +61,9 @@ void analogout_init(dac_t *obj, PinName pin) // Configure GPIO pinmap_pinout(pin, PinMap_DAC); + // Save the pin for future use + obj->pin = pin; + __GPIOA_CLK_ENABLE(); __HAL_RCC_DAC12_CLK_ENABLE(); @@ -73,12 +82,50 @@ void analogout_init(dac_t *obj, PinName pin) error("HAL_DAC_ConfigChannel failed"); } + if (obj->channel == DAC_CHANNEL_1) { + channel1_used = 1; + } +#if defined(DAC_CHANNEL_2) + if (obj->channel == DAC_CHANNEL_2) { + channel2_used = 1; + } +#endif analogout_write_u16(obj, 0); HAL_DAC_Start(&obj->handle, obj->channel); } void analogout_free(dac_t *obj) { + if (obj->channel == DAC_CHANNEL_1) { + channel1_used = 0; + } +#if defined(DAC_CHANNEL_2) + if (obj->channel == DAC_CHANNEL_2) { + channel2_used = 0; + } +#endif + + if ((channel1_used == 0) +#if defined(DAC_CHANNEL_2) + && (channel2_used == 0) +#endif + ) { + // Reset DAC and disable clock + __HAL_RCC_DAC12_FORCE_RESET(); + __HAL_RCC_DAC12_RELEASE_RESET(); + __HAL_RCC_DAC12_CLK_DISABLE(); + } + +#if defined(DAC2) + if (obj->dac == DAC_2) { + __HAL_RCC_DAC2_FORCE_RESET(); + __HAL_RCC_DAC2_RELEASE_RESET(); + __HAL_RCC_DAC2_CLK_DISABLE(); + } +#endif + + // Configure GPIO back to reset value + pin_function(obj->pin, STM_PIN_DATA(STM_MODE_ANALOG, GPIO_NOPULL, 0)); } const PinMap *analogout_pinmap()