@@ -139,9 +139,50 @@ typedef struct _pyb_dac_obj_t {
139
139
mp_obj_base_t base ;
140
140
uint32_t dac_channel ; // DAC_CHANNEL_1 or DAC_CHANNEL_2
141
141
DMA_Stream_TypeDef * dma_stream ; // DMA1_Stream5 or DMA1_Stream6
142
- pyb_dac_state_t state ;
142
+ uint16_t pin ; // GPIO_PIN_4 or GPIO_PIN_5
143
+ uint8_t bits ; // 8 or 12
144
+ uint8_t state ;
143
145
} pyb_dac_obj_t ;
144
146
147
+ STATIC mp_obj_t pyb_dac_init_helper (pyb_dac_obj_t * self , mp_uint_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
148
+ static const mp_arg_t allowed_args [] = {
149
+ { MP_QSTR_bits , MP_ARG_INT , {.u_int = 8 } },
150
+ };
151
+
152
+ // parse args
153
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
154
+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
155
+
156
+ // GPIO configuration
157
+ GPIO_InitTypeDef GPIO_InitStructure ;
158
+ GPIO_InitStructure .Pin = self -> pin ;
159
+ GPIO_InitStructure .Mode = GPIO_MODE_ANALOG ;
160
+ GPIO_InitStructure .Pull = GPIO_NOPULL ;
161
+ HAL_GPIO_Init (GPIOA , & GPIO_InitStructure );
162
+
163
+ // DAC peripheral clock
164
+ __DAC_CLK_ENABLE ();
165
+
166
+ // stop anything already going on
167
+ HAL_DAC_Stop (& DAC_Handle , self -> dac_channel );
168
+ if ((self -> dac_channel == DAC_CHANNEL_1 && DAC_Handle .DMA_Handle1 != NULL )
169
+ || (self -> dac_channel == DAC_CHANNEL_2 && DAC_Handle .DMA_Handle2 != NULL )) {
170
+ HAL_DAC_Stop_DMA (& DAC_Handle , self -> dac_channel );
171
+ }
172
+
173
+ // set bit resolution
174
+ if (args [0 ].u_int == 8 || args [0 ].u_int == 12 ) {
175
+ self -> bits = args [0 ].u_int ;
176
+ } else {
177
+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "unsupported bits" ));
178
+ }
179
+
180
+ // reset state of DAC
181
+ self -> state = DAC_STATE_RESET ;
182
+
183
+ return mp_const_none ;
184
+ }
185
+
145
186
// create the dac object
146
187
// currently support either DAC1 on X5 (id = 1) or DAC2 on X6 (id = 2)
147
188
@@ -152,7 +193,7 @@ typedef struct _pyb_dac_obj_t {
152
193
/// DAC(1) is on pin X5 and DAC(2) is on pin X6.
153
194
STATIC mp_obj_t pyb_dac_make_new (mp_obj_t type_in , mp_uint_t n_args , mp_uint_t n_kw , const mp_obj_t * args ) {
154
195
// check arguments
155
- mp_arg_check_num (n_args , n_kw , 1 , 1 , false );
196
+ mp_arg_check_num (n_args , n_kw , 1 , MP_OBJ_FUN_ARGS_MAX , true );
156
197
157
198
// get pin/channel to output on
158
199
mp_int_t dac_id ;
@@ -172,42 +213,32 @@ STATIC mp_obj_t pyb_dac_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n
172
213
pyb_dac_obj_t * dac = m_new_obj (pyb_dac_obj_t );
173
214
dac -> base .type = & pyb_dac_type ;
174
215
175
- uint32_t pin ;
176
216
if (dac_id == 1 ) {
177
- pin = GPIO_PIN_4 ;
217
+ dac -> pin = GPIO_PIN_4 ;
178
218
dac -> dac_channel = DAC_CHANNEL_1 ;
179
219
dac -> dma_stream = DMA1_Stream5 ;
180
220
} else if (dac_id == 2 ) {
181
- pin = GPIO_PIN_5 ;
221
+ dac -> pin = GPIO_PIN_5 ;
182
222
dac -> dac_channel = DAC_CHANNEL_2 ;
183
223
dac -> dma_stream = DMA1_Stream6 ;
184
224
} else {
185
225
nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "DAC %d does not exist" , dac_id ));
186
226
}
187
227
188
- // GPIO configuration
189
- GPIO_InitTypeDef GPIO_InitStructure ;
190
- GPIO_InitStructure .Pin = pin ;
191
- GPIO_InitStructure .Mode = GPIO_MODE_ANALOG ;
192
- GPIO_InitStructure .Pull = GPIO_NOPULL ;
193
- HAL_GPIO_Init (GPIOA , & GPIO_InitStructure );
194
-
195
- // DAC peripheral clock
196
- __DAC_CLK_ENABLE ();
197
-
198
- // stop anything already going on
199
- HAL_DAC_Stop (& DAC_Handle , dac -> dac_channel );
200
- if ((dac -> dac_channel == DAC_CHANNEL_1 && DAC_Handle .DMA_Handle1 != NULL )
201
- || (dac -> dac_channel == DAC_CHANNEL_2 && DAC_Handle .DMA_Handle2 != NULL )) {
202
- HAL_DAC_Stop_DMA (& DAC_Handle , dac -> dac_channel );
203
- }
204
-
205
- dac -> state = DAC_STATE_RESET ;
228
+ // configure the peripheral
229
+ mp_map_t kw_args ;
230
+ mp_map_init_fixed_table (& kw_args , n_kw , args + n_args );
231
+ pyb_dac_init_helper (dac , n_args - 1 , args + 1 , & kw_args );
206
232
207
233
// return object
208
234
return dac ;
209
235
}
210
236
237
+ STATIC mp_obj_t pyb_dac_init (mp_uint_t n_args , const mp_obj_t * args , mp_map_t * kw_args ) {
238
+ return pyb_dac_init_helper (args [0 ], n_args - 1 , args + 1 , kw_args );
239
+ }
240
+ STATIC MP_DEFINE_CONST_FUN_OBJ_KW (pyb_dac_init_obj , 1 , pyb_dac_init );
241
+
211
242
#if defined(TIM6 )
212
243
/// \method noise(freq)
213
244
/// Generate a pseudo-random noise signal. A new random sample is written
@@ -280,7 +311,11 @@ STATIC mp_obj_t pyb_dac_write(mp_obj_t self_in, mp_obj_t val) {
280
311
self -> state = DAC_STATE_WRITE_SINGLE ;
281
312
}
282
313
283
- HAL_DAC_SetValue (& DAC_Handle , self -> dac_channel , DAC_ALIGN_8B_R , mp_obj_get_int (val ));
314
+ // DAC output is always 12-bit at the hardware level, and we provide support
315
+ // for multiple bit "resolutions" simply by shifting the input value.
316
+ HAL_DAC_SetValue (& DAC_Handle , self -> dac_channel , DAC_ALIGN_12B_R ,
317
+ mp_obj_get_int (val ) << (12 - self -> bits ));
318
+
284
319
HAL_DAC_Start (& DAC_Handle , self -> dac_channel );
285
320
286
321
return mp_const_none ;
@@ -365,8 +400,13 @@ mp_obj_t pyb_dac_write_timed(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
365
400
DMA_Handle .Init .Direction = DMA_MEMORY_TO_PERIPH ;
366
401
DMA_Handle .Init .PeriphInc = DMA_PINC_DISABLE ;
367
402
DMA_Handle .Init .MemInc = DMA_MINC_ENABLE ;
368
- DMA_Handle .Init .PeriphDataAlignment = DMA_PDATAALIGN_BYTE ;
369
- DMA_Handle .Init .MemDataAlignment = DMA_MDATAALIGN_BYTE ;
403
+ if (self -> bits == 8 ) {
404
+ DMA_Handle .Init .PeriphDataAlignment = DMA_PDATAALIGN_BYTE ;
405
+ DMA_Handle .Init .MemDataAlignment = DMA_MDATAALIGN_BYTE ;
406
+ } else {
407
+ DMA_Handle .Init .PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD ;
408
+ DMA_Handle .Init .MemDataAlignment = DMA_MDATAALIGN_HALFWORD ;
409
+ }
370
410
DMA_Handle .Init .Mode = args [2 ].u_int ;
371
411
DMA_Handle .Init .Priority = DMA_PRIORITY_HIGH ;
372
412
DMA_Handle .Init .FIFOMode = DMA_FIFOMODE_DISABLE ;
@@ -393,7 +433,13 @@ mp_obj_t pyb_dac_write_timed(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_
393
433
self -> state = DAC_STATE_DMA_WAVEFORM + dac_trigger ;
394
434
}
395
435
396
- HAL_DAC_Start_DMA (& DAC_Handle , self -> dac_channel , (uint32_t * )bufinfo .buf , bufinfo .len , DAC_ALIGN_8B_R );
436
+ if (self -> bits == 8 ) {
437
+ HAL_DAC_Start_DMA (& DAC_Handle , self -> dac_channel ,
438
+ (uint32_t * )bufinfo .buf , bufinfo .len , DAC_ALIGN_8B_R );
439
+ } else {
440
+ HAL_DAC_Start_DMA (& DAC_Handle , self -> dac_channel ,
441
+ (uint32_t * )bufinfo .buf , bufinfo .len / 2 , DAC_ALIGN_12B_R );
442
+ }
397
443
398
444
/*
399
445
// enable DMA stream
@@ -417,6 +463,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_dac_write_timed_obj, 1, pyb_dac_write_time
417
463
418
464
STATIC const mp_map_elem_t pyb_dac_locals_dict_table [] = {
419
465
// instance methods
466
+ { MP_OBJ_NEW_QSTR (MP_QSTR_init ), (mp_obj_t )& pyb_dac_init_obj },
420
467
{ MP_OBJ_NEW_QSTR (MP_QSTR_write ), (mp_obj_t )& pyb_dac_write_obj },
421
468
#if defined(TIM6 )
422
469
{ MP_OBJ_NEW_QSTR (MP_QSTR_noise ), (mp_obj_t )& pyb_dac_noise_obj },
0 commit comments