CommunityGD32Cores / ArduinoCore-GD32

Arduino core for GD32 devices, community developed, based on original GigaDevice's core
Other
89 stars 33 forks source link

DAC buffer on/off #104

Open flute2k3 opened 1 year ago

flute2k3 commented 1 year ago

I noticed that with analogWrite() function, even I put 0, the output is not zero, something around xx - xxx mV, I happened to find that it is due to DAC buffer on - maybe by default? refer to below link ... I have no negative power available so this non-zero output is a little bit disturbing.

Is that possible we can turn the buffer off to get the zero voltage output using Arduino way? I anyway have to connect a buffer using low drift opamp so it does not matter.

https://stcommunity.st.com/t5/stm32-mcu-products/minimum-dac-output-voltage-on-stm32f30x/m-p/410862

maxgerhardt commented 1 year ago

The DAC buffer is indeed turned on by default.

https://github.com/CommunityGD32Cores/ArduinoCore-GD32/blob/dfa7ccbef5161f0215d28d9b59aa9f24e61d07f5/cores/arduino/analog.cpp#L73-L125

Sounds like we should disable the DAC altogether when analogWrite(0); is called and output LOW as a GPIO pin? How bad is the offset at analogWrite(1);? is it a general offset that is always there as long as the buffer is enabled?

flute2k3 commented 1 year ago

the output changes proportionally with 1, 2 ... etc, it is a constant offset as far as I tested.

maxgerhardt commented 1 year ago

So when you put

dac_output_buffer_disable(DAC0);
dac_output_buffer_disable(DAC1);

after every analogWrite() call, the offset problem is mostly gone and the DAC output curve is more ideal?

flute2k3 commented 1 year ago

I tested writing 0 on a standalone bluepill plus board, without dac_output_buffer_disable(DAC0); PA4 = 6.303 mV with dac_output_buffer_disable(DAC0); PA4 = 0.228 mV it makes notable difference at 0 output now.

maxgerhardt commented 1 year ago

We can definitely add an API for this but I'm not sure if this should be the default behavior. The datasheet says that the purpose of the buffer is to provide a low-impedence output that can directly drive stuff without needing an external opamp. I can't repredict the user's application for this, whether the drive capability or voltage accuracy is more important :( .

A static +6mV offset in a total voltage swing of 3300mV doesn't seem neck-breaking to me, but I'm also willing to be convinced of the opposite.

flute2k3 commented 1 year ago

keep the default maxgerhardt, no action needed, I will use dac_output_buffer_disable(DAC0) for my application :-) cheers ~