mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #2771 from kwagyeman/kwabena/remove_old_fir_module
modules/py_fir_lepton: Remove lepton control through fir module.
This commit is contained in:
commit
813b707de0
@ -51,7 +51,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 16
|
||||
@ -307,9 +306,4 @@
|
||||
#define OMV_SPI_DISPLAY_RS_PIN (&omv_pin_G12_GPIO)
|
||||
#define OMV_SPI_DISPLAY_RST_PIN (&omv_pin_G1_GPIO)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_FIR_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_FIR_I2C_SPEED)
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI4_ID)
|
||||
|
||||
#endif //__OMV_BOARDCONFIG_H__
|
||||
|
||||
@ -60,7 +60,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 256
|
||||
@ -345,9 +344,4 @@
|
||||
#define OMV_SPI_DISPLAY_RST_PIN (&omv_pin_C7_GPIO)
|
||||
#define OMV_SPI_DISPLAY_TRIPLE_BUFFER (1)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_FIR_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_FIR_I2C_SPEED)
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI2_ID)
|
||||
|
||||
#endif //__OMV_BOARDCONFIG_H__
|
||||
|
||||
@ -53,7 +53,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 16
|
||||
@ -202,9 +201,4 @@
|
||||
#define OMV_SPI_DISPLAY_RST_PIN (&omv_pin_D12_GPIO)
|
||||
#define OMV_SPI_DISPLAY_BL_PIN (&omv_pin_A5_GPIO)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_FIR_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_FIR_I2C_SPEED)
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI2_ID)
|
||||
|
||||
#endif //__OMV_BOARDCONFIG_H__
|
||||
|
||||
@ -53,7 +53,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 16
|
||||
@ -202,9 +201,4 @@
|
||||
#define OMV_SPI_DISPLAY_RST_PIN (&omv_pin_D12_GPIO)
|
||||
#define OMV_SPI_DISPLAY_BL_PIN (&omv_pin_A5_GPIO)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_FIR_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_FIR_I2C_SPEED)
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI2_ID)
|
||||
|
||||
#endif //__OMV_BOARDCONFIG_H__
|
||||
|
||||
@ -67,7 +67,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 16
|
||||
@ -282,9 +281,4 @@
|
||||
#define OMV_SPI_DISPLAY_RST_PIN (&omv_pin_D12_GPIO)
|
||||
#define OMV_SPI_DISPLAY_BL_PIN (&omv_pin_A5_GPIO)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_FIR_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_FIR_I2C_SPEED)
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI2_ID)
|
||||
|
||||
#endif //__OMV_BOARDCONFIG_H__
|
||||
|
||||
@ -54,7 +54,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 256
|
||||
@ -282,9 +281,4 @@
|
||||
#define OMV_SPI_DISPLAY_BL_PIN (&omv_pin_A5_GPIO)
|
||||
#define OMV_SPI_DISPLAY_TRIPLE_BUFFER (1)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_FIR_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_FIR_I2C_SPEED)
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI2_ID)
|
||||
|
||||
#endif //__OMV_BOARDCONFIG_H__
|
||||
|
||||
@ -33,12 +33,13 @@
|
||||
#define OMV_OV5640_PLL_CTRL2 (0x64)
|
||||
#define OMV_OV5640_PLL_CTRL3 (0x13)
|
||||
|
||||
#define OMV_LEPTON_ENABLE (1)
|
||||
|
||||
// FIR drivers configuration.
|
||||
#define OMV_FIR_MLX90621_ENABLE (1)
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 256
|
||||
@ -186,6 +187,9 @@
|
||||
#define OMV_SOFT_I2C_SIOD_PIN (&omv_pin_B11_GPIO)
|
||||
#define OMV_SOFT_I2C_SPIN_DELAY 64
|
||||
|
||||
// CSI SPI bus
|
||||
#define OMV_CSI_SPI_ID (3)
|
||||
|
||||
// WINC1500 WiFi module SPI bus
|
||||
#define OMV_WINC_SPI_ID (5)
|
||||
#define OMV_WINC_SPI_BAUDRATE (50000000)
|
||||
@ -209,6 +213,7 @@
|
||||
#define OMV_CSI_DMA_REQUEST (DMA_REQUEST_DCMI)
|
||||
#define OMV_CSI_DMA_MEMCPY_ENABLE (1)
|
||||
#define OMV_CSI_HW_CROP_ENABLE (1)
|
||||
#define OMV_CSI_MAX_DEVICES (2)
|
||||
|
||||
#define OMV_CSI_D0_PIN (&omv_pin_C6_DCMI)
|
||||
#define OMV_CSI_D1_PIN (&omv_pin_C7_DCMI)
|
||||
@ -225,6 +230,8 @@
|
||||
#define OMV_CSI_RESET_PIN (&omv_pin_A10_GPIO)
|
||||
#define OMV_CSI_POWER_PIN (&omv_pin_D7_GPIO)
|
||||
|
||||
#define OMV_CSI_POLARITY_CONFIG { OMV_CSI_ACTIVE_HIGH, OMV_CSI_ACTIVE_LOW }
|
||||
|
||||
// Physical I2C buses.
|
||||
|
||||
// I2C bus 1
|
||||
@ -244,7 +251,7 @@
|
||||
#define OMV_SPI2_SCLK_PIN (&omv_pin_B13_SPI2)
|
||||
#define OMV_SPI2_MISO_PIN (&omv_pin_B14_SPI2)
|
||||
#define OMV_SPI2_MOSI_PIN (&omv_pin_B15_SPI2)
|
||||
#define OMV_SPI2_SSEL_PIN (&omv_pin_B12_GPIO)
|
||||
#define OMV_SPI2_SSEL_PIN (&omv_pin_B12_SPI2)
|
||||
#define OMV_SPI2_DMA_TX_CHANNEL (DMA1_Stream4)
|
||||
#define OMV_SPI2_DMA_TX_REQUEST (DMA_REQUEST_SPI2_TX)
|
||||
#define OMV_SPI2_DMA_RX_CHANNEL (DMA1_Stream3)
|
||||
@ -255,7 +262,7 @@
|
||||
#define OMV_SPI3_SCLK_PIN (&omv_pin_B3_SPI3)
|
||||
#define OMV_SPI3_MISO_PIN (&omv_pin_B4_SPI3)
|
||||
#define OMV_SPI3_MOSI_PIN (&omv_pin_B5_SPI3)
|
||||
#define OMV_SPI3_SSEL_PIN (&omv_pin_A15_GPIO)
|
||||
#define OMV_SPI3_SSEL_PIN (&omv_pin_A15_SPI3)
|
||||
#define OMV_SPI3_DMA_TX_CHANNEL (DMA1_Stream7)
|
||||
#define OMV_SPI3_DMA_TX_REQUEST (DMA_REQUEST_SPI3_TX)
|
||||
#define OMV_SPI3_DMA_RX_CHANNEL (DMA1_Stream2)
|
||||
@ -266,7 +273,7 @@
|
||||
#define OMV_SPI5_SCLK_PIN (&omv_pin_H6_SPI5)
|
||||
#define OMV_SPI5_MISO_PIN (&omv_pin_H7_SPI5)
|
||||
#define OMV_SPI5_MOSI_PIN (&omv_pin_J10_SPI5)
|
||||
#define OMV_SPI5_SSEL_PIN (&omv_pin_K1_GPIO)
|
||||
#define OMV_SPI5_SSEL_PIN (&omv_pin_K1_SPI5)
|
||||
#define OMV_SPI5_DMA_TX_CHANNEL (DMA2_Stream4)
|
||||
#define OMV_SPI5_DMA_TX_REQUEST (DMA_REQUEST_SPI5_TX)
|
||||
#define OMV_SPI5_DMA_RX_CHANNEL (DMA2_Stream3)
|
||||
@ -346,25 +353,4 @@
|
||||
#define OMV_FT5X06_SDA_PIN (pin_J14)
|
||||
#define OMV_FT5X06_INT_PIN (&omv_pin_J6_GPIO)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_CSI_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_CSI_I2C_SPEED)
|
||||
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI3_ID)
|
||||
|
||||
#define OMV_FIR_LEPTON_RESET_PIN (&omv_pin_D5_GPIO)
|
||||
#define OMV_FIR_LEPTON_POWER_PIN (&omv_pin_D4_GPIO)
|
||||
#define OMV_FIR_LEPTON_VSYNC_PIN (&omv_pin_E3_GPIO)
|
||||
|
||||
#define OMV_FIR_LEPTON_MCLK_PIN (&omv_pin_A3_TIM15)
|
||||
#define OMV_FIR_LEPTON_MCLK_FREQ (24000000)
|
||||
|
||||
#define OMV_FIR_LEPTON_MCLK_TIM (TIM15)
|
||||
#define OMV_FIR_LEPTON_MCLK_TIM_CHANNEL (TIM_CHANNEL_2)
|
||||
#define OMV_FIR_LEPTON_MCLK_TIM_CLK_ENABLE() __HAL_RCC_TIM15_CLK_ENABLE()
|
||||
#define OMV_FIR_LEPTON_MCLK_TIM_CLK_DISABLE() __HAL_RCC_TIM15_CLK_DISABLE()
|
||||
#define OMV_FIR_LEPTON_MCLK_TIM_FORCE_RESET() __HAL_RCC_TIM15_FORCE_RESET()
|
||||
#define OMV_FIR_LEPTON_MCLK_TIM_RELEASE_RESET() __HAL_RCC_TIM15_RELEASE_RESET()
|
||||
#define OMV_FIR_LEPTON_MCLK_TIM_PCLK_FREQ() HAL_RCC_GetPCLK2Freq()
|
||||
|
||||
#endif //__OMV_BOARDCONFIG_H__
|
||||
|
||||
@ -8,7 +8,7 @@ OMV_GPIO_DEFINE(A, 5, NONE, GPIO)
|
||||
OMV_GPIO_DEFINE(A, 6, AF13, DCMI)
|
||||
OMV_GPIO_DEFINE(A, 8, AF1, TIM1)
|
||||
OMV_GPIO_DEFINE(A, 10, NONE, GPIO)
|
||||
OMV_GPIO_DEFINE(A, 15, NONE, GPIO)
|
||||
OMV_GPIO_DEFINE(A, 15, AF6, SPI3)
|
||||
OMV_GPIO_DEFINE(B, 0, AF2, TIM3)
|
||||
OMV_GPIO_DEFINE(B, 3, AF6, SPI3)
|
||||
OMV_GPIO_DEFINE(B, 4, AF6, SPI3)
|
||||
@ -22,6 +22,7 @@ OMV_GPIO_DEFINE(B, 10, AF4, I2C2)
|
||||
OMV_GPIO_DEFINE(B, 11, NONE, GPIO)
|
||||
OMV_GPIO_DEFINE(B, 11, AF4, I2C2)
|
||||
OMV_GPIO_DEFINE(B, 12, NONE, GPIO)
|
||||
OMV_GPIO_DEFINE(B, 12, AF5, SPI2)
|
||||
OMV_GPIO_DEFINE(B, 13, AF5, SPI2)
|
||||
OMV_GPIO_DEFINE(B, 14, AF5, SPI2)
|
||||
OMV_GPIO_DEFINE(B, 15, AF5, SPI2)
|
||||
@ -72,6 +73,7 @@ OMV_GPIO_DEFINE(J, 12, AF9, LTDC)
|
||||
OMV_GPIO_DEFINE(J, 15, AF14, LTDC)
|
||||
OMV_GPIO_DEFINE(K, 0, AF14, LTDC)
|
||||
OMV_GPIO_DEFINE(K, 1, NONE, GPIO)
|
||||
OMV_GPIO_DEFINE(K, 1, AF5, SPI5)
|
||||
OMV_GPIO_DEFINE(K, 2, NONE, GPIO)
|
||||
OMV_GPIO_DEFINE(K, 3, AF14, LTDC)
|
||||
OMV_GPIO_DEFINE(K, 4, AF14, LTDC)
|
||||
|
||||
@ -66,7 +66,6 @@ extern unsigned char OMV_BOARD_UID_ADDR[12]; // Unique address.
|
||||
#define OMV_FIR_MLX90640_ENABLE (0)
|
||||
#define OMV_FIR_MLX90641_ENABLE (0)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (0)
|
||||
|
||||
// Debugging configuration.
|
||||
#define OMV_TUSBDBG_ENABLE (CORE_M55_HP)
|
||||
|
||||
@ -57,7 +57,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (0)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 256
|
||||
|
||||
@ -47,7 +47,6 @@
|
||||
#define OMV_FIR_MLX90640_ENABLE (1)
|
||||
#define OMV_FIR_MLX90641_ENABLE (1)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (1)
|
||||
|
||||
// Debugging configuration.
|
||||
#define OMV_TUSBDBG_ENABLE (1)
|
||||
@ -182,11 +181,6 @@
|
||||
#define OMV_SPI_DISPLAY_TRIPLE_BUFFER (0)
|
||||
#define OMV_SPI_DISPLAY_RX_CLK_DIV (8)
|
||||
|
||||
// FIR Lepton
|
||||
#define OMV_FIR_LEPTON_I2C_BUS (OMV_FIR_I2C_ID)
|
||||
#define OMV_FIR_LEPTON_I2C_BUS_SPEED (OMV_FIR_I2C_SPEED)
|
||||
#define OMV_FIR_LEPTON_SPI_BUS (OMV_SPI3_ID)
|
||||
|
||||
// Camera interface configuration.
|
||||
#define OMV_CSI_BASE (CSI)
|
||||
#define OMV_CSI_DMA (DMA0)
|
||||
|
||||
@ -36,7 +36,6 @@ extern unsigned char *OMV_BOARD_UID_ADDR; // Unique ID address.
|
||||
#define OMV_FIR_MLX90640_ENABLE (0)
|
||||
#define OMV_FIR_MLX90641_ENABLE (0)
|
||||
#define OMV_FIR_AMG8833_ENABLE (1)
|
||||
#define OMV_FIR_LEPTON_ENABLE (0)
|
||||
|
||||
// UMM heap block size
|
||||
#define OMV_UMM_BLOCK_SIZE 16
|
||||
|
||||
@ -464,10 +464,14 @@ int omv_csi_probe(omv_i2c_t *i2c) {
|
||||
// Active power-down state, active reset state
|
||||
// This order is required for all sensors to work correctly.
|
||||
const omv_csi_polarity_t polarity_configs[][2] = {
|
||||
#if defined(OMV_CSI_POLARITY_CONFIG)
|
||||
OMV_CSI_POLARITY_CONFIG
|
||||
#else
|
||||
{ OMV_CSI_ACTIVE_HIGH, OMV_CSI_ACTIVE_HIGH },
|
||||
{ OMV_CSI_ACTIVE_HIGH, OMV_CSI_ACTIVE_LOW },
|
||||
{ OMV_CSI_ACTIVE_LOW, OMV_CSI_ACTIVE_HIGH },
|
||||
{ OMV_CSI_ACTIVE_LOW, OMV_CSI_ACTIVE_LOW },
|
||||
#endif // OMV_CSI_POLARITY_CONFIG
|
||||
};
|
||||
|
||||
// Scan the bus multiple times using different reset and power polarities,
|
||||
|
||||
@ -68,7 +68,7 @@
|
||||
/** INCLUDE FILES **/
|
||||
/******************************************************************************/
|
||||
#include "omv_boardconfig.h"
|
||||
#if ((OMV_LEPTON_ENABLE == 1) || (OMV_FIR_LEPTON_ENABLE == 1))
|
||||
#if (OMV_LEPTON_ENABLE == 1)
|
||||
|
||||
#include "LEPTON_Types.h"
|
||||
#include "LEPTON_ErrorCodes.h"
|
||||
@ -232,4 +232,4 @@ LEP_RESULT LEP_I2C_MasterStatus(omv_i2c_t *bus,
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif // ((OMV_LEPTON_ENABLE == 1) || (OMV_FIR_LEPTON_ENABLE == 1))
|
||||
#endif // (OMV_LEPTON_ENABLE == 1)
|
||||
|
||||
@ -314,7 +314,11 @@ static int lepton_reset(omv_csi_t *csi, bool measurement_mode, bool high_temp_mo
|
||||
// Use the low gain mode to enable high temperature readings (~450C) on Lepton 3.5
|
||||
LEP_SYS_GAIN_MODE_E gain_mode = high_temp_mode ? LEP_SYS_GAIN_MODE_LOW : LEP_SYS_GAIN_MODE_HIGH;
|
||||
|
||||
if (LEP_SetSysGainMode(&lepton.port, gain_mode) != LEP_OK ||
|
||||
bool hasSetSysGainMode = csi->chip_id == LEPTON_3_5 ||
|
||||
csi->chip_id == LEPTON_3_0 ||
|
||||
csi->chip_id == LEPTON_2_5;
|
||||
|
||||
if ((hasSetSysGainMode && LEP_SetSysGainMode(&lepton.port, gain_mode) != LEP_OK) ||
|
||||
LEP_GetAgcROI(&lepton.port, &roi) != LEP_OK ||
|
||||
LEP_SetRadEnableState(&lepton.port, measurement_mode) != LEP_OK ||
|
||||
LEP_SetAgcEnableState(&lepton.port, !measurement_mode) != LEP_OK ||
|
||||
|
||||
154
modules/py_fir.c
154
modules/py_fir.c
@ -30,8 +30,7 @@
|
||||
#if OMV_FIR_MLX90621_ENABLE || \
|
||||
OMV_FIR_MLX90640_ENABLE || \
|
||||
OMV_FIR_MLX90641_ENABLE || \
|
||||
OMV_FIR_AMG8833_ENABLE || \
|
||||
OMV_FIR_LEPTON_ENABLE
|
||||
OMV_FIR_AMG8833_ENABLE
|
||||
#include "omv_i2c.h"
|
||||
#if (OMV_FIR_MLX90621_ENABLE == 1)
|
||||
#include "MLX90621_API.h"
|
||||
@ -51,10 +50,6 @@
|
||||
#include "py_helper.h"
|
||||
#include "py_image.h"
|
||||
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
#include "py_fir_lepton.h"
|
||||
#endif
|
||||
|
||||
#define MLX90621_ADDR 0x50
|
||||
#define MLX90621_WIDTH 16
|
||||
#define MLX90621_HEIGHT 4
|
||||
@ -108,9 +103,6 @@ typedef enum fir_sensor_type {
|
||||
#if (OMV_FIR_AMG8833_ENABLE == 1)
|
||||
FIR_AMG8833,
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
FIR_LEPTON
|
||||
#endif
|
||||
} fir_sensor_type_t;
|
||||
|
||||
static int fir_width = 0;
|
||||
@ -308,12 +300,6 @@ static mp_obj_t fir_get_ir(int w, int h, float Ta, float *To, bool mirror,
|
||||
}
|
||||
|
||||
static mp_obj_t py_fir_deinit() {
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
fir_lepton_deinit();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (fir_sensor != FIR_NONE) {
|
||||
omv_i2c_deinit(&fir_bus);
|
||||
fir_sensor = FIR_NONE;
|
||||
@ -382,12 +368,6 @@ mp_obj_t py_fir_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
case LEPTON_ADDR: {
|
||||
type = FIR_LEPTON;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
@ -571,28 +551,6 @@ mp_obj_t py_fir_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args)
|
||||
return mp_const_none;
|
||||
}
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
case FIR_LEPTON: {
|
||||
fir_sensor = FIR_LEPTON;
|
||||
FIR_LEPTON_RETRY:
|
||||
omv_i2c_init(&fir_bus, OMV_FIR_LEPTON_I2C_BUS, OMV_FIR_LEPTON_I2C_BUS_SPEED);
|
||||
|
||||
int error = fir_lepton_init(&fir_bus, &fir_width, &fir_height, &fir_ir_fresh_rate, &fir_adc_resolution);
|
||||
|
||||
if (error != 0) {
|
||||
if (first_init) {
|
||||
first_init = false;
|
||||
omv_i2c_pulse_scl(&fir_bus);
|
||||
goto FIR_LEPTON_RETRY;
|
||||
} else {
|
||||
py_fir_deinit();
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Failed to init the Lepton!"));
|
||||
}
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Failed to detect a supported FIR sensor."));
|
||||
}
|
||||
@ -650,10 +608,6 @@ static mp_obj_t py_fir_refresh() {
|
||||
case FIR_AMG8833:
|
||||
return mp_obj_new_int(fir_ir_fresh_rate);
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
case FIR_LEPTON:
|
||||
return mp_obj_new_int(fir_ir_fresh_rate);
|
||||
#endif
|
||||
default:
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
@ -678,77 +632,12 @@ static mp_obj_t py_fir_resolution() {
|
||||
case FIR_AMG8833:
|
||||
return mp_obj_new_int(fir_adc_resolution);
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
case FIR_LEPTON:
|
||||
return mp_obj_new_int(fir_adc_resolution);
|
||||
#endif
|
||||
default:
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(py_fir_resolution_obj, py_fir_resolution);
|
||||
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
static mp_obj_t py_fir_radiometric() {
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
return fir_lepton_get_radiometry();
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_0(py_fir_radiometric_obj, py_fir_radiometric);
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_VSYNC_PRESENT)
|
||||
static mp_obj_t py_fir_register_vsync_cb(mp_obj_t cb) {
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
fir_lepton_register_vsync_cb(cb);
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
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);
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
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();
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
}
|
||||
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(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_timeout };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_timeout, MP_ARG_INT, {.u_int = -1 } },
|
||||
};
|
||||
|
||||
// Parse args.
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if (fir_sensor == FIR_LEPTON) {
|
||||
fir_lepton_trigger_ffc(args[ARG_timeout].u_int);
|
||||
} else {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("Operation not supported by this FIR sensor"));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_KW(py_fir_trigger_ffc_obj, 0, py_fir_trigger_ffc);
|
||||
#endif
|
||||
|
||||
mp_obj_t py_fir_read_ta() {
|
||||
switch (fir_sensor) {
|
||||
#if (OMV_FIR_MLX90621_ENABLE == 1)
|
||||
@ -798,11 +687,6 @@ mp_obj_t py_fir_read_ta() {
|
||||
return mp_obj_new_float(AMG8833_12_TO_16(temp) * 0.0625f);
|
||||
}
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
case FIR_LEPTON: {
|
||||
return fir_lepton_read_ta();
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
@ -872,12 +756,6 @@ mp_obj_t py_fir_read_ir(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ar
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
case FIR_LEPTON: {
|
||||
return fir_lepton_read_ir(fir_width, fir_height, args[ARG_hmirror].u_bool,
|
||||
args[ARG_vflip].u_bool, args[ARG_transpose].u_bool, args[ARG_timeout].u_int);
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
@ -1086,16 +964,6 @@ mp_obj_t py_fir_snapshot(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_a
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
case FIR_LEPTON: {
|
||||
bool auto_range = args[ARG_scale].u_obj == mp_const_none;
|
||||
imlib_fill_image_from_lepton(&src_img, fir_width, fir_height,
|
||||
fir_lepton_get_frame(args[ARG_timeout].u_int), min, max, auto_range,
|
||||
fir_lepton_get_radiometry_enabled(), fir_lepton_get_temperature(),
|
||||
args[ARG_hmirror].u_bool, args[ARG_vflip].u_bool, args[ARG_transpose].u_bool);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default: {
|
||||
mp_raise_msg(&mp_type_ValueError, MP_ERROR_TEXT("FIR sensor is not initialized"));
|
||||
}
|
||||
@ -1129,9 +997,6 @@ static const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
#if (OMV_FIR_AMG8833_ENABLE == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_AMG8833), MP_ROM_INT(FIR_AMG8833) },
|
||||
#endif
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_FIR_LEPTON), MP_ROM_INT(FIR_LEPTON) },
|
||||
#endif
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&py_fir_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&py_fir_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&py_fir_type_obj) },
|
||||
@ -1139,23 +1004,6 @@ static const mp_rom_map_elem_t globals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&py_fir_height_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&py_fir_refresh_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_resolution), MP_ROM_PTR(&py_fir_resolution_obj) },
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
{ MP_ROM_QSTR(MP_QSTR_radiometric), MP_ROM_PTR(&py_fir_radiometric_obj) },
|
||||
#if defined(OMV_FIR_LEPTON_VSYNC_PRESENT)
|
||||
{ MP_ROM_QSTR(MP_QSTR_register_vsync_cb), MP_ROM_PTR(&py_fir_register_vsync_cb_obj) },
|
||||
#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) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read_ir), MP_ROM_PTR(&py_fir_read_ir_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_draw_ir), MP_ROM_PTR(&py_fir_draw_ir_obj) },
|
||||
|
||||
@ -1,562 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright (C) 2013-2024 OpenMV, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* FIR Python module.
|
||||
*/
|
||||
#include "omv_boardconfig.h"
|
||||
#if (OMV_FIR_LEPTON_ENABLE == 1)
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "softtimer.h"
|
||||
|
||||
#include "crc16.h"
|
||||
#include "LEPTON_SDK.h"
|
||||
#include "LEPTON_AGC.h"
|
||||
#include "LEPTON_SYS.h"
|
||||
#include "LEPTON_VID.h"
|
||||
#include "LEPTON_OEM.h"
|
||||
#include "LEPTON_RAD.h"
|
||||
#include "LEPTON_I2C_Reg.h"
|
||||
|
||||
#include "py_helper.h"
|
||||
#include "omv_common.h"
|
||||
#include "omv_gpio.h"
|
||||
#include "omv_spi.h"
|
||||
|
||||
#define FRAMEBUFFER_COUNT 3
|
||||
static volatile int framebuffer_tail = 0;
|
||||
static int framebuffer_head = 0;
|
||||
static uint16_t *framebuffers[FRAMEBUFFER_COUNT] = {};
|
||||
|
||||
static int fir_lepton_rad_en = false;
|
||||
static bool fir_lepton_3 = false;
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_MCLK_TIM)
|
||||
static TIM_HandleTypeDef fir_lepton_mclk_tim_handle = {};
|
||||
#endif
|
||||
|
||||
static LEP_CAMERA_PORT_DESC_T fir_lepton_handle = {};
|
||||
static omv_spi_t spi_bus = {};
|
||||
|
||||
#define VOSPI_HEADER_WORDS (2) // 16-bits
|
||||
#define VOSPI_PID_SIZE_PIXELS (80) // w, 16-bits per pixel
|
||||
#define VOSPI_PIDS_PER_SID (60) // h
|
||||
#define VOSPI_SIDS_PER_FRAME (4)
|
||||
#define VOSPI_PACKET_SIZE (VOSPI_HEADER_WORDS + VOSPI_PID_SIZE_PIXELS) // 16-bits
|
||||
#define VOSPI_SID_SIZE_PIXELS (VOSPI_PIDS_PER_SID * VOSPI_PID_SIZE_PIXELS) // 16-bits
|
||||
|
||||
#define VOSPI_BUFFER_SIZE (VOSPI_PACKET_SIZE * 2) // 16-bits
|
||||
#define VOSPI_CLOCK_SPEED 20000000 // hz
|
||||
#define VOSPI_SYNC_MS 200 // ms
|
||||
|
||||
#define VOSPI_SPECIAL_PACKET (20)
|
||||
#define VOSPI_DONT_CARE_PACKET (0x0F00)
|
||||
#define VOSPI_HEADER_DONT_CARE(x) (((x) & VOSPI_DONT_CARE_PACKET) == VOSPI_DONT_CARE_PACKET)
|
||||
#define VOSPI_HEADER_PID(id) ((id) & 0x0FFF)
|
||||
#define VOSPI_HEADER_SID(id) (((id) >> 12) & 0x7)
|
||||
|
||||
static soft_timer_entry_t flir_lepton_spi_rx_timer = {};
|
||||
static int fir_lepton_spi_rx_cb_tail = 0;
|
||||
static int fir_lepton_spi_rx_cb_expected_pid = 0;
|
||||
static int fir_lepton_spi_rx_cb_expected_sid = 0;
|
||||
static uint16_t OMV_ATTR_SEC_ALIGN(fir_lepton_buf[VOSPI_BUFFER_SIZE], OMV_VOSPI_DMA_BUFFER, OMV_DMA_ALIGNMENT);
|
||||
static void fir_lepton_spi_callback(omv_spi_t *spi, void *userdata, void *buf);
|
||||
|
||||
static mp_obj_t fir_lepton_spi_resync_callback(mp_obj_t unused) {
|
||||
// For triple buffering we are never drawing where tail or head
|
||||
// (which may instantly update to be equal to tail) is.
|
||||
fir_lepton_spi_rx_cb_tail = (framebuffer_tail + 1) % FRAMEBUFFER_COUNT;
|
||||
if (fir_lepton_spi_rx_cb_tail == framebuffer_head) {
|
||||
fir_lepton_spi_rx_cb_tail = (fir_lepton_spi_rx_cb_tail + 1) % FRAMEBUFFER_COUNT;
|
||||
}
|
||||
|
||||
omv_spi_transfer_t spi_xfer = {
|
||||
.rxbuf = fir_lepton_buf,
|
||||
.size = VOSPI_BUFFER_SIZE,
|
||||
.flags = OMV_SPI_XFER_DMA,
|
||||
.callback = fir_lepton_spi_callback,
|
||||
};
|
||||
|
||||
omv_gpio_write(spi_bus.cs, 0);
|
||||
omv_spi_transfer_start(&spi_bus, &spi_xfer);
|
||||
return mp_const_none;
|
||||
}
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(fir_lepton_spi_resync_callback_obj, fir_lepton_spi_resync_callback);
|
||||
|
||||
static void fir_lepton_spi_resync() {
|
||||
flir_lepton_spi_rx_timer.flags = SOFT_TIMER_FLAG_PY_CALLBACK;
|
||||
flir_lepton_spi_rx_timer.mode = SOFT_TIMER_MODE_ONE_SHOT;
|
||||
flir_lepton_spi_rx_timer.delta_ms = VOSPI_SYNC_MS;
|
||||
flir_lepton_spi_rx_timer.py_callback = (mp_obj_t) &fir_lepton_spi_resync_callback_obj;
|
||||
soft_timer_insert(&flir_lepton_spi_rx_timer, VOSPI_SYNC_MS);
|
||||
}
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_CHECK_CRC)
|
||||
static bool fir_lepton_spi_check_crc(const uint16_t *base) {
|
||||
int id = base[0];
|
||||
int packet_crc = base[1];
|
||||
int crc = ByteCRC16((id >> 8) & 0x0F, 0);
|
||||
crc = ByteCRC16(id, crc);
|
||||
crc = ByteCRC16(0, crc);
|
||||
crc = ByteCRC16(0, crc);
|
||||
|
||||
for (int i = VOSPI_HEADER_WORDS; i < VOSPI_PACKET_SIZE; i++) {
|
||||
int value = base[i];
|
||||
crc = ByteCRC16(value >> 8, crc);
|
||||
crc = ByteCRC16(value, crc);
|
||||
}
|
||||
|
||||
return packet_crc == crc;
|
||||
}
|
||||
#endif
|
||||
|
||||
static mp_obj_t fir_lepton_frame_cb = mp_const_none;
|
||||
|
||||
void fir_lepton_spi_callback(omv_spi_t *spi, void *userdata, void *buf) {
|
||||
const uint16_t *base = (uint16_t *) buf;
|
||||
|
||||
int id = base[0];
|
||||
|
||||
// Ignore don't care packets.
|
||||
if (VOSPI_HEADER_DONT_CARE(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int pid = VOSPI_HEADER_PID(id);
|
||||
int sid = VOSPI_HEADER_SID(id) - 1;
|
||||
|
||||
// Discard packets with a pid != 0 when waiting for the first packet.
|
||||
if ((fir_lepton_spi_rx_cb_expected_pid == 0) && (pid != 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Discard sidments with a sid != 0 when waiting for the first segment.
|
||||
if (fir_lepton_3 && (pid == VOSPI_SPECIAL_PACKET) && (fir_lepton_spi_rx_cb_expected_sid == 0) && (sid != 0)) {
|
||||
fir_lepton_spi_rx_cb_expected_pid = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Are we in sync with the flir lepton?
|
||||
if ((pid != fir_lepton_spi_rx_cb_expected_pid)
|
||||
#if defined(OMV_FIR_LEPTON_CHECK_CRC)
|
||||
|| (!fir_lepton_spi_check_crc(base))
|
||||
#endif
|
||||
|| (fir_lepton_3 && (pid == VOSPI_SPECIAL_PACKET) && (sid != fir_lepton_spi_rx_cb_expected_sid))) {
|
||||
fir_lepton_spi_rx_cb_expected_pid = 0;
|
||||
fir_lepton_spi_rx_cb_expected_sid = 0;
|
||||
omv_spi_transfer_abort(&spi_bus);
|
||||
omv_gpio_write(spi_bus.cs, 1);
|
||||
fir_lepton_spi_resync();
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(framebuffers[fir_lepton_spi_rx_cb_tail]
|
||||
+ (fir_lepton_spi_rx_cb_expected_pid * VOSPI_PID_SIZE_PIXELS)
|
||||
+ (fir_lepton_spi_rx_cb_expected_sid * VOSPI_SID_SIZE_PIXELS),
|
||||
base + VOSPI_HEADER_WORDS, VOSPI_PID_SIZE_PIXELS * sizeof(uint16_t));
|
||||
|
||||
fir_lepton_spi_rx_cb_expected_pid += 1;
|
||||
if (fir_lepton_spi_rx_cb_expected_pid == VOSPI_PIDS_PER_SID) {
|
||||
fir_lepton_spi_rx_cb_expected_pid = 0;
|
||||
|
||||
bool frame_ready = false;
|
||||
|
||||
// For the FLIR Lepton 3 we have to receive all the pids in all the segments.
|
||||
if (fir_lepton_3) {
|
||||
fir_lepton_spi_rx_cb_expected_sid += 1;
|
||||
if (fir_lepton_spi_rx_cb_expected_sid == VOSPI_SIDS_PER_FRAME) {
|
||||
fir_lepton_spi_rx_cb_expected_sid = 0;
|
||||
frame_ready = true;
|
||||
}
|
||||
// For the FLIR Lepton 1/2 we just have to receive all the pids.
|
||||
} else {
|
||||
frame_ready = true;
|
||||
}
|
||||
|
||||
if (frame_ready) {
|
||||
// Update tail which means a new image is ready.
|
||||
framebuffer_tail = fir_lepton_spi_rx_cb_tail;
|
||||
|
||||
// For triple buffering we are never drawing where tail or head
|
||||
// (which may instantly update to be equal to tail) is.
|
||||
fir_lepton_spi_rx_cb_tail = (fir_lepton_spi_rx_cb_tail + 1) % FRAMEBUFFER_COUNT;
|
||||
if (fir_lepton_spi_rx_cb_tail == framebuffer_head) {
|
||||
fir_lepton_spi_rx_cb_tail = (fir_lepton_spi_rx_cb_tail + 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_VSYNC_PIN)
|
||||
static mp_obj_t fir_lepton_vsync_cb = NULL;
|
||||
|
||||
static void fir_lepton_extint_callback(void *data) {
|
||||
if (fir_lepton_vsync_cb) {
|
||||
mp_call_function_0(fir_lepton_vsync_cb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void fir_lepton_deinit() {
|
||||
omv_spi_transfer_abort(&spi_bus);
|
||||
fir_lepton_spi_rx_cb_expected_pid = 0;
|
||||
fir_lepton_spi_rx_cb_expected_sid = 0;
|
||||
fb_alloc_free_till_mark_past_mark_permanent();
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_MCLK)
|
||||
HAL_TIM_PWM_Stop(&fir_lepton_mclk_tim_handle, OMV_FIR_LEPTON_MCLK_TIM_CHANNEL);
|
||||
HAL_TIM_PWM_DeInit(&fir_lepton_mclk_tim_handle);
|
||||
OMV_FIR_LEPTON_MCLK_TIM_FORCE_RESET();
|
||||
OMV_FIR_LEPTON_MCLK_TIM_RELEASE_RESET();
|
||||
OMV_FIR_LEPTON_MCLK_TIM_CLK_DISABLE();
|
||||
omv_gpio_deinit(OMV_FIR_LEPTON_MCLK_PIN);
|
||||
#endif
|
||||
|
||||
omv_spi_deinit(&spi_bus);
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_RESET_PIN)
|
||||
omv_gpio_deinit(OMV_FIR_LEPTON_RESET_PIN);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_POWER_PIN)
|
||||
omv_gpio_deinit(OMV_FIR_LEPTON_POWER_PIN);
|
||||
#endif
|
||||
}
|
||||
|
||||
int fir_lepton_init(omv_i2c_t *bus, int *w, int *h, int *refresh, int *resolution) {
|
||||
omv_spi_config_t spi_config;
|
||||
omv_spi_default_config(&spi_config, OMV_FIR_LEPTON_SPI_BUS);
|
||||
|
||||
spi_config.baudrate = VOSPI_CLOCK_SPEED;
|
||||
|
||||
spi_config.datasize = 16;
|
||||
spi_config.bus_mode = OMV_SPI_BUS_RX;
|
||||
spi_config.nss_enable = false;
|
||||
spi_config.clk_pol = OMV_SPI_CPOL_HIGH;
|
||||
spi_config.clk_pha = OMV_SPI_CPHA_2EDGE;
|
||||
spi_config.dma_flags = OMV_SPI_DMA_CIRCULAR | OMV_SPI_DMA_DOUBLE;
|
||||
omv_spi_init(&spi_bus, &spi_config);
|
||||
|
||||
omv_gpio_write(spi_bus.cs, 1);
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_RESET_PIN)
|
||||
omv_gpio_config(OMV_FIR_LEPTON_RESET_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_UP, OMV_GPIO_SPEED_LOW, -1);
|
||||
omv_gpio_write(OMV_FIR_LEPTON_RESET_PIN, 1);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_POWER_PIN)
|
||||
omv_gpio_config(OMV_FIR_LEPTON_POWER_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_UP, OMV_GPIO_SPEED_LOW, -1);
|
||||
omv_gpio_write(OMV_FIR_LEPTON_POWER_PIN, 1);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_MCLK_TIM)
|
||||
int tclk = OMV_FIR_LEPTON_MCLK_TIM_PCLK_FREQ() * 2;
|
||||
int period = (tclk / OMV_FIR_LEPTON_MCLK_FREQ) - 1;
|
||||
|
||||
omv_gpio_config(OMV_FIR_LEPTON_MCLK_PIN, OMV_GPIO_MODE_ALT, GPIO_PULLUP, OMV_GPIO_SPEED_MED, -1);
|
||||
|
||||
fir_lepton_mclk_tim_handle.Instance = OMV_FIR_LEPTON_MCLK_TIM;
|
||||
fir_lepton_mclk_tim_handle.Init.Prescaler = 0;
|
||||
fir_lepton_mclk_tim_handle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
fir_lepton_mclk_tim_handle.Init.Period = period;
|
||||
fir_lepton_mclk_tim_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
fir_lepton_mclk_tim_handle.Init.RepetitionCounter = 0;
|
||||
fir_lepton_mclk_tim_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
|
||||
TIM_OC_InitTypeDef fir_lepton_mclk_tim_oc_handle;
|
||||
fir_lepton_mclk_tim_oc_handle.Pulse = period / 2;
|
||||
fir_lepton_mclk_tim_oc_handle.OCMode = TIM_OCMODE_PWM1;
|
||||
fir_lepton_mclk_tim_oc_handle.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
fir_lepton_mclk_tim_oc_handle.OCNPolarity = TIM_OCNPOLARITY_HIGH;
|
||||
fir_lepton_mclk_tim_oc_handle.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
fir_lepton_mclk_tim_oc_handle.OCIdleState = TIM_OCIDLESTATE_RESET;
|
||||
fir_lepton_mclk_tim_oc_handle.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||
|
||||
OMV_FIR_LEPTON_MCLK_TIM_CLK_ENABLE();
|
||||
HAL_TIM_PWM_Init(&fir_lepton_mclk_tim_handle);
|
||||
HAL_TIM_PWM_ConfigChannel(&fir_lepton_mclk_tim_handle,
|
||||
&fir_lepton_mclk_tim_oc_handle,
|
||||
OMV_FIR_LEPTON_MCLK_TIM_CHANNEL);
|
||||
HAL_TIM_PWM_Start(&fir_lepton_mclk_tim_handle, OMV_FIR_LEPTON_MCLK_TIM_CHANNEL);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_POWER_PIN)
|
||||
omv_gpio_write(OMV_FIR_LEPTON_POWER_PIN, 0);
|
||||
mp_hal_delay_ms(10);
|
||||
|
||||
omv_gpio_write(OMV_FIR_LEPTON_POWER_PIN, 1);
|
||||
mp_hal_delay_ms(10);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_RESET_PIN)
|
||||
omv_gpio_write(OMV_FIR_LEPTON_RESET_PIN, 0);
|
||||
mp_hal_delay_ms(10);
|
||||
|
||||
omv_gpio_write(OMV_FIR_LEPTON_RESET_PIN, 1);
|
||||
mp_hal_delay_ms(1000);
|
||||
#endif
|
||||
|
||||
LEP_RAD_ENABLE_E rad;
|
||||
LEP_AGC_ROI_T roi;
|
||||
|
||||
for (uint32_t start = mp_hal_ticks_ms();; mp_hal_delay_ms(1)) {
|
||||
if (LEP_OpenPort(bus, LEP_CCI_TWI, 0, &fir_lepton_handle) == LEP_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - start) >= 1000) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if (!defined(OMV_FIR_LEPTON_POWER_PIN)) && (!defined(OMV_FIR_LEPTON_RESET_PIN))
|
||||
if (LEP_RunOemReboot(&fir_lepton_handle) != LEP_OK) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
mp_hal_delay_ms(1000);
|
||||
#endif
|
||||
|
||||
for (uint32_t start = mp_hal_ticks_ms();; mp_hal_delay_ms(1)) {
|
||||
LEP_SDK_BOOT_STATUS_E status;
|
||||
|
||||
if (LEP_GetCameraBootStatus(&fir_lepton_handle, &status) != LEP_OK) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (status == LEP_BOOT_STATUS_BOOTED) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - start) >= 1000) {
|
||||
return -4;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t start = mp_hal_ticks_ms();; mp_hal_delay_ms(1)) {
|
||||
LEP_UINT16 status;
|
||||
|
||||
if (LEP_DirectReadRegister(&fir_lepton_handle, LEP_I2C_STATUS_REG, &status) != LEP_OK) {
|
||||
return -5;
|
||||
}
|
||||
|
||||
if (!(status & LEP_I2C_STATUS_BUSY_BIT_MASK)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - start) >= 1000) {
|
||||
return -6;
|
||||
}
|
||||
}
|
||||
|
||||
if (LEP_GetAgcROI(&fir_lepton_handle, &roi) != LEP_OK) {
|
||||
return -7;
|
||||
}
|
||||
|
||||
if (LEP_GetRadEnableState(&fir_lepton_handle, &rad) != LEP_OK) {
|
||||
return -8;
|
||||
}
|
||||
|
||||
int flir_w = roi.endCol + 1;
|
||||
int flir_h = roi.endRow + 1;
|
||||
fir_lepton_3 = flir_h > VOSPI_PIDS_PER_SID;
|
||||
fir_lepton_rad_en = rad == LEP_RAD_ENABLE;
|
||||
*w = flir_w;
|
||||
*h = flir_h;
|
||||
*refresh = fir_lepton_3 ? 9 : 27;
|
||||
*resolution = fir_lepton_rad_en ? 16 : 14;
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_VSYNC_PIN)
|
||||
if (LEP_SetOemGpioMode(&fir_lepton_handle, LEP_OEM_GPIO_MODE_VSYNC) != LEP_OK) {
|
||||
return -9;
|
||||
}
|
||||
omv_gpio_config(OMV_FIR_LEPTON_VSYNC_PIN, OMV_GPIO_MODE_IT_FALL, OMV_GPIO_PULL_UP, OMV_GPIO_SPEED_LOW, -1);
|
||||
omv_gpio_irq_register(OMV_FIR_LEPTON_VSYNC_PIN, fir_lepton_extint_callback, NULL);
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
fb_alloc_mark();
|
||||
|
||||
framebuffer_tail = 0;
|
||||
framebuffer_head = 0;
|
||||
|
||||
for (int i = 0; i < FRAMEBUFFER_COUNT; i++) {
|
||||
framebuffers[i] = (uint16_t *) fb_alloc0(flir_w * flir_h * sizeof(uint16_t), FB_ALLOC_NO_HINT);
|
||||
}
|
||||
|
||||
fb_alloc_mark_permanent();
|
||||
fir_lepton_spi_resync();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_VSYNC_PIN)
|
||||
void fir_lepton_register_vsync_cb(mp_obj_t cb) {
|
||||
omv_gpio_irq_enable(OMV_FIR_LEPTON_VSYNC_PIN, false);
|
||||
|
||||
fir_lepton_vsync_cb = cb;
|
||||
|
||||
if (cb != mp_const_none) {
|
||||
omv_gpio_irq_enable(OMV_FIR_LEPTON_VSYNC_PIN, true);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
mp_obj_t fir_lepton_get_radiometry() {
|
||||
return mp_obj_new_bool(fir_lepton_rad_en);
|
||||
}
|
||||
|
||||
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_tail != framebuffer_head);
|
||||
}
|
||||
|
||||
uint16_t *fir_lepton_get_frame(int timeout) {
|
||||
int sampled_framebuffer_tail = framebuffer_tail;
|
||||
|
||||
if (timeout >= 0) {
|
||||
for (uint32_t start = mp_hal_ticks_ms();;) {
|
||||
sampled_framebuffer_tail = framebuffer_tail;
|
||||
|
||||
if (framebuffer_head != sampled_framebuffer_tail) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - start) >= timeout) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Timeout!"));
|
||||
}
|
||||
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
}
|
||||
}
|
||||
|
||||
framebuffer_head = sampled_framebuffer_tail;
|
||||
return framebuffers[sampled_framebuffer_tail];
|
||||
}
|
||||
|
||||
bool fir_lepton_get_radiometry_enabled() {
|
||||
return fir_lepton_rad_en;
|
||||
}
|
||||
|
||||
int fir_lepton_get_temperature() {
|
||||
LEP_SYS_FPA_TEMPERATURE_KELVIN_T kelvin;
|
||||
|
||||
if (LEP_GetSysFpaTemperatureKelvin(&fir_lepton_handle, &kelvin) != LEP_OK) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("FPA Error!"));
|
||||
}
|
||||
|
||||
return kelvin;
|
||||
}
|
||||
|
||||
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, 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(timeout);
|
||||
float min = +FLT_MAX;
|
||||
float max = -FLT_MAX;
|
||||
int w_1 = w - 1;
|
||||
int h_1 = h - 1;
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
int y_dst = flip ? (h_1 - y) : y;
|
||||
const uint16_t *raw_row = data + (y * w);
|
||||
mp_obj_t *list_row = list->items + (y_dst * w);
|
||||
mp_obj_t *t_list_row = list->items + y_dst;
|
||||
|
||||
for (int x = 0; x < w; x++) {
|
||||
int x_dst = mirror ? (w_1 - x) : x;
|
||||
int raw = raw_row[x];
|
||||
|
||||
if (!fir_lepton_rad_en) {
|
||||
raw = (raw - 8192) + kelvin;
|
||||
}
|
||||
|
||||
float celcius = (raw * 0.01f) - 273.15f;
|
||||
|
||||
if (celcius < min) {
|
||||
min = celcius;
|
||||
}
|
||||
|
||||
if (celcius > max) {
|
||||
max = celcius;
|
||||
}
|
||||
|
||||
mp_obj_t f = mp_obj_new_float(celcius);
|
||||
|
||||
if (!transpose) {
|
||||
list_row[x_dst] = f;
|
||||
} else {
|
||||
t_list_row[x_dst * h] = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mp_obj_t tuple[4];
|
||||
tuple[0] = mp_obj_new_float((kelvin * 0.01f) - 273.15f);
|
||||
tuple[1] = MP_OBJ_FROM_PTR(list);
|
||||
tuple[2] = mp_obj_new_float(min);
|
||||
tuple[3] = mp_obj_new_float(max);
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
}
|
||||
|
||||
void fir_lepton_trigger_ffc(int timeout) {
|
||||
if (LEP_RunSysFFCNormalization(&fir_lepton_handle) != LEP_OK) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("FFC Error!"));
|
||||
}
|
||||
|
||||
if (timeout >= 0) {
|
||||
for (uint32_t start = mp_hal_ticks_ms();;) {
|
||||
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 (status == LEP_SYS_STATUS_READY) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - start) >= timeout) {
|
||||
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Timeout!"));
|
||||
}
|
||||
|
||||
mp_hal_delay_ms(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OMV_FIR_LEPTON_ENABLE
|
||||
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* Copyright (C) 2013-2024 OpenMV, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* FIR Python module.
|
||||
*/
|
||||
#ifndef __PY_FIR_LEPTON_H__
|
||||
#define __PY_FIR_LEPTON_H__
|
||||
void fir_lepton_deinit();
|
||||
int fir_lepton_init(omv_i2c_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();
|
||||
uint16_t *fir_lepton_get_frame(int timeout);
|
||||
bool fir_lepton_get_radiometry_enabled();
|
||||
int fir_lepton_get_temperature();
|
||||
mp_obj_t fir_lepton_read_ta();
|
||||
mp_obj_t fir_lepton_read_ir(int w, int h, bool mirror, bool flip, bool transpose, int timeout);
|
||||
void fir_lepton_trigger_ffc(int timeout);
|
||||
#endif // __PY_FIR_LEPTON_H__
|
||||
@ -271,16 +271,6 @@ void HAL_MspInit(void) {
|
||||
OMV_AXI_QOS_LTDC_W_SET(OMV_AXI_QOS_LTDC_W_PRI);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_RESET_PIN)
|
||||
omv_gpio_config(OMV_FIR_LEPTON_RESET_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
|
||||
omv_gpio_write(OMV_FIR_LEPTON_RESET_PIN, 0);
|
||||
#endif
|
||||
|
||||
#if defined(OMV_FIR_LEPTON_POWER_PIN)
|
||||
omv_gpio_config(OMV_FIR_LEPTON_POWER_PIN, OMV_GPIO_MODE_OUTPUT, OMV_GPIO_PULL_NONE, OMV_GPIO_SPEED_LOW, -1);
|
||||
omv_gpio_write(OMV_FIR_LEPTON_POWER_PIN, 0);
|
||||
#endif
|
||||
|
||||
#if defined(STM32H7)
|
||||
// This disconnects PA0/PA1 from PA0_C/PA1_C.
|
||||
// PA0_C/PA1_C connect to ADC1/2 Channels P0/P1
|
||||
|
||||
@ -4,14 +4,14 @@
|
||||
#
|
||||
# Pure Thermal Example Script
|
||||
#
|
||||
# Thanks for buying the Pure Thermal OpenMV! This example script shows off thermal video
|
||||
# overlay onto the color camera image and driving the attached LCD screen and HDMI output.
|
||||
# Thanks for buying the Pure Thermal OpenMV! This example script shows
|
||||
# off thermal video overlay onto the color camera image and driving
|
||||
# the attached LCD screen and HDMI output.
|
||||
|
||||
import sensor
|
||||
import csi
|
||||
import image
|
||||
import time
|
||||
import display
|
||||
import fir
|
||||
import math
|
||||
import tfp410
|
||||
|
||||
@ -19,13 +19,42 @@ import tfp410
|
||||
# Color Tracking Thresholds (Grayscale Min, Grayscale Max)
|
||||
threshold_list = [(200, 255)]
|
||||
|
||||
sensor.reset()
|
||||
sensor.set_pixformat(sensor.RGB565)
|
||||
sensor.set_framesize(sensor.WVGA)
|
||||
# Set the target temp range here
|
||||
min_temp_in_celsius = 20.0
|
||||
max_temp_in_celsius = 40.0
|
||||
|
||||
csi0 = csi.CSI(cid=csi.OV5640)
|
||||
csi0.reset()
|
||||
csi0.pixformat(csi.RGB565)
|
||||
csi0.framesize(csi.WVGA)
|
||||
time.sleep_ms(50)
|
||||
|
||||
fir.init(fir.FIR_LEPTON)
|
||||
fir_img = image.Image(fir.width(), fir.height(), sensor.GRAYSCALE)
|
||||
csi1 = csi.CSI(cid=csi.LEPTON)
|
||||
csi1.reset(hard=False)
|
||||
csi1.pixformat(csi.GRAYSCALE)
|
||||
csi1.framesize(csi.QQVGA)
|
||||
|
||||
# Enables exact temperature measurments from the flir lepton.
|
||||
# The second argument turns high gain mode on for high temp reading.
|
||||
csi1.ioctl(csi.IOCTL_LEPTON_SET_MODE, True, False)
|
||||
csi1.ioctl(
|
||||
csi.IOCTL_LEPTON_SET_RANGE, min_temp_in_celsius, max_temp_in_celsius
|
||||
)
|
||||
|
||||
print(
|
||||
"Lepton Res (%dx%d)"
|
||||
% (
|
||||
csi1.ioctl(csi.IOCTL_LEPTON_GET_WIDTH),
|
||||
csi1.ioctl(csi.IOCTL_LEPTON_GET_HEIGHT),
|
||||
)
|
||||
)
|
||||
|
||||
print(
|
||||
"Radiometry Available: "
|
||||
+ ("Yes" if csi1.ioctl(csi.IOCTL_LEPTON_GET_RADIOMETRY) else "No")
|
||||
)
|
||||
|
||||
fir_img = image.Image(csi1.width(), csi1.height(), image.GRAYSCALE)
|
||||
time.sleep_ms(50)
|
||||
|
||||
lcd = display.RGBDisplay(framesize=display.FWVGA, refresh=60)
|
||||
@ -33,7 +62,7 @@ lcd.backlight(True)
|
||||
hdmi = tfp410.TFP410()
|
||||
time.sleep_ms(50)
|
||||
|
||||
alpha_pal = image.Image(256, 1, sensor.GRAYSCALE)
|
||||
alpha_pal = image.Image(256, 1, image.GRAYSCALE)
|
||||
for i in range(256):
|
||||
alpha_pal[i] = int(math.pow((i / 255), 2) * 255)
|
||||
|
||||
@ -42,18 +71,20 @@ to_max = None
|
||||
|
||||
|
||||
def map_g_to_temp(g):
|
||||
return ((g * (to_max - to_min)) / 255.0) + to_min
|
||||
return (
|
||||
(g * (max_temp_in_celsius - min_temp_in_celsius)) / 255.0
|
||||
) + min_temp_in_celsius
|
||||
|
||||
|
||||
# Kickstart thermal camera capture.
|
||||
csi1.snapshot(update=False, blocking=True, image=fir_img)
|
||||
|
||||
while True:
|
||||
img = sensor.snapshot()
|
||||
# ta: Ambient temperature
|
||||
# ir: Object temperatures (IR array)
|
||||
# to_min: Minimum object temperature
|
||||
# to_max: Maximum object temperature
|
||||
ta, ir, to_min, to_max = fir.read_ir()
|
||||
img = csi0.snapshot()
|
||||
|
||||
# Capture the thermal image without blocking.
|
||||
csi1.snapshot(update=False, blocking=False, image=fir_img)
|
||||
|
||||
fir.draw_ir(fir_img, ir, color_palette=None)
|
||||
fir_img_size = fir_img.width() * fir_img.height()
|
||||
|
||||
# Find IR Blobs
|
||||
@ -65,8 +96,12 @@ while True:
|
||||
# Collect stats into a list of tuples
|
||||
blob_stats = []
|
||||
for b in blobs:
|
||||
blob_stats.append((b.rect(), map_g_to_temp(img.get_statistics(thresholds=threshold_list,
|
||||
roi=b.rect()).mean())))
|
||||
blob_stats.append(
|
||||
(b.rect(), map_g_to_temp(fir_img.get_statistics(
|
||||
thresholds=threshold_list, roi=b.rect()
|
||||
).mean()))
|
||||
)
|
||||
|
||||
x_scale = img.width() / fir_img.width()
|
||||
y_scale = img.height() / fir_img.height()
|
||||
img.draw_image(fir_img, 0, 0, x_scale=x_scale, y_scale=y_scale,
|
||||
@ -76,19 +111,17 @@ while True:
|
||||
|
||||
# Draw stuff on the colored image
|
||||
for b in blobs:
|
||||
img.draw_rectangle(int(b.rect()[0] * x_scale), int(b.rect()[1] * y_scale),
|
||||
int(b.rect()[2] * x_scale), int(b.rect()[3] * y_scale))
|
||||
img.draw_rectangle(int(b.rect()[0] * x_scale),
|
||||
int(b.rect()[1] * y_scale),
|
||||
int(b.rect()[2] * x_scale),
|
||||
int(b.rect()[3] * y_scale))
|
||||
img.draw_cross(int(b.cx() * x_scale), int(b.cy() * y_scale))
|
||||
|
||||
for blob_stat in blob_stats:
|
||||
img.draw_string(int((blob_stat[0][0] * x_scale) + 4), int((blob_stat[0][1] * y_scale) + 1),
|
||||
img.draw_string(int((blob_stat[0][0] * x_scale) + 4),
|
||||
int((blob_stat[0][1] * y_scale) + 1),
|
||||
'%.2f C' % blob_stat[1], mono_space=False, scale=2)
|
||||
|
||||
# Draw ambient, min and max temperatures.
|
||||
img.draw_string(4, 0, 'Lepton Temp: %0.2f C' % ta,
|
||||
color=(255, 255, 255), mono_space=False, scale=2)
|
||||
img.draw_string(4, 18, 'Min Temp: %0.2f C' % to_min,
|
||||
color=(255, 255, 255), mono_space=False, scale=2)
|
||||
img.draw_string(4, 36, 'Max Temp: %0.2f C' % to_max,
|
||||
color=(255, 255, 255), mono_space=False, scale=2)
|
||||
|
||||
lcd.write(img, hint=(image.BILINEAR | image.CENTER | image.SCALE_ASPECT_KEEP))
|
||||
lcd.write(img, hint=(
|
||||
image.BILINEAR | image.CENTER | image.SCALE_ASPECT_KEEP
|
||||
))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user