stm32/dac: Add buffering argument to constructor and init() method.
This can be used to select the output buffer behaviour of the DAC. The default values are chosen to retain backwards compatibility with existing behaviour. Thanks to @peterhinch for the initial idea to add this feature.
This commit is contained in:
parent
aebd9701a7
commit
b30e0d2f26
|
@ -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()
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue