diff --git a/scripts/examples/Arduino/Portenta-H7/19-Low-Power/himax_wakeup_on_motion_detection.py b/scripts/examples/Arduino/Portenta-H7/19-Low-Power/himax_wakeup_on_motion_detection.py new file mode 100644 index 000000000..9aa5f504e --- /dev/null +++ b/scripts/examples/Arduino/Portenta-H7/19-Low-Power/himax_wakeup_on_motion_detection.py @@ -0,0 +1,31 @@ +# This examples shows how to use the Himax Motion Detection feature +# to wake up from low-power Stop Mode on motion detection interrupts. + +import sensor, image, time, pyb, machine +from pyb import Pin, ExtInt + +sensor.reset() +sensor.set_pixformat(sensor.GRAYSCALE) +sensor.set_framesize(sensor.QVGA) +sensor.set_framerate(15) + +sensor.ioctl(sensor.IOCTL_HIMAX_MD_THRESHOLD, 10) +sensor.ioctl(sensor.IOCTL_HIMAX_MD_WINDOW, (0, 0, 320, 240)) +sensor.ioctl(sensor.IOCTL_HIMAX_MD_CLEAR) +sensor.ioctl(sensor.IOCTL_HIMAX_MD_ENABLE, True) + +def on_motion(line): + pass + +led = pyb.LED(3) +ext = ExtInt(Pin("PC15"), ExtInt.IRQ_RISING, Pin.PULL_DOWN, on_motion) + +while(True): + led.off() + sensor.ioctl(sensor.IOCTL_HIMAX_OSC_ENABLE, True) # Switch to internal OSC + sensor.ioctl(sensor.IOCTL_HIMAX_MD_CLEAR) # Clear MD flag + machine.sleep() # Enter low-power mode, will wake up on MD interrupt. + sensor.ioctl(sensor.IOCTL_HIMAX_OSC_ENABLE, False) # Switch back to MCLK + led.on() + for i in range(0, 60): # Capture a few frames + img = sensor.snapshot() diff --git a/src/micropython b/src/micropython index 7e9eeadd0..88661daa7 160000 --- a/src/micropython +++ b/src/micropython @@ -1 +1 @@ -Subproject commit 7e9eeadd0a64f9f69f3447d0c090349595e3071f +Subproject commit 88661daa71e2c975aeb64bd758a834ba86371cc0 diff --git a/src/omv/common/sensor.h b/src/omv/common/sensor.h index 37e2948a6..f1fade0a8 100644 --- a/src/omv/common/sensor.h +++ b/src/omv/common/sensor.h @@ -131,6 +131,7 @@ typedef enum { IOCTL_HIMAX_MD_CLEAR, IOCTL_HIMAX_MD_WINDOW, IOCTL_HIMAX_MD_THRESHOLD, + IOCTL_HIMAX_OSC_ENABLE, } ioctl_t; #define SENSOR_HW_FLAGS_VSYNC (0) // vertical sync polarity. diff --git a/src/omv/modules/py_sensor.c b/src/omv/modules/py_sensor.c index 47faa4f1d..6f5957533 100644 --- a/src/omv/modules/py_sensor.c +++ b/src/omv/modules/py_sensor.c @@ -814,6 +814,13 @@ static mp_obj_t py_sensor_ioctl(uint n_args, const mp_obj_t *args) break; } + case IOCTL_HIMAX_OSC_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; + } + #endif // (OMV_ENABLE_HM01B0 == 1) default: { @@ -1007,6 +1014,7 @@ STATIC const mp_map_elem_t globals_dict_table[] = { { 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)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_IOCTL_HIMAX_OSC_ENABLE), MP_OBJ_NEW_SMALL_INT(IOCTL_HIMAX_OSC_ENABLE)}, #endif // Sensor functions { MP_OBJ_NEW_QSTR(MP_QSTR___init__), (mp_obj_t)&py_sensor__init__obj }, diff --git a/src/omv/sensors/hm01b0.c b/src/omv/sensors/hm01b0.c index ec92372a0..b58b0e9d9 100644 --- a/src/omv/sensors/hm01b0.c +++ b/src/omv/sensors/hm01b0.c @@ -45,6 +45,7 @@ static const uint16_t default_regs[][2] = { {0x3059, 0x1E}, {0x3064, 0x00}, {0x3065, 0x04}, // pad pull 0 + {ANA_Register_17, 0x00}, // Disable internal oscillator {BLC_CFG, 0x43}, // BLC_on, IIR @@ -399,6 +400,13 @@ static int ioctl(sensor_t *sensor, int request, va_list ap) int ret = 0; switch (request) { + case IOCTL_HIMAX_OSC_ENABLE: { + uint32_t enable = va_arg(ap, uint32_t); + ret = cambus_writeb2(&sensor->bus, sensor->slv_addr, ANA_Register_17, enable ? 1:0); + mp_hal_delay_ms(100); + break; + } + 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);