summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/library/pyb.DAC.rst21
-rw-r--r--ports/stm32/dac.c24
-rw-r--r--tests/pyb/dac.py4
3 files changed, 42 insertions, 7 deletions
diff --git a/docs/library/pyb.DAC.rst b/docs/library/pyb.DAC.rst
index fd786b63b..3e236a3da 100644
--- a/docs/library/pyb.DAC.rst
+++ b/docs/library/pyb.DAC.rst
@@ -49,7 +49,7 @@ To output a continuous sine-wave at 12-bit resolution::
Constructors
------------
-.. class:: pyb.DAC(port, bits=8)
+.. class:: pyb.DAC(port, bits=8, \*, buffering=None)
Construct a new DAC object.
@@ -60,12 +60,27 @@ Constructors
The maximum value for the write and write_timed methods will be
2\*\*``bits``-1.
+ The *buffering* parameter selects the behaviour of the DAC op-amp output
+ buffer, whose purpose is to reduce the output impedance. It can be
+ ``None`` to select the default (buffering enabled for :meth:`DAC.noise`,
+ :meth:`DAC.triangle` and :meth:`DAC.write_timed`, and disabled for
+ :meth:`DAC.write`), ``False`` to disable buffering completely, or ``True``
+ to enable output buffering.
+
+ When buffering is enabled the DAC pin can drive loads down to 5KΩ.
+ Otherwise it has an output impedance of 15KΩ maximum: consequently
+ to achieve a 1% accuracy without buffering requires the applied load
+ to be less than 1.5MΩ. Using the buffer incurs a penalty in accuracy,
+ especially near the extremes of range.
+
Methods
-------
-.. method:: DAC.init(bits=8)
+.. method:: DAC.init(bits=8, \*, buffering=None)
- Reinitialise the DAC. ``bits`` can be 8 or 12.
+ Reinitialise the DAC. *bits* can be 8 or 12. *buffering* can be
+ ``None``, ``False`` or ``True`; see above constructor for the meaning
+ of this parameter.
.. method:: DAC.deinit()
diff --git a/ports/stm32/dac.c b/ports/stm32/dac.c
index bce30dbc7..04acfb8aa 100644
--- a/ports/stm32/dac.c
+++ b/ports/stm32/dac.c
@@ -143,11 +143,14 @@ typedef struct _pyb_dac_obj_t {
uint16_t pin; // GPIO_PIN_4 or GPIO_PIN_5
uint8_t bits; // 8 or 12
uint8_t state;
+ uint8_t outbuf_single;
+ uint8_t outbuf_waveform;
} pyb_dac_obj_t;
STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 8} },
+ { MP_QSTR_buffering, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
};
// parse args
@@ -194,6 +197,19 @@ STATIC mp_obj_t pyb_dac_init_helper(pyb_dac_obj_t *self, size_t n_args, const mp
mp_raise_ValueError("unsupported bits");
}
+ // set output buffer config
+ if (args[1].u_obj == mp_const_none) {
+ // due to legacy, default values differ for single and waveform outputs
+ self->outbuf_single = DAC_OUTPUTBUFFER_DISABLE;
+ self->outbuf_waveform = DAC_OUTPUTBUFFER_ENABLE;
+ } else if (mp_obj_is_true(args[1].u_obj)) {
+ self->outbuf_single = DAC_OUTPUTBUFFER_ENABLE;
+ self->outbuf_waveform = DAC_OUTPUTBUFFER_ENABLE;
+ } else {
+ self->outbuf_single = DAC_OUTPUTBUFFER_DISABLE;
+ self->outbuf_waveform = DAC_OUTPUTBUFFER_DISABLE;
+ }
+
// reset state of DAC
self->state = DAC_STATE_RESET;
@@ -289,7 +305,7 @@ STATIC mp_obj_t pyb_dac_noise(mp_obj_t self_in, mp_obj_t freq) {
// configure DAC to trigger via TIM6
DAC_ChannelConfTypeDef config;
config.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
- config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+ config.DAC_OutputBuffer = self->outbuf_waveform;
HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
self->state = DAC_STATE_BUILTIN_WAVEFORM;
}
@@ -319,7 +335,7 @@ STATIC mp_obj_t pyb_dac_triangle(mp_obj_t self_in, mp_obj_t freq) {
// configure DAC to trigger via TIM6
DAC_ChannelConfTypeDef config;
config.DAC_Trigger = DAC_TRIGGER_T6_TRGO;
- config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+ config.DAC_OutputBuffer = self->outbuf_waveform;
HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
self->state = DAC_STATE_BUILTIN_WAVEFORM;
}
@@ -342,7 +358,7 @@ STATIC mp_obj_t pyb_dac_write(mp_obj_t self_in, mp_obj_t val) {
if (self->state != DAC_STATE_WRITE_SINGLE) {
DAC_ChannelConfTypeDef config;
config.DAC_Trigger = DAC_TRIGGER_NONE;
- config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
+ config.DAC_OutputBuffer = self->outbuf_single;
HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
self->state = DAC_STATE_WRITE_SINGLE;
}
@@ -454,7 +470,7 @@ mp_obj_t pyb_dac_write_timed(size_t n_args, const mp_obj_t *pos_args, mp_map_t *
if (self->state != DAC_STATE_DMA_WAVEFORM + dac_trigger) {
DAC_ChannelConfTypeDef config;
config.DAC_Trigger = dac_trigger;
- config.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE;
+ config.DAC_OutputBuffer = self->outbuf_waveform;
HAL_DAC_ConfigChannel(&DAC_Handle, &config, self->dac_channel);
self->state = DAC_STATE_DMA_WAVEFORM + dac_trigger;
}
diff --git a/tests/pyb/dac.py b/tests/pyb/dac.py
index 6f03bbc64..ca68ec709 100644
--- a/tests/pyb/dac.py
+++ b/tests/pyb/dac.py
@@ -12,3 +12,7 @@ dac.write(0)
dac.write_timed(bytearray(10), 100, mode=pyb.DAC.NORMAL)
pyb.delay(20)
dac.write(0)
+
+# test buffering arg
+dac = pyb.DAC(1, buffering=True)
+dac.write(0)