@@ -72,7 +72,8 @@ static uint8_t dac_vref_table[] = {
72
72
#define MAX_DAC_VALUE (4095)
73
73
#define DEFAULT_DAC_VREF (2)
74
74
#define MAX_DAC_VREF (3)
75
- static bool dac_init = false;
75
+ static bool dac_init [2 ] = {false, false};
76
+
76
77
#endif
77
78
78
79
@@ -91,20 +92,21 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
91
92
92
93
uint8_t id = args [ARG_id ].u_int ;
93
94
dac_obj_t * self = NULL ;
94
- if (0 <= id && id <= MP_ARRAY_SIZE (dac_obj )) {
95
+ if (0 <= id && id < MP_ARRAY_SIZE (dac_obj )) {
95
96
self = & dac_obj [id ];
96
97
} else {
97
- mp_raise_ValueError (MP_ERROR_TEXT ("invalid Pin for DAC" ));
98
+ mp_raise_ValueError (MP_ERROR_TEXT ("invalid id for DAC" ));
98
99
}
99
100
100
101
uint8_t vref = args [ARG_vref ].u_int ;
101
102
if (0 <= vref && vref <= MAX_DAC_VREF ) {
102
103
self -> vref = vref ;
103
104
}
104
105
105
- Dac * dac = dac_bases [0 ]; // Just one DAC
106
+ Dac * dac = dac_bases [0 ]; // Just one DAC register block
107
+
108
+ // initialize DAC
106
109
107
- // Init DAC
108
110
#if defined(MCU_SAMD21 )
109
111
110
112
// Configuration SAMD21
@@ -127,21 +129,39 @@ static mp_obj_t dac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_
127
129
128
130
// Configuration SAMD51
129
131
// Enable APBD clocks and PCHCTRL clocks; GCLK3 at 8 MHz
130
- dac_init = true;
131
- MCLK -> APBDMASK .reg |= MCLK_APBDMASK_DAC ;
132
- GCLK -> PCHCTRL [DAC_GCLK_ID ].reg = GCLK_PCHCTRL_GEN_GCLK3 | GCLK_PCHCTRL_CHEN ;
133
132
134
- // Reset DAC registers
135
- dac -> CTRLA .bit .SWRST = 1 ;
136
- while (dac -> CTRLA .bit .SWRST ) {
133
+ if (!(dac_init [0 ] | dac_init [1 ])) {
134
+ MCLK -> APBDMASK .reg |= MCLK_APBDMASK_DAC ;
135
+ GCLK -> PCHCTRL [DAC_GCLK_ID ].reg = GCLK_PCHCTRL_GEN_GCLK3 | \
136
+ GCLK_PCHCTRL_CHEN ;
137
+
138
+ // Reset DAC registers
139
+ dac -> CTRLA .bit .SWRST = 1 ;
140
+ while (dac -> CTRLA .bit .SWRST ) {
141
+ }
142
+ dac -> CTRLB .reg = DAC_CTRLB_REFSEL (dac_vref_table [self -> vref ]);
143
+
137
144
}
138
- dac -> CTRLB .reg = DAC_CTRLB_REFSEL (dac_vref_table [self -> vref ]);
139
- dac -> DACCTRL [self -> id ].reg = DAC_DACCTRL_ENABLE | DAC_DACCTRL_REFRESH (2 ) | DAC_DACCTRL_CCTRL_CC12M ;
140
145
141
- // Enable DAC and wait to be ready
142
- dac -> CTRLA .bit .ENABLE = 1 ;
143
- while (dac -> SYNCBUSY .bit .ENABLE ) {
146
+ // Modify DAC config - requires disabling see Section 47.6.2.3 of data sheet
147
+ if (!dac_init [self -> id ]) {
148
+ // Disable DAC and wait
149
+ dac -> CTRLA .bit .ENABLE = 0 ;
150
+ while (dac -> SYNCBUSY .bit .ENABLE ) {
151
+ }
152
+
153
+ // Modify configuration
154
+ dac -> DACCTRL [self -> id ].reg = DAC_DACCTRL_ENABLE | \
155
+ DAC_DACCTRL_REFRESH (2 ) | DAC_DACCTRL_CCTRL_CC12M ;
156
+ dac -> DATA [self -> id ].reg = 0 ;
157
+ dac_init [self -> id ] = true;
158
+
159
+ // Enable DAC and wait
160
+ dac -> CTRLA .bit .ENABLE = 1 ;
161
+ while (dac -> SYNCBUSY .bit .ENABLE ) {
162
+ }
144
163
}
164
+
145
165
#endif
146
166
147
167
// Set the port as given in self->gpio_id as DAC
0 commit comments