summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-04-21 13:06:19 +0100
committerDamien George <damien.p.george@gmail.com>2014-04-21 13:06:19 +0100
commit764af4b7c585831afa4996c2cf371403330faa35 (patch)
treee6dd794d0a79df35de62131a86a0b9d9011d51a1
parent83407ad0824df26ea11f8473e0ca4a32eaa5dbd1 (diff)
downloadmicropython-764af4b7c585831afa4996c2cf371403330faa35.tar.gz
micropython-764af4b7c585831afa4996c2cf371403330faa35.zip
stmhal: Make DAC dynamically allocate instances; rename dma->write_timed.
-rw-r--r--stmhal/dac.c67
-rw-r--r--stmhal/qstrdefsport.h10
2 files changed, 47 insertions, 30 deletions
diff --git a/stmhal/dac.c b/stmhal/dac.c
index db18127001..92edb24d76 100644
--- a/stmhal/dac.c
+++ b/stmhal/dac.c
@@ -45,9 +45,6 @@ typedef struct _pyb_dac_obj_t {
machine_uint_t state;
} pyb_dac_obj_t;
-STATIC pyb_dac_obj_t pyb_dac_channel_1 = {{&pyb_dac_type}, DAC_CHANNEL_1, DMA1_Stream5};
-STATIC pyb_dac_obj_t pyb_dac_channel_2 = {{&pyb_dac_type}, DAC_CHANNEL_2, DMA1_Stream6};
-
// create the dac object
// currently support either DAC1 on X5 (id = 1) or DAC2 on X6 (id = 2)
@@ -55,18 +52,21 @@ STATIC mp_obj_t pyb_dac_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
// check arguments
mp_arg_check_num(n_args, n_kw, 1, 1, false);
+ pyb_dac_obj_t *dac = m_new_obj(pyb_dac_obj_t);
+ dac->base.type = &pyb_dac_type;
+
machine_int_t dac_id = mp_obj_get_int(args[0]);
uint32_t pin;
- pyb_dac_obj_t *dac_obj;
-
if (dac_id == 1) {
pin = GPIO_PIN_4;
- dac_obj = &pyb_dac_channel_1;
+ dac->dac_channel = DAC_CHANNEL_1;
+ dac->dma_stream = DMA1_Stream5;
} else if (dac_id == 2) {
pin = GPIO_PIN_5;
- dac_obj = &pyb_dac_channel_2;
+ dac->dac_channel = DAC_CHANNEL_2;
+ dac->dma_stream = DMA1_Stream6;
} else {
- nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Dac %d does not exist", dac_id));
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "DAC %d does not exist", dac_id));
}
// GPIO configuration
@@ -80,13 +80,13 @@ STATIC mp_obj_t pyb_dac_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const
__DAC_CLK_ENABLE();
// stop anything already going on
- HAL_DAC_Stop(&DAC_Handle, dac_obj->dac_channel);
- HAL_DAC_Stop_DMA(&DAC_Handle, dac_obj->dac_channel);
+ HAL_DAC_Stop(&DAC_Handle, dac->dac_channel);
+ HAL_DAC_Stop_DMA(&DAC_Handle, dac->dac_channel);
- dac_obj->state = 0;
+ dac->state = 0;
// return object
- return dac_obj;
+ return dac;
}
STATIC mp_obj_t pyb_dac_noise(mp_obj_t self_in, mp_obj_t freq) {
@@ -111,7 +111,6 @@ STATIC mp_obj_t pyb_dac_noise(mp_obj_t self_in, mp_obj_t freq) {
return mp_const_none;
}
-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_noise_obj, pyb_dac_noise);
STATIC mp_obj_t pyb_dac_triangle(mp_obj_t self_in, mp_obj_t freq) {
@@ -136,7 +135,6 @@ STATIC mp_obj_t pyb_dac_triangle(mp_obj_t self_in, mp_obj_t freq) {
return mp_const_none;
}
-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_triangle_obj, pyb_dac_triangle);
// direct access to DAC (8 bit only at the moment)
@@ -156,21 +154,34 @@ STATIC mp_obj_t pyb_dac_write(mp_obj_t self_in, mp_obj_t val) {
return mp_const_none;
}
-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_dac_write_obj, pyb_dac_write);
// initiates a burst of RAM->DAC using DMA
// input data is treated as an array of bytes (8 bit data)
// TIM6 is used to set the frequency of the transfer
-// TODO still needs some attention to get it working properly
-mp_obj_t pyb_dac_dma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+// TODO add callback argument, to call when transfer is finished
+// TODO add double buffer argument
+
+STATIC const mp_arg_parse_t pyb_dac_write_timed_accepted_args[] = {
+ { MP_QSTR_data, MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_OBJ, {.u_obj = MP_OBJ_NULL} },
+ { MP_QSTR_freq, MP_ARG_PARSE_REQUIRED | MP_ARG_PARSE_INT, {.u_int = 0} },
+ { MP_QSTR_mode, MP_ARG_PARSE_KW_ONLY | MP_ARG_PARSE_INT, {.u_int = DMA_NORMAL} },
+};
+#define PYB_DAC_WRITE_TIMED_NUM_ARGS (sizeof(pyb_dac_write_timed_accepted_args) / sizeof(pyb_dac_write_timed_accepted_args[0]))
+
+mp_obj_t pyb_dac_write_timed(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
pyb_dac_obj_t *self = args[0];
- // set TIM6 to trigger the DAC at the given frequency
- TIM6_Config(mp_obj_get_int(args[2]));
+ // parse args
+ mp_arg_parse_val_t vals[PYB_DAC_WRITE_TIMED_NUM_ARGS];
+ mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_DAC_WRITE_TIMED_NUM_ARGS, pyb_dac_write_timed_accepted_args, vals);
+ // get the data to write
mp_buffer_info_t bufinfo;
- mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
+ mp_get_buffer_raise(vals[0].u_obj, &bufinfo, MP_BUFFER_READ);
+
+ // set TIM6 to trigger the DAC at the given frequency
+ TIM6_Config(vals[1].u_int);
__DMA1_CLK_ENABLE();
@@ -206,8 +217,7 @@ mp_obj_t pyb_dac_dma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
DMA_Handle.Init.MemInc = DMA_MINC_ENABLE;
DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
- mp_map_elem_t *kw_mode = mp_map_lookup(kw_args, MP_OBJ_NEW_QSTR(qstr_from_str("mode")), MP_MAP_LOOKUP);
- DMA_Handle.Init.Mode = kw_mode == NULL ? DMA_NORMAL : mp_obj_get_int(kw_mode->value); // normal = 0, circular = 0x100
+ DMA_Handle.Init.Mode = vals[2].u_int;
DMA_Handle.Init.Priority = DMA_PRIORITY_HIGH;
DMA_Handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
DMA_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
@@ -248,17 +258,18 @@ mp_obj_t pyb_dac_dma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
return mp_const_none;
}
-
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_dac_dma_obj, 3, pyb_dac_dma);
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_dac_write_timed_obj, 1, pyb_dac_write_timed);
STATIC const mp_map_elem_t pyb_dac_locals_dict_table[] = {
+ // instance methods
{ MP_OBJ_NEW_QSTR(MP_QSTR_noise), (mp_obj_t)&pyb_dac_noise_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_triangle), (mp_obj_t)&pyb_dac_triangle_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&pyb_dac_write_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_dma), (mp_obj_t)&pyb_dac_dma_obj },
- // TODO add function that does double buffering:
- // dma2(freq, buf1, buf2, callback)
- // where callback is called when the buffer has been drained
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write_timed), (mp_obj_t)&pyb_dac_write_timed_obj },
+
+ // class constants
+ { MP_OBJ_NEW_QSTR(MP_QSTR_NORMAL), MP_OBJ_NEW_SMALL_INT(DMA_NORMAL) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CIRCULAR), MP_OBJ_NEW_SMALL_INT(DMA_CIRCULAR) },
};
STATIC MP_DEFINE_CONST_DICT(pyb_dac_locals_dict, pyb_dac_locals_dict_table);
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index 830514d35b..390c8fca9f 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -166,11 +166,17 @@ Q(read_core_temp)
Q(read_core_vbat)
Q(read_core_vref)
-// for DAC object
+// for DAC class
Q(DAC)
Q(noise)
Q(triangle)
-Q(dma)
+Q(write)
+Q(write_timed)
+Q(data)
+Q(freq)
+Q(mode)
+Q(NORMAL)
+Q(CIRCULAR)
// for Servo object
Q(Servo)