mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Merge pull request #2743 from openmv/add_csi_shutdown
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
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
common/csi: Add csi shutdown op.
This commit is contained in:
commit
7bd8c2ce53
@ -50,7 +50,7 @@
|
||||
#define OMV_LEPTON_ENABLE (1)
|
||||
#define OMV_PAG7936_ENABLE (1)
|
||||
#define OMV_PAG7936_MIPI_CSI2 (1)
|
||||
#define OMV_SOFTCSI_ENABLE (0)
|
||||
#define OMV_SOFTCSI_ENABLE (1)
|
||||
#define OMV_PS5520_ENABLE (1)
|
||||
#define OMV_GENX320_EHC_ENABLE (1)
|
||||
#define OMV_GENX320_HSYNC_VALUE (0x1)
|
||||
|
||||
@ -130,9 +130,6 @@ __weak void omv_csi_init0() {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Abort ongoing transfer
|
||||
omv_csi_abort(csi, true, false);
|
||||
|
||||
// Reset delays
|
||||
csi->disable_delays = false;
|
||||
|
||||
@ -202,9 +199,23 @@ __weak int omv_csi_abort(omv_csi_t *csi, bool fifo_flush, bool in_irq) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void omv_csi_abort_all(void) {
|
||||
for (size_t i=0; i<OMV_CSI_MAX_DEVICES; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
|
||||
// Abort ongoing transfer
|
||||
if (csi->detected) {
|
||||
omv_csi_abort(csi, true, false);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__weak int omv_csi_reset(omv_csi_t *csi, bool hard) {
|
||||
// Disable any ongoing frame capture.
|
||||
omv_csi_abort(csi, true, false);
|
||||
if (csi->power_on) {
|
||||
omv_csi_abort(csi, true, false);
|
||||
}
|
||||
|
||||
// Reset the csi state
|
||||
csi->sde = 0;
|
||||
@ -224,16 +235,15 @@ __weak int omv_csi_reset(omv_csi_t *csi, bool hard) {
|
||||
#else
|
||||
csi->auto_rotation = false;
|
||||
#endif // MICROPY_PY_IMU
|
||||
|
||||
csi->vsync_cb = (omv_csi_cb_t) { NULL, NULL };
|
||||
csi->frame_cb = (omv_csi_cb_t) { NULL, NULL };
|
||||
|
||||
// Reset default color palette.
|
||||
csi->color_palette = rainbow_table;
|
||||
csi->disable_full_flush = false;
|
||||
|
||||
csi->vsync_cb = (omv_csi_cb_t) { NULL, NULL };
|
||||
csi->frame_cb = (omv_csi_cb_t) { NULL, NULL };
|
||||
|
||||
// Restore shutdown state on reset.
|
||||
omv_csi_shutdown(csi, false);
|
||||
if (!csi->power_on) {
|
||||
omv_csi_shutdown(csi, false);
|
||||
}
|
||||
|
||||
if (hard) {
|
||||
// Disable the bus before reset.
|
||||
@ -437,22 +447,21 @@ int omv_csi_probe(omv_i2c_t *i2c) {
|
||||
// Initialize detected sensors.
|
||||
for (size_t i=0; i<dev_count; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
sensor_init_t init_fun = NULL;
|
||||
|
||||
csi->detected = true;
|
||||
csi->power_on = true;
|
||||
csi->power_pol = power_pol;
|
||||
csi->reset_pol = reset_pol;
|
||||
csi->chip_id = dev_list[i].chip_id;
|
||||
csi->slv_addr = dev_list[i].slv_addr;
|
||||
csi->detected = true;
|
||||
|
||||
uint32_t clk_hz = 0;
|
||||
sensor_init_t init_fun = NULL;
|
||||
|
||||
// Find the sensors init function.
|
||||
for (size_t i=0; i<OMV_ARRAY_SIZE(sensor_config_table); i++) {
|
||||
const sensor_config_t *config = &sensor_config_table[i];
|
||||
if (csi->chip_id == config->chip_id) {
|
||||
clk_hz = config->clk_hz;
|
||||
init_fun = config->init_fun;
|
||||
csi->clk_hz = config->clk_hz;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -466,35 +475,34 @@ int omv_csi_probe(omv_i2c_t *i2c) {
|
||||
// Special case for OV5640.
|
||||
#if (OMV_OV5640_REV_Y_CHECK == 1)
|
||||
if (csi->chip_id == OV5640_ID && HAL_GetREVID() < 0x2003) {
|
||||
clk_hz = OMV_OV5640_REV_Y_FREQ;
|
||||
csi->clk_hz = OMV_OV5640_REV_Y_FREQ;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Allow reconfiguring (or disabling) the external clock
|
||||
// if just one sensor is detected, or for main sensors.
|
||||
if (dev_count == 1 || !csi->auxiliary) {
|
||||
omv_csi_set_clk_frequency(clk_hz);
|
||||
omv_csi_set_clk_frequency(csi->clk_hz);
|
||||
}
|
||||
|
||||
// Count aux devices.
|
||||
aux_count += csi->auxiliary;
|
||||
}
|
||||
|
||||
// Special case: A single aux sensor was detected, clear
|
||||
// the auxiliary flag so it gets used as the main sensor.
|
||||
if (dev_count == 1 && csi_all[0].auxiliary) {
|
||||
csi_all[0].auxiliary = 0;
|
||||
aux_count--;
|
||||
}
|
||||
|
||||
// Special case: Soft-CSI and another aux sensor detected,
|
||||
// (Lepton for example). Use Soft-CSI for the main sensor.
|
||||
// Special case: all detected sensors are aux (e.g., Soft-CSI or
|
||||
// Soft-CSI + Lepton). If only one is found, use it as main. If
|
||||
// multiple, pick the first non-Soft-CSI sensor as main.
|
||||
if (dev_count == aux_count) {
|
||||
for (size_t i=0; i<dev_count; i++) {
|
||||
omv_csi_t *csi = &csi_all[i];
|
||||
if (csi->chip_id == SOFTCSI_ID) {
|
||||
csi->auxiliary = 0;
|
||||
if (dev_count == 1 || csi->chip_id != SOFTCSI_ID) {
|
||||
aux_count--;
|
||||
csi->auxiliary = 0;
|
||||
// If more than one aux sensor was detected, the clock
|
||||
// hasn't been changed, so reconfigure using this freq.
|
||||
if (dev_count > 1) {
|
||||
omv_csi_set_clk_frequency(csi->clk_hz);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -576,10 +584,18 @@ __weak int omv_csi_shutdown(omv_csi_t *csi, int enable) {
|
||||
} else {
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 1);
|
||||
}
|
||||
mp_hal_delay_ms(OMV_CSI_POWER_DELAY);
|
||||
}
|
||||
#endif
|
||||
|
||||
mp_hal_delay_ms(10);
|
||||
// Call csi-specific shutdown function
|
||||
if (csi->shutdown != NULL &&
|
||||
csi->shutdown(csi, enable) != 0) {
|
||||
return OMV_CSI_ERROR_CTL_FAILED;
|
||||
}
|
||||
|
||||
// Update power-on flag.
|
||||
csi->power_on = !enable;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -115,9 +115,10 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
OMV_CSI_CONFIG_INIT = (1 << 0),
|
||||
OMV_CSI_CONFIG_FRAMESIZE = (1 << 1),
|
||||
OMV_CSI_CONFIG_PIXFORMAT = (1 << 2),
|
||||
OMV_CSI_CONFIG_WINDOWING = (1 << 3),
|
||||
OMV_CSI_CONFIG_DEINIT = (1 << 1),
|
||||
OMV_CSI_CONFIG_FRAMESIZE = (1 << 2),
|
||||
OMV_CSI_CONFIG_PIXFORMAT = (1 << 3),
|
||||
OMV_CSI_CONFIG_WINDOWING = (1 << 4),
|
||||
} omv_csi_config_t;
|
||||
|
||||
typedef enum {
|
||||
@ -337,6 +338,8 @@ typedef struct _omv_csi {
|
||||
bool transpose; // Transpose Image
|
||||
bool auto_rotation; // Rotate Image Automatically
|
||||
bool detected; // Set to true when the sensor is initialized.
|
||||
bool power_on; // Set to true when the sensor is active.
|
||||
uint32_t clk_hz; // Clock frequency requested by the driver.
|
||||
|
||||
omv_i2c_t *i2c; // SCCB/I2C bus.
|
||||
framebuffer_t *fb; // Frame buffer pointer
|
||||
@ -354,6 +357,7 @@ typedef struct _omv_csi {
|
||||
// Sensor function pointers
|
||||
int (*reset) (omv_csi_t *csi);
|
||||
int (*sleep) (omv_csi_t *csi, int enable);
|
||||
int (*shutdown) (omv_csi_t *csi, int enable);
|
||||
int (*match) (omv_csi_t *csi, size_t id);
|
||||
int (*read_reg) (omv_csi_t *csi, uint16_t reg_addr);
|
||||
int (*write_reg) (omv_csi_t *csi, uint16_t reg_addr, uint16_t reg_data);
|
||||
@ -413,6 +417,9 @@ int omv_csi_config(omv_csi_t *csi, omv_csi_config_t config);
|
||||
// Abort frame capture and disable IRQs, DMA etc..
|
||||
int omv_csi_abort(omv_csi_t *csi, bool fifo_flush, bool in_irq);
|
||||
|
||||
// Call on soft-reboot
|
||||
void omv_csi_abort_all(void);
|
||||
|
||||
// Reset the sensor to its default state.
|
||||
int omv_csi_reset(omv_csi_t *csi, bool hard);
|
||||
|
||||
|
||||
@ -136,10 +136,8 @@ void vospi_callback(omv_spi_t *spi, void *userdata, void *buf) {
|
||||
|| (!vospi_check_crc(base))
|
||||
#endif
|
||||
|| (vospi.lepton_3 && (pid == VOSPI_SPECIAL_PACKET) && (sid != vospi.sid))) {
|
||||
vospi.pid = 0;
|
||||
vospi.sid = 0;
|
||||
omv_spi_transfer_abort(&vospi.spi_bus);
|
||||
vospi.flags |= VOSPI_FLAGS_RESYNC;
|
||||
vospi_abort();
|
||||
vospi.flags |= VOSPI_FLAGS_CAPTURE;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -196,6 +194,15 @@ int vospi_deinit() {
|
||||
return omv_spi_deinit(&vospi.spi_bus);
|
||||
}
|
||||
|
||||
int vospi_abort(void) {
|
||||
vospi.flags &= ~VOSPI_FLAGS_CAPTURE;
|
||||
int ret = omv_spi_transfer_abort(&vospi.spi_bus);
|
||||
vospi.pid = 0;
|
||||
vospi.sid = 0;
|
||||
vospi.flags |= VOSPI_FLAGS_RESYNC;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool vospi_active(void) {
|
||||
return vospi.flags & VOSPI_FLAGS_CAPTURE;
|
||||
}
|
||||
@ -224,10 +231,7 @@ int vospi_snapshot(uint32_t timeout_ms) {
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - tick_start) > timeout_ms) {
|
||||
omv_spi_transfer_abort(&vospi.spi_bus);
|
||||
vospi.pid = 0;
|
||||
vospi.sid = 0;
|
||||
vospi.flags = VOSPI_FLAGS_RESYNC;
|
||||
vospi_abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
#include "framebuffer.h"
|
||||
int vospi_init(uint32_t n_packets, framebuffer_t *fb);
|
||||
int vospi_deinit();
|
||||
int vospi_abort(void);
|
||||
bool vospi_active(void);
|
||||
int vospi_snapshot(uint32_t timeout_ms);
|
||||
#endif // __VOSPI_H__
|
||||
|
||||
@ -129,7 +129,8 @@ extern "C"
|
||||
#define LEP_I2C_DATA_BUFFER_1_LENGTH 0x400
|
||||
|
||||
#define LEP_I2C_STATUS_BUSY_BIT_MASK 0x0001 /* Bit 0 is the Busy Bit */
|
||||
|
||||
#define LEP_I2C_STATUS_BOOT_MODE_MASK 0x0002 /* Bit 1 is the boot mode */
|
||||
#define LEP_I2C_STATUS_BOOT_STAT_MASK 0x0004 /* Bit 2 is the boot status */
|
||||
|
||||
/******************************************************************************/
|
||||
/** EXPORTED TYPE DEFINITIONS **/
|
||||
|
||||
@ -43,9 +43,10 @@
|
||||
#include "LEPTON_RAD.h"
|
||||
#include "LEPTON_I2C_Reg.h"
|
||||
|
||||
#define LEPTON_BOOT_TIMEOUT (1000)
|
||||
#define LEPTON_BOOT_TIMEOUT (3000)
|
||||
#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)
|
||||
|
||||
// Min/Max temperatures in Celsius.
|
||||
#define LEPTON_MIN_TEMP_NORM (-10.0f)
|
||||
@ -271,23 +272,18 @@ static int ioctl(omv_csi_t *csi, int request, va_list ap) {
|
||||
static int lepton_reset(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_POWER_PIN, 0);
|
||||
mp_hal_delay_ms(10);
|
||||
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 1);
|
||||
mp_hal_delay_ms(10);
|
||||
|
||||
omv_gpio_write(OMV_CSI_RESET_PIN, 0);
|
||||
mp_hal_delay_ms(10);
|
||||
mp_hal_delay_ms(100);
|
||||
|
||||
omv_gpio_write(OMV_CSI_RESET_PIN, 1);
|
||||
mp_hal_delay_ms(1000);
|
||||
mp_hal_delay_ms(2500);
|
||||
}
|
||||
|
||||
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(1)) {
|
||||
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;
|
||||
}
|
||||
@ -299,31 +295,14 @@ 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(1000);
|
||||
mp_hal_delay_ms(1500);
|
||||
}
|
||||
|
||||
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(1)) {
|
||||
LEP_SDK_BOOT_STATUS_E status;
|
||||
if (LEP_GetCameraBootStatus(&lepton.port, &status) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (status == LEP_BOOT_STATUS_BOOTED) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mp_hal_ticks_ms() - start) >= LEPTON_BOOT_TIMEOUT) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(1)) {
|
||||
for (mp_uint_t start = mp_hal_ticks_ms(); ; mp_hal_delay_ms(10)) {
|
||||
LEP_UINT16 status;
|
||||
if (LEP_DirectReadRegister(&lepton.port, LEP_I2C_STATUS_REG, &status) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
LEP_DirectReadRegister(&lepton.port, LEP_I2C_STATUS_REG, &status);
|
||||
|
||||
if (!(status & LEP_I2C_STATUS_BUSY_BIT_MASK)) {
|
||||
if (status == LEPTON_I2C_STATUS_BOOT) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -332,23 +311,16 @@ static int lepton_reset(omv_csi_t *csi, bool measurement_mode, bool high_temp_mo
|
||||
}
|
||||
}
|
||||
|
||||
if (LEP_GetRadEnableState(&lepton.port, &rad) != LEP_OK
|
||||
|| LEP_GetAgcROI(&lepton.port, &roi) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Use the low gain mode to enable high temperature readings (~450C) on Lepton 3.5
|
||||
LEP_SYS_GAIN_MODE_E gain_mode = lepton.high_temp_mode ? LEP_SYS_GAIN_MODE_LOW : LEP_SYS_GAIN_MODE_HIGH;
|
||||
if (LEP_SetSysGainMode(&lepton.port, gain_mode) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
LEP_SYS_GAIN_MODE_E gain_mode = high_temp_mode ? LEP_SYS_GAIN_MODE_LOW : LEP_SYS_GAIN_MODE_HIGH;
|
||||
|
||||
if (!lepton.measurement_mode) {
|
||||
if (LEP_SetRadEnableState(&lepton.port, LEP_RAD_DISABLE) != LEP_OK
|
||||
|| LEP_SetAgcEnableState(&lepton.port, LEP_AGC_ENABLE) != LEP_OK
|
||||
|| LEP_SetAgcCalcEnableState(&lepton.port, LEP_AGC_ENABLE) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
if (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 ||
|
||||
LEP_SetAgcCalcEnableState(&lepton.port, !measurement_mode) != LEP_OK ||
|
||||
LEP_GetRadEnableState(&lepton.port, &rad) != LEP_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
lepton.h_res = roi.endCol + 1;
|
||||
@ -373,7 +345,7 @@ static int reset(omv_csi_t *csi) {
|
||||
lepton.max_temp = LEPTON_MAX_TEMP_DEFAULT;
|
||||
|
||||
// Extra delay after power-on
|
||||
mp_hal_delay_ms(1000);
|
||||
mp_hal_delay_ms(1500);
|
||||
|
||||
if (lepton_reset(csi, false, false) != 0) {
|
||||
return OMV_CSI_ERROR_CTL_FAILED;
|
||||
@ -386,6 +358,42 @@ static int reset(omv_csi_t *csi) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _abort(omv_csi_t *csi, bool fifo_flush, bool in_irq) {
|
||||
return vospi_abort();
|
||||
}
|
||||
|
||||
static int config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
if (config == OMV_CSI_CONFIG_INIT) {
|
||||
if (reset(csi) != 0) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
|
||||
LEP_OEM_PART_NUMBER_T part;
|
||||
if (LEP_GetOemFlirPartNumber(&lepton.port, &part) != LEP_OK) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
|
||||
// 500 == Lepton
|
||||
// xxxx == Version
|
||||
// 01/00 == Shutter/NoShutter
|
||||
if (!strncmp(part.value, "500-0771", 8)) {
|
||||
csi->chip_id = LEPTON_3_5;
|
||||
} else if (!strncmp(part.value, "500-0726", 8)) {
|
||||
csi->chip_id = LEPTON_3_0;
|
||||
} else if (!strncmp(part.value, "500-0763", 8)) {
|
||||
csi->chip_id = LEPTON_2_5;
|
||||
} else if (!strncmp(part.value, "500-0659", 8)) {
|
||||
csi->chip_id = LEPTON_2_0;
|
||||
} else if (!strncmp(part.value, "500-0690", 8)) {
|
||||
csi->chip_id = LEPTON_1_6;
|
||||
} else if (!strncmp(part.value, "500-0643", 8)) {
|
||||
csi->chip_id = LEPTON_1_5;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
framebuffer_t *fb = csi->fb;
|
||||
|
||||
@ -493,43 +501,12 @@ static int snapshot(omv_csi_t *csi, image_t *image, uint32_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
if (config == OMV_CSI_CONFIG_INIT) {
|
||||
if (reset(csi) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
LEP_OEM_PART_NUMBER_T part;
|
||||
if (LEP_GetOemFlirPartNumber(&lepton.port, &part) != LEP_OK) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
}
|
||||
|
||||
// 500 == Lepton
|
||||
// xxxx == Version
|
||||
// 01/00 == Shutter/NoShutter
|
||||
if (!strncmp(part.value, "500-0771", 8)) {
|
||||
csi->chip_id = LEPTON_3_5;
|
||||
} else if (!strncmp(part.value, "500-0726", 8)) {
|
||||
csi->chip_id = LEPTON_3_0;
|
||||
} else if (!strncmp(part.value, "500-0763", 8)) {
|
||||
csi->chip_id = LEPTON_2_5;
|
||||
} else if (!strncmp(part.value, "500-0659", 8)) {
|
||||
csi->chip_id = LEPTON_2_0;
|
||||
} else if (!strncmp(part.value, "500-0690", 8)) {
|
||||
csi->chip_id = LEPTON_1_6;
|
||||
} else if (!strncmp(part.value, "500-0643", 8)) {
|
||||
csi->chip_id = LEPTON_1_5;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lepton_init(omv_csi_t *csi) {
|
||||
csi->reset = reset;
|
||||
csi->sleep = sleep;
|
||||
csi->config = config;
|
||||
csi->abort = NULL;
|
||||
csi->abort = _abort;
|
||||
csi->shutdown = NULL;
|
||||
csi->match = match;
|
||||
csi->snapshot = snapshot;
|
||||
csi->read_reg = read_reg;
|
||||
|
||||
@ -235,6 +235,9 @@ soft_reset:
|
||||
|
||||
soft_reset_exit:
|
||||
mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n");
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_abort_all();
|
||||
#endif
|
||||
#if MICROPY_PY_AUDIO
|
||||
py_audio_deinit();
|
||||
#endif
|
||||
|
||||
@ -75,7 +75,6 @@
|
||||
#include "file_utils.h"
|
||||
#include "mp_utils.h"
|
||||
#include "mimxrt_hal.h"
|
||||
#include "vospi.h"
|
||||
|
||||
int main(void) {
|
||||
bool first_soft_reset = true;
|
||||
@ -223,8 +222,8 @@ soft_reset:
|
||||
|
||||
soft_reset_exit:
|
||||
mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n");
|
||||
#if OMV_ENABLE_VOSPI || OMV_LEPTON_ENABLE
|
||||
vospi_deinit();
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_abort_all();
|
||||
#endif
|
||||
#if MICROPY_PY_MACHINE_CAN
|
||||
machine_can_irq_deinit();
|
||||
|
||||
@ -318,12 +318,15 @@ soft_reset:
|
||||
|
||||
soft_reset_exit:
|
||||
printf("MPY: soft reboot\n");
|
||||
#if MICROPY_PY_MACHINE_HW_PWM
|
||||
pwm_deinit_all();
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_abort_all();
|
||||
#endif
|
||||
#if MICROPY_PY_AUDIO
|
||||
py_audio_deinit();
|
||||
#endif
|
||||
#if MICROPY_PY_MACHINE_HW_PWM
|
||||
pwm_deinit_all();
|
||||
#endif
|
||||
#if BLUETOOTH_SD
|
||||
sd_softdevice_disable();
|
||||
#endif
|
||||
|
||||
@ -252,6 +252,9 @@ soft_reset:
|
||||
|
||||
soft_reset_exit:
|
||||
mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n");
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_abort_all();
|
||||
#endif
|
||||
#if MICROPY_PY_AUDIO
|
||||
py_audio_deinit();
|
||||
#endif
|
||||
|
||||
@ -88,7 +88,6 @@
|
||||
#include "fb_alloc.h"
|
||||
#include "dma_alloc.h"
|
||||
#include "file_utils.h"
|
||||
#include "vospi.h"
|
||||
|
||||
#include "py_image.h"
|
||||
#include "py_fir.h"
|
||||
@ -373,9 +372,8 @@ soft_reset:
|
||||
soft_reset_exit:
|
||||
// soft reset
|
||||
mp_printf(MP_PYTHON_PRINTER, "MPY: soft reboot\n");
|
||||
|
||||
#if OMV_ENABLE_VOSPI || OMV_LEPTON_ENABLE
|
||||
vospi_deinit();
|
||||
#if MICROPY_PY_CSI
|
||||
omv_csi_abort_all();
|
||||
#endif
|
||||
#if MICROPY_PY_LWIP
|
||||
systick_disable_dispatch(SYSTICK_DISPATCH_LWIP);
|
||||
|
||||
@ -179,11 +179,27 @@ static int stm_csi_config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
NVIC_SetPriority(DCMI_IRQn, IRQ_PRI_DCMI);
|
||||
HAL_NVIC_EnableIRQ(DCMI_IRQn);
|
||||
#endif
|
||||
} else if (config == OMV_CSI_CONFIG_DEINIT) {
|
||||
#if USE_DCMI
|
||||
HAL_NVIC_DisableIRQ(DCMI_IRQn);
|
||||
HAL_DCMI_DeInit(&csi->dcmi);
|
||||
#else
|
||||
HAL_NVIC_DisableIRQ(DCMIPP_IRQn);
|
||||
HAL_DCMIPP_DeInit(&csi->dcmi);
|
||||
#endif
|
||||
} else if (config == OMV_CSI_CONFIG_PIXFORMAT) {
|
||||
#if USE_DCMI
|
||||
DCMI->CR &= ~(DCMI_CR_JPEG_Msk << DCMI_CR_JPEG_Pos);
|
||||
DCMI->CR |= (csi->pixformat == PIXFORMAT_JPEG) ? DCMI_JPEG_ENABLE : DCMI_JPEG_DISABLE;
|
||||
#else
|
||||
|
||||
// Reset DCMI and pipes states to allow reconfiguring them. Note
|
||||
// that abort() doesn't reset the state unless the pipe is active.
|
||||
csi->dcmi.State = HAL_DCMIPP_STATE_INIT;
|
||||
for (size_t i=0; i<DCMIPP_NUM_OF_PIPES; i++) {
|
||||
csi->dcmi.PipeState[i] = HAL_DCMIPP_PIPE_STATE_RESET;
|
||||
}
|
||||
|
||||
// Select and configure the DCMIPP source.
|
||||
if (csi->mipi_if) {
|
||||
DCMIPP_CSI_ConfTypeDef scfg = {
|
||||
@ -200,6 +216,7 @@ static int stm_csi_config(omv_csi_t *csi, omv_csi_config_t config) {
|
||||
.DataTypeIDA = DCMIPP_DT_RAW10,
|
||||
.DataTypeIDB = DCMIPP_DT_RAW10,
|
||||
};
|
||||
|
||||
if (HAL_DCMIPP_CSI_SetVCConfig(&csi->dcmi, DCMIPP_VIRTUAL_CHANNEL0,
|
||||
DCMIPP_CSI_DT_BPP10) != HAL_OK) {
|
||||
return OMV_CSI_ERROR_CSI_INIT_FAILED;
|
||||
@ -354,6 +371,16 @@ static int stm_csi_abort(omv_csi_t *csi, bool fifo_flush, bool in_irq) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm_csi_shutdown(omv_csi_t *csi, int enable) {
|
||||
int ret = 0;
|
||||
if (enable) {
|
||||
ret = omv_csi_config(csi, OMV_CSI_CONFIG_DEINIT);
|
||||
} else {
|
||||
ret = omv_csi_config(csi, OMV_CSI_CONFIG_INIT);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t omv_csi_get_clk_frequency() {
|
||||
omv_csi_t *csi = omv_csi_get(-1);
|
||||
|
||||
@ -429,37 +456,6 @@ int omv_csi_set_clk_frequency(uint32_t frequency) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omv_csi_shutdown(omv_csi_t *csi, int enable) {
|
||||
int ret = 0;
|
||||
omv_csi_abort(csi, true, false);
|
||||
|
||||
if (enable) {
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
if (csi->power_pol == OMV_CSI_ACTIVE_HIGH) {
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 1);
|
||||
} else {
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 0);
|
||||
}
|
||||
#endif
|
||||
#if USE_DCMI
|
||||
HAL_NVIC_DisableIRQ(DCMI_IRQn);
|
||||
HAL_DCMI_DeInit(&csi->dcmi);
|
||||
#endif
|
||||
} else {
|
||||
#if defined(OMV_CSI_POWER_PIN)
|
||||
if (csi->power_pol == OMV_CSI_ACTIVE_HIGH) {
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 0);
|
||||
} else {
|
||||
omv_gpio_write(OMV_CSI_POWER_PIN, 1);
|
||||
}
|
||||
#endif
|
||||
ret = omv_csi_config(csi, OMV_CSI_CONFIG_INIT);
|
||||
}
|
||||
|
||||
mp_hal_delay_ms(10);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int omv_csi_set_vsync_callback(omv_csi_t *csi, omv_csi_cb_t cb) {
|
||||
if (cb.fun == NULL) {
|
||||
#if (DCMI_VSYNC_EXTI_SHARED == 0)
|
||||
@ -1093,6 +1089,7 @@ int omv_csi_init() {
|
||||
csi->fb = framebuffer_get(-1);
|
||||
csi->abort = stm_csi_abort;
|
||||
csi->config = stm_csi_config;
|
||||
csi->shutdown = stm_csi_shutdown;
|
||||
csi->snapshot = stm_csi_snapshot;
|
||||
csi->color_palette = rainbow_table;
|
||||
}
|
||||
|
||||
@ -320,6 +320,15 @@ int omv_i2c_scan(omv_i2c_t *i2c, uint8_t *list, uint8_t size) {
|
||||
return idx;
|
||||
}
|
||||
|
||||
static int omv_i2c_reset(omv_i2c_t *i2c) {
|
||||
__HAL_I2C_DISABLE(i2c->inst);
|
||||
mp_hal_delay_ms(10);
|
||||
__HAL_I2C_ENABLE(i2c->inst);
|
||||
i2c->inst->ErrorCode = 0;
|
||||
i2c->inst->State = HAL_I2C_STATE_READY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int omv_i2c_enable(omv_i2c_t *i2c, bool enable) {
|
||||
if (i2c->initialized) {
|
||||
if (enable) {
|
||||
@ -333,6 +342,7 @@ int omv_i2c_enable(omv_i2c_t *i2c, bool enable) {
|
||||
|
||||
int omv_i2c_gencall(omv_i2c_t *i2c, uint8_t cmd) {
|
||||
if (HAL_I2C_Master_Transmit(i2c->inst, 0x00, &cmd, 1, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
@ -343,6 +353,7 @@ int omv_i2c_readb(omv_i2c_t *i2c, uint8_t slv_addr, uint8_t reg_addr, uint8_t *r
|
||||
|
||||
if ((HAL_I2C_Master_Transmit(i2c->inst, slv_addr, ®_addr, 1, I2C_TIMEOUT) != HAL_OK)
|
||||
|| (HAL_I2C_Master_Receive(i2c->inst, slv_addr, reg_data, 1, I2C_TIMEOUT) != HAL_OK)) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@ -353,6 +364,7 @@ int omv_i2c_writeb(omv_i2c_t *i2c, uint8_t slv_addr, uint8_t reg_addr, uint8_t r
|
||||
uint8_t buf[] = {reg_addr, reg_data};
|
||||
|
||||
if (HAL_I2C_Master_Transmit(i2c->inst, slv_addr, buf, 2, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@ -362,6 +374,7 @@ int omv_i2c_readb2(omv_i2c_t *i2c, uint8_t slv_addr, uint16_t reg_addr, uint8_t
|
||||
int ret = 0;
|
||||
if (HAL_I2C_Mem_Read(i2c->inst, slv_addr, reg_addr,
|
||||
I2C_MEMADD_SIZE_16BIT, reg_data, 1, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@ -371,6 +384,7 @@ int omv_i2c_writeb2(omv_i2c_t *i2c, uint8_t slv_addr, uint16_t reg_addr, uint8_t
|
||||
int ret = 0;
|
||||
if (HAL_I2C_Mem_Write(i2c->inst, slv_addr, reg_addr,
|
||||
I2C_MEMADD_SIZE_16BIT, ®_data, 1, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@ -380,6 +394,7 @@ int omv_i2c_readw(omv_i2c_t *i2c, uint8_t slv_addr, uint8_t reg_addr, uint16_t *
|
||||
int ret = 0;
|
||||
if (HAL_I2C_Mem_Read(i2c->inst, slv_addr, reg_addr,
|
||||
I2C_MEMADD_SIZE_8BIT, (uint8_t *) reg_data, 2, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
*reg_data = (*reg_data >> 8) | (*reg_data << 8);
|
||||
@ -391,6 +406,7 @@ int omv_i2c_writew(omv_i2c_t *i2c, uint8_t slv_addr, uint8_t reg_addr, uint16_t
|
||||
reg_data = (reg_data >> 8) | (reg_data << 8);
|
||||
if (HAL_I2C_Mem_Write(i2c->inst, slv_addr, reg_addr,
|
||||
I2C_MEMADD_SIZE_8BIT, (uint8_t *) ®_data, 2, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@ -400,6 +416,7 @@ int omv_i2c_readw2(omv_i2c_t *i2c, uint8_t slv_addr, uint16_t reg_addr, uint16_t
|
||||
int ret = 0;
|
||||
if (HAL_I2C_Mem_Read(i2c->inst, slv_addr, reg_addr,
|
||||
I2C_MEMADD_SIZE_16BIT, (uint8_t *) reg_data, 2, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
*reg_data = (*reg_data >> 8) | (*reg_data << 8);
|
||||
@ -411,6 +428,7 @@ int omv_i2c_writew2(omv_i2c_t *i2c, uint8_t slv_addr, uint16_t reg_addr, uint16_
|
||||
reg_data = (reg_data >> 8) | (reg_data << 8);
|
||||
if (HAL_I2C_Mem_Write(i2c->inst, slv_addr, reg_addr,
|
||||
I2C_MEMADD_SIZE_16BIT, (uint8_t *) ®_data, 2, I2C_TIMEOUT) != HAL_OK) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
return ret;
|
||||
@ -431,6 +449,7 @@ int omv_i2c_read_bytes(omv_i2c_t *i2c, uint8_t slv_addr, uint8_t *buf, int len,
|
||||
|
||||
if (HAL_I2C_Master_Seq_Receive_IT(i2c->inst, slv_addr, buf, len, xfer_flags) != HAL_OK
|
||||
|| omv_i2c_wait_timeout(i2c, I2C_TIMEOUT) != 0) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
@ -453,6 +472,7 @@ int omv_i2c_write_bytes(omv_i2c_t *i2c, uint8_t slv_addr, uint8_t *buf, int len,
|
||||
|
||||
if (HAL_I2C_Master_Seq_Transmit_IT(i2c->inst, slv_addr, buf, len, xfer_flags) != HAL_OK
|
||||
|| omv_i2c_wait_timeout(i2c, I2C_TIMEOUT) != 0) {
|
||||
omv_i2c_reset(i2c);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
|
||||
@ -278,10 +278,12 @@ int omv_spi_transfer_start(omv_spi_t *spi, omv_spi_transfer_t *xfer) {
|
||||
}
|
||||
|
||||
int omv_spi_transfer_abort(omv_spi_t *spi) {
|
||||
if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) {
|
||||
HAL_SPI_Abort_IT(spi->descr);
|
||||
} else {
|
||||
HAL_SPI_Abort(spi->descr);
|
||||
if (spi && spi->initialized) {
|
||||
if (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) {
|
||||
HAL_SPI_Abort_IT(spi->descr);
|
||||
} else {
|
||||
HAL_SPI_Abort(spi->descr);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user