/// \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); }
/// \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++]; }
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"); }