Example #1
0
/// \classmethod \constructor(pin)
/// Create an ADC object associated with the given pin.
/// This allows you to then read analog values on that pin.
STATIC mp_obj_t adc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    // check number of arguments
    mp_arg_check_num(n_args, n_kw, 1, 1, false);

    // 1st argument is the pin name
    mp_obj_t pin_obj = args[0];

    uint32_t channel;

    if (mp_obj_is_int(pin_obj)) {
        channel = adc_get_internal_channel(mp_obj_get_int(pin_obj));
    } else {
        const pin_obj_t *pin = pin_find(pin_obj);
        if ((pin->adc_num & PIN_ADC_MASK) == 0) {
            // No ADC1 function on that pin
            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %q does not have ADC capabilities", pin->name));
        }
        channel = pin->adc_channel;
    }

    if (!is_adcx_channel(channel)) {
        nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "not a valid ADC Channel: %d", channel));
    }


    if (ADC_FIRST_GPIO_CHANNEL <= channel && channel <= ADC_LAST_GPIO_CHANNEL) {
        // these channels correspond to physical GPIO ports so make sure they exist
        if (pin_adc_table[channel] == NULL) {
            nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
                "channel %d not available on this board", channel));
        }
    }

    pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t);
    memset(o, 0, sizeof(*o));
    o->base.type = &pyb_adc_type;
    o->pin_name = pin_obj;
    o->channel = channel;
    adc_init_single(o);

    return MP_OBJ_FROM_PTR(o);
}
Example #2
0
/// \method register(obj[, eventmask])
STATIC mp_obj_t poll_register(size_t n_args, const mp_obj_t *args) {
    mp_obj_poll_t *self = MP_OBJ_TO_PTR(args[0]);
    bool is_fd = mp_obj_is_int(args[1]);
    int fd = get_fd(args[1]);

    mp_uint_t flags;
    if (n_args == 3) {
        flags = mp_obj_get_int(args[2]);
    } else {
        flags = POLLIN | POLLOUT;
    }

    struct pollfd *free_slot = NULL;

    struct pollfd *entry = self->entries;
    for (int i = 0; i < self->len; i++, entry++) {
        int entry_fd = entry->fd;
        if (entry_fd == fd) {
            entry->events = flags;
            return mp_const_false;
        }
        if (entry_fd == -1) {
            free_slot = entry;
        }
    }

    if (free_slot == NULL) {
        if (self->len >= self->alloc) {
            self->entries = m_renew(struct pollfd, self->entries, self->alloc, self->alloc + 4);
            if (self->obj_map) {
                self->obj_map = m_renew(mp_obj_t, self->obj_map, self->alloc, self->alloc + 4);
            }
            self->alloc += 4;
        }
        free_slot = &self->entries[self->len++];
    }
Example #3
0
STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
    (void)n_kw;
    mp_obj_ffifunc_t *self = MP_OBJ_TO_PTR(self_in);
    assert(n_kw == 0);
    assert(n_args == self->cif.nargs);

    ffi_arg values[n_args];
    void *valueptrs[n_args];
    const char *argtype = self->argtypes;
    for (uint i = 0; i < n_args; i++, argtype++) {
        mp_obj_t a = args[i];
        if (*argtype == 'O') {
            values[i] = (ffi_arg)(intptr_t)a;
        #if MICROPY_PY_BUILTINS_FLOAT
        } else if (*argtype == 'f') {
            float *p = (float*)&values[i];
            *p = mp_obj_get_float(a);
        } else if (*argtype == 'd') {
            double *p = (double*)&values[i];
            *p = mp_obj_get_float(a);
        #endif
        } else if (a == mp_const_none) {
            values[i] = 0;
        } else if (mp_obj_is_int(a)) {
            values[i] = mp_obj_int_get_truncated(a);
        } else if (mp_obj_is_str(a)) {
            const char *s = mp_obj_str_get_str(a);
            values[i] = (ffi_arg)(intptr_t)s;
        } else if (((mp_obj_base_t*)MP_OBJ_TO_PTR(a))->type->buffer_p.get_buffer != NULL) {
            mp_obj_base_t *o = (mp_obj_base_t*)MP_OBJ_TO_PTR(a);
            mp_buffer_info_t bufinfo;
            int ret = o->type->buffer_p.get_buffer(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ?
            if (ret != 0) {
                goto error;
            }
            values[i] = (ffi_arg)(intptr_t)bufinfo.buf;
        } else if (mp_obj_is_type(a, &fficallback_type)) {
            mp_obj_fficallback_t *p = MP_OBJ_TO_PTR(a);
            values[i] = (ffi_arg)(intptr_t)p->func;
        } else {
            goto error;
        }
        valueptrs[i] = &values[i];
    }

    // If ffi_arg is not big enough to hold a double, then we must pass along a
    // pointer to a memory location of the correct size.
    // TODO check if this needs to be done for other types which don't fit into
    // ffi_arg.
    #if MICROPY_PY_BUILTINS_FLOAT
    if (sizeof(ffi_arg) == 4 && self->rettype == 'd') {
        double retval;
        ffi_call(&self->cif, self->func, &retval, valueptrs);
        return mp_obj_new_float(retval);
    } else
    #endif
    {
        ffi_arg retval;
        ffi_call(&self->cif, self->func, &retval, valueptrs);
        return return_ffi_value(retval, self->rettype);
    }

error:
    mp_raise_TypeError("Don't know how to pass object to native function");
}