diff --git a/src/main.c b/src/main.c index 6403e6636..12913ddfb 100644 --- a/src/main.c +++ b/src/main.c @@ -15,7 +15,6 @@ #include "usbdbg.h" #include "py_led.h" #include "py_sensor.h" -#include "py_imlib.h" #include "py_file.h" #include "py_time.h" #include "py_spi.h" @@ -216,17 +215,16 @@ gc_info_t get_gc_info() } typedef struct { - const char *name; - mp_obj_t (*init)(void); + qstr name; + const mp_obj_module_t *(*init)(void); } module_t; static module_t exported_modules[] ={ - {"led", py_led_init}, - {"sensor", py_sensor_init}, - {"imlib", py_imlib_init}, - {"time", py_time_init}, - {"spi", py_spi_init}, - {"gpio", py_gpio_init}, + {MP_QSTR_led, py_led_init}, + {MP_QSTR_time, py_time_init}, + {MP_QSTR_sensor,py_sensor_init}, + {MP_QSTR_gpio, py_gpio_init}, + {MP_QSTR_spi, py_spi_init}, {NULL, NULL} }; @@ -255,11 +253,11 @@ int main(void) /* Export Python modules to the global python namespace */ for (module_t *p = exported_modules; p->name != NULL; p++) { - mp_obj_t module = p->init(); + const mp_obj_module_t *module = p->init(); if (module == NULL) { __fatal_error("failed to init module"); } else { - rt_store_name(qstr_from_str(p->name), module); + mp_module_register(p->name, (mp_obj_t)module); } } @@ -291,7 +289,7 @@ int main(void) #if 1 /* run main script */ if (!libmp_do_file("0:/main.py")) { - __fatal_error("failed to run main script"); + printf("failed to run main script\n"); } libmp_do_repl(); diff --git a/src/py/py_gpio.c b/src/py/py_gpio.c index 7e80b2ecc..4e54df9ba 100644 --- a/src/py/py_gpio.c +++ b/src/py/py_gpio.c @@ -16,47 +16,45 @@ typedef enum { } gpio_id_t; typedef struct { - const char *sym; - int val; GPIO_TypeDef* port; uint32_t pin; } gpio_t; /* GPIOs */ -static gpio_t gpio_constants[] = { - {"PC9", GPIO_PC9 , GPIOC, GPIO_Pin_9 }, - {"PC10", GPIO_PC10, GPIOC, GPIO_Pin_10}, - {"PC11", GPIO_PC11, GPIOC, GPIO_Pin_11}, - {"PC12", GPIO_PC12, GPIOC, GPIO_Pin_12}, - {"PA8", GPIO_PA8 , GPIOA, GPIO_Pin_8 }, - {"PA15", GPIO_PA15, GPIOA, GPIO_Pin_15}, +static const gpio_t gpio_constants[] = { + {GPIOC, GPIO_Pin_9 }, + {GPIOC, GPIO_Pin_10}, + {GPIOC, GPIO_Pin_11}, + {GPIOC, GPIO_Pin_12}, + {GPIOA, GPIO_Pin_8 }, + {GPIOA, GPIO_Pin_15}, {NULL, 0} }; typedef struct _py_gpio_obj_t { mp_obj_base_t base; - gpio_t *info; + const gpio_t *info; } py_gpio_obj_t; -mp_obj_t py_gpio_low(py_gpio_obj_t *gpio) +static mp_obj_t py_gpio_low(py_gpio_obj_t *gpio) { GPIO_ResetBits(gpio->info->port, gpio->info->pin); return mp_const_none; } -mp_obj_t py_gpio_high(py_gpio_obj_t *gpio) +static mp_obj_t py_gpio_high(py_gpio_obj_t *gpio) { GPIO_SetBits(gpio->info->port, gpio->info->pin); return mp_const_none; } -void py_gpio_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) +static void py_gpio_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { print(env, ""); } -static MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_low_obj, py_gpio_low); -static MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_high_obj, py_gpio_high); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_low_obj, py_gpio_low); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_high_obj, py_gpio_high); static const mp_method_t py_gpio_methods[] = { { "low", &py_gpio_low_obj}, @@ -71,7 +69,7 @@ static const mp_obj_type_t py_gpio_type = { .methods = py_gpio_methods, }; -static void gpio_init(gpio_t *gpio) +static void gpio_init(const gpio_t *gpio) { GPIO_InitTypeDef GPIO_InitStructure; /* Configure the GPIO pin */ @@ -97,21 +95,37 @@ mp_obj_t py_gpio_new(mp_obj_t id_obj) return gpio_obj; } -mp_obj_t py_gpio_init() +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_gpio_new_obj, py_gpio_new); +STATIC const mp_map_elem_t module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_gpio) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_P1), MP_OBJ_NEW_SMALL_INT(GPIO_PC10)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_P2), MP_OBJ_NEW_SMALL_INT(GPIO_PC11)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_P3), MP_OBJ_NEW_SMALL_INT(GPIO_PC12)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_P4), MP_OBJ_NEW_SMALL_INT(GPIO_PA15)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_P5), MP_OBJ_NEW_SMALL_INT(GPIO_PC9 )}, + { MP_OBJ_NEW_QSTR(MP_QSTR_P6), MP_OBJ_NEW_SMALL_INT(GPIO_PA8 )}, + { MP_OBJ_NEW_QSTR(MP_QSTR_GPIO), (mp_obj_t)&py_gpio_new_obj }, +}; + +STATIC const mp_map_t module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)module_globals_table, +}; + +static const mp_obj_module_t py_gpio_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_gpio, + .globals = (mp_map_t*)&module_globals, +}; + +const mp_obj_module_t *py_gpio_init() { /* Enable GPIO clocks */ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); - /* Create module */ - mp_obj_t m = mp_obj_new_module(qstr_from_str("gpio")); - - /* Store module functions */ - rt_store_attr(m, qstr_from_str("GPIO"), rt_make_function_n(1, py_gpio_new)); - - /* Store module constants */ - for (gpio_t *p = gpio_constants; p->sym != NULL; p++) { - rt_store_attr(m, QSTR_FROM_STR_STATIC(p->sym), MP_OBJ_NEW_SMALL_INT((machine_int_t)p->val)); - } - return m; + return &py_gpio_module; } diff --git a/src/py/py_gpio.h b/src/py/py_gpio.h index 7c3fc0dd8..571157a7b 100644 --- a/src/py/py_gpio.h +++ b/src/py/py_gpio.h @@ -1,5 +1,5 @@ #ifndef __PY_GPIO_H__ #define __PY_GPIO_H__ -mp_obj_t py_gpio_init(); +const mp_obj_module_t *py_gpio_init(); #endif /* __PY_GPIO_H__ */ diff --git a/src/py/py_image.c b/src/py/py_image.c index abe6cf6f7..65041833c 100644 --- a/src/py/py_image.c +++ b/src/py/py_image.c @@ -1,30 +1,469 @@ #include +#include "xalloc.h" #include "imlib.h" -#include "py_assert.h" +#include "array.h" +#include "sensor.h" #include "py_image.h" +#include "py_assert.h" +#include "py_file.h" + +extern struct sensor_dev sensor; +static const mp_obj_type_t py_cascade_type; +static const mp_obj_type_t py_surf_type; +static const mp_obj_type_t py_image_type; + +/* Haar Cascade */ +typedef struct _py_cascade_obj_t { + mp_obj_base_t base; + struct cascade _cobj; +} py_cascade_obj_t; + +void *py_cascade_cobj(mp_obj_t cascade) +{ + PY_ASSERT_TYPE(cascade, &py_cascade_type); + return &((py_cascade_obj_t *)cascade)->_cobj; +} + +static void py_cascade_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) +{ + py_cascade_obj_t *self = self_in; + /* print some info */ + print(env, "width:%d height:%d n_stages:%d n_features:%d n_rectangles:%d\n", self->_cobj.window.w, + self->_cobj.window.h, self->_cobj.n_stages, self->_cobj.n_features, self->_cobj.n_rectangles); +} + +static const mp_obj_type_t py_cascade_type = { + { &mp_type_type }, + .name = MP_QSTR_Cascade, + .print = py_cascade_print, +}; + +/* SURF Detector */ +typedef struct _py_surf_obj_t { + mp_obj_base_t base; + struct surf _cobj; +} py_surf_obj_t; + +void *py_surf_cobj(mp_obj_t surf) +{ + PY_ASSERT_TYPE(surf, &py_surf_type); + return &((py_surf_obj_t *)surf)->_cobj; +} + +static void py_surf_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) +{ + py_surf_obj_t *self = self_in; + /* print some info */ + print(env, "upright:%d octaves:%d intervals:%d init_sample:%d thresh:%f\n", + self->_cobj.upright, self->_cobj.octaves, self->_cobj.intervals, (double) self->_cobj.thresh); +} + +static const mp_obj_type_t py_surf_type = { + { &mp_type_type }, + .name = MP_QSTR_Surf, + .print = py_surf_print, + .print = NULL, +}; + +/* Image */ typedef struct _py_image_obj_t { mp_obj_base_t base; struct image _cobj; } py_image_obj_t; -void py_image_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) +void *py_image_cobj(mp_obj_t image) { -// py_image_obj_t *self = self_in; -// dest[0] = mp_obj_new_int(self->width); + PY_ASSERT_TYPE(image, &py_image_type); + return &((py_image_obj_t *)image)->_cobj; } -bool py_image_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) -{ - return true; -} - -void py_image_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) +static void py_image_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { py_image_obj_t *self = self_in; print(env, "", self->_cobj.w, self->_cobj.h, self->_cobj.bpp); } +static mp_obj_t py_image_histeq(mp_obj_t image_obj) +{ + struct image *image; + /* get image pointer */ + image = (struct image*) py_image_cobj(image_obj); + + /* sanity checks */ + PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); + + imlib_histeq(image); + return mp_const_none; +} + +static mp_obj_t py_image_median(mp_obj_t image_obj, mp_obj_t ksize) +{ + struct image *image; + /* get image pointer */ + image = (struct image*) py_image_cobj(image_obj); + + /* sanity checks */ + //PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); + + imlib_median_filter(image, mp_obj_get_int(ksize)); + return mp_const_none; +} + +static mp_obj_t py_image_draw_rectangle(mp_obj_t image_obj, mp_obj_t rectangle_obj) +{ + struct rectangle r; + struct image *image; + mp_obj_t *array; + + mp_obj_get_array_fixed_n(rectangle_obj, 4, &array); + r.x = mp_obj_get_int(array[0]); + r.y = mp_obj_get_int(array[1]); + r.w = mp_obj_get_int(array[2]); + r.h = mp_obj_get_int(array[3]); + + /* get image pointer */ + image = py_image_cobj(image_obj); + + imlib_draw_rectangle(image, &r); + 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; + + /* 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); + return mp_const_none; +} + +static mp_obj_t py_image_threshold(mp_obj_t image_obj, mp_obj_t color_obj, mp_obj_t threshold) +{ + /* C stuff */ + struct color color; + struct image *image; + + /* sanity checks */ + PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565); + + mp_obj_t *col_obj; + mp_obj_get_array_fixed_n(color_obj, 3, &col_obj); + color.r = mp_obj_get_int(col_obj[0]); + color.g = mp_obj_get_int(col_obj[1]); + color.b = mp_obj_get_int(col_obj[2]); + + /* get image pointer */ + image = py_image_cobj(image_obj); + + /* Threshold image using reference color */ + imlib_threshold(image, &color, mp_obj_get_int(threshold)); + + return mp_const_none; +} + +static mp_obj_t py_image_count_blobs(mp_obj_t image_obj) +{ + /* C stuff */ + array_t *blobs; + struct image *image; + + /* MP List */ + mp_obj_t objects_list = mp_const_none; + + /* sanity checks */ + PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565); + + /* get image pointer */ + image = py_image_cobj(image_obj); + + /* run color dector */ + blobs = imlib_count_blobs(image); + + /* Create empty Python list */ + objects_list = rt_build_list(0, NULL); + + if (array_length(blobs)) { + for (int j=0; jx); + r[1] = mp_obj_new_int(b->y); + r[2] = mp_obj_new_int(b->w); + r[3] = mp_obj_new_int(b->h); + rt_list_append(objects_list, rt_build_tuple(4, r)); + } + } + array_free(blobs); + return objects_list; +} + +static mp_obj_t py_image_detect_objects(mp_obj_t image_obj, mp_obj_t cascade_obj) +{ + struct image *image = NULL; + struct cascade *cascade = NULL; + + struct array *objects_array=NULL; + mp_obj_t objects_list = mp_const_none; + + /* sanity checks */ + PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA); + PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); + + /* get C image pointer */ + image = py_image_cobj(image_obj); + /* get C cascade pointer */ + cascade = py_cascade_cobj(cascade_obj); + + /* Detect objects */ + objects_array = imlib_detect_objects(image, cascade); + + /* Create empty Python list */ + objects_list = rt_build_list(0, NULL); + + /* Add detected objects to the list */ + for (int i=0; ix); + rec_obj[1] = mp_obj_new_int(r->y); + rec_obj[2] = mp_obj_new_int(r->w); + rec_obj[3] = mp_obj_new_int(r->h); + rt_list_append(objects_list, rt_build_tuple(4, rec_obj)); + } + + /* Free the objects array */ + array_free(objects_array); + + return objects_list; +} + +static mp_obj_t py_image_load_cascade(mp_obj_t path_obj) +{ + py_cascade_obj_t *o =NULL; + + /* detection parameters */ + struct cascade cascade = { + .step = 2, + .scale_factor = 1.25f, + }; + + const char *path = mp_obj_str_get_str(path_obj); + int res = imlib_load_cascade(&cascade, path); + if (res != FR_OK) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); + } + + o = m_new_obj(py_cascade_obj_t); + o->base.type = &py_cascade_type; + o->_cobj = cascade; + return o; +} + +static mp_obj_t py_image_load_template(mp_obj_t path_obj) +{ + mp_obj_t image_obj =NULL; + struct image *image; + const char *path = mp_obj_str_get_str(path_obj); + image_obj = py_image(0, 0, 0, 0); + + /* get image pointer */ + image = py_image_cobj(image_obj); + + int res = imlib_load_template(image, path); + if (res != FR_OK) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); + } + + return image_obj; +} + +static mp_obj_t py_image_save_template(mp_obj_t image_obj, mp_obj_t rectangle_obj, mp_obj_t path_obj) +{ + struct image t; + struct image *image = NULL; + + struct rectangle r; + mp_obj_t *array; + + const char *path = mp_obj_str_get_str(path_obj); + + mp_obj_get_array_fixed_n(rectangle_obj, 4, &array); + r.x = mp_obj_get_int(array[0]); + r.y = mp_obj_get_int(array[1]); + r.w = mp_obj_get_int(array[2]); + r.h = mp_obj_get_int(array[3]); + + + /* get C image pointer */ + image = py_image_cobj(image_obj); + t.w = r.w; + t.h = r.h; + t.data = xalloc(sizeof(*t.data)*t.w*t.h); /* TODO this is not really needed */ + + imlib_subimage(image, &t, r.x, r.y); + + int res = imlib_save_template(&t, path); + xfree(t.data); + + if (res != FR_OK) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); + } + + return mp_const_true; +} + +static mp_obj_t py_image_template_match(mp_obj_t image_obj, mp_obj_t template_obj, mp_obj_t threshold) +{ + struct rectangle r; + struct image *image = NULL; + struct image *template = NULL; + mp_obj_t rec_obj[4]; + mp_obj_t obj=mp_const_none; + + /* sanity checks */ + PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA); + PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); + + /* get C image pointer */ + image = py_image_cobj(image_obj); + template= py_image_cobj(template_obj); + + float t = mp_obj_get_float(threshold); + + /* look for object */ + float corr = imlib_template_match(image, template, &r); + if (corr> t) { + rec_obj[0] = mp_obj_new_int(r.x); + rec_obj[1] = mp_obj_new_int(r.y); + rec_obj[2] = mp_obj_new_int(r.w); + rec_obj[3] = mp_obj_new_int(r.h); + obj=rt_build_tuple(4, rec_obj); + } + return obj; +} + +static mp_obj_t py_image_blit(mp_obj_t image_obj, mp_obj_t template_obj) +{ + struct image *image = NULL; + struct image *template = NULL; + + /* sanity checks */ + PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA); + PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); + + /* get C image pointer */ + image = py_image_cobj(image_obj); + template= py_image_cobj(template_obj); + imlib_blit(image, template, 0, 0); + + return mp_const_true; +} + +static mp_obj_t py_image_surf_detector(mp_obj_t image_obj, mp_obj_t upright, mp_obj_t thresh) +{ + struct image *image; + py_surf_obj_t *o =NULL; + + surf_t surf = { + .upright=mp_obj_get_int(upright), + .octaves=5, + .init_sample=2, + .thresh=mp_obj_get_float(thresh), + }; + + /* get image pointer */ + image = (struct image*) py_image_cobj(image_obj); + + /* sanity checks */ + PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); + + /* run SURF detector */ + surf_detector(image, &surf); + + o = m_new_obj(py_surf_obj_t); + o->base.type = &py_surf_type; + o->_cobj = surf; + return o; +} + +static mp_obj_t py_image_surf_match(mp_obj_t image_obj, mp_obj_t surf1_obj, mp_obj_t surf2_obj) +{ + surf_t *surf1 = NULL; + surf_t *surf2 = NULL; + image_t *image = NULL; + + /* get C image pointer */ + image = py_image_cobj(image_obj); + /* get C cascade pointer */ + surf1 = py_surf_cobj(surf1_obj); + surf2 = py_surf_cobj(surf2_obj); + + /* Detect objects */ + array_t *match = surf_match(surf1, surf2); + surf_draw_ipts(image, match); + array_free(match); //TODO + array_free(surf2->ipts); //TODO + return mp_const_none; +} + +static mp_obj_t py_image_surf_draw_ipts(mp_obj_t image_obj, mp_obj_t surf_obj) +{ + surf_t *surf = NULL; + image_t *image = NULL; + + /* get C image pointer */ + image = py_image_cobj(image_obj); + + /* get C cascade pointer */ + surf = py_surf_cobj(surf_obj); + + surf_draw_ipts(image, surf->ipts); + return mp_const_none; +} + +STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_blit_obj, py_image_blit); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_load_cascade_obj, py_image_load_cascade); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_load_template_obj, py_image_load_template); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_save_template_obj, py_image_save_template); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_template_match_obj, py_image_template_match); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_histeq_obj, py_image_histeq); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_median_obj, py_image_median); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_draw_rectangle_obj, py_image_draw_rectangle); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_draw_circle_obj, py_image_draw_circle); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_threshold_obj, py_image_threshold); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_image_count_blobs_obj, py_image_count_blobs); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_detect_objects_obj, py_image_detect_objects); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_surf_detector_obj, py_image_surf_detector); +STATIC MP_DEFINE_CONST_FUN_OBJ_3(py_image_surf_match_obj, py_image_surf_match); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_image_surf_draw_ipts_obj, py_image_surf_draw_ipts); + static const mp_method_t py_image_methods[] = { + {"blit", &py_image_blit_obj}, + {"load_cascade", &py_image_load_cascade_obj}, + {"load_template", &py_image_load_template_obj}, + {"save_template", &py_image_save_template_obj}, + {"template_match", &py_image_template_match_obj}, + {"histeq", &py_image_histeq_obj}, + {"median", &py_image_median_obj}, + {"draw_rectangle", &py_image_draw_rectangle_obj}, + {"draw_circle", &py_image_draw_circle_obj}, + {"threshold", &py_image_threshold_obj}, + {"count_blobs", &py_image_count_blobs_obj}, + {"detect_objects", &py_image_detect_objects_obj}, + {"surf_detector", &py_image_surf_detector_obj}, + {"surf_match", &py_image_surf_match_obj}, + {"surf_draw_ipts", &py_image_surf_draw_ipts_obj}, { NULL, NULL }, }; @@ -33,9 +472,6 @@ static const mp_obj_type_t py_image_type = { .name = MP_QSTR_Image, .print = py_image_print, .methods = py_image_methods, -// .load_attr = py_image_load_attr, -// .store_attr = py_image_store_attr, - }; mp_obj_t py_image(int w, int h, int bpp, void *pixels) @@ -50,9 +486,35 @@ mp_obj_t py_image(int w, int h, int bpp, void *pixels) return o; } -void *py_image_cobj(mp_obj_t image) -{ - PY_ASSERT_TYPE(image, &py_image_type); - return &((py_image_obj_t *)image)->_cobj; +#if 0 +typedef struct _mp_obj_array_it_t { + mp_obj_base_t base; + mp_obj_array_t *array; + machine_uint_t cur; +} mp_obj_array_it_t; + +mp_obj_t array_it_iternext(mp_obj_t self_in) { + mp_obj_array_it_t *self = self_in; + if (self->cur < self->array->len) { + machine_int_t val = array_get_el(self->array, self->cur++); + return mp_obj_new_int(val); + } else { + return mp_const_stop_iteration; + } } +static const mp_obj_type_t array_it_type = { + { &mp_const_type }, + "array_iterator", + .iternext = array_it_iternext, +}; + +mp_obj_t array_iterator_new(mp_obj_t array_in) { + mp_obj_array_t *array = array_in; + mp_obj_array_it_t *o = m_new_obj(mp_obj_array_it_t); + o->base.type = &array_it_type; + o->array = array; + o->cur = 0; + return o; +} +#endif diff --git a/src/py/py_imlib.c b/src/py/py_imlib.c deleted file mode 100644 index 879bda6b6..000000000 --- a/src/py/py_imlib.c +++ /dev/null @@ -1,481 +0,0 @@ -#include -#include "xalloc.h" -#include "imlib.h" -#include "array.h" -#include "sensor.h" -#include "py_image.h" -#include "py_imlib.h" -#include "py_assert.h" -#include "py_file.h" - -extern struct sensor_dev sensor; - -typedef struct _py_cascade_obj_t { - mp_obj_base_t base; - struct cascade _cobj; -} py_cascade_obj_t; - -typedef struct _py_surf_obj_t { - mp_obj_base_t base; - struct surf _cobj; -} py_surf_obj_t; - -static void py_cascade_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) -{ - py_cascade_obj_t *self = self_in; - - /* print some info */ - print(env, "width:%d height:%d n_stages:%d n_features:%d n_rectangles:%d\n", - self->_cobj.window.w, - self->_cobj.window.h, - self->_cobj.n_stages, - self->_cobj.n_features, - self->_cobj.n_rectangles); -} - -static const mp_obj_type_t py_cascade_type = { - { &mp_type_type }, - .name = MP_QSTR_Cascade, - .print = py_cascade_print, -}; - -static const mp_obj_type_t py_surf_type = { - { &mp_type_type }, - .name = MP_QSTR_Cascade, -// .print = py_cascade_print, - .print = NULL, -}; - -void *py_cascade_cobj(mp_obj_t cascade) -{ - PY_ASSERT_TYPE(cascade, &py_cascade_type); - return &((py_cascade_obj_t *)cascade)->_cobj; -} - -void *py_surf_cobj(mp_obj_t surf) -{ - PY_ASSERT_TYPE(surf, &py_surf_type); - return &((py_surf_obj_t *)surf)->_cobj; -} - -mp_obj_t py_imlib_histeq(mp_obj_t image_obj) -{ - struct image *image; - /* get image pointer */ - image = (struct image*) py_image_cobj(image_obj); - - /* sanity checks */ - PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); - - imlib_histeq(image); - return mp_const_none; -} - -mp_obj_t py_imlib_median(mp_obj_t image_obj, mp_obj_t ksize) -{ - struct image *image; - /* get image pointer */ - image = (struct image*) py_image_cobj(image_obj); - - /* sanity checks */ - //PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); - - imlib_median_filter(image, mp_obj_get_int(ksize)); - return mp_const_none; -} - -mp_obj_t py_imlib_draw_rectangle(mp_obj_t image_obj, mp_obj_t rectangle_obj) -{ - struct rectangle r; - struct image *image; - mp_obj_t *array; - - mp_obj_get_array_fixed_n(rectangle_obj, 4, &array); - r.x = mp_obj_get_int(array[0]); - r.y = mp_obj_get_int(array[1]); - r.w = mp_obj_get_int(array[2]); - r.h = mp_obj_get_int(array[3]); - - /* get image pointer */ - image = py_image_cobj(image_obj); - - imlib_draw_rectangle(image, &r); - return mp_const_none; -} - -mp_obj_t py_imlib_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; - - /* 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); - return mp_const_none; -} -mp_obj_t py_imlib_threshold(mp_obj_t image_obj, mp_obj_t color_obj, mp_obj_t threshold) -{ - /* C stuff */ - struct color color; - struct image *image; - - /* sanity checks */ - PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565); - - mp_obj_t *col_obj; - mp_obj_get_array_fixed_n(color_obj, 3, &col_obj); - color.r = mp_obj_get_int(col_obj[0]); - color.g = mp_obj_get_int(col_obj[1]); - color.b = mp_obj_get_int(col_obj[2]); - - /* get image pointer */ - image = py_image_cobj(image_obj); - - /* Threshold image using reference color */ - imlib_threshold(image, &color, mp_obj_get_int(threshold)); - - return mp_const_none; -} - -mp_obj_t py_imlib_count_blobs(mp_obj_t image_obj) -{ - /* C stuff */ - array_t *blobs; - struct image *image; - - /* MP List */ - mp_obj_t objects_list = mp_const_none; - - /* sanity checks */ - PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_RGB565); - - /* get image pointer */ - image = py_image_cobj(image_obj); - - /* run color dector */ - blobs = imlib_count_blobs(image); - - /* Create empty Python list */ - objects_list = rt_build_list(0, NULL); - - if (array_length(blobs)) { - for (int j=0; jx); - r[1] = mp_obj_new_int(b->y); - r[2] = mp_obj_new_int(b->w); - r[3] = mp_obj_new_int(b->h); - rt_list_append(objects_list, rt_build_tuple(4, r)); - } - } - array_free(blobs); - return objects_list; -} - -mp_obj_t py_imlib_detect_objects(mp_obj_t image_obj, mp_obj_t cascade_obj) -{ - struct image *image = NULL; - struct cascade *cascade = NULL; - - struct array *objects_array=NULL; - mp_obj_t objects_list = mp_const_none; - - /* sanity checks */ - PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA); - PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); - - /* get C image pointer */ - image = py_image_cobj(image_obj); - /* get C cascade pointer */ - cascade = py_cascade_cobj(cascade_obj); - - /* Detect objects */ - objects_array = imlib_detect_objects(image, cascade); - - /* Create empty Python list */ - objects_list = rt_build_list(0, NULL); - - /* Add detected objects to the list */ - for (int i=0; ix); - rec_obj[1] = mp_obj_new_int(r->y); - rec_obj[2] = mp_obj_new_int(r->w); - rec_obj[3] = mp_obj_new_int(r->h); - rt_list_append(objects_list, rt_build_tuple(4, rec_obj)); - } - - /* Free the objects array */ - array_free(objects_array); - - return objects_list; -} - -mp_obj_t py_imlib_load_cascade(mp_obj_t path_obj) -{ - py_cascade_obj_t *o =NULL; - - /* detection parameters */ - struct cascade cascade = { - .step = 2, - .scale_factor = 1.25f, - }; - - const char *path = mp_obj_str_get_str(path_obj); - int res = imlib_load_cascade(&cascade, path); - if (res != FR_OK) { - nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); - } - - o = m_new_obj(py_cascade_obj_t); - o->base.type = &py_cascade_type; - o->_cobj = cascade; - return o; -} - -mp_obj_t py_imlib_load_template(mp_obj_t path_obj) -{ - mp_obj_t image_obj =NULL; - struct image *image; - const char *path = mp_obj_str_get_str(path_obj); - image_obj = py_image(0, 0, 0, 0); - - /* get image pointer */ - image = py_image_cobj(image_obj); - - int res = imlib_load_template(image, path); - if (res != FR_OK) { - nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); - } - - return image_obj; -} - -mp_obj_t py_imlib_save_template(mp_obj_t image_obj, mp_obj_t rectangle_obj, mp_obj_t path_obj) -{ - struct image t; - struct image *image = NULL; - - struct rectangle r; - mp_obj_t *array; - - const char *path = mp_obj_str_get_str(path_obj); - - mp_obj_get_array_fixed_n(rectangle_obj, 4, &array); - r.x = mp_obj_get_int(array[0]); - r.y = mp_obj_get_int(array[1]); - r.w = mp_obj_get_int(array[2]); - r.h = mp_obj_get_int(array[3]); - - - /* get C image pointer */ - image = py_image_cobj(image_obj); - t.w = r.w; - t.h = r.h; - t.data = xalloc(sizeof(*t.data)*t.w*t.h); /* TODO this is not really needed */ - - imlib_subimage(image, &t, r.x, r.y); - - int res = imlib_save_template(&t, path); - xfree(t.data); - - if (res != FR_OK) { - nlr_jump(mp_obj_new_exception_msg(&mp_type_OSError, ffs_strerror(res))); - } - - return mp_const_true; -} - -mp_obj_t py_imlib_template_match(mp_obj_t image_obj, mp_obj_t template_obj, mp_obj_t threshold) -{ - struct rectangle r; - struct image *image = NULL; - struct image *template = NULL; - mp_obj_t rec_obj[4]; - mp_obj_t obj=mp_const_none; - - /* sanity checks */ - PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA); - PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); - - /* get C image pointer */ - image = py_image_cobj(image_obj); - template= py_image_cobj(template_obj); - - float t = mp_obj_get_float(threshold); - - /* look for object */ - float corr = imlib_template_match(image, template, &r); - if (corr> t) { - rec_obj[0] = mp_obj_new_int(r.x); - rec_obj[1] = mp_obj_new_int(r.y); - rec_obj[2] = mp_obj_new_int(r.w); - rec_obj[3] = mp_obj_new_int(r.h); - obj=rt_build_tuple(4, rec_obj); - } - return obj; -} - -mp_obj_t py_imlib_blit(mp_obj_t image_obj, mp_obj_t template_obj) -{ - struct image *image = NULL; - struct image *template = NULL; - - /* sanity checks */ - PY_ASSERT_TRUE(sensor.framesize <= FRAMESIZE_QQVGA); - PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); - - /* get C image pointer */ - image = py_image_cobj(image_obj); - template= py_image_cobj(template_obj); - imlib_blit(image, template, 0, 0); - - return mp_const_true; -} - -mp_obj_t py_imlib_surf_detector(mp_obj_t image_obj, mp_obj_t upright, mp_obj_t thresh) -{ - struct image *image; - py_surf_obj_t *o =NULL; - - surf_t surf = { - .upright=mp_obj_get_int(upright), - .octaves=5, - .init_sample=2, - .thresh=mp_obj_get_float(thresh), - }; - - /* get image pointer */ - image = (struct image*) py_image_cobj(image_obj); - - /* sanity checks */ - PY_ASSERT_TRUE(sensor.pixformat == PIXFORMAT_GRAYSCALE); - - /* run SURF detector */ - surf_detector(image, &surf); - - o = m_new_obj(py_surf_obj_t); - o->base.type = &py_surf_type; - o->_cobj = surf; - return o; -} - -mp_obj_t py_imlib_surf_match(mp_obj_t image_obj, mp_obj_t surf1_obj, mp_obj_t surf2_obj) -{ - surf_t *surf1 = NULL; - surf_t *surf2 = NULL; - image_t *image = NULL; - - /* get C image pointer */ - image = py_image_cobj(image_obj); - /* get C cascade pointer */ - surf1 = py_surf_cobj(surf1_obj); - surf2 = py_surf_cobj(surf2_obj); - - /* Detect objects */ - array_t *match = surf_match(surf1, surf2); - surf_draw_ipts(image, match); - array_free(match); //TODO - array_free(surf2->ipts); //TODO - return mp_const_none; -} - -mp_obj_t py_imlib_surf_dump_ipts(mp_obj_t surf_obj) -{ - surf_t *surf = NULL; - /* get C cascade pointer */ - surf = py_surf_cobj(surf_obj); - - surf_dump_ipts(surf->ipts); - return mp_const_none; -} - -mp_obj_t py_imlib_surf_draw_ipts(mp_obj_t image_obj, mp_obj_t surf_obj) -{ - surf_t *surf = NULL; - image_t *image = NULL; - - /* get C image pointer */ - image = py_image_cobj(image_obj); - - /* get C cascade pointer */ - surf = py_surf_cobj(surf_obj); - - surf_draw_ipts(image, surf->ipts); - return mp_const_none; -} - -void py_imlib_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) -{ -//print(env, "", self->width, self->height, self->bpp); -} - -mp_obj_t py_imlib_init() -{ - /* Create module */ - mp_obj_t m = mp_obj_new_module(qstr_from_str("imlib")); - - /* Export functions */ - rt_store_attr(m, qstr_from_str("blit"), rt_make_function_n(2, py_imlib_blit)); - rt_store_attr(m, qstr_from_str("load_cascade"), rt_make_function_n(1, py_imlib_load_cascade)); - rt_store_attr(m, qstr_from_str("load_template"), rt_make_function_n(1, py_imlib_load_template)); - rt_store_attr(m, qstr_from_str("save_template"), rt_make_function_n(3, py_imlib_save_template)); - rt_store_attr(m, qstr_from_str("template_match"), rt_make_function_n(3, py_imlib_template_match)); - rt_store_attr(m, qstr_from_str("histeq"), rt_make_function_n(1, py_imlib_histeq)); - rt_store_attr(m, qstr_from_str("median"), rt_make_function_n(2, py_imlib_median)); - rt_store_attr(m, qstr_from_str("draw_rectangle"), rt_make_function_n(2, py_imlib_draw_rectangle)); - rt_store_attr(m, qstr_from_str("draw_circle"), rt_make_function_n(3, py_imlib_draw_circle)); - rt_store_attr(m, qstr_from_str("threshold"), rt_make_function_n(3, py_imlib_threshold)); - rt_store_attr(m, qstr_from_str("count_blobs"), rt_make_function_n(1, py_imlib_count_blobs)); - rt_store_attr(m, qstr_from_str("detect_objects"), rt_make_function_n(2, py_imlib_detect_objects)); - rt_store_attr(m, qstr_from_str("surf_detector"), rt_make_function_n(3, py_imlib_surf_detector)); - rt_store_attr(m, qstr_from_str("surf_match"), rt_make_function_n(3, py_imlib_surf_match)); - rt_store_attr(m, qstr_from_str("surf_draw_ipts"), rt_make_function_n(2, py_imlib_surf_draw_ipts)); - return m; -} - -//MP_DEFINE_CONST_FUN_OBJ_0(image_obj, image); - -#if 0 -typedef struct _mp_obj_array_it_t { - mp_obj_base_t base; - mp_obj_array_t *array; - machine_uint_t cur; -} mp_obj_array_it_t; - -mp_obj_t array_it_iternext(mp_obj_t self_in) { - mp_obj_array_it_t *self = self_in; - if (self->cur < self->array->len) { - machine_int_t val = array_get_el(self->array, self->cur++); - return mp_obj_new_int(val); - } else { - return mp_const_stop_iteration; - } -} - -static const mp_obj_type_t array_it_type = { - { &mp_const_type }, - "array_iterator", - .iternext = array_it_iternext, -}; - -mp_obj_t array_iterator_new(mp_obj_t array_in) { - mp_obj_array_t *array = array_in; - mp_obj_array_it_t *o = m_new_obj(mp_obj_array_it_t); - o->base.type = &array_it_type; - o->array = array; - o->cur = 0; - return o; -} -#endif diff --git a/src/py/py_imlib.h b/src/py/py_imlib.h deleted file mode 100644 index 13367660f..000000000 --- a/src/py/py_imlib.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __PY_IMLIB_H__ -#define __PY_IMLIB_H__ -mp_obj_t py_imlib_init(); -#endif /* __PY_IMLIB_H__ */ - diff --git a/src/py/py_led.c b/src/py/py_led.c index 684ff905f..41d99175e 100644 --- a/src/py/py_led.c +++ b/src/py/py_led.c @@ -1,17 +1,6 @@ #include #include "led.h" #include "py_led.h" - -struct sym_entry { - const char *sym; - int val; -} static constants[] = { - {"RED", LED_RED}, - {"GREEN", LED_GREEN}, - {"BLUE", LED_BLUE}, - {NULL} -}; - static mp_obj_t py_led_on(mp_obj_t led_id) { led_state(mp_obj_get_int(led_id), 1); return mp_const_none; @@ -27,21 +16,37 @@ static mp_obj_t py_led_toggle(mp_obj_t led_id) { return mp_const_none; } -mp_obj_t py_led_init() +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_led_on_obj, py_led_on); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_led_off_obj, py_led_off); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_led_toggle_obj, py_led_toggle); + +STATIC const mp_map_elem_t module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_led) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RED), MP_OBJ_NEW_SMALL_INT(LED_RED)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_GREEN), MP_OBJ_NEW_SMALL_INT(LED_GREEN)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_BLUE), MP_OBJ_NEW_SMALL_INT(LED_BLUE)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&py_led_on_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&py_led_off_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&py_led_toggle_obj }, +}; + +STATIC const mp_map_t module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)module_globals_table, +}; + +static const mp_obj_module_t py_led_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_led, + .globals = (mp_map_t*)&module_globals, +}; + +const mp_obj_module_t *py_led_init() { /* Init LED */ led_init(LED_BLUE); - - /* Create module */ - mp_obj_t m = mp_obj_new_module(qstr_from_str("led")); - rt_store_attr(m, qstr_from_str("on"), rt_make_function_n(1, py_led_on)); - rt_store_attr(m, qstr_from_str("off"), rt_make_function_n(1, py_led_off)); - rt_store_attr(m, qstr_from_str("toggle"), rt_make_function_n(1, py_led_toggle)); - - /* Store module attributes */ - for (struct sym_entry *p = constants; p->sym != NULL; p++) { - rt_store_attr(m, QSTR_FROM_STR_STATIC(p->sym), MP_OBJ_NEW_SMALL_INT((machine_int_t)p->val)); - } - - return m; + return &py_led_module; } diff --git a/src/py/py_led.h b/src/py/py_led.h index 6cc3dc7e4..ef54b108d 100644 --- a/src/py/py_led.h +++ b/src/py/py_led.h @@ -1,4 +1,4 @@ #ifndef __PY_LED_H__ #define __PY_LED_H__ -mp_obj_t py_led_init(); +const mp_obj_module_t *py_led_init(); #endif /* __PY_LED_H__ */ diff --git a/src/py/py_sensor.c b/src/py/py_sensor.c index f24751e4e..a6bf024c4 100644 --- a/src/py/py_sensor.c +++ b/src/py/py_sensor.c @@ -4,52 +4,7 @@ #include "py_sensor.h" #include "py_image.h" -struct sym_entry { - const char *sym; - int val; -}; - -static struct sym_entry pixformat_constants[] = { - {"RGB565", PIXFORMAT_RGB565}, /* 2BPP/RGB565*/ - {"YUV422", PIXFORMAT_YUV422}, /* 2BPP/YUV422*/ - {"GRAYSCALE", PIXFORMAT_GRAYSCALE}, /* 1BPP/GRAYSCALE*/ - {NULL, 0} -}; - -static struct sym_entry framesize_constants[] = { - {"QQCIF", FRAMESIZE_QQCIF}, /* 88x72 */ - {"QQVGA", FRAMESIZE_QQVGA}, /* 160x120 */ - {"QCIF", FRAMESIZE_QCIF}, /* 176x144 */ - {"QVGA", FRAMESIZE_QVGA}, /* 320x240 */ - {"CIF", FRAMESIZE_CIF}, /* 352x288 */ - {"VGA", FRAMESIZE_VGA}, /* 640x480 */ - {"SXGA", FRAMESIZE_SXGA}, /* 1280x1024 */ - {NULL, 0} -}; - -static struct sym_entry framerate_constants[] = { - {"FPS2", FRAMERATE_2FPS }, - {"FPS8", FRAMERATE_8FPS }, - {"FPS15", FRAMERATE_15FPS}, - {"FPS30", FRAMERATE_30FPS}, - {"FPS60", FRAMERATE_60FPS}, - {NULL, 0} -}; - -static struct sym_entry gainceiling_constants[] = { - {"X2", GAINCEILING_2X}, - {"X4", GAINCEILING_4X}, - {"X8", GAINCEILING_8X}, - {"X16", GAINCEILING_16X}, - {"X32", GAINCEILING_32X}, - {"X64", GAINCEILING_64X}, - {"X128", GAINCEILING_128X}, - {NULL, 0} -}; - -mp_obj_t py_sensor_sinit() { - sensor_init(); - /* hack */ +static mp_obj_t py_sensor_reset() { sensor_reset(); sensor_set_pixformat(PIXFORMAT_RGB565); sensor_set_framesize(FRAMESIZE_QQVGA); @@ -59,75 +14,112 @@ mp_obj_t py_sensor_sinit() { return mp_const_none; } -mp_obj_t py_sensor_reset() { - sensor_reset(); - return mp_const_none; -} - -mp_obj_t py_sensor_snapshot() { +static mp_obj_t py_sensor_snapshot() { mp_obj_t image = py_image(0, 0, 0, 0); sensor_snapshot((struct image*) py_image_cobj(image)); return image; } -mp_obj_t py_sensor_set_pixformat(mp_obj_t pixformat) { +static mp_obj_t py_sensor_set_pixformat(mp_obj_t pixformat) { if (sensor_set_pixformat(mp_obj_get_int(pixformat)) != 0) { return mp_const_false; } return mp_const_true; } -mp_obj_t py_sensor_set_framerate(mp_obj_t framerate) { +static mp_obj_t py_sensor_set_framerate(mp_obj_t framerate) { if (sensor_set_framerate(mp_obj_get_int(framerate)) != 0) { return mp_const_false; } return mp_const_true; } -mp_obj_t py_sensor_set_framesize(mp_obj_t framesize) { +static mp_obj_t py_sensor_set_framesize(mp_obj_t framesize) { if (sensor_set_framesize(mp_obj_get_int(framesize)) != 0) { return mp_const_false; } return mp_const_true; } -mp_obj_t py_sensor_set_gainceiling(mp_obj_t gainceiling) { +static mp_obj_t py_sensor_set_gainceiling(mp_obj_t gainceiling) { if (sensor_set_gainceiling(mp_obj_get_int(gainceiling)) != 0) { return mp_const_false; } return mp_const_true; } -mp_obj_t py_sensor_set_brightness(mp_obj_t brightness) { +static mp_obj_t py_sensor_set_brightness(mp_obj_t brightness) { if (sensor_set_brightness(mp_obj_get_int(brightness)) != 0) { return mp_const_false; } return mp_const_true; } -mp_obj_t py_sensor_write_reg(mp_obj_t addr, mp_obj_t val) { +static mp_obj_t py_sensor_write_reg(mp_obj_t addr, mp_obj_t val) { SCCB_Write(mp_obj_get_int(addr), mp_obj_get_int(val)); return mp_const_none; } -mp_obj_t py_sensor_read_reg(mp_obj_t addr) { +static mp_obj_t py_sensor_read_reg(mp_obj_t addr) { return mp_obj_new_int(SCCB_Read(mp_obj_get_int(addr))); } -void py_sensor_print(void (*print)(void *env, const char *fmt, ...), +static void py_sensor_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - //print(env, "", - //sensor.id.MIDH, sensor.id.MIDL, sensor.id.PID, sensor.id.VER); +// printf(env, "", + // sensor.id.MIDH, sensor.id.MIDL, sensor.id.PID, sensor.id.VER); } -static void rt_store_constants(mp_obj_t m, struct sym_entry *constants) -{ - for (struct sym_entry *p = constants; p->sym != NULL; p++) { - rt_store_attr(m, QSTR_FROM_STR_STATIC(p->sym), MP_OBJ_NEW_SMALL_INT((machine_int_t)p->val)); - } -} +STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_reset_obj, py_sensor_reset); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_sensor_snapshot_obj, py_sensor_snapshot); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_pixformat_obj, py_sensor_set_pixformat); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_framerate_obj, py_sensor_set_framerate); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_gainceiling_obj, py_sensor_set_gainceiling); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_brightness_obj, py_sensor_set_brightness); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(py_sensor_write_reg_obj, py_sensor_write_reg); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_read_reg_obj, py_sensor_read_reg); -mp_obj_t py_sensor_init() +STATIC const mp_map_elem_t module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sensor) }, + /* Pixel format */ + { MP_OBJ_NEW_QSTR(MP_QSTR_RGB565), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_RGB565)}, /* 2BPP/RGB565*/ + { MP_OBJ_NEW_QSTR(MP_QSTR_YUV422), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_YUV422)}, /* 2BPP/YUV422*/ + { MP_OBJ_NEW_QSTR(MP_QSTR_GRAYSCALE), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_GRAYSCALE)},/* 1BPP/GRAYSCALE*/ +// { MP_OBJ_NEW_QSTR(MP_QSTR_JPEG), MP_OBJ_NEW_SMALL_INT(PIXFORMAT_JPEG)}, /* JPEG/COMPRESSED*/ + /* Frame size */ + { MP_OBJ_NEW_QSTR(MP_QSTR_QQCIF), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_QQCIF)}, /* 88x72 */ + { MP_OBJ_NEW_QSTR(MP_QSTR_QQVGA), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_QQVGA)}, /* 160x120 */ + { MP_OBJ_NEW_QSTR(MP_QSTR_QCIF), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_QCIF)}, /* 176x144 */ + { MP_OBJ_NEW_QSTR(MP_QSTR_QVGA), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_QVGA)}, /* 320x240 */ + { MP_OBJ_NEW_QSTR(MP_QSTR_CIF), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_CIF)}, /* 352x288 */ + { MP_OBJ_NEW_QSTR(MP_QSTR_VGA), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_VGA)}, /* 640x480 */ + { MP_OBJ_NEW_QSTR(MP_QSTR_SXGA), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_SXGA)}, /* 1280x1024 */ + + /* Sensor functions */ + { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&py_sensor_reset_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_snapshot), (mp_obj_t)&py_sensor_snapshot_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_set_pixformat), (mp_obj_t)&py_sensor_set_pixformat_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_set_framerate), (mp_obj_t)&py_sensor_set_framerate_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_set_gainceiling), (mp_obj_t)&py_sensor_set_gainceiling_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR___write_reg), (mp_obj_t)&py_sensor_write_reg_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR___read_reg), (mp_obj_t)&py_sensor_read_reg_obj }, +}; + +STATIC const mp_map_t module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)module_globals_table, +}; + +static const mp_obj_module_t py_sensor_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_sensor, + .globals = (mp_map_t*)&module_globals, +}; + +const mp_obj_module_t *py_sensor_init() { /* Init sensor */ if (sensor_init() != 0) { @@ -144,25 +136,5 @@ mp_obj_t py_sensor_init() sensor_set_gainceiling(GAINCEILING_8X); sensor_set_brightness(-2); - /* Create module */ - mp_obj_t m = mp_obj_new_module(qstr_from_str("sensor")); - - /* Store module functions */ - rt_store_attr(m, qstr_from_str("init"), rt_make_function_n(0, py_sensor_sinit)); - rt_store_attr(m, qstr_from_str("reset"), rt_make_function_n(0, py_sensor_reset)); - rt_store_attr(m, qstr_from_str("snapshot"), rt_make_function_n(0, py_sensor_snapshot)); - rt_store_attr(m, qstr_from_str("set_pixformat"), rt_make_function_n(1, py_sensor_set_pixformat)); - rt_store_attr(m, qstr_from_str("set_framerate"), rt_make_function_n(1, py_sensor_set_framerate)); - rt_store_attr(m, qstr_from_str("set_framesize"), rt_make_function_n(1, py_sensor_set_framesize)); - rt_store_attr(m, qstr_from_str("set_gainceiling"), rt_make_function_n(1, py_sensor_set_gainceiling)); - rt_store_attr(m, qstr_from_str("set_brightness"), rt_make_function_n(1, py_sensor_set_brightness)); - rt_store_attr(m, qstr_from_str("__write_reg"), rt_make_function_n(2, py_sensor_write_reg)); - rt_store_attr(m, qstr_from_str("__read_reg"), rt_make_function_n(1, py_sensor_read_reg)); - - /* Store module constants */ - rt_store_constants(m, pixformat_constants); - rt_store_constants(m, framesize_constants); - rt_store_constants(m, framerate_constants); - rt_store_constants(m, gainceiling_constants); - return m; + return &py_sensor_module; } diff --git a/src/py/py_sensor.h b/src/py/py_sensor.h index bc7438339..b99153730 100644 --- a/src/py/py_sensor.h +++ b/src/py/py_sensor.h @@ -1,4 +1,4 @@ #ifndef __PY_SENSOR_H__ #define __PY_SENSOR_H__ -mp_obj_t py_sensor_init(); +const mp_obj_module_t *py_sensor_init(); #endif /* __PY_SENSOR_H__ */ diff --git a/src/py/py_spi.c b/src/py/py_spi.c index 182c2d226..e0e39145d 100644 --- a/src/py/py_spi.c +++ b/src/py/py_spi.c @@ -5,18 +5,18 @@ #include "imlib.h" #include "py_image.h" -mp_obj_t py_spi_read() +static mp_obj_t py_spi_read() { return mp_obj_new_int(spi_read()); } -mp_obj_t py_spi_write(mp_obj_t c) +static mp_obj_t py_spi_write(mp_obj_t c) { spi_write(mp_obj_get_int(c)); return mp_const_true; } -mp_obj_t py_spi_write_image(mp_obj_t image_obj) +static mp_obj_t py_spi_write_image(mp_obj_t image_obj) { struct image *image; /* get image pointer */ @@ -33,16 +33,34 @@ mp_obj_t py_spi_write_image(mp_obj_t image_obj) return mp_const_none; } -mp_obj_t py_spi_init() +STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_spi_read_obj, py_spi_read); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_spi_write_obj, py_spi_write); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_spi_write_image_obj, py_spi_write_image); + +STATIC const mp_map_elem_t module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_spi) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_read), (mp_obj_t)&py_spi_read_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&py_spi_write_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_write_image), (mp_obj_t)&py_spi_write_image_obj }, +}; + +STATIC const mp_map_t module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)module_globals_table, +}; + +static const mp_obj_module_t py_spi_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_spi, + .globals = (mp_map_t*)&module_globals, +}; + +const mp_obj_module_t *py_spi_init() { + /* Init spi */ spi_init(); - - /* Create module */ - mp_obj_t m = mp_obj_new_module(qstr_from_str("spi")); - - /* Export functions */ - rt_store_attr(m, qstr_from_str("read"), rt_make_function_n(0, py_spi_read)); - rt_store_attr(m, qstr_from_str("write"), rt_make_function_n(1, py_spi_write)); - rt_store_attr(m, qstr_from_str("write_image"), rt_make_function_n(1, py_spi_write_image)); - return m; + return &py_spi_module; } diff --git a/src/py/py_spi.h b/src/py/py_spi.h index 13b75e522..00afe1370 100644 --- a/src/py/py_spi.h +++ b/src/py/py_spi.h @@ -1,5 +1,5 @@ #ifndef __PY_SPI_H__ #define __PY_SPI_H__ -mp_obj_t py_spi_init(); +const mp_obj_module_t *py_spi_init(); #endif /* __PY_SPI_H__ */ diff --git a/src/py/py_time.c b/src/py/py_time.c index d22137a51..c8c5263a5 100644 --- a/src/py/py_time.c +++ b/src/py/py_time.c @@ -3,30 +3,48 @@ #include "py_time.h" #include "py_clock.h" -mp_obj_t py_time_ticks() +static mp_obj_t py_time_ticks() { return mp_obj_new_int(systick_current_millis()); } -mp_obj_t py_time_clock() +static mp_obj_t py_time_clock() { return py_clock(); } -mp_obj_t py_time_sleep(mp_obj_t ms) +static mp_obj_t py_time_sleep(mp_obj_t ms) { systick_sleep(mp_obj_get_int(ms)); return mp_const_none; } -mp_obj_t py_time_init() -{ - /* Create module */ - mp_obj_t m = mp_obj_new_module(qstr_from_str("time")); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_time_ticks_obj, py_time_ticks); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_time_clock_obj, py_time_clock); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_time_sleep_obj, py_time_sleep); - /* Store module functions */ - rt_store_attr(m, qstr_from_str("clock"), rt_make_function_n(0, py_time_clock)); - rt_store_attr(m, qstr_from_str("ticks"), rt_make_function_n(0, py_time_ticks)); - rt_store_attr(m, qstr_from_str("sleep"), rt_make_function_n(1, py_time_sleep)); - return m; +STATIC const mp_map_elem_t module_globals_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_time) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ticks), (mp_obj_t)&py_time_ticks_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_clock), (mp_obj_t)&py_time_clock_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&py_time_sleep_obj }, +}; + +STATIC const mp_map_t module_globals = { + .all_keys_are_qstrs = 1, + .table_is_fixed_array = 1, + .used = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .alloc = sizeof(module_globals_table) / sizeof(mp_map_elem_t), + .table = (mp_map_elem_t*)module_globals_table, +}; + +static const mp_obj_module_t py_time_module = { + .base = { &mp_type_module }, + .name = MP_QSTR_time, + .globals = (mp_map_t*)&module_globals, +}; + +const mp_obj_module_t *py_time_init() +{ + return &py_time_module; } diff --git a/src/py/py_time.h b/src/py/py_time.h index e88eef573..a6b97c57a 100644 --- a/src/py/py_time.h +++ b/src/py/py_time.h @@ -1,4 +1,4 @@ #ifndef __PY_TIME_H__ #define __PY_TIME_H__ -mp_obj_t py_time_init(); +const mp_obj_module_t *py_time_init(); #endif /* __PY_TIME_H__ */