From 54e431adb25ce4d0e6c0bd7d93dd751df224232f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Mon, 4 Mar 2019 20:55:17 +0200 Subject: [PATCH] Implement MT triggered mode using ioctls --- .../28-Global-Shutter/triggered_mode.py | 2 +- src/omv/mt9v034.c | 43 +++++++++++------- src/omv/py/py_sensor.c | 45 ++++++++++++------- src/omv/py/qstrdefsomv.h | 6 ++- src/omv/sensor.c | 20 --------- src/omv/sensor.h | 13 +++--- 6 files changed, 66 insertions(+), 63 deletions(-) diff --git a/scripts/examples/28-Global-Shutter/triggered_mode.py b/scripts/examples/28-Global-Shutter/triggered_mode.py index cbbec8ac7..08e78c916 100644 --- a/scripts/examples/28-Global-Shutter/triggered_mode.py +++ b/scripts/examples/28-Global-Shutter/triggered_mode.py @@ -20,7 +20,7 @@ sensor.set_framesize(sensor.VGA) # Set frame size to VGA (640x480) sensor.skip_frames(time = 2000) # Wait for settings take effect. clock = time.clock() # Create a clock object to track the FPS. -sensor.mt9v034_set_triggered_mode(True) +sensor.ioctl(sensor.IOCTL_SET_TRIGGERED_MODE, True) while(True): clock.tick() # Update the FPS clock. diff --git a/src/omv/mt9v034.c b/src/omv/mt9v034.c index ec368e833..a0ff0681d 100644 --- a/src/omv/mt9v034.c +++ b/src/omv/mt9v034.c @@ -385,22 +385,36 @@ static int set_lens_correction(sensor_t *sensor, int enable, int radi, int coef) return 0; } -int mt9v034_set_triggered_mode(sensor_t *sensor, int enable) +static int ioctl(sensor_t *sensor, int request, va_list ap) { + int ret = 0; uint16_t chip_control; - int ret = cambus_readw(sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control); - ret |= cambus_writew(sensor->slv_addr, MT9V034_CHIP_CONTROL, - (chip_control & (~MT9V034_CHIP_CONTROL_MODE_MASK)) - | ((enable != 0) ? MT9V034_CHIP_CONTROL_SNAP_MODE : MT9V034_CHIP_CONTROL_MASTER_MODE)); - ret |= sensor->snapshot(sensor, NULL, NULL); // Force shadow mode register to update... - return ret; -} -int mt9v034_get_triggered_mode(sensor_t *sensor) -{ - uint16_t chip_control; - int ret = cambus_readw(sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control); - return (ret >= 0) ? ((chip_control & MT9V034_CHIP_CONTROL_MODE_MASK) == MT9V034_CHIP_CONTROL_SNAP_MODE) : -1; + switch (request) { + case IOCTL_SET_TRIGGERED_MODE: { + int enable = va_arg(ap, int); + ret = cambus_readw(sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control); + ret |= cambus_writew(sensor->slv_addr, MT9V034_CHIP_CONTROL, + (chip_control & (~MT9V034_CHIP_CONTROL_MODE_MASK)) + | ((enable != 0) ? MT9V034_CHIP_CONTROL_SNAP_MODE : MT9V034_CHIP_CONTROL_MASTER_MODE)); + ret |= sensor->snapshot(sensor, NULL, NULL); // Force shadow mode register to update... + break; + } + case IOCTL_GET_TRIGGERED_MODE: { + int *enable = va_arg(ap, int *); + ret = cambus_readw(sensor->slv_addr, MT9V034_CHIP_CONTROL, &chip_control); + if (ret >= 0) { + *enable = ((chip_control & MT9V034_CHIP_CONTROL_MODE_MASK) == MT9V034_CHIP_CONTROL_SNAP_MODE); + } + break; + } + default: { + ret = -1; + break; + } + } + + return ret; } int mt9v034_init(sensor_t *sensor) @@ -429,8 +443,7 @@ int mt9v034_init(sensor_t *sensor) sensor->set_vflip = set_vflip; sensor->set_special_effect = set_special_effect; sensor->set_lens_correction = set_lens_correction; - sensor->mt9v034_set_triggered_mode = mt9v034_set_triggered_mode; - sensor->mt9v034_get_triggered_mode = mt9v034_get_triggered_mode; + sensor->ioctl = ioctl; SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_VSYNC, 0); SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_HSYNC, 0); diff --git a/src/omv/py/py_sensor.c b/src/omv/py/py_sensor.c index c85561989..6f7b942d4 100644 --- a/src/omv/py/py_sensor.c +++ b/src/omv/py/py_sensor.c @@ -409,7 +409,30 @@ static mp_obj_t py_sensor_set_vsync_output(mp_obj_t pin_obj) { static mp_obj_t py_sensor_ioctl(uint n_args, const mp_obj_t *args) { - return mp_obj_new_int(-1); + mp_obj_t ret_obj = mp_const_true; + int request = mp_obj_get_int(args[0]); + + switch (request) { + case IOCTL_SET_TRIGGERED_MODE: + if (n_args < 2 || sensor_ioctl(request, mp_obj_get_int(args[1])) != 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!")); + } + break; + + case IOCTL_GET_TRIGGERED_MODE: { + int enabled; + if (sensor_ioctl(request, &enabled) != 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!")); + } + ret_obj = mp_obj_new_bool(enabled); + break; + } + + default: + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Operation not supported!")); + break; + } + return ret_obj; } static mp_obj_t py_sensor_write_reg(mp_obj_t addr, mp_obj_t val) { @@ -421,18 +444,6 @@ static mp_obj_t py_sensor_read_reg(mp_obj_t addr) { return mp_obj_new_int(sensor_read_reg(mp_obj_get_int(addr))); } -static mp_obj_t py_mt9v034_set_triggered_mode(mp_obj_t enable) { - int temp = sensor_mt9v034_set_triggered_mode(mp_obj_get_int(enable)); - if (temp < 0) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!")); - return mp_const_none; -} - -static mp_obj_t py_mt9v034_get_triggered_mode() { - int temp = sensor_mt9v034_get_triggered_mode(); - if (temp < 0) nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sensor control failed!")); - return mp_obj_new_bool(temp); -} - //static void py_sensor_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { // mp_printf(print, "", // sensor.id.MIDH, sensor.id.MIDL, sensor.id.PID, sensor.id.VER); @@ -474,8 +485,6 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_sensor_set_vsync_output_obj, py_sensor_se 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); STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(py_sensor_ioctl_obj, 1, 5, py_sensor_ioctl); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_mt9v034_set_triggered_mode_obj, py_mt9v034_set_triggered_mode); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_mt9v034_get_triggered_mode_obj, py_mt9v034_get_triggered_mode); STATIC const mp_map_elem_t globals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_sensor) }, @@ -525,6 +534,10 @@ STATIC const mp_map_elem_t globals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_SXGA), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_SXGA)}, /* 1280x1024 */ { MP_OBJ_NEW_QSTR(MP_QSTR_UXGA), MP_OBJ_NEW_SMALL_INT(FRAMESIZE_UXGA)}, /* 1600x1200 */ + // IOCTLs + { MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_SET_TRIGGERED_MODE), MP_OBJ_NEW_SMALL_INT(IOCTL_SET_TRIGGERED_MODE)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_GET_TRIGGERED_MODE), MP_OBJ_NEW_SMALL_INT(IOCTL_GET_TRIGGERED_MODE)}, + // Sensor functions { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&py_sensor_reset_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_sleep), (mp_obj_t)&py_sensor_sleep_obj }, @@ -562,8 +575,6 @@ STATIC const mp_map_elem_t globals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_ioctl), (mp_obj_t)&py_sensor_ioctl_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 }, - { MP_OBJ_NEW_QSTR(MP_QSTR_mt9v034_set_triggered_mode), (mp_obj_t)&py_mt9v034_set_triggered_mode_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_mt9v034_get_triggered_mode), (mp_obj_t)&py_mt9v034_get_triggered_mode_obj }, }; STATIC MP_DEFINE_CONST_DICT(globals_dict, globals_dict_table); diff --git a/src/omv/py/qstrdefsomv.h b/src/omv/py/qstrdefsomv.h index 766fbae84..301b28c8e 100644 --- a/src/omv/py/qstrdefsomv.h +++ b/src/omv/py/qstrdefsomv.h @@ -201,6 +201,10 @@ Q(UXGA) Q(NORMAL) Q(NEGATIVE) +//IOCTLs +Q(IOCTL_SET_TRIGGERED_MODE) +Q(IOCTL_GET_TRIGGERED_MODE) + Q(reset) Q(flush) Q(snapshot) @@ -238,8 +242,6 @@ Q(set_lens_correction) Q(ioctl) Q(__write_reg) Q(__read_reg) -Q(mt9v034_set_triggered_mode) -Q(mt9v034_get_triggered_mode) // GPIOS Q(P1) diff --git a/src/omv/sensor.c b/src/omv/sensor.c index b2a3262b9..b08b9d2f9 100644 --- a/src/omv/sensor.c +++ b/src/omv/sensor.c @@ -1001,23 +1001,3 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_c return 0; } - -int sensor_mt9v034_set_triggered_mode(int enable) -{ - /* call the sensor specific function */ - if (sensor.mt9v034_set_triggered_mode == NULL) { - /* operation not supported */ - return -1; - } - return sensor.mt9v034_set_triggered_mode(&sensor, enable); -} - -int sensor_mt9v034_get_triggered_mode() -{ - /* call the sensor specific function */ - if (sensor.mt9v034_get_triggered_mode == NULL) { - /* operation not supported */ - return -1; - } - return sensor.mt9v034_get_triggered_mode(&sensor); -} diff --git a/src/omv/sensor.h b/src/omv/sensor.h index 952c8c545..ca207df50 100644 --- a/src/omv/sensor.h +++ b/src/omv/sensor.h @@ -96,6 +96,11 @@ typedef enum { ACTIVE_HIGH } polarity_t; +typedef enum { + IOCTL_SET_TRIGGERED_MODE, + IOCTL_GET_TRIGGERED_MODE, +} ioctl_t; + #define SENSOR_HW_FLAGS_VSYNC (0) // vertical sync polarity. #define SENSOR_HW_FLAGS_HSYNC (1) // horizontal sync polarity. #define SENSOR_HW_FLAGS_PIXCK (2) // pixel clock edge. @@ -153,8 +158,6 @@ typedef struct _sensor { int (*set_lens_correction) (sensor_t *sensor, int enable, int radi, int coef); int (*ioctl) (sensor_t *sensor, int request, va_list ap); int (*snapshot) (sensor_t *sensor, image_t *image, streaming_cb_t streaming_cb); - int (*mt9v034_set_triggered_mode) (sensor_t *sensor, int enable); - int (*mt9v034_get_triggered_mode) (sensor_t *sensor); } sensor_t; // Resolution table @@ -253,10 +256,4 @@ int sensor_set_vsync_output(GPIO_TypeDef *gpio, uint32_t pin); // Default snapshot function. int sensor_snapshot(sensor_t *sensor, image_t *image, streaming_cb_t streaming_cb); - -// MT9V034 Set Triggered Mode register -int sensor_mt9v034_set_triggered_mode(int enable); - -// MT9V034 Get Triggered Mode register -int sensor_mt9v034_get_triggered_mode(); #endif /* __SENSOR_H__ */