Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DAC buffer on/off #104

Open
flute2k3 opened this issue Jun 20, 2023 · 6 comments
Open

DAC buffer on/off #104

flute2k3 opened this issue Jun 20, 2023 · 6 comments

Comments

@flute2k3
Copy link

flute2k3 commented Jun 20, 2023

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
Copy link
Member

The DAC buffer is indeed turned on by default.

void set_dac_value(PinName pinname, uint16_t value)
{
#if DAC_NUMS != 0
uint32_t dac_periph = pinmap_peripheral(pinname, PinMap_DAC);
uint8_t index = get_dac_index(dac_periph);
if (!DAC_[index].isactive) {
pinmap_pinout(pinname, PinMap_DAC);
rcu_periph_clock_enable(RCU_DAC);
// only do reset of DAC clock domain once when *every* DAC is being inactive.
bool do_reset = true;
for(uint8_t i = 0; i < DAC_NUMS; i++) {
if(DAC_[i].isactive) {
do_reset = false;
break;
}
}
if(do_reset) {
dac_deinit();
}
#if (defined(GD32F1x0) && defined(GD32F170_190)) || defined(GD32F30x) || defined(GD32E50X)
dac_trigger_disable(dac_periph);
#if defined(GD32F30x) || defined(GD32E50X)
dac_wave_mode_config(dac_periph, DAC_WAVE_DISABLE);
#endif
dac_output_buffer_enable(dac_periph);
dac_enable(dac_periph);
dac_data_set(dac_periph, DAC_ALIGN_12B_R, value);
#elif defined(GD32F1x0) && !defined(GD32F170_190)
dac0_trigger_disable();
dac0_output_buffer_enable();
dac0_enable();
dac0_data_set(DAC_ALIGN_12B_R, value);
#elif defined(GD32F3x0)
/* only has 1 DAC at maximum, no need for a parameter... */
dac_trigger_disable();
dac_wave_mode_config(DAC_WAVE_DISABLE);
dac_output_buffer_enable();
dac_enable();
dac_data_set(DAC_ALIGN_12B_R, value);
#endif
DAC_[index].isactive = true;
} else {
//set dac value
#if defined(GD32F30x) || (defined(GD32F1x0) && defined(GD32F170_190)) || defined(GD32E50X)
dac_data_set(dac_periph, DAC_ALIGN_12B_R, value);
#elif defined(GD32F10x) && !defined(GD32F170_190)
dac0_data_set(DAC_ALIGN_12B_R, value);
#elif defined(GD32F3x0)
dac_data_set(DAC_ALIGN_12B_R, value);
#endif
}
#endif
}

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
Copy link
Author

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

@maxgerhardt
Copy link
Member

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
Copy link
Author

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
Copy link
Member

maxgerhardt commented Jun 20, 2023

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
Copy link
Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants