Example #1
0
mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args) {
    const pin_obj_t *pin = pin_map_user_obj(args[0]);
    if (n_args == 1) {
        // get pin
        return MP_OBJ_NEW_SMALL_INT(HAL_GPIO_ReadPin(pin->gpio, pin->pin_mask));
    }

    // set pin
    HAL_GPIO_WritePin(pin->gpio, pin->pin_mask, rt_is_true(args[1]));
    return mp_const_none;
}
Example #2
0
mp_obj_t pyb_gpio_input(uint n_args, mp_obj_t *args) {
    const pin_obj_t *pin = pin_map_user_obj(args[0]);

    uint32_t pull = GPIO_NOPULL;
    if (n_args > 1) {
        pull = mp_obj_get_int(args[1]);
    }
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin = pin->pin_mask;
    GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
    GPIO_InitStructure.Pull = pull;
    HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure);

    return mp_const_none;
}
Example #3
0
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_check_nargs(n_args, 1, 2, n_kw, 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]);
}
Example #4
0
mp_obj_t pyb_gpio_output(uint n_args, mp_obj_t *args) {
    const pin_obj_t *pin = pin_map_user_obj(args[0]);

    uint32_t mode = GPIO_MODE_OUTPUT_PP;
    if (n_args > 1) {
        mode = mp_obj_get_int(args[1]) == GPIO_MODE_OUTPUT_OD ?
               GPIO_MODE_OUTPUT_OD: GPIO_MODE_OUTPUT_PP;
    }
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin = pin->pin_mask;
    GPIO_InitStructure.Mode = mode;
    GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
    GPIO_InitStructure.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure);

    return mp_const_none;
}
Example #5
0
// NOTE: param is for C callers. Python can use closure to get an object bound
//       with the function.
uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t trigger_obj, mp_obj_t callback_obj, void *param) {
    const pin_obj_t *pin = NULL;
    uint v_line;

    if (MP_OBJ_IS_INT(pin_obj)) {
        // If an integer is passed in, then use it to identify lines 16 thru 22
        // We expect lines 0 thru 15 to be passed in as a pin, so that we can
        // get both the port number and line number.
        v_line = mp_obj_get_int(pin_obj);
        if (v_line < 16) {
            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d < 16, use a Pin object", v_line));
        }
        if (v_line >= EXTI_NUM_VECTORS) {
            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d >= max of %d", v_line, EXTI_NUM_VECTORS));
        }
    } else {
        pin = pin_map_user_obj(pin_obj);
        v_line = pin->pin;
    }
    int mode = mp_obj_get_int(mode_obj);
    if (!IS_EXTI_MODE(mode)) {
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid EXTI Mode: %d", mode));
    }
    int trigger = mp_obj_get_int(trigger_obj);
    if (!IS_EXTI_TRIGGER(trigger)) {
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid EXTI Trigger: %d", trigger));
    }

    exti_vector_t *v = &exti_vector[v_line];
    if (v->callback_obj != mp_const_none && callback_obj != mp_const_none) {
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d is already in use", v_line));
    }

    // We need to update callback and param atomically, so we disable the line
    // before we update anything.

    exti_disable(v_line);

    if (pin && callback_obj) {
        // Enable SYSCFG clock
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

        // For EXTI lines 0 thru 15, we need to configure which port controls
        // the line.
        SYSCFG_EXTILineConfig(pin->port, v_line);
    }
    v->callback_obj = callback_obj;
    v->param = param;
    v->mode = mode;

    if (v->callback_obj != mp_const_none) {
        // The EXTI_Init function isn't atomic. It uses |= and &=.
        // We use bit band operations to make it atomic.
        EXTI_EDGE_BB(EXTI_Trigger_Rising, v_line) =
            trigger == EXTI_Trigger_Rising || trigger == EXTI_Trigger_Rising_Falling;
        EXTI_EDGE_BB(EXTI_Trigger_Falling, v_line) =
            trigger == EXTI_Trigger_Falling || trigger == EXTI_Trigger_Rising_Falling;
        exti_enable(v_line);

        /* Enable and set NVIC Interrupt to the lowest priority */
        NVIC_InitTypeDef NVIC_InitStructure;
        NVIC_InitStructure.NVIC_IRQChannel = nvic_irq_channel[v_line];
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
    }
    return v_line;
}