Esempio n. 1
0
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
 ******************************************************************************/
STATIC pin_obj_t *pin_find_named_pin(const mp_obj_dict_t *named_pins, mp_obj_t name) {
    mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
    mp_map_elem_t *named_elem = mp_map_lookup(named_map, name, MP_MAP_LOOKUP);
    if (named_elem != NULL && named_elem->value != NULL) {
        return named_elem->value;
    }
    return NULL;
}
Esempio n. 2
0
pin_obj_t *pin_find_pin(const mp_obj_dict_t *named_pins, uint pin_num) {
    mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
    for (uint i = 0; i < named_map->used; i++) {
        if (((pin_obj_t *)named_map->table[i].value)->pin_num == pin_num) {
            return named_map->table[i].value;
        }
    }
    return NULL;
}
Esempio n. 3
0
STATIC void pyb_sleep_iopark (bool hibernate) {
    mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
    for (uint i = 0; i < named_map->used; i++) {
        pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
        switch (pin->pin_num) {
#ifdef DEBUG
        // skip the JTAG pins
        case PIN_16:
        case PIN_17:
        case PIN_19:
        case PIN_20:
            break;
#endif
        default:
            // enable a weak pull-up if the pin is unused
            if (!pin->used) {
                MAP_PinConfigSet(pin->pin_num, pin->strength, PIN_TYPE_STD_PU);
            }
            if (hibernate) {
                // make it an input
                MAP_PinDirModeSet(pin->pin_num, PIN_DIR_MODE_IN);
            }
            break;
        }
    }

    // park the sflash pins
    HWREG(0x4402E0E8) &= ~(0x3 << 8);
    HWREG(0x4402E0E8) |= (0x2 << 8);
    HWREG(0x4402E0EC) &= ~(0x3 << 8);
    HWREG(0x4402E0EC) |= (0x2 << 8);
    HWREG(0x4402E0F0) &= ~(0x3 << 8);
    HWREG(0x4402E0F0) |= (0x2 << 8);
    HWREG(0x4402E0F4) &= ~(0x3 << 8);
    HWREG(0x4402E0F4) |= (0x1 << 8);

    // if the board has antenna diversity, only park the antenna
    // selection pins when going into hibernation
#if MICROPY_HW_ANTENNA_DIVERSITY
    if (hibernate) {
#endif
        // park the antenna selection pins
        // (tri-stated with pull down enabled)
        HWREG(0x4402E108) = 0x00000E61;
        HWREG(0x4402E10C) = 0x00000E61;
#if MICROPY_HW_ANTENNA_DIVERSITY
    } else {
        // park the antenna selection pins
        // (tri-stated without changing the pull up/down resistors)
        HWREG(0x4402E108) &= ~0x000000FF;
        HWREG(0x4402E108) |=  0x00000C61;
        HWREG(0x4402E10C) &= ~0x000000FF;
        HWREG(0x4402E10C) |=  0x00000C61;
    }
#endif
}
Esempio n. 4
0
STATIC pin_obj_t *pin_find_pin_by_port_bit (const mp_obj_dict_t *named_pins, uint port, uint bit) {
    mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)named_pins);
    for (uint i = 0; i < named_map->used; i++) {
        if ((((pin_obj_t *)named_map->table[i].value)->port == port) &&
                (((pin_obj_t *)named_map->table[i].value)->bit == bit)) {
            return named_map->table[i].value;
        }
    }
    return NULL;
}
Esempio n. 5
0
/******************************************************************************
 DEFINE PUBLIC FUNCTIONS
 ******************************************************************************/
