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