Skip to content
Snippets Groups Projects
Select Git revision
  • bdd77470739bdb23944ac3940184a70c14fbcc95
  • master default
  • test
  • rahix/hw-lock-new-mutex
  • dx/somewhat-more-dynamic-config
  • schneider/sdk-0.2.1-7
  • schneider/bsec
  • dx/meh-bdf-to-stm
  • dx/flatten-config-module
  • genofire/ble-follow-py
  • schneider/ble-stability
  • schneider/ble-stability-new-phy
  • add_menu_vibration
  • plaetzchen/ios-workaround
  • blinkisync-as-preload
  • schneider/max30001-pycardium
  • schneider/max30001-epicaridum
  • schneider/max30001
  • schneider/stream-locks
  • schneider/fundamental-test
  • schneider/ble-buffers
  • v1.12
  • v1.11
  • v1.10
  • v1.9
  • v1.8
  • v1.7
  • v1.6
  • v1.5
  • v1.4
  • v1.3
  • v1.2
  • v1.1
  • v1.0
  • release-1
  • bootloader-v1
  • v0.0
37 results

beacon_api.h

Blame
  • Forked from card10 / firmware
    Source project has a limited visibility.
    pin_map.c 6.73 KiB
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    #include <stm32f4xx.h>
    
    #include "misc.h"
    #include "mpconfig.h"
    #include "qstr.h"
    #include "obj.h"
    #include "runtime.h"
    #include "nlr.h"
    
    #include "pin.h"
    
    // Usage Model:
    //
    // All Board Pins are predefined as pyb.Pin.board.Name
    //
    //   x1_pin = pyb.Pin.board.X1
    //
    //   g = pyb.gpio(pyb.Pin.board.X1, 0)
    // 
    // CPU pins which correspond to the board pins are available
    // as pyb.cpu.Name. For the CPU pins, the names are the port letter
    // followed by the pin number. On the PYBOARD4, pyb.Pin.board.X1 and
    // pyb.Pin.cpu.B6 are the same pin. 
    //
    // You can also use strings:
    //
    //   g = pyb.gpio('X1', 0)
    //
    // Users can add their own names:
    //
    //   pyb.Pin("LeftMotorDir", pyb.Pin.cpu.C12)
    //   g = pyb.gpio("LeftMotorDir", 0)
    //
    // and can query mappings
    //
    //   pin = pyb.Pin("LeftMotorDir");
    //
    // Users can also add their own mapping function:
    //
    //   def MyMapper(pin_name):
    //      if pin_name == "LeftMotorDir":
    //          return pyb.Pin.cpu.A0
    //
    //   pyb.Pin.mapper(MyMapper)
    //
    // So, if you were to call: pyb.gpio("LeftMotorDir", 0)
    // then "LeftMotorDir" is passed directly to the mapper function.
    //
    // To summarize, the following order determines how things get mapped into
    // an ordinal pin number:
    //
    // 1 - Directly specify a pin object
    // 2 - User supplied mapping function
    // 3 - User supplied mapping (object must be usable as a dictionary key)
    // 4 - Supply a string which matches a board pin
    // 5 - Supply a string which matches a CPU port/pin
    //
    // You can set pyb.Pin.debug(True) to get some debug information about
    // how a particular object gets mapped to a pin.
    
    static void pin_map_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
        (void)self_in;
        print(env, "<PinMap>");
    }
    
    static mp_obj_t pin_map_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
        pin_map_obj_t *self = self_in;
        mp_arg_check_num(n_args, n_kw, 1, 2, false);
    
        if (n_args > 1) {
            if (!self->map_dict) {
                self->map_dict = mp_obj_new_dict(1);
            }
            mp_obj_dict_store(self->map_dict, args[0], args[1]);
            return mp_const_none;
        }
    
        // Run an argument through the mapper and return the result.
        return (mp_obj_t)pin_map_user_obj(args[0]);
    }
    
    static mp_obj_t pin_map_obj_mapper(uint n_args, mp_obj_t *args) {
        pin_map_obj_t *self = args[0];
        if (n_args > 1) {
            self->mapper = args[1];
            return mp_const_none;
        }
        return self->mapper;
    }
    static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_obj_mapper_obj, 1, 2, pin_map_obj_mapper);
    
    static mp_obj_t pin_map_obj_debug(uint n_args, mp_obj_t *args) {
        pin_map_obj_t *self = args[0];
        if (n_args > 1) {
            self->debug = mp_obj_is_true(args[1]);
            return mp_const_none;
        }
        return MP_BOOL(self->debug);
    }
    static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_obj_debug_obj, 1, 2, pin_map_obj_debug);
    
    static void pin_map_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) {
        (void)self_in;
        const char *attr = qstr_str(attr_qstr);
    
        if (strcmp(attr, "mapper") == 0) {
            dest[0] = (mp_obj_t)&pin_map_obj_mapper_obj;
            dest[1] = self_in;
        }
        if (strcmp(attr, "debug") == 0) {
            dest[0] = (mp_obj_t)&pin_map_obj_debug_obj;
            dest[1] = self_in;
        }
        if (strcmp(attr, pin_board_pins_obj.name) == 0) {
            dest[0] = (mp_obj_t)&pin_board_pins_obj;
            dest[1] = MP_OBJ_NULL;
        }
        if (strcmp(attr, pin_cpu_pins_obj.name) == 0) {
            dest[0] = (mp_obj_t)&pin_cpu_pins_obj;
            dest[1] = MP_OBJ_NULL;
        }
    }
    
    static const mp_obj_type_t pin_map_obj_type = {
        { &mp_type_type },
        .name = MP_QSTR_PinMap,
        .print = pin_map_obj_print,
        .call = pin_map_call,
        .load_attr = pin_map_load_attr,
    };
    
    static const pin_map_obj_t pin_map_obj_init = {
        { &pin_map_obj_type },
        .mapper = MP_OBJ_NULL,
        .map_dict = MP_OBJ_NULL,
        .debug = false,
    };
    
    pin_map_obj_t pin_map_obj;
    
    void pin_map_init(void) {
        pin_map_obj = pin_map_obj_init;
    }
    
    // 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));
    }