void pin_init0(void) {
// this initalization also reconfigures the JTAG/SWD pins
#ifndef DEBUG
    // assign all pins to the GPIO module so that peripherals can be connected to any
    // pins without conflicts after a soft reset
    mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
    for (uint i = 0; i < named_map->used - 1; i++) {
        pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
        pin_deassign (pin);
    }
#endif
}
Esempio n. 6
0
/// \method getScanData()
/// Return list of the scan data tupples (ad_type, description, value)
///
STATIC mp_obj_t scan_entry_get_scan_data(mp_obj_t self_in) {
    ubluepy_scan_entry_obj_t * self = MP_OBJ_TO_PTR(self_in);

    mp_obj_t retval_list = mp_obj_new_list(0, NULL);

    // TODO: check if self->data is set
    mp_obj_array_t * data = MP_OBJ_TO_PTR(self->data);

    uint16_t byte_index = 0;

    while (byte_index < data->len) {
        mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));

        uint8_t adv_item_len  = ((uint8_t * )data->items)[byte_index];
        uint8_t adv_item_type = ((uint8_t * )data->items)[byte_index + 1];

        mp_obj_t description = mp_const_none;

        mp_map_t *constant_map = mp_obj_dict_get_map(ubluepy_constants_ad_types_type.locals_dict);
        mp_map_elem_t *ad_types_table = MP_OBJ_TO_PTR(constant_map->table);

        uint16_t num_of_elements = constant_map->used;

        for (uint16_t i = 0; i < num_of_elements; i++) {
            mp_map_elem_t element = (mp_map_elem_t)*ad_types_table;
            ad_types_table++;
            uint16_t element_value = mp_obj_get_int(element.value);

            if (adv_item_type == element_value) {
                qstr key_qstr = MP_OBJ_QSTR_VALUE(element.key);
                const char * text = qstr_str(key_qstr);
                size_t len = qstr_len(key_qstr);

                vstr_t vstr;
                vstr_init(&vstr, len);
                vstr_printf(&vstr, "%s", text);
                description = mp_obj_new_str(vstr.buf, vstr.len);
                vstr_clear(&vstr);
            }
        }

        t->items[0] = MP_OBJ_NEW_SMALL_INT(adv_item_type);
        t->items[1] = description;
        t->items[2] = mp_obj_new_bytearray(adv_item_len - 1,
                                           &((uint8_t * )data->items)[byte_index + 2]);
        mp_obj_list_append(retval_list, MP_OBJ_FROM_PTR(t));

        byte_index += adv_item_len + 1;
    }

    return retval_list;
}
Esempio n. 7
0
STATIC mp_obj_t mp_builtin_exec(uint n_args, const mp_obj_t *args) {
    // Unconditional getting/setting assumes that these operations
    // are cheap, which is the case when this comment was written.
    mp_map_t *old_globals = rt_globals_get();
    mp_map_t *old_locals = rt_locals_get();
    if (n_args > 1) {
        mp_obj_t globals = args[1];
        mp_obj_t locals;
        if (n_args > 2) {
            locals = args[2];
        } else {
            locals = globals;
        }
        rt_globals_set(mp_obj_dict_get_map(globals));
        rt_locals_set(mp_obj_dict_get_map(locals));
    }
    mp_obj_t res = parse_compile_execute(args[0], MP_PARSE_FILE_INPUT);
    // TODO if the above call throws an exception, then we never get to reset the globals/locals
    rt_globals_set(old_globals);
    rt_locals_set(old_locals);
    return res;
}
Esempio n. 8
0
STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
    if (n_args == 0) {
        // print a general help message
        printf("%s", help_text);

    } else {
        // try to print something sensible about the given object

        printf("object ");
        mp_obj_print(args[0], PRINT_STR);
        printf(" is of type %s\n", mp_obj_get_type_str(args[0]));

        mp_map_t *map = NULL;
        if (MP_OBJ_IS_TYPE(args[0], &mp_type_module)) {
            map = mp_obj_dict_get_map(mp_obj_module_get_globals(args[0]));
        } else {
            mp_obj_type_t *type;
            if (MP_OBJ_IS_TYPE(args[0], &mp_type_type)) {
                type = args[0];
            } else {
                type = mp_obj_get_type(args[0]);
            }
            if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &mp_type_dict)) {
                map = mp_obj_dict_get_map(type->locals_dict);
            }
        }
        if (map != NULL) {
            for (uint i = 0; i < map->alloc; i++) {
                if (map->table[i].key != MP_OBJ_NULL) {
                    pyb_help_print_info_about_object(map->table[i].key, map->table[i].value);
                }
            }
        }
    }

    return mp_const_none;
}
Esempio n. 9
0
STATIC void pin_free_af_from_pins (uint8_t fn, uint8_t unit, uint8_t type) {
    mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
    for (uint i = 0; i < named_map->used - 1; i++) {
        pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
        // af is different than GPIO
        if (pin->af > PIN_MODE_0) {
            // check if the pin supports the target af
            int af = pin_obj_find_af(pin, fn, unit, type);
            if (af > 0 && af == pin->af) {
                // the pin is assigned to the target af, de-assign it
                pin_deassign (pin);
            }
        }
    }
}
Esempio n. 10
0
/// \method names()
/// Returns the cpu and board names for this pin.
STATIC mp_obj_t pin_names(mp_obj_t self_in) {
    pin_obj_t *self = self_in;
    mp_obj_t result = mp_obj_new_list(0, NULL);
    mp_obj_list_append(result, MP_OBJ_NEW_QSTR(self->name));

    mp_map_t *map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
    mp_map_elem_t *elem = map->table;

    for (mp_uint_t i = 0; i < map->used; i++, elem++) {
        if (elem->value == self) {
            mp_obj_list_append(result, elem->key);
        }
    }
    return result;
}
Esempio n. 11
0
mp_obj_t mp_builtin___import__(mp_uint_t n_args, const mp_obj_t *args) {
#if DEBUG_PRINT
    DEBUG_printf("__import__:\n");
    for (mp_uint_t i = 0; i < n_args; i++) {
        DEBUG_printf("  ");
        mp_obj_print(args[i], PRINT_REPR);
        DEBUG_printf("\n");
    }
#endif

    mp_obj_t module_name = args[0];
    mp_obj_t fromtuple = mp_const_none;
    mp_int_t level = 0;
    if (n_args >= 4) {
        fromtuple = args[3];
        if (n_args >= 5) {
            level = MP_OBJ_SMALL_INT_VALUE(args[4]);
        }
    }

    mp_uint_t mod_len;
    const char *mod_str = mp_obj_str_get_data(module_name, &mod_len);

    if (level != 0) {
        // What we want to do here is to take name of current module,
        // chop <level> trailing components, and concatenate with passed-in
        // module name, thus resolving relative import name into absolue.
        // This even appears to be correct per
        // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name
        // "Relative imports use a module's __name__ attribute to determine that
        // module's position in the package hierarchy."
        level--;
        mp_obj_t this_name_q = mp_obj_dict_get(mp_globals_get(), MP_OBJ_NEW_QSTR(MP_QSTR___name__));
        assert(this_name_q != MP_OBJ_NULL);
        #if MICROPY_CPYTHON_COMPAT
        if (MP_OBJ_QSTR_VALUE(this_name_q) == MP_QSTR___main__) {
            // This is a module run by -m command-line switch, get its real name from backup attribute
            this_name_q = mp_obj_dict_get(mp_globals_get(), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
        }
        #endif
        mp_map_t *globals_map = mp_obj_dict_get_map(mp_globals_get());
        mp_map_elem_t *elem = mp_map_lookup(globals_map, MP_OBJ_NEW_QSTR(MP_QSTR___path__), MP_MAP_LOOKUP);
        bool is_pkg = (elem != NULL);

#if DEBUG_PRINT
        DEBUG_printf("Current module/package: ");
        mp_obj_print(this_name_q, PRINT_REPR);
        DEBUG_printf(", is_package: %d", is_pkg);
        DEBUG_printf("\n");
#endif

        mp_uint_t this_name_l;
        const char *this_name = mp_obj_str_get_data(this_name_q, &this_name_l);

        const char *p = this_name + this_name_l;
        if (!is_pkg) {
            // We have module, but relative imports are anchored at package, so
            // go there.
            chop_component(this_name, &p);
        }


        uint dots_seen = 0;
        while (level--) {
            chop_component(this_name, &p);
            dots_seen++;
        }

        if (dots_seen == 0 && level >= 1) {
            // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name
            // "If the module's name does not contain any package information
            // (e.g. it is set to '__main__') then relative imports are
            // resolved as if the module were a top level module, regardless
            // of where the module is actually located on the file system."
            // Supposedly this if catches this condition and resolve it properly
            // TODO: But nobody knows for sure. This condition happens when
            // package's __init__.py does something like "import .submod". So,
            // maybe we should check for package here? But quote above doesn't
            // talk about packages, it talks about dot-less module names.
            DEBUG_printf("Warning: no dots in current module name and level>0\n");
            p = this_name + this_name_l;
        } else if (level != -1) {
            nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "Invalid relative import"));
        }

        uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len);
        char *new_mod = alloca(new_mod_l);
        memcpy(new_mod, this_name, p - this_name);
        if (mod_len != 0) {
            new_mod[p - this_name] = '.';
            memcpy(new_mod + (p - this_name) + 1, mod_str, mod_len);
        }

        qstr new_mod_q = qstr_from_strn(new_mod, new_mod_l);
        DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q));
        if (new_mod_q == MP_QSTR_) {
            // CPython raises SystemError
            nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "cannot perform relative import"));
        }
        module_name = MP_OBJ_NEW_QSTR(new_mod_q);
        mod_str = new_mod;
        mod_len = new_mod_l;
    }

    // check if module already exists
    qstr module_name_qstr = mp_obj_str_get_qstr(module_name);
    mp_obj_t module_obj = mp_module_get(module_name_qstr);
    if (module_obj != MP_OBJ_NULL) {
        DEBUG_printf("Module already loaded\n");
        // If it's not a package, return module right away
        char *p = strchr(mod_str, '.');
        if (p == NULL) {
            return module_obj;
        }
        // If fromlist is not empty, return leaf module
        if (fromtuple != mp_const_none) {
            return module_obj;
        }
        // Otherwise, we need to return top-level package
        qstr pkg_name = qstr_from_strn(mod_str, p - mod_str);
        return mp_module_get(pkg_name);
    }
    DEBUG_printf("Module not yet loaded\n");

    #if MICROPY_MODULE_FROZEN
    mp_lexer_t *lex = mp_find_frozen_module(mod_str, mod_len);
    if (lex != NULL) {
        module_obj = mp_obj_new_module(module_name_qstr);
        // if args[3] (fromtuple) has magic value False, set up
        // this module for command-line "-m" option (set module's
        // name to __main__ instead of real name).
        // TODO: Duplicated below too.
        if (fromtuple == mp_const_false) {
            mp_obj_module_t *o = module_obj;
            mp_obj_dict_store(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
        }
        do_load_from_lexer(module_obj, lex, mod_str);
        return module_obj;
    }
    #endif

    uint last = 0;
    VSTR_FIXED(path, MICROPY_ALLOC_PATH_MAX)
    module_obj = MP_OBJ_NULL;
    mp_obj_t top_module_obj = MP_OBJ_NULL;
    mp_obj_t outer_module_obj = MP_OBJ_NULL;
    uint i;
    for (i = 1; i <= mod_len; i++) {
        if (i == mod_len || mod_str[i] == '.') {
            // create a qstr for the module name up to this depth
            qstr mod_name = qstr_from_strn(mod_str, i);
            DEBUG_printf("Processing module: %s\n", qstr_str(mod_name));
            DEBUG_printf("Previous path: =%.*s=\n", vstr_len(&path), vstr_str(&path));

            // find the file corresponding to the module name
            mp_import_stat_t stat;
            if (vstr_len(&path) == 0) {
                // first module in the dotted-name; search for a directory or file
                stat = find_file(mod_str, i, &path);
            } else {
                // latter module in the dotted-name; append to path
                vstr_add_char(&path, PATH_SEP_CHAR);
                vstr_add_strn(&path, mod_str + last, i - last);
                stat = stat_dir_or_file(&path);
            }
            DEBUG_printf("Current path: %.*s\n", vstr_len(&path), vstr_str(&path));

            if (stat == MP_IMPORT_STAT_NO_EXIST) {
                #if MICROPY_MODULE_WEAK_LINKS
                // check if there is a weak link to this module
                if (i == mod_len) {
                    mp_map_elem_t *el = mp_map_lookup((mp_map_t*)&mp_builtin_module_weak_links_map, MP_OBJ_NEW_QSTR(mod_name), MP_MAP_LOOKUP);
                    if (el == NULL) {
                        goto no_exist;
                    }
                    // found weak linked module
                    module_obj = el->value;
                } else {
                    no_exist:
                #else
                {
                #endif
                    // couldn't find the file, so fail
                    if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
                        nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found"));
                    } else {
                        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
                            "no module named '%q'", mod_name));
                    }
                }
            } else {
                // found the file, so get the module
                module_obj = mp_module_get(mod_name);
            }

            if (module_obj == MP_OBJ_NULL) {
                // module not already loaded, so load it!

                module_obj = mp_obj_new_module(mod_name);

                // if args[3] (fromtuple) has magic value False, set up
                // this module for command-line "-m" option (set module's
                // name to __main__ instead of real name).
                if (i == mod_len && fromtuple == mp_const_false) {
                    mp_obj_module_t *o = module_obj;
                    mp_obj_dict_store(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));
                    #if MICROPY_CPYTHON_COMPAT
                    // Store real name in "__main__" attribute. Choosen semi-randonly, to reuse existing qstr's.
                    mp_obj_dict_store(o->globals, MP_OBJ_NEW_QSTR(MP_QSTR___main__), MP_OBJ_NEW_QSTR(mod_name));
                    #endif
                }

                if (stat == MP_IMPORT_STAT_DIR) {
                    DEBUG_printf("%.*s is dir\n", vstr_len(&path), vstr_str(&path));
                    // https://docs.python.org/3/reference/import.html
                    // "Specifically, any module that contains a __path__ attribute is considered a package."
                    mp_store_attr(module_obj, MP_QSTR___path__, mp_obj_new_str(vstr_str(&path), vstr_len(&path), false));
                    vstr_add_char(&path, PATH_SEP_CHAR);
                    vstr_add_str(&path, "__init__.py");
                    if (mp_import_stat(vstr_null_terminated_str(&path)) != MP_IMPORT_STAT_FILE) {
                        vstr_cut_tail_bytes(&path, sizeof("/__init__.py") - 1); // cut off /__init__.py
                        mp_warning("%s is imported as namespace package", vstr_str(&path));
                    } else {
                        do_load(module_obj, &path);
                        vstr_cut_tail_bytes(&path, sizeof("/__init__.py") - 1); // cut off /__init__.py
                    }
                } else { // MP_IMPORT_STAT_FILE
                    do_load(module_obj, &path);
                    // TODO: We cannot just break here, at the very least, we must execute
                    // trailer code below. But otherwise if there're remaining components,
                    // that would be (??) object path within module, not modules path within FS.
                    // break;
                }
            }
            if (outer_module_obj != MP_OBJ_NULL) {
                qstr s = qstr_from_strn(mod_str + last, i - last);
                mp_store_attr(outer_module_obj, s, module_obj);
            }
            outer_module_obj = module_obj;
            if (top_module_obj == MP_OBJ_NULL) {
                top_module_obj = module_obj;
            }
            last = i + 1;
        }
    }
