Merge pull request #2787 from openmv/fix_lepton_driver
Some checks are pending
🔥 Firmware Build / build-firmware (ARDUINO_GIGA) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_33_BLE_SENSE) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NANO_RP2040_CONNECT) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_NICLA_VISION) (push) Waiting to run
🔥 Firmware Build / build-firmware (ARDUINO_PORTENTA_H7) (push) Waiting to run
🔥 Firmware Build / build-firmware (DOCKER) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV2) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV4P) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMVPT) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_AE3) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_N6) (push) Waiting to run
🔥 Firmware Build / build-firmware (OPENMV_RT1060) (push) Waiting to run
🔥 Firmware Build / code-size-report (push) Blocked by required conditions
🔥 Firmware Build / stable-release (push) Blocked by required conditions
🔥 Firmware Build / development-release (push) Blocked by required conditions

drivers/sensors: Optimize Lepton delays.
This commit is contained in:
Ibrahim Abdelkader 2025-08-02 14:38:04 +03:00 committed by GitHub
commit a11eb9d6a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 51 additions and 59 deletions

View File

@ -334,6 +334,17 @@ __weak int omv_csi_reset(omv_csi_t *csi, bool hard) {
mp_hal_delay_ms(10);
omv_gpio_write(OMV_CSI_RESET_PIN, 1);
}
// Track elapsed time since last hard-reset.
// Note hard-reset is shared between all CSIs.
uint32_t reset_time_ms = mp_hal_ticks_ms();
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
omv_csi_t *csi = &csi_all[i];
if (csi->detected) {
csi->reset_time_ms = reset_time_ms;
}
}
#endif
mp_hal_delay_ms(OMV_CSI_RESET_DELAY);
@ -501,7 +512,7 @@ int omv_csi_probe(omv_i2c_t *i2c) {
dev_count = omv_csi_detect(i2c, dev_list);
}
// Set the current ms for tracking elapsed time since power-on.
// Track elapsed time since power-on.
uint32_t power_time_ms = mp_hal_ticks_ms();
// Add special devices, such as SPI sensors, soft-CSI etc...
@ -537,6 +548,7 @@ int omv_csi_probe(omv_i2c_t *i2c) {
csi->chip_id = dev_list[i].chip_id;
csi->slv_addr = dev_list[i].slv_addr;
csi->power_time_ms = power_time_ms;
csi->reset_time_ms = power_time_ms;
// Find the sensors init function.
for (size_t i=0; i<OMV_ARRAY_SIZE(sensor_config_table); i++) {

View File

@ -355,6 +355,7 @@ typedef struct _omv_csi {
framebuffer_t *fb; // Frame buffer pointer
omv_clk_t *clk; // Clock controller.
uint32_t clk_hz; // Clock freqeuency request by this CSI.
uint32_t reset_time_ms; // To track elapsed time since hard-reset.
uint32_t power_time_ms; // To track elapsed time since power on.
#ifdef OMV_CSI_PORT_BITS

View File

@ -79,7 +79,7 @@ extern "C"
/* Timeout count to wait for I2C command to complete
*/
#define LEPTON_I2C_COMMAND_BUSY_WAIT_COUNT 1000
#define LEPTON_I2C_COMMAND_BUSY_WAIT_COUNT 5000
/******************************************************************************/
/** EXPORTED TYPE DEFINITIONS **/

View File

@ -436,14 +436,12 @@ LEP_RESULT LEP_I2C_SetAttribute(LEP_CAMERA_PORT_DESC_T_PTR portDescPtr,
return(result);
}
LEP_RESULT LEP_I2C_RunCommand(LEP_CAMERA_PORT_DESC_T_PTR portDescPtr,
LEP_COMMAND_ID commandID)
{
LEP_RESULT result;
LEP_UINT16 statusReg;
LEP_INT16 statusCode;
LEP_UINT32 done;
LEP_UINT16 timeoutCount = LEPTON_I2C_COMMAND_BUSY_WAIT_COUNT;
/* Implement the Lepton TWI WRITE Protocol
@ -452,30 +450,25 @@ LEP_RESULT LEP_I2C_RunCommand(LEP_CAMERA_PORT_DESC_T_PTR portDescPtr,
** command by polling the STATUS REGISTER BUSY Bit until it
** reports NOT BUSY.
*/
do
{
do {
/* Read the Status REGISTER and peek at the BUSY Bit
*/
result = LEP_I2C_MasterReadRegister( portDescPtr->bus,
portDescPtr->deviceAddress,
LEP_I2C_STATUS_REG,
&statusReg);
if(result != LEP_OK)
{
return(result);
if (result != LEP_OK) {
return result;
}
done = (statusReg & LEP_I2C_STATUS_BUSY_BIT_MASK)? 0: 1;
/* Add timout check */
if( timeoutCount-- == 0 )
{
/* Timed out waiting for command busy to go away
*/
if (timeoutCount-- == 0) {
return LEP_ERROR;
}
}while( !done );
} while((statusReg & LEP_I2C_STATUS_BUSY_BIT_MASK));
if( result == LEP_OK )
{
timeoutCount = LEPTON_I2C_COMMAND_BUSY_WAIT_COUNT;
if( result == LEP_OK ) {
/* Set the Lepton's DATA LENGTH REGISTER first to inform the
** Lepton Camera no 16-bit DATA words being transferred.
*/
@ -484,51 +477,43 @@ LEP_RESULT LEP_I2C_RunCommand(LEP_CAMERA_PORT_DESC_T_PTR portDescPtr,
LEP_I2C_DATA_LENGTH_REG,
(LEP_UINT16)0);
if( result == LEP_OK )
{
if (result == LEP_OK) {
/* Now issue the Run Command
*/
result = LEP_I2C_MasterWriteRegister( portDescPtr->bus,
portDescPtr->deviceAddress,
LEP_I2C_COMMAND_REG,
commandID);
if( result == LEP_OK )
{
if( result == LEP_OK ) {
/* Now wait until the Camera has completed this command by
** polling the statusReg REGISTER BUSY Bit until it reports NOT
** BUSY.
*/
do
{
do {
/* Read the statusReg REGISTER and peek at the BUSY Bit
*/
result = LEP_I2C_MasterReadRegister( portDescPtr->bus,
portDescPtr->deviceAddress,
LEP_I2C_STATUS_REG,
&statusReg);
if(result != LEP_OK)
{
if (result != LEP_OK) {
return(result);
}
done = (statusReg & LEP_I2C_STATUS_BUSY_BIT_MASK)? 0: 1;
/* Timeout? */
}while( !done );
if (timeoutCount-- == 0) {
return LEP_ERROR;
}
} while(statusReg & LEP_I2C_STATUS_BUSY_BIT_MASK);
statusCode = (statusReg >> 8) ? ((statusReg >> 8) | 0xFF00) : 0;
if(statusCode)
{
return((LEP_RESULT)statusCode);
if (statusCode) {
return (LEP_RESULT) statusCode;
}
}
}
}
/* Check statusReg word for Errors?
*/
return(result);
return result;
}
LEP_RESULT LEP_I2C_DirectReadRegister(LEP_CAMERA_PORT_DESC_T_PTR portDescPtr,

View File

@ -44,6 +44,8 @@
#include "LEPTON_I2C_Reg.h"
#define LEPTON_BOOT_TIMEOUT (3000)
#define LEPTON_COLD_BOOT_DELAY (2000)
#define LEPTON_WARM_BOOT_DELAY (1000)
#define LEPTON_SNAPSHOT_RETRY (3)
#define LEPTON_SNAPSHOT_TIMEOUT (5000)
#define LEPTON_I2C_STATUS_BOOT (LEP_I2C_STATUS_BOOT_MODE_MASK | LEP_I2C_STATUS_BOOT_STAT_MASK)
@ -72,7 +74,7 @@ typedef struct lepton_state {
static lepton_state_t lepton;
static int lepton_reset(omv_csi_t *csi, bool measurement_mode, bool high_temp_mode);
static int lepton_config(omv_csi_t *csi, bool measurement_mode, bool high_temp_mode);
static int read_reg(omv_csi_t *csi, uint16_t reg_addr) {
uint16_t reg_data;
@ -232,7 +234,7 @@ static int ioctl(omv_csi_t *csi, int request, va_list ap) {
if (lepton.measurement_mode != measurement_mode_in) {
lepton.measurement_mode = measurement_mode_in;
lepton.high_temp_mode = high_temp_mode_in;
ret = lepton_reset(csi, lepton.measurement_mode, lepton.high_temp_mode);
ret = lepton_config(csi, lepton.measurement_mode, lepton.high_temp_mode);
}
break;
}
@ -269,20 +271,10 @@ static int ioctl(omv_csi_t *csi, int request, va_list ap) {
return ret;
}
static int lepton_reset(omv_csi_t *csi, bool measurement_mode, bool high_temp_mode) {
static int lepton_config(omv_csi_t *csi, bool measurement_mode, bool high_temp_mode) {
LEP_RAD_ENABLE_E rad;
LEP_AGC_ROI_T roi;
memset(&lepton.port, 0, sizeof(LEP_CAMERA_PORT_DESC_T));
if (!csi->auxiliary) {
omv_gpio_write(OMV_CSI_RESET_PIN, 0);
mp_hal_delay_ms(100);
omv_gpio_write(OMV_CSI_RESET_PIN, 1);
mp_hal_delay_ms(2500);
}
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) {
if (LEP_OpenPort(csi->i2c, LEP_CCI_TWI, 0, &lepton.port) == LEP_OK) {
break;
@ -293,10 +285,9 @@ static int lepton_reset(omv_csi_t *csi, bool measurement_mode, bool high_temp_mo
}
}
if (csi->auxiliary) {
LEP_RunOemReboot(&lepton.port);
mp_hal_delay_ms(1500);
}
// Soft-reboot Lepton
LEP_RunOemReboot(&lepton.port);
mp_hal_delay_ms(LEPTON_WARM_BOOT_DELAY);
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) {
LEP_UINT16 status;
@ -348,10 +339,13 @@ static int reset(omv_csi_t *csi) {
lepton.min_temp = LEPTON_MIN_TEMP_DEFAULT;
lepton.max_temp = LEPTON_MAX_TEMP_DEFAULT;
// Extra delay after power-on
mp_hal_delay_ms(1500);
// Extra delay after hard-reset.
uint32_t ticks_diff = mp_hal_ticks_ms() - csi->reset_time_ms;
if (ticks_diff < LEPTON_COLD_BOOT_DELAY) {
mp_hal_delay_ms(LEPTON_COLD_BOOT_DELAY - ticks_diff);
}
if (lepton_reset(csi, false, false) != 0) {
if (lepton_config(csi, false, false) != 0) {
return OMV_CSI_ERROR_CTL_FAILED;
}
@ -426,14 +420,14 @@ static int snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
return OMV_CSI_ERROR_WOULD_BLOCK;
}
// Reset the FLIR lepton on timeout, up to LEPTON_SNAPSHOT_RETRY.
// Reset the module on timeout, up to LEPTON_SNAPSHOT_RETRY times.
if ((mp_hal_ticks_ms() - tick_start) > LEPTON_SNAPSHOT_TIMEOUT) {
if (reset_retry++ == LEPTON_SNAPSHOT_RETRY) {
vospi_abort();
return OMV_CSI_ERROR_CAPTURE_TIMEOUT;
}
if (lepton_reset(csi, lepton.measurement_mode, lepton.high_temp_mode) != 0) {
if (lepton_config(csi, lepton.measurement_mode, lepton.high_temp_mode) != 0) {
return OMV_CSI_ERROR_CTL_FAILED;
}