Skip to content

ports/samd/machine_dac.c: Fix SAMD51 DAC for two channels. #15890

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

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 36 additions & 16 deletions ports/samd/machine_dac.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ static uint8_t dac_vref_table[] = {
#define MAX_DAC_VALUE (4095)
#define DEFAULT_DAC_VREF (2)
#define MAX_DAC_VREF (3)
static bool dac_init = false;
static bool dac_init[2] = {false, false};
#endif


Expand All @@ -91,20 +91,21 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_

uint8_t id = args[ARG_id].u_int;
dac_obj_t *self = NULL;
if (0 <= id && id <= MP_ARRAY_SIZE(dac_obj)) {
if (0 <= id && id < MP_ARRAY_SIZE(dac_obj)) {
self = &dac_obj[id];
} else {
mp_raise_ValueError(MP_ERROR_TEXT("invalid Pin for DAC"));
mp_raise_ValueError(MP_ERROR_TEXT("invalid id for DAC"));
}

uint8_t vref = args[ARG_vref].u_int;
if (0 <= vref && vref <= MAX_DAC_VREF) {
self->vref = vref;
}

Dac *dac = dac_bases[0]; // Just one DAC
Dac *dac = dac_bases[0]; // Just one DAC register block

// initialize DAC

// Init DAC
#if defined(MCU_SAMD21)

// Configuration SAMD21
Expand All @@ -127,21 +128,39 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_

// Configuration SAMD51
// Enable APBD clocks and PCHCTRL clocks; GCLK3 at 8 MHz
dac_init = true;
MCLK->APBDMASK.reg |= MCLK_APBDMASK_DAC;
GCLK->PCHCTRL[DAC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK3 | GCLK_PCHCTRL_CHEN;

// Reset DAC registers
dac->CTRLA.bit.SWRST = 1;
while (dac->CTRLA.bit.SWRST) {
if (!(dac_init[0] | dac_init[1])) {
MCLK->APBDMASK.reg |= MCLK_APBDMASK_DAC;
GCLK->PCHCTRL[DAC_GCLK_ID].reg = GCLK_PCHCTRL_GEN_GCLK3 | \
GCLK_PCHCTRL_CHEN;

// Reset DAC registers
dac->CTRLA.bit.SWRST = 1;
while (dac->CTRLA.bit.SWRST) {
}
dac->CTRLB.reg = DAC_CTRLB_REFSEL(dac_vref_table[self->vref]);

}
dac->CTRLB.reg = DAC_CTRLB_REFSEL(dac_vref_table[self->vref]);
dac->DACCTRL[self->id].reg = DAC_DACCTRL_ENABLE | DAC_DACCTRL_REFRESH(2) | DAC_DACCTRL_CCTRL_CC12M;

// Enable DAC and wait to be ready
dac->CTRLA.bit.ENABLE = 1;
while (dac->SYNCBUSY.bit.ENABLE) {
// Modify DAC config - requires disabling see §47.6.2.3 of data sheet
if (!dac_init[self->id]) {
// Disable DAC and wait
dac->CTRLA.bit.ENABLE = 0;
while (dac->SYNCBUSY.bit.ENABLE) {
}

// Modify configuration
dac->DACCTRL[self->id].reg = DAC_DACCTRL_ENABLE | \
DAC_DACCTRL_REFRESH(2) | DAC_DACCTRL_CCTRL_CC12M;
dac->DATA[self->id].reg = 0;
dac_init[self->id] = true;

// Enable DAC and wait
dac->CTRLA.bit.ENABLE = 1;
while (dac->SYNCBUSY.bit.ENABLE) {
}
}

#endif

// Set the port as given in self->gpio_id as DAC
Expand Down Expand Up @@ -170,6 +189,7 @@ static mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t value_in) {

return mp_const_none;
}

MP_DEFINE_CONST_FUN_OBJ_2(dac_write_obj, dac_write);

static const mp_rom_map_elem_t dac_locals_dict_table[] = {
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy