mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Implement Himax motion detection with ioctls.
This commit is contained in:
parent
935b58d0ae
commit
d36cfb2313
@ -126,7 +126,11 @@ typedef enum {
|
||||
IOCTL_LEPTON_SET_MEASUREMENT_MODE,
|
||||
IOCTL_LEPTON_GET_MEASUREMENT_MODE,
|
||||
IOCTL_LEPTON_SET_MEASUREMENT_RANGE,
|
||||
IOCTL_LEPTON_GET_MEASUREMENT_RANGE
|
||||
IOCTL_LEPTON_GET_MEASUREMENT_RANGE,
|
||||
IOCTL_HIMAX_MD_ENABLE,
|
||||
IOCTL_HIMAX_MD_CLEAR,
|
||||
IOCTL_HIMAX_MD_WINDOW,
|
||||
IOCTL_HIMAX_MD_THRESHOLD,
|
||||
} ioctl_t;
|
||||
|
||||
#define SENSOR_HW_FLAGS_VSYNC (0) // vertical sync polarity.
|
||||
|
||||
@ -759,6 +759,63 @@ static mp_obj_t py_sensor_ioctl(uint n_args, const mp_obj_t *args)
|
||||
break;
|
||||
}
|
||||
|
||||
#if (OMV_ENABLE_HM01B0 == 1)
|
||||
case IOCTL_HIMAX_MD_ENABLE: {
|
||||
if (n_args < 2 || sensor_ioctl(request, mp_obj_get_int(args[1])) != 0) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Sensor control failed!"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_WINDOW: {
|
||||
if (n_args < 2) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Sensor control failed!"));
|
||||
}
|
||||
|
||||
int x, y, w, h;
|
||||
|
||||
mp_obj_t *array;
|
||||
mp_uint_t array_len;
|
||||
mp_obj_get_array(args[1], &array_len, &array);
|
||||
|
||||
if (array_len == 4) {
|
||||
x = mp_obj_get_int(array[0]);
|
||||
y = mp_obj_get_int(array[1]);
|
||||
w = mp_obj_get_int(array[2]);
|
||||
h = mp_obj_get_int(array[3]);
|
||||
} else if (array_len == 2) {
|
||||
w = mp_obj_get_int(array[0]);
|
||||
h = mp_obj_get_int(array[1]);
|
||||
x = 0;
|
||||
y = 0;
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError,
|
||||
MP_ERROR_TEXT("The tuple/list must either be (x, y, w, h) or (w, h)"));
|
||||
}
|
||||
|
||||
if (sensor_ioctl(request, x, y, w, h) != 0) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Sensor control failed!"));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_THRESHOLD: {
|
||||
if (n_args < 2 || sensor_ioctl(request, mp_obj_get_int(args[1])) != 0) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Sensor control failed!"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_CLEAR: {
|
||||
if (sensor_ioctl(request) != 0) {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Sensor control failed!"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#endif // (OMV_ENABLE_HM01B0 == 1)
|
||||
|
||||
default: {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported!"));
|
||||
break;
|
||||
@ -945,7 +1002,12 @@ STATIC const mp_map_elem_t globals_dict_table[] = {
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_LEPTON_GET_MEASUREMENT_MODE), MP_OBJ_NEW_SMALL_INT(IOCTL_LEPTON_GET_MEASUREMENT_MODE)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_LEPTON_SET_MEASUREMENT_RANGE), MP_OBJ_NEW_SMALL_INT(IOCTL_LEPTON_SET_MEASUREMENT_RANGE)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_LEPTON_GET_MEASUREMENT_RANGE), MP_OBJ_NEW_SMALL_INT(IOCTL_LEPTON_GET_MEASUREMENT_RANGE)},
|
||||
|
||||
#if (OMV_ENABLE_HM01B0 == 1)
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_HIMAX_MD_ENABLE), MP_OBJ_NEW_SMALL_INT(IOCTL_HIMAX_MD_ENABLE)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_HIMAX_MD_WINDOW), MP_OBJ_NEW_SMALL_INT(IOCTL_HIMAX_MD_WINDOW)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_HIMAX_MD_THRESHOLD), MP_OBJ_NEW_SMALL_INT(IOCTL_HIMAX_MD_THRESHOLD)},
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_HIMAX_MD_CLEAR), MP_OBJ_NEW_SMALL_INT(IOCTL_HIMAX_MD_CLEAR)},
|
||||
#endif
|
||||
// Sensor functions
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___init__), (mp_obj_t)&py_sensor__init__obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&py_sensor_reset_obj },
|
||||
|
||||
@ -60,7 +60,7 @@ static const uint16_t default_regs[][2] = {
|
||||
{SINGLE_THR_HOT, 0x90}, // single hot pixel th
|
||||
{SINGLE_THR_COLD, 0x40}, // single cold pixel th
|
||||
{0x1012, 0x00}, // Sync. shift disable
|
||||
{0x2000, 0x07},
|
||||
{STATISTIC_CTRL, 0x07}, // AE stat en | MD LROI stat en | magic
|
||||
{0x2003, 0x00},
|
||||
{0x2004, 0x1C},
|
||||
{0x2007, 0x00},
|
||||
@ -99,7 +99,7 @@ static const uint16_t default_regs[][2] = {
|
||||
{FS_50HZ_H, 0x00},
|
||||
{FS_50HZ_L, 0x32},
|
||||
|
||||
{MD_CTRL, 0x30},
|
||||
{MD_CTRL, 0x00},
|
||||
{FRAME_LEN_LINES_H, HIMAX_FRAME_LENGTH_QVGA>>8},
|
||||
{FRAME_LEN_LINES_L, HIMAX_FRAME_LENGTH_QVGA&0xFF},
|
||||
{LINE_LEN_PCK_H, HIMAX_LINE_LEN_PCK_QVGA>>8},
|
||||
@ -394,6 +394,53 @@ static int set_vflip(sensor_t *sensor, int enable)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ioctl(sensor_t *sensor, int request, va_list ap)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (request) {
|
||||
case IOCTL_HIMAX_MD_ENABLE: {
|
||||
uint32_t enable = va_arg(ap, uint32_t);
|
||||
ret = cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_CTRL, enable ? 1:0);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_WINDOW: {
|
||||
uint32_t x1 = va_arg(ap, uint32_t);
|
||||
uint32_t y1 = va_arg(ap, uint32_t);
|
||||
uint32_t x2 = va_arg(ap, uint32_t) + x1;
|
||||
uint32_t y2 = va_arg(ap, uint32_t) + y1;
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_X_START_H, (x1>>8));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_X_START_L, (x1&0xff));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_Y_START_H, (y1>>8));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_Y_START_L, (y1&0xff));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_X_END_H, (x2>>8));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_X_END_L, (x2&0xff));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_Y_END_H, (y2>>8));
|
||||
ret |= cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_LROI_Y_END_L, (y2&0xff));
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_THRESHOLD: {
|
||||
uint32_t threshold = va_arg(ap, uint32_t);
|
||||
ret = cambus_writeb2(&sensor->bus, sensor->slv_addr, MD_THL, threshold);
|
||||
break;
|
||||
}
|
||||
|
||||
case IOCTL_HIMAX_MD_CLEAR: {
|
||||
ret = cambus_writeb2(&sensor->bus, sensor->slv_addr, I2C_CLEAR, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int hm01b0_init(sensor_t *sensor)
|
||||
{
|
||||
// Initialize sensor structure.
|
||||
@ -419,6 +466,7 @@ int hm01b0_init(sensor_t *sensor)
|
||||
sensor->get_rgb_gain_db = get_rgb_gain_db;
|
||||
sensor->set_hmirror = set_hmirror;
|
||||
sensor->set_vflip = set_vflip;
|
||||
sensor->ioctl = ioctl;
|
||||
|
||||
// Set sensor flags
|
||||
SENSOR_HW_FLAGS_SET(sensor, SENSOR_HW_FLAGS_VSYNC, 0);
|
||||
|
||||
@ -80,6 +80,16 @@
|
||||
#define MD_THM1 0x2159
|
||||
#define MD_THM2 0x215A
|
||||
#define MD_THL 0x215B
|
||||
#define STATISTIC_CTRL 0x2000
|
||||
#define MD_LROI_X_START_H 0x2011
|
||||
#define MD_LROI_X_START_L 0x2012
|
||||
#define MD_LROI_Y_START_H 0x2013
|
||||
#define MD_LROI_Y_START_L 0x2014
|
||||
#define MD_LROI_X_END_H 0x2015
|
||||
#define MD_LROI_X_END_L 0x2016
|
||||
#define MD_LROI_Y_END_H 0x2017
|
||||
#define MD_LROI_Y_END_L 0x2018
|
||||
#define MD_INTERRUPT 0x2160
|
||||
// Sensor timing control
|
||||
#define QVGA_WIN_EN 0x3010
|
||||
#define SIX_BIT_MODE_EN 0x3011
|
||||
|
||||
Loading…
Reference in New Issue
Block a user