mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Convert all MP modules to static modules
This commit is contained in:
parent
5bfc56d33a
commit
b23eeda8e5
22
src/main.c
22
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();
|
||||
|
||||
@ -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, "<gpio>");
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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__ */
|
||||
|
||||
|
||||
@ -1,30 +1,469 @@
|
||||
#include <libmp.h>
|
||||
#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, "<image width:%d height:%d bpp:%d>", 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; j<array_length(blobs); j++) {
|
||||
rectangle_t *b = array_at(blobs, j);
|
||||
mp_obj_t r[4];
|
||||
r[0] = mp_obj_new_int(b->x);
|
||||
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; i<array_length(objects_array); i++) {
|
||||
struct rectangle *r = array_at(objects_array, 0);
|
||||
mp_obj_t rec_obj[4];
|
||||
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);
|
||||
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
|
||||
|
||||
@ -1,481 +0,0 @@
|
||||
#include <libmp.h>
|
||||
#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; j<array_length(blobs); j++) {
|
||||
rectangle_t *b = array_at(blobs, j);
|
||||
mp_obj_t r[4];
|
||||
r[0] = mp_obj_new_int(b->x);
|
||||
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; i<array_length(objects_array); i++) {
|
||||
struct rectangle *r = array_at(objects_array, 0);
|
||||
mp_obj_t rec_obj[4];
|
||||
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);
|
||||
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, "<image width:%d height:%d bpp:%d>", 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
|
||||
@ -1,5 +0,0 @@
|
||||
#ifndef __PY_IMLIB_H__
|
||||
#define __PY_IMLIB_H__
|
||||
mp_obj_t py_imlib_init();
|
||||
#endif /* __PY_IMLIB_H__ */
|
||||
|
||||
@ -1,17 +1,6 @@
|
||||
#include <libmp.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@ -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__ */
|
||||
|
||||
@ -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 MID:0x%.2X%.2X PID:0x%.2X VER:0x%.2X>",
|
||||
//sensor.id.MIDH, sensor.id.MIDL, sensor.id.PID, sensor.id.VER);
|
||||
// printf(env, "<Sensor MID:0x%.2X%.2X PID:0x%.2X VER:0x%.2X>",
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -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__ */
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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__ */
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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__ */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user