2023-05-24 02:55 AM
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);
}
2023-05-24 03:25 AM
Check errata.
Read out and check/post content of DAC, OPAMP, relevant GPIO registers.
JW
2023-05-24 04:01 AM
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:
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