1 /*
2 * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3 */
4
5 #if MICROPY_PY_MACHINE_DAC
6
7 #include <stdio.h>
8
9 #include "aos_hal_dac.h"
10 #include "modmachine.h"
11 #include "py/mphal.h"
12 #include "py/runtime.h"
13 #include "ulog/ulog.h"
14
15 #define LOG_TAG "machine_dac"
16
17 #define MDAC_CHECK_PARAMS() \
18 mdac_obj_t *self = (mdac_obj_t *)MP_OBJ_TO_PTR(self_in); \
19 do { \
20 if (self == NULL) { \
21 mp_raise_OSError(MP_EINVAL); \
22 return mp_const_none; \
23 } \
24 } while (0)
25
26 enum {
27 DAC_CHANNEL_0,
28 DAC_CHANNEL_1,
29 DAC_CHANNEL_MAX
30 };
31
32 typedef struct _mdac_obj_t {
33 mp_obj_base_t base;
34 dac_dev_t dev;
35 uint8_t channel_id;
36 } mdac_obj_t;
37
38 const mp_obj_type_t machine_dac_type;
39
40 STATIC mdac_obj_t mdac_obj[] = {
41 { { &machine_dac_type }, { DAC_CHANNEL_0, NULL }, DAC_CHANNEL_0 },
42 { { &machine_dac_type }, { DAC_CHANNEL_1, NULL }, DAC_CHANNEL_1 },
43 };
44
mdac_make_new(const mp_obj_type_t * type,size_t n_args,size_t n_kw,const mp_obj_t * args)45 STATIC mp_obj_t mdac_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args)
46 {
47 mp_arg_check_num(n_args, n_kw, 1, 1, true);
48
49 mp_int_t channel_id = mp_obj_get_int(args[0]);
50 mdac_obj_t *self = NULL;
51 for (int i = 0; i < MP_ARRAY_SIZE(mdac_obj); i++) {
52 if (channel_id == mdac_obj[i].channel_id) {
53 self = &mdac_obj[i];
54 break;
55 }
56 }
57 if (!self) {
58 mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("ChannelId[%d] Should Smaller Than %d"), channel_id,
59 DAC_CHANNEL_MAX);
60 }
61
62 int status = aos_hal_dac_init(&self->dev);
63 if (status != 0) {
64 mp_raise_ValueError(MP_ERROR_TEXT("Failed to init DAC, parameter error"));
65 }
66
67 return MP_OBJ_FROM_PTR(self);
68 }
69
mdac_print(const mp_print_t * print,mp_obj_t self_in,mp_print_kind_t kind)70 STATIC void mdac_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind)
71 {
72 MDAC_CHECK_PARAMS();
73 mp_printf(print, "DAC(Channel(%u))", self->channel_id);
74 }
75
mdac_write(mp_obj_t self_in,mp_obj_t value_in)76 STATIC mp_obj_t mdac_write(mp_obj_t self_in, mp_obj_t value_in)
77 {
78 MDAC_CHECK_PARAMS();
79
80 int value = mp_obj_get_int(value_in);
81 if (value < 0 || value > 255) {
82 mp_raise_ValueError(MP_ERROR_TEXT("value out of range"));
83 }
84
85 int status = aos_hal_dac_set_value(&self->dev, self->channel_id, value);
86 if (status != 0) {
87 LOGE(LOG_TAG, "DAC write fail!");
88 }
89
90 return mp_const_none;
91 }
92 MP_DEFINE_CONST_FUN_OBJ_2(mdac_write_obj, mdac_write);
93
mdac_read(mp_obj_t self_in)94 STATIC mp_obj_t mdac_read(mp_obj_t self_in)
95 {
96 MDAC_CHECK_PARAMS();
97
98 mp_int_t res = aos_hal_dac_get_value(&self->dev, self->channel_id);
99 return MP_OBJ_NEW_SMALL_INT(res);
100 }
101 MP_DEFINE_CONST_FUN_OBJ_2(mdac_read_obj, mdac_read);
102
mdac_start(mp_obj_t self_in)103 STATIC mp_obj_t mdac_start(mp_obj_t self_in)
104 {
105 MDAC_CHECK_PARAMS();
106
107 mp_int_t status = aos_hal_dac_start(&self->dev, self->channel_id);
108 return MP_OBJ_NEW_SMALL_INT(status);
109 }
110 MP_DEFINE_CONST_FUN_OBJ_2(mdac_start_obj, mdac_start);
111
mdac_stop(mp_obj_t self_in)112 STATIC mp_obj_t mdac_stop(mp_obj_t self_in)
113 {
114 MDAC_CHECK_PARAMS();
115
116 mp_int_t status = aos_hal_dac_stop(&self->dev, self->channel_id);
117 return MP_OBJ_NEW_SMALL_INT(status);
118 }
119 MP_DEFINE_CONST_FUN_OBJ_2(mdac_stop_obj, mdac_stop);
120
mdac_deinit(mp_obj_t self_in)121 STATIC mp_obj_t mdac_deinit(mp_obj_t self_in)
122 {
123 MDAC_CHECK_PARAMS();
124
125 mp_int_t status = aos_hal_dac_finalize(&self->dev);
126 return MP_OBJ_NEW_SMALL_INT(status);
127 }
128 MP_DEFINE_CONST_FUN_OBJ_2(mdac_deinit_obj, mdac_deinit);
129
130 STATIC const mp_rom_map_elem_t mdac_locals_dict_table[] = {
131 { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&mdac_start_obj) },
132 { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&mdac_stop_obj) },
133 { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mdac_write_obj) },
134 { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mdac_read_obj) },
135 { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mdac_deinit_obj) },
136 };
137
138 STATIC MP_DEFINE_CONST_DICT(mdac_locals_dict, mdac_locals_dict_table);
139
140 const mp_obj_type_t machine_dac_type = {
141 { &mp_type_type },
142 .name = MP_QSTR_DAC,
143 .print = mdac_print,
144 .make_new = mdac_make_new,
145 .locals_dict = (mp_obj_t)&mdac_locals_dict,
146 };
147
148 #endif