cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L562 DAC output on PA3 via OPAMP1 follower breaks when using PA4 as GPIO output

Peter3
Associate

I can successfully output an analog voltage on PA3 from DAC1 Channel 1 via OPAMP1 in follower mode. If I try to use PA4 as a GPIO output the analog voltage on PA3 disappears. Is this a known issue with this chip? Are there any workarounds?

The reference manual says "The DACx_OUTy pin can be used as general purpose input/output (GPIO) when the DAC output is disconnected from output pad and connected to on chip peripheral." What I've encountered seems to contradict this.

Full code below which does not work, unless MX_GPIO_Init() (line 17) is commented out.

#include "main.h"
 
DAC_HandleTypeDef hdac1;
 
OPAMP_HandleTypeDef hopamp1;
 
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DAC1_Init(void);
static void MX_OPAMP1_Init(void);
static void MX_ICACHE_Init(void);
int main(void)
{
  HAL_Init();
  SystemClock_Config();
 
  MX_GPIO_Init();
  MX_DAC1_Init();
  MX_OPAMP1_Init();
  MX_ICACHE_Init();
 
  HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);
  HAL_OPAMP_Start(&hopamp1);
 
  HAL_DAC_SetValue(&hdac1, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0x7FF);
  while (1);
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2) != HAL_OK)
  {
    Error_Handler();
  }
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_DAC1_Init(void)
{
  DAC_ChannelConfTypeDef sConfig = {0};
 
  hdac1.Instance = DAC1;
  if (HAL_DAC_Init(&hdac1) != HAL_OK)
  {
    Error_Handler();
  }
 
  sConfig.DAC_SampleAndHold = DAC_SAMPLEANDHOLD_DISABLE;
  sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
  sConfig.DAC_HighFrequency = DAC_HIGH_FREQUENCY_INTERFACE_MODE_DISABLE;
  sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
  sConfig.DAC_ConnectOnChipPeripheral = DAC_CHIPCONNECT_ENABLE;
  sConfig.DAC_UserTrimming = DAC_TRIMMING_FACTORY;
  if (HAL_DAC_ConfigChannel(&hdac1, &sConfig, DAC_CHANNEL_1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_ICACHE_Init(void)
{
  if (HAL_ICACHE_ConfigAssociativityMode(ICACHE_1WAY) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_ICACHE_Enable() != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_OPAMP1_Init(void)
{
  hopamp1.Instance = OPAMP1;
  hopamp1.Init.PowerSupplyRange = OPAMP_POWERSUPPLY_HIGH;
  hopamp1.Init.Mode = OPAMP_FOLLOWER_MODE;
  hopamp1.Init.NonInvertingInput = OPAMP_NONINVERTINGINPUT_DAC_CH;
  hopamp1.Init.PowerMode = OPAMP_POWERMODE_NORMALPOWER;
  hopamp1.Init.UserTrimming = OPAMP_TRIMMING_FACTORY;
  if (HAL_OPAMP_Init(&hopamp1) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
 
  HAL_GPIO_WritePin(CSS_GPIO_Port, CSS_Pin, GPIO_PIN_RESET);
 
  GPIO_InitStruct.Pin = CSS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(CSS_GPIO_Port, &GPIO_InitStruct);
}
 
void Error_Handler(void)
{
  __disable_irq();
  while (1);
}

2 REPLIES 2

Check errata.

Read out and check/post content of DAC, OPAMP, relevant GPIO registers.

JW

Peter3
Associate

Errata as follows, I don't think any of this is relevant.

DAC

2.6.1 Invalid DAC channel analog output if the DAC channel MODE bitfield is programmed before

DAC initialization Description

When the DAC operates in Normal mode and the DAC enable bit is cleared, writing a value different from 000 to the DAC channel MODE bitfield of the DAC_MCR register before performing data initialization causes the corresponding DAC channel analog output to be invalid.

Workaround

Apply the following sequence:

  1. Perform one write access to any data register.
  2. Program the MODE bitfield of the DAC_MCR register.

2.6.2 DMA underrun flag not set when an internal trigger is detected on the clock cycle of the DMA request acknowledge

Description

When the DAC channel operates in DMA mode (DMAEN of DAC_CR register set), the DMA channel underrun flag (DMAUDR of DAC_SR register) fails to rise upon an internal trigger detection if that detection occurs during the same clock cycle as a DMA request acknowledge. As a result, the user application is not informed that an underrun error occurred.

This issue occurs when software and hardware triggers are used concurrently to trigger DMA transfers.

Workaround

None.

Registers as follows:

              WORKING     BROKEN
DAC
DAC_CR        0x00000001  0x00000001
DAC_DHR12R1   0x000007ff  0x000007ff
DAC_DHR12L1   0x00007ff0  0x00007ff0
DAC_DHR8R1    0x0000007f  0x0000007f
DAC_DHR12R2   0x00000000  0x00000000
DAC_DHR12L2   0x00000000  0x00000000
DAC_DHR8R2    0x00000000  0x00000000
DAC_DHR12RD   0x000007ff  0x000007ff
DAC_DHR12LD   0x00007ff0  0x00007ff0
DAC_DHR8RD    0x0000007f  0x0000007f
DAC_DOR1      0x000007ff  0x000007ff
DAC_DOR2      0x00000000  0x00000000
DAC_SR        0x00000000  0x00000000
DAC_CCR       0x00160012  0x00160012
DAC_MCR       0x00000003  0x00000003
DAC_SHSR1     0x00000000  0x00000000
DAC_SHSR2     0x00000000  0x00000000
DAC_SHHR      0x00010001  0x00010001
DAC_SHRR      0x00010001  0x00010001
 
GPIOA
MODER         0xabffffff  0xabfffdff
OTYPER        0x00000000  0x00000000
OSPEEDR       0x0c000000  0x0c000000
PUPDR         0x64000000  0x64000000
IDR           0x0000a000  0x0000a000
ODR           0x00000000  0x00000000
LCKR          0x00000000  0x00000000
AFRL          0x00000000  0x00000000
AFRH          0x00000000  0x00000000
 
OPAMP
OPAMP1_CSR    0x8000040d  0x8000040d
OPAMP1_OTR    0x00001010  0x00001010
OPAMP1_LPOTR  0x00001011  0x00001011