1 /*
2  * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3  */
4 
5 #include <string.h>
6 
7 #include "aos_hal_wdg.h"
8 #include "py/nlr.h"
9 #include "py/obj.h"
10 #include "py/runtime.h"
11 #include "ulog/ulog.h"
12 
13 #define LOG_TAG             "machine-wdt"
14 
15 #define DEFAULT_WDT_TIMEOUT (5000)
16 
17 const mp_obj_type_t machine_wdt_type;
18 
19 typedef struct _machine_wdt_obj_t {
20     mp_obj_base_t base;
21     wdg_dev_t dev;
22 } machine_wdt_obj_t;
23 
24 STATIC machine_wdt_obj_t wdt_default = { { &machine_wdt_type }, { 0, { DEFAULT_WDT_TIMEOUT }, NULL } };
25 
machine_wdt_make_new(const mp_obj_type_t * type_in,size_t n_args,size_t n_kw,const mp_obj_t * all_args)26 STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args)
27 {
28     enum {
29         ARG_id,
30         ARG_timeout
31     };
32     static const mp_arg_t allowed_args[] = { { MP_QSTR_id, MP_ARG_INT, { .u_int = 0 } },
33                                              { MP_QSTR_timeout, MP_ARG_INT, { .u_int = DEFAULT_WDT_TIMEOUT } } };
34     mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
35     mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
36 
37     if (args[ARG_id].u_int != 0) {
38         mp_raise_ValueError(NULL);
39     }
40 
41     // Convert milliseconds to seconds
42     args[ARG_timeout].u_int /= 1000;
43 
44     if (args[ARG_timeout].u_int <= 0) {
45         mp_raise_ValueError(MP_ERROR_TEXT("WDT timeout too short"));
46     }
47 
48     wdg_dev_t *dev = &(wdt_default.dev);
49     wdg_config_t cfg = { 0 };
50     cfg.timeout = args[ARG_timeout].u_int;
51     dev->config = cfg;
52 
53     mp_int_t rs_code = aos_hal_wdg_init(dev);
54     if (rs_code != 0) {
55         mp_raise_OSError(rs_code);
56     }
57 
58     return &wdt_default;
59 }
60 
machine_wdt_feed(mp_obj_t self_in)61 STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in)
62 {
63     machine_wdt_obj_t *self = (machine_wdt_obj_t *)self_in;
64     aos_hal_wdg_reload(&self->dev);
65     return mp_const_none;
66 }
67 STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed);
68 
machine_wdt_deinit(mp_obj_t self_in)69 STATIC mp_obj_t machine_wdt_deinit(mp_obj_t self_in)
70 {
71     machine_wdt_obj_t *self = (machine_wdt_obj_t *)self_in;
72     mp_int_t status = aos_hal_wdg_finalize(&self->dev);
73     return MP_OBJ_NEW_SMALL_INT(status);
74 }
75 STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_deinit_obj, machine_wdt_deinit);
76 
77 STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = {
78     { MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&machine_wdt_feed_obj) },
79     { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_wdt_deinit_obj) },
80 };
81 STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table);
82 
83 const mp_obj_type_t machine_wdt_type = {
84     { &mp_type_type },
85     .name = MP_QSTR_WDT,
86     .make_new = machine_wdt_make_new,
87     .locals_dict = (mp_obj_t)&machine_wdt_locals_dict,
88 };
89