Kwabena/flir lepton updates (#1150)

* Add timeout support for grabbing a new frame
* Fix ffc with a timeout
This commit is contained in:
Kwabena W. Agyeman 2021-02-02 11:20:01 -08:00 committed by GitHub
parent 10f9600008
commit 8907be98a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 31 deletions

View File

@ -680,6 +680,26 @@ static mp_obj_t py_fir_register_vsync_cb(mp_obj_t cb)
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_fir_register_vsync_cb_obj, py_fir_register_vsync_cb);
#endif
static mp_obj_t py_fir_register_frame_cb(mp_obj_t cb)
{
if (fir_sensor == FIR_LEPTON) {
fir_lepton_register_frame_cb(cb);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_fir_register_frame_cb_obj, py_fir_register_frame_cb);
static mp_obj_t py_fir_get_frame_available()
{
if (fir_sensor == FIR_LEPTON) {
return fir_lepton_get_frame_available();
}
return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(py_fir_get_frame_available_obj, py_fir_get_frame_available);
static mp_obj_t py_fir_trigger_ffc(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
if (fir_sensor == FIR_LEPTON) {
@ -756,6 +776,9 @@ mp_obj_t py_fir_read_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
bool arg_hmirror = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_hmirror), false);
bool arg_vflip = py_helper_keyword_int(n_args, args, 1, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_vflip), false);
fir_transposed = py_helper_keyword_int(n_args, args, 2, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_transpose), false);
#if (OMV_ENABLE_FIR_LEPTON == 1)
int arg_timeout = py_helper_keyword_int(n_args, args, 3, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_timeout), -1);
#endif
switch(fir_sensor) {
case FIR_NONE: {
@ -807,7 +830,7 @@ mp_obj_t py_fir_read_ir(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
#endif
#if (OMV_ENABLE_FIR_LEPTON == 1)
case FIR_LEPTON: {
return fir_lepton_read_ir(fir_width, fir_height, arg_hmirror, arg_vflip, fir_transposed);
return fir_lepton_read_ir(fir_width, fir_height, arg_hmirror, arg_vflip, fir_transposed, arg_timeout);
}
#endif
}
@ -1089,8 +1112,11 @@ mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
dst_img.data = xalloc(image_size(&dst_img));
}
fb_alloc_mark();
#if (OMV_ENABLE_FIR_LEPTON == 1)
int arg_timeout = py_helper_keyword_int(n_args, args, 16, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_timeout), -1);
#endif
fb_alloc_mark();
src_img.data = fb_alloc(src_img.w * src_img.h * sizeof(uint8_t), FB_ALLOC_NO_HINT);
switch(fir_sensor) {
@ -1157,7 +1183,7 @@ mp_obj_t py_fir_snapshot(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
#if (OMV_ENABLE_FIR_LEPTON == 1)
case FIR_LEPTON: {
fir_lepton_fill_image(&src_img, fir_width, fir_height, !scale_obj, min, max,
arg_hmirror, arg_vflip, arg_transpose);
arg_hmirror, arg_vflip, arg_transpose, arg_timeout);
break;
}
#endif
@ -1213,10 +1239,14 @@ STATIC const mp_rom_map_elem_t globals_dict_table[] = {
#else
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_register_frame_cb), MP_ROM_PTR(&py_fir_register_frame_cb_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_frame_available), MP_ROM_PTR(&py_fir_get_frame_available_obj) },
{ MP_ROM_QSTR(MP_QSTR_trigger_ffc), MP_ROM_PTR(&py_fir_trigger_ffc_obj) },
#else
{ MP_ROM_QSTR(MP_QSTR_radiometric), MP_ROM_PTR(&py_func_unavailable_obj) },
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
{ MP_ROM_QSTR(MP_QSTR_register_frame_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
{ MP_ROM_QSTR(MP_QSTR_get_frame_available), MP_ROM_PTR(&py_func_unavailable_obj) },
{ MP_ROM_QSTR(MP_QSTR_trigger_ffc), MP_ROM_PTR(&py_func_unavailable_obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_read_ta), MP_ROM_PTR(&py_fir_read_ta_obj) },

View File

@ -17,7 +17,7 @@
#include "softtimer.h"
#include "systick.h"
#include "imlib.h"
#include "py_helper.h"
#include "omv_boardconfig.h"
#include STM32_HAL_H
@ -115,6 +115,8 @@ static bool fir_lepton_spi_check_crc(const uint16_t *base)
}
#endif
static mp_obj_t fir_lepton_frame_cb = mp_const_none;
void fir_lepton_spi_callback(const uint16_t *base)
{
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
@ -189,6 +191,11 @@ void fir_lepton_spi_callback(const uint16_t *base)
if (fir_lepton_spi_rx_cb_head == framebuffer_tail) {
fir_lepton_spi_rx_cb_head = (fir_lepton_spi_rx_cb_head + 1) % FRAMEBUFFER_COUNT;
}
// User should use micropython.schedule() in their callback to process the new frame.
if (fir_lepton_frame_cb != mp_const_none) {
mp_call_function_0(fir_lepton_frame_cb);
}
}
}
}
@ -530,9 +537,36 @@ mp_obj_t fir_lepton_get_radiometry()
return mp_obj_new_bool(fir_lepton_rad_en);
}
static const uint16_t *fir_lepton_get_frame()
void fir_lepton_register_frame_cb(mp_obj_t cb)
{
fir_lepton_frame_cb = cb;
}
mp_obj_t fir_lepton_get_frame_available()
{
return mp_obj_new_bool(framebuffer_head != framebuffer_tail);
}
static const uint16_t *fir_lepton_get_frame(int timeout)
{
int sampled_framebuffer_head = framebuffer_head;
if (timeout >= 0) {
for (uint32_t start = systick_current_millis();;) {
sampled_framebuffer_head = framebuffer_head;
if (framebuffer_tail != sampled_framebuffer_head) {
break;
}
if ((systick_current_millis() - start) >= timeout) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Timeout!"));
}
__WFI();
}
}
framebuffer_tail = sampled_framebuffer_head;
return framebuffers[sampled_framebuffer_head];
}
@ -553,11 +587,11 @@ mp_obj_t fir_lepton_read_ta()
return mp_obj_new_float((fir_lepton_get_temperature() * 0.01f) - 273.15f);
}
mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose)
mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose, int timeout)
{
int kelvin = fir_lepton_get_temperature();
mp_obj_list_t *list = (mp_obj_list_t *) mp_obj_new_list(w * h, NULL);
const uint16_t *data = fir_lepton_get_frame();
const uint16_t *data = fir_lepton_get_frame(timeout);
float min = +FLT_MAX;
float max = -FLT_MAX;
int w_1 = w - 1;
@ -606,10 +640,10 @@ mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose
}
void fir_lepton_fill_image(image_t *img, int w, int h, bool auto_range, float min, float max,
bool mirror, bool flip, bool transpose)
bool mirror, bool flip, bool transpose, int timeout)
{
int kelvin = fir_lepton_get_temperature();
const uint16_t *data = fir_lepton_get_frame();
const uint16_t *data = fir_lepton_get_frame(timeout);
int new_min;
int new_max;
@ -678,34 +712,32 @@ void fir_lepton_fill_image(image_t *img, int w, int h, bool auto_range, float mi
}
}
void fir_lepton_trigger_ffc()
void fir_lepton_trigger_ffc(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
if (LEP_RunSysFFCNormalization(&fir_lepton_handle) != LEP_OK) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("FFC Error!"));
}
}
void fir_lepton_wait_on_ffc(uint n_args, const mp_obj_t *args)
{
uint32_t start = systick_current_millis();
uint32_t delay_ms = (n_args < 1) ? 5000 : mp_obj_get_int(args[0]);
int timeout = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_timeout), -1);
for (;;) {
LEP_SYS_STATUS_E status;
if (timeout >= 0) {
for (uint32_t start = systick_current_millis();;) {
LEP_SYS_STATUS_E status;
if (LEP_GetSysFFCStatus(&fir_lepton_handle, &status) != LEP_OK) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SYS Error!"));
if (LEP_GetSysFFCStatus(&fir_lepton_handle, &status) != LEP_OK) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("SYS Error!"));
}
if (status == LEP_SYS_STATUS_READY) {
break;
}
if ((systick_current_millis() - start) >= timeout) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Timeout!"));
}
systick_sleep(1);
}
if (status == LEP_SYS_STATUS_READY) {
break;
}
if ((systick_current_millis() - start) >= delay_ms) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Timeout!"));
}
systick_sleep(1);
}
}

View File

@ -14,9 +14,11 @@ void fir_lepton_deinit();
int fir_lepton_init(cambus_t *bus, int *w, int *h, int *refresh, int *resolution);
void fir_lepton_register_vsync_cb(mp_obj_t cb);
mp_obj_t fir_lepton_get_radiometry();
void fir_lepton_register_frame_cb(mp_obj_t cb);
mp_obj_t fir_lepton_get_frame_available();
mp_obj_t fir_lepton_read_ta();
mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose);
mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose, int timeout);
void fir_lepton_fill_image(image_t *img, int w, int h, bool auto_range, float min, float max,
bool mirror, bool flip, bool transpose);
bool mirror, bool flip, bool transpose, int timeout);
void fir_lepton_trigger_ffc(uint n_args, const mp_obj_t *args, mp_map_t *kw_args);
#endif // __PY_FIR_LEPTON_H__