mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Kwabena/flir lepton updates (#1150)
* Add timeout support for grabbing a new frame * Fix ffc with a timeout
This commit is contained in:
parent
10f9600008
commit
8907be98a4
@ -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);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(py_fir_register_vsync_cb_obj, py_fir_register_vsync_cb);
|
||||||
#endif
|
#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)
|
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) {
|
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_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);
|
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);
|
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) {
|
switch(fir_sensor) {
|
||||||
case FIR_NONE: {
|
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
|
#endif
|
||||||
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||||
case FIR_LEPTON: {
|
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
|
#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));
|
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);
|
src_img.data = fb_alloc(src_img.w * src_img.h * sizeof(uint8_t), FB_ALLOC_NO_HINT);
|
||||||
|
|
||||||
switch(fir_sensor) {
|
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)
|
#if (OMV_ENABLE_FIR_LEPTON == 1)
|
||||||
case FIR_LEPTON: {
|
case FIR_LEPTON: {
|
||||||
fir_lepton_fill_image(&src_img, fir_width, fir_height, !scale_obj, min, max,
|
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;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1213,10 +1239,14 @@ STATIC const mp_rom_map_elem_t globals_dict_table[] = {
|
|||||||
#else
|
#else
|
||||||
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||||
#endif
|
#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) },
|
{ MP_ROM_QSTR(MP_QSTR_trigger_ffc), MP_ROM_PTR(&py_fir_trigger_ffc_obj) },
|
||||||
#else
|
#else
|
||||||
{ MP_ROM_QSTR(MP_QSTR_radiometric), MP_ROM_PTR(&py_func_unavailable_obj) },
|
{ 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_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) },
|
{ MP_ROM_QSTR(MP_QSTR_trigger_ffc), MP_ROM_PTR(&py_func_unavailable_obj) },
|
||||||
#endif
|
#endif
|
||||||
{ MP_ROM_QSTR(MP_QSTR_read_ta), MP_ROM_PTR(&py_fir_read_ta_obj) },
|
{ MP_ROM_QSTR(MP_QSTR_read_ta), MP_ROM_PTR(&py_fir_read_ta_obj) },
|
||||||
|
|||||||
@ -17,7 +17,7 @@
|
|||||||
#include "softtimer.h"
|
#include "softtimer.h"
|
||||||
#include "systick.h"
|
#include "systick.h"
|
||||||
|
|
||||||
#include "imlib.h"
|
#include "py_helper.h"
|
||||||
#include "omv_boardconfig.h"
|
#include "omv_boardconfig.h"
|
||||||
#include STM32_HAL_H
|
#include STM32_HAL_H
|
||||||
|
|
||||||
@ -115,6 +115,8 @@ static bool fir_lepton_spi_check_crc(const uint16_t *base)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static mp_obj_t fir_lepton_frame_cb = mp_const_none;
|
||||||
|
|
||||||
void fir_lepton_spi_callback(const uint16_t *base)
|
void fir_lepton_spi_callback(const uint16_t *base)
|
||||||
{
|
{
|
||||||
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
|
#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) {
|
if (fir_lepton_spi_rx_cb_head == framebuffer_tail) {
|
||||||
fir_lepton_spi_rx_cb_head = (fir_lepton_spi_rx_cb_head + 1) % FRAMEBUFFER_COUNT;
|
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);
|
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;
|
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;
|
framebuffer_tail = sampled_framebuffer_head;
|
||||||
return framebuffers[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);
|
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();
|
int kelvin = fir_lepton_get_temperature();
|
||||||
mp_obj_list_t *list = (mp_obj_list_t *) mp_obj_new_list(w * h, NULL);
|
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 min = +FLT_MAX;
|
||||||
float max = -FLT_MAX;
|
float max = -FLT_MAX;
|
||||||
int w_1 = w - 1;
|
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,
|
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();
|
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_min;
|
||||||
int new_max;
|
int new_max;
|
||||||
|
|
||||||
@ -678,19 +712,16 @@ 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) {
|
if (LEP_RunSysFFCNormalization(&fir_lepton_handle) != LEP_OK) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("FFC Error!"));
|
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)
|
int timeout = py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_timeout), -1);
|
||||||
{
|
|
||||||
uint32_t start = systick_current_millis();
|
|
||||||
uint32_t delay_ms = (n_args < 1) ? 5000 : mp_obj_get_int(args[0]);
|
|
||||||
|
|
||||||
for (;;) {
|
if (timeout >= 0) {
|
||||||
|
for (uint32_t start = systick_current_millis();;) {
|
||||||
LEP_SYS_STATUS_E status;
|
LEP_SYS_STATUS_E status;
|
||||||
|
|
||||||
if (LEP_GetSysFFCStatus(&fir_lepton_handle, &status) != LEP_OK) {
|
if (LEP_GetSysFFCStatus(&fir_lepton_handle, &status) != LEP_OK) {
|
||||||
@ -701,12 +732,13 @@ void fir_lepton_wait_on_ffc(uint n_args, const mp_obj_t *args)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((systick_current_millis() - start) >= delay_ms) {
|
if ((systick_current_millis() - start) >= timeout) {
|
||||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Timeout!"));
|
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Timeout!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
systick_sleep(1);
|
systick_sleep(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // OMV_FIR_LEPTON_PRESENT
|
#endif // OMV_FIR_LEPTON_PRESENT
|
||||||
|
|||||||
@ -14,9 +14,11 @@ void fir_lepton_deinit();
|
|||||||
int fir_lepton_init(cambus_t *bus, int *w, int *h, int *refresh, int *resolution);
|
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);
|
void fir_lepton_register_vsync_cb(mp_obj_t cb);
|
||||||
mp_obj_t fir_lepton_get_radiometry();
|
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_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,
|
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);
|
void fir_lepton_trigger_ffc(uint n_args, const mp_obj_t *args, mp_map_t *kw_args);
|
||||||
#endif // __PY_FIR_LEPTON_H__
|
#endif // __PY_FIR_LEPTON_H__
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user