Esempio n. 12
0
STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
    if (n_args == 0) {
        // print a general help message
        mp_printf(&mp_plat_print, "%s", help_text);

    } else {
        mp_obj_t args0 = args[0];
        mp_obj_type_t *args0_type = mp_obj_get_type(args0);
        if (args0_type->name == MP_QSTR_bound_method) {
            args0 = ((mp_obj_t*)args0)[1]; // extract method
            args0_type = mp_obj_get_type(args0);
        }

        // see if we have specific help info for this instance
        for (size_t i = 0; i < MP_ARRAY_SIZE(help_table_instances); i++) {
            if (args0 == help_table_instances[i].obj) {
                mp_print_str(&mp_plat_print, help_table_instances[i].doc);
                //if (args0_type == &mp_type_module) {
                //TODO here we can list the things inside the module
                //}
                return mp_const_none;
            }
        }

        // see if we have specific help info for this type
        for (size_t i = 0; i < MP_ARRAY_SIZE(help_table_types); i++) {
            if (args0 == help_table_types[i].obj || args0_type == help_table_types[i].obj) {
                mp_print_str(&mp_plat_print, help_table_types[i].doc);
                return mp_const_none;
            }
        }

        // don't have specific help info, try instead to print something sensible

        mp_printf(&mp_plat_print, "object ");
        mp_obj_print(args0, PRINT_STR);
        mp_printf(&mp_plat_print, " is of type %q\n", args0_type->name);

        mp_map_t *map = NULL;
        if (args0_type == &mp_type_module) {
            map = mp_obj_dict_get_map(mp_obj_module_get_globals(args0));
        } else {
            mp_obj_type_t *type;
            if (args0_type == &mp_type_type) {
                type = args0;
            } else {
                type = args0_type;
            }
            if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &mp_type_dict)) {
                map = mp_obj_dict_get_map(type->locals_dict);
            }
        }
        if (map != NULL) {
            for (uint i = 0; i < map->alloc; i++) {
                if (map->table[i].key != MP_OBJ_NULL) {
                    pyb_help_print_info_about_object(map->table[i].key, map->table[i].value);
                }
            }
        }
    }

    return mp_const_none;
}
Esempio n. 13
0
// C API used to convert a user-supplied pin name  into an ordinal pin number.
const pin_obj_t *pin_map_user_obj(mp_obj_t user_obj) {
    const pin_obj_t *pin_obj;

    // If a pin was provided, then use it
    if (MP_OBJ_IS_TYPE(user_obj, &pin_obj_type)) {
        pin_obj = user_obj;
        if (pin_map_obj.debug) {
            printf("Pin map passed pin ");
            mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
            printf("\n");
        }
        return pin_obj;
    }

    if (pin_map_obj.mapper) {
        pin_obj = mp_call_function_1(pin_map_obj.mapper, user_obj);
        if (pin_obj != mp_const_none) {
            if (!MP_OBJ_IS_TYPE(pin_obj, &pin_obj_type)) {
                nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Pin.mapper didn't return a Pin object"));
            }
            if (pin_map_obj.debug) {
                printf("Pin.mapper maps ");
                mp_obj_print(user_obj, PRINT_REPR);
                printf(" to ");
                mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
                printf("\n");
            }
            return pin_obj;
        }
        // The pin mapping function returned mp_const_none, fall through to
        // other lookup methods.
    }

    if (pin_map_obj.map_dict) {
        mp_map_t *pin_map_map = mp_obj_dict_get_map(pin_map_obj.map_dict);
        mp_map_elem_t *elem = mp_map_lookup(pin_map_map, user_obj, MP_MAP_LOOKUP);
        if (elem != NULL && elem->value != NULL) {
            pin_obj = elem->value;
            if (pin_map_obj.debug) {
                printf("Pin.map_dict maps ");
                mp_obj_print(user_obj, PRINT_REPR);
                printf(" to ");
                mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
                printf("\n");
            }
            return pin_obj;
        }
    }

    // See if the pin name matches a board pin
    const char *pin_name = mp_obj_str_get_str(user_obj);
    pin_obj = pin_find_named_pin(pin_board_pins, pin_name);
    if (pin_obj) {
        if (pin_map_obj.debug) {
            printf("Pin.board maps ");
            mp_obj_print(user_obj, PRINT_REPR);
            printf(" to ");
            mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
            printf("\n");
        }
        return pin_obj;
    }

    // See if the pin name matches a cpu pin
    pin_obj = pin_find_named_pin(pin_cpu_pins, pin_name);
    if (pin_obj) {
        if (pin_map_obj.debug) {
            printf("Pin.cpu maps ");
            mp_obj_print(user_obj, PRINT_REPR);
            printf(" to ");
            mp_obj_print((mp_obj_t)pin_obj, PRINT_STR);
            printf("\n");
        }
        return pin_obj;
    }

    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin '%s' not a valid pin identifier", pin_name));
}
Esempio n. 14
0
// C API used to convert a user-supplied pin name into an ordinal pin number.
const pin_obj_t *pin_find(mp_obj_t user_obj) {
    const pin_obj_t *pin_obj;

    // If a pin was provided, then use it
    if (mp_obj_is_type(user_obj, &pin_type)) {
        pin_obj = MP_OBJ_TO_PTR(user_obj);
        if (pin_class_debug) {
            printf("Pin map passed pin ");
            mp_obj_print(MP_OBJ_FROM_PTR(pin_obj), PRINT_STR);
            printf("\n");
        }
        return pin_obj;
    }

    if (MP_STATE_PORT(pin_class_mapper) != mp_const_none) {
        mp_obj_t o = mp_call_function_1(MP_STATE_PORT(pin_class_mapper), user_obj);
        if (o != mp_const_none) {
            if (!mp_obj_is_type(o, &pin_type)) {
                mp_raise_ValueError("Pin.mapper didn't return a Pin object");
            }
            if (pin_class_debug) {
                printf("Pin.mapper maps ");
                mp_obj_print(user_obj, PRINT_REPR);
                printf(" to ");
                mp_obj_print(o, PRINT_STR);
                printf("\n");
            }
            return MP_OBJ_TO_PTR(o);
        }
        // The pin mapping function returned mp_const_none, fall through to
        // other lookup methods.
    }

    if (MP_STATE_PORT(pin_class_map_dict) != mp_const_none) {
        mp_map_t *pin_map_map = mp_obj_dict_get_map(MP_STATE_PORT(pin_class_map_dict));
        mp_map_elem_t *elem = mp_map_lookup(pin_map_map, user_obj, MP_MAP_LOOKUP);
        if (elem != NULL && elem->value != MP_OBJ_NULL) {
            mp_obj_t o = elem->value;
            if (pin_class_debug) {
                printf("Pin.map_dict maps ");
                mp_obj_print(user_obj, PRINT_REPR);
                printf(" to ");
                mp_obj_print(o, PRINT_STR);
                printf("\n");
            }
            return MP_OBJ_TO_PTR(o);
        }
    }

    // See if the pin name matches a board pin
    pin_obj = pin_find_named_pin(&pin_board_pins_locals_dict, user_obj);
    if (pin_obj) {
        if (pin_class_debug) {
            printf("Pin.board maps ");
            mp_obj_print(user_obj, PRINT_REPR);
            printf(" to ");
            mp_obj_print(MP_OBJ_FROM_PTR(pin_obj), PRINT_STR);
            printf("\n");
        }
        return pin_obj;
    }

    // See if the pin name matches a cpu pin
    pin_obj = pin_find_named_pin(&pin_cpu_pins_locals_dict, user_obj);
    if (pin_obj) {
        if (pin_class_debug) {
            printf("Pin.cpu maps ");
            mp_obj_print(user_obj, PRINT_REPR);
            printf(" to ");
            mp_obj_print(MP_OBJ_FROM_PTR(pin_obj), PRINT_STR);
            printf("\n");
        }
        return pin_obj;
    }

    nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin(%s) doesn't exist", mp_obj_str_get_str(user_obj)));
}