static mp_obj_t py_select(uint n_args, const mp_obj_t *args) { int nfds=0; //highest-numbered fd plus 1 timeval tv={0}; fd_set rfds, wfds, xfds; mp_obj_t *rlist, *wlist, *xlist; uint rlist_len, wlist_len, xlist_len; /* read args */ mp_obj_get_array(args[0], &rlist_len, &rlist); mp_obj_get_array(args[1], &wlist_len, &wlist); mp_obj_get_array(args[2], &xlist_len, &xlist); if (n_args == 4) { float timeout = mp_obj_get_float(args[3]); tv.tv_sec = (int)timeout; tv.tv_usec = (timeout-(int)timeout)*1000*1000; } // add fds to their respective sets set_fds(&nfds, rlist, rlist_len, &rfds); set_fds(&nfds, wlist, wlist_len, &wfds); set_fds(&nfds, xlist, xlist_len, &xfds); // call select nfds = select(nfds+1, &rfds, &wfds, &xfds, &tv); // if any of the read sockets is closed, we add it to the read fd set, // a subsequent call to recv() returns 0. This behavior is consistent with BSD. for (int i=0; i<rlist_len; i++) { socket_t *s = rlist[i]; if (wlan_get_fd_state(s->fd)) { FD_SET(s->fd, &rfds); nfds = max(nfds, s->fd); } } // return value; a tuple of 3 lists mp_obj_t fds[3] = { mp_obj_new_list(0, NULL), mp_obj_new_list(0, NULL), mp_obj_new_list(0, NULL) }; // On success, select() returns the number of file descriptors contained // in the three returned descriptor sets which may be zero if the timeout // expires before anything interesting happens, -1 is returned on error. if (nfds == -1) { // select failed nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "select failed")); } else if (nfds) { // an fd is ready get_fds(rlist, rlist_len, fds[0], &rfds); get_fds(wlist, wlist_len, fds[1], &wfds); get_fds(xlist, xlist_len, fds[2], &xfds); } // select timedout return mp_obj_new_tuple(3, fds); }
int _socket_getaddrinfo(const mp_obj_t addrtuple, struct addrinfo **resp) { mp_uint_t len = 0; mp_obj_t *elem; mp_obj_get_array(addrtuple, &len, &elem); if (len != 2) return -1; return _socket_getaddrinfo2(elem[0], elem[1], resp); }
/// \method alarm_datetime([datetimetuple,alarmMask]) STATIC mp_obj_t rtc_alarm_datetime(mp_uint_t n_args, const mp_obj_t *args) { //pyb_rtc_obj_t *self = args[0]; if (n_args == 1) { // get uint32_t yr; uint32_t mon; uint32_t day; uint32_t wd; uint32_t hr; uint32_t min; uint32_t sec; mp_obj_t tuple[7]; mp_hal_getAlarmTimeRTC(&hr, &min, &sec, &day, &mon, &yr, &wd); tuple[0] = MP_OBJ_NEW_SMALL_INT(yr); tuple[1] = MP_OBJ_NEW_SMALL_INT(mon); tuple[2] = MP_OBJ_NEW_SMALL_INT(day); tuple[3] = MP_OBJ_NEW_SMALL_INT(wd); tuple[4] = MP_OBJ_NEW_SMALL_INT(hr); tuple[5] = MP_OBJ_NEW_SMALL_INT(min); tuple[6] = MP_OBJ_NEW_SMALL_INT(sec); return mp_obj_new_tuple(7,tuple); } else if(n_args == 3) { // set //(year, month, day, weekday, hours, minutes, seconds) mp_buffer_info_t bufinfo; mp_obj_t *items; mp_obj_get_array(args[1], &bufinfo.len, &items); uint32_t alarmMask = mp_obj_get_int(args[2]); if(bufinfo.len==7) { uint32_t yr = mp_obj_get_int(items[0]); uint32_t mon = mp_obj_get_int(items[1]); uint32_t day = mp_obj_get_int(items[2]); uint32_t wd = mp_obj_get_int(items[3]); uint32_t hr = mp_obj_get_int(items[4]); uint32_t min = mp_obj_get_int(items[5]); uint32_t sec = mp_obj_get_int(items[6]); mp_hal_setAlarmTimeRTC(hr,min,sec,day,mon,yr,wd,alarmMask); } else{ nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "7 arguments are required in tuple")); } return mp_const_none; } else { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "2 arguments are required")); } }
STATIC mp_obj_t mod_thread_start_new_thread(size_t n_args, const mp_obj_t *args) { // This structure holds the Python function and arguments for thread entry. // We copy all arguments into this structure to keep ownership of them. // We must be very careful about root pointers because this pointer may // disappear from our address space before the thread is created. thread_entry_args_t *th_args; // get positional arguments size_t pos_args_len; mp_obj_t *pos_args_items; mp_obj_get_array(args[1], &pos_args_len, &pos_args_items); // check for keyword arguments if (n_args == 2) { // just position arguments th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len); th_args->n_kw = 0; } else { // positional and keyword arguments if (mp_obj_get_type(args[2]) != &mp_type_dict) { mp_raise_TypeError("expecting a dict for keyword args"); } mp_map_t *map = &((mp_obj_dict_t*)MP_OBJ_TO_PTR(args[2]))->map; th_args = m_new_obj_var(thread_entry_args_t, mp_obj_t, pos_args_len + 2 * map->used); th_args->n_kw = map->used; // copy across the keyword arguments for (size_t i = 0, n = pos_args_len; i < map->alloc; ++i) { if (mp_map_slot_is_filled(map, i)) { th_args->args[n++] = map->table[i].key; th_args->args[n++] = map->table[i].value; } } } // copy agross the positional arguments th_args->n_args = pos_args_len; memcpy(th_args->args, pos_args_items, pos_args_len * sizeof(mp_obj_t)); // pass our locals and globals into the new thread th_args->dict_locals = mp_locals_get(); th_args->dict_globals = mp_globals_get(); // set the stack size to use th_args->stack_size = thread_stack_size; // set the function for thread entry th_args->fun = args[0]; // spawn the thread! mp_thread_create(thread_entry, th_args, &th_args->stack_size); return mp_const_none; }
STATIC mp_obj_t new_namedtuple_type(mp_obj_t name_in, mp_obj_t fields_in) { qstr name = mp_obj_str_get_qstr(name_in); mp_uint_t n_fields; mp_obj_t *fields; #if MICROPY_CPYTHON_COMPAT if (MP_OBJ_IS_STR(fields_in)) { fields_in = mp_obj_str_split(1, &fields_in); } #endif mp_obj_get_array(fields_in, &n_fields, &fields); return mp_obj_new_namedtuple_type(name, n_fields, fields); }
// note: returned value in *items may point to the interior of a GC block void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { size_t seq_len; mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_raise_ValueError("tuple/list has wrong length"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "requested length %d but object has length %d", (int)len, (int)seq_len)); } } }
STATIC mp_obj_t time_mktime(mp_obj_t tuple) { mp_uint_t len; mp_obj_t *elem; mp_obj_get_array(tuple, &len, &elem); // localtime generates a tuple of len 8. CPython uses 9, so we accept both. if (len < 8 || len > 9) { nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, mpexception_num_type_invalid_arguments)); } return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]))); }
/// \function mktime() /// This is inverse function of localtime. It's argument is a full 8-tuple /// which expresses a time as per localtime. It returns an integer which is /// the number of seconds since Jan 1, 2000. STATIC mp_obj_t time_mktime(mp_obj_t tuple) { size_t len; mp_obj_t *elem; mp_obj_get_array(tuple, &len, &elem); // localtime generates a tuple of len 8. CPython uses 9, so we accept both. if (len < 8 || len > 9) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len)); } return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]))); }
/// \function select(rlist, wlist, xlist[, timeout]) STATIC mp_obj_t select_select(uint n_args, const mp_obj_t *args) { // get array data from tuple/list arguments mp_uint_t rwx_len[3]; mp_obj_t *r_array, *w_array, *x_array; mp_obj_get_array(args[0], &rwx_len[0], &r_array); mp_obj_get_array(args[1], &rwx_len[1], &w_array); mp_obj_get_array(args[2], &rwx_len[2], &x_array); // get timeout mp_uint_t timeout = -1; if (n_args == 4) { if (args[3] != mp_const_none) { #if MICROPY_PY_BUILTINS_FLOAT float timeout_f = mp_obj_get_float(args[3]); if (timeout_f >= 0) { timeout = (mp_uint_t)(timeout_f * 1000); } #else timeout = mp_obj_get_int(args[3]) * 1000; #endif } } // merge separate lists and get the ioctl function for each object mp_map_t poll_map; mp_map_init(&poll_map, rwx_len[0] + rwx_len[1] + rwx_len[2]); poll_map_add(&poll_map, r_array, rwx_len[0], MP_IOCTL_POLL_RD, true); poll_map_add(&poll_map, w_array, rwx_len[1], MP_IOCTL_POLL_WR, true); poll_map_add(&poll_map, x_array, rwx_len[2], MP_IOCTL_POLL_ERR | MP_IOCTL_POLL_HUP, true); mp_uint_t start_tick = HAL_GetTick(); rwx_len[0] = rwx_len[1] = rwx_len[2] = 0; for (;;) { // poll the objects mp_uint_t n_ready = poll_map_poll(&poll_map, rwx_len); if (n_ready > 0 || (timeout != -1 && HAL_GetTick() - start_tick >= timeout)) { // one or more objects are ready, or we had a timeout mp_obj_t list_array[3]; list_array[0] = mp_obj_new_list(rwx_len[0], NULL); list_array[1] = mp_obj_new_list(rwx_len[1], NULL); list_array[2] = mp_obj_new_list(rwx_len[2], NULL); rwx_len[0] = rwx_len[1] = rwx_len[2] = 0; for (mp_uint_t i = 0; i < poll_map.alloc; ++i) { if (!MP_MAP_SLOT_IS_FILLED(&poll_map, i)) { continue; } poll_obj_t *poll_obj = (poll_obj_t*)poll_map.table[i].value; if (poll_obj->flags_ret & MP_IOCTL_POLL_RD) { ((mp_obj_list_t*)list_array[0])->items[rwx_len[0]++] = poll_obj->obj; } if (poll_obj->flags_ret & MP_IOCTL_POLL_WR) { ((mp_obj_list_t*)list_array[1])->items[rwx_len[1]++] = poll_obj->obj; } if ((poll_obj->flags_ret & ~(MP_IOCTL_POLL_RD | MP_IOCTL_POLL_WR)) != 0) { ((mp_obj_list_t*)list_array[2])->items[rwx_len[2]++] = poll_obj->obj; } } mp_map_deinit(&poll_map); return mp_obj_new_tuple(3, list_array); } __WFI(); } }
static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_list_obj, mp_obj_t threshold) { color_t *color; image_t *image; /* sanity checks */ PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565); PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QCIF); /* read arguments */ image = py_image_cobj(image_obj); int thresh = mp_obj_get_int(threshold); /* returned image */ image_t bimage = { .w=image->w, .h=image->h, .bpp=1, .pixels=image->data+(image->w*image->h*image->bpp) }; /* copy color list */ uint len; mp_obj_t *color_arr; mp_obj_get_array(color_list_obj, &len, &color_arr); color = xalloc(len*sizeof*color); for (int i=0; i<len; i++) { mp_obj_t *color_obj; mp_obj_get_array_fixed_n(color_arr[i], 3, &color_obj); color[i].r = mp_obj_get_int(color_obj[0]); color[i].g = mp_obj_get_int(color_obj[1]); color[i].b = mp_obj_get_int(color_obj[2]); } /* Threshold image using reference color */ imlib_threshold(image, &bimage, color, len, thresh); return py_image_from_struct(&bimage); } static mp_obj_t py_image_rainbow(mp_obj_t src_image_obj) { image_t *src_image = NULL; /* get C image pointer */ src_image = py_image_cobj(src_image_obj); /* sanity checks */ PY_ASSERT_TRUE(src_image->bpp==1); image_t dst_image = { .w=src_image->w, .h=src_image->h, .bpp=2, .pixels=xalloc(src_image->w*src_image->h*2) }; imlib_rainbow(src_image, &dst_image); *src_image = dst_image; return src_image_obj; } static mp_obj_t py_image_compress(mp_obj_t image_obj, mp_obj_t quality) { image_t *image = py_image_cobj(image_obj); image_t cimage = { .w=image->w, .h=image->h, .bpp=0, .pixels= NULL }; jpeg_compress(image, &cimage, mp_obj_get_int(quality)); return py_image_from_struct(&cimage); } static mp_obj_t py_image_draw_line(mp_obj_t image_obj, mp_obj_t line_obj) { /* get image pointer */ struct image *image; image = py_image_cobj(image_obj); mp_obj_t *array; mp_obj_get_array_fixed_n(line_obj, 4, &array); int x0 = mp_obj_get_int(array[0]); int y0 = mp_obj_get_int(array[1]); int x1 = mp_obj_get_int(array[2]); int y1 = mp_obj_get_int(array[3]); imlib_draw_line(image, x0, y0, x1, y1); return mp_const_none; } static mp_obj_t py_image_draw_circle(mp_obj_t image_obj, mp_obj_t c_obj, mp_obj_t r_obj) { int cx, cy, r; mp_obj_t *array; struct image *image; color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; /* get image pointer */ image = py_image_cobj(image_obj); /* center */ mp_obj_get_array_fixed_n(c_obj, 2, &array); cx = mp_obj_get_int(array[0]); cy = mp_obj_get_int(array[1]); /* radius */ r = mp_obj_get_int(r_obj); imlib_draw_circle(image, cx, cy, r, &c); return mp_const_none; } static mp_obj_t py_image_draw_string(uint n_args, const mp_obj_t *args) { int x = mp_obj_get_int(args[1]); int y = mp_obj_get_int(args[2]); image_t *image =py_image_cobj(args[0]); const char *str = mp_obj_str_get_str(args[3]); color_t c = {.r=0xFF, .g=0xFF, .b=0xFF}; if (n_args == 5) { // get color mp_obj_t *array; mp_obj_get_array_fixed_n(args[4], 3, &array); c.r = mp_obj_get_int(array[0]); c.g = mp_obj_get_int(array[1]); c.b = mp_obj_get_int(array[2]); } imlib_draw_string(image, x, y, str, &c); return mp_const_none; } static mp_obj_t py_image_erode(mp_obj_t image_obj, mp_obj_t ksize_obj) { image_t *image = NULL; image = py_image_cobj(image_obj); /* sanity checks */ PY_ASSERT_TRUE(image->bpp==1); imlib_erode(image, mp_obj_get_int(ksize_obj)); return mp_const_none; }
STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { mp_raise_NotImplementedError(NULL); } mp_int_t len_adj = slice.start - slice.stop; //printf("Len adj: %d\n", len_adj); assert(len_adj <= 0); mp_seq_replace_slice_no_grow(self->items, self->len, slice.start, slice.stop, self->items/*NULL*/, 0, sizeof(*self->items)); // Clear "freed" elements at the end of list mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); self->len += len_adj; return mp_const_none; } #endif mp_obj_t args[2] = {self_in, index}; list_pop(2, args); return mp_const_none; } else if (value == MP_OBJ_SENTINEL) { // load mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { return mp_seq_extract_slice(self->len, self->items, &slice); } mp_obj_list_t *res = list_new(slice.stop - slice.start); mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t); return MP_OBJ_FROM_PTR(res); } #endif size_t index_val = mp_get_index(self->base.type, self->len, index, false); return self->items[index_val]; } else { #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); size_t value_len; mp_obj_t *value_items; mp_obj_get_array(value, &value_len, &value_items); mp_bound_slice_t slice_out; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) { mp_raise_NotImplementedError(NULL); } mp_int_t len_adj = value_len - (slice_out.stop - slice_out.start); //printf("Len adj: %d\n", len_adj); if (len_adj > 0) { if (self->len + len_adj > self->alloc) { // TODO: Might optimize memory copies here by checking if block can // be grown inplace or not self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + len_adj); self->alloc = self->len + len_adj; } mp_seq_replace_slice_grow_inplace(self->items, self->len, slice_out.start, slice_out.stop, value_items, value_len, len_adj, sizeof(*self->items)); } else { mp_seq_replace_slice_no_grow(self->items, self->len, slice_out.start, slice_out.stop, value_items, value_len, sizeof(*self->items)); // Clear "freed" elements at the end of list mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); // TODO: apply allocation policy re: alloc_size } self->len += len_adj; return mp_const_none; } #endif mp_obj_list_store(self_in, index, value); return mp_const_none; } }
static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_list_obj, mp_obj_t threshold) { color_t *color; image_t *image; /* sanity checks */ PY_ASSERT_TRUE_MSG(sensor.pixformat == PIXFORMAT_RGB565, "This function is only supported on RGB565 images"); PY_ASSERT_TRUE_MSG(sensor.framesize <= OMV_MAX_BLOB_FRAME, "This function is only supported on "OMV_MAX_BLOB_FRAME_STR" and smaller frames"); /* read arguments */ image = py_image_cobj(image_obj); int thresh = mp_obj_get_int(threshold); /* returned image */ image_t bimage = { .w=image->w, .h=image->h, .bpp=1, .pixels=image->data+(image->w*image->h*image->bpp) }; /* copy color list */ uint len; mp_obj_t *color_arr; mp_obj_get_array(color_list_obj, &len, &color_arr); color = xalloc(len*sizeof*color); for (int i=0; i<len; i++) { mp_obj_t *color_obj; mp_obj_get_array_fixed_n(color_arr[i], 3, &color_obj); color[i].r = mp_obj_get_int(color_obj[0]); color[i].g = mp_obj_get_int(color_obj[1]); color[i].b = mp_obj_get_int(color_obj[2]); } /* Threshold image using reference color */ imlib_threshold(image, &bimage, color, len, thresh); return py_image_from_struct(&bimage); } static mp_obj_t py_image_rainbow(mp_obj_t src_image_obj) { image_t *src_image = NULL; /* get C image pointer */ src_image = py_image_cobj(src_image_obj); /* sanity checks */ PY_ASSERT_TRUE_MSG(src_image->bpp == 1, "This function is only supported on GRAYSCALE images"); image_t dst_image = { .w=src_image->w, .h=src_image->h, .bpp=2, .pixels=xalloc(src_image->w*src_image->h*2) }; imlib_rainbow(src_image, &dst_image); *src_image = dst_image; return src_image_obj; } static mp_obj_t py_image_compress(mp_obj_t image_obj, mp_obj_t quality) { image_t *image = py_image_cobj(image_obj); image_t cimage = { .w=image->w, .h=image->h, .bpp = JPEG_INIT_BUF, .pixels = xalloc(JPEG_INIT_BUF) }; jpeg_compress(image, &cimage, mp_obj_get_int(quality)); return py_image_from_struct(&cimage); }
/// \function mktime() /// This is inverse function of localtime. It's argument is a full 8-tuple /// which expresses a time as per localtime. It returns an integer which is /// the number of seconds since Jan 1, 2000. STATIC mp_obj_t time_mktime(mp_obj_t tuple) { mp_uint_t len; mp_obj_t *elem; mp_obj_get_array(tuple, &len, &elem); // localtime generates a tuple of len 8. CPython uses 9, so we accept both. if (len < 8 || len > 9) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len)); } mp_int_t year = mp_obj_get_int(elem[0]); mp_int_t month = mp_obj_get_int(elem[1]); mp_int_t mday = mp_obj_get_int(elem[2]); mp_int_t hours = mp_obj_get_int(elem[3]); mp_int_t minutes = mp_obj_get_int(elem[4]); mp_int_t seconds = mp_obj_get_int(elem[5]); // Normalise the tuple. This allows things like: // // tm_tomorrow = list(time.localtime()) // tm_tomorrow[2] += 1 # Adds 1 to mday // tomorrow = time.mktime(tm_tommorrow) // // And not have to worry about all the weird overflows. // // You can subtract dates/times this way as well. minutes += seconds / 60; if ((seconds = seconds % 60) < 0) { seconds += 60; minutes--; } hours += minutes / 60; if ((minutes = minutes % 60) < 0) { minutes += 60; hours--; } mday += hours / 24; if ((hours = hours % 24) < 0) { hours += 24; mday--; } month--; // make month zero based year += month / 12; if ((month = month % 12) < 0) { month += 12; year--; } month++; // back to one based while (mday < 1) { if (--month == 0) { month = 12; year--; } mday += mod_time_days_in_month(year, month); } while (mday > mod_time_days_in_month(year, month)) { mday -= mod_time_days_in_month(year, month); if (++month == 13) { month = 1; year++; } } return mp_obj_new_int_from_uint(mod_time_seconds_since_2000(year, month, mday, hours, minutes, seconds)); }