Add sensor error codes.

This commit is contained in:
iabdalkader 2021-07-01 17:50:39 +02:00
parent abe508a92a
commit 0491a6a884
5 changed files with 366 additions and 175 deletions

View File

@ -149,15 +149,39 @@ typedef enum {
IOCTL_HIMAX_OSC_ENABLE,
} ioctl_t;
#define SENSOR_HW_FLAGS_VSYNC (0) // vertical sync polarity.
#define SENSOR_HW_FLAGS_HSYNC (1) // horizontal sync polarity.
#define SENSOR_HW_FLAGS_PIXCK (2) // pixel clock edge.
#define SENSOR_HW_FLAGS_FSYNC (3) // hardware frame sync.
#define SENSOR_HW_FLAGS_JPEGE (4) // hardware JPEG encoder.
#define SENSOR_HW_FLAGS_RGB565_REV (5) // byte reverse rgb565.
#define SENSOR_HW_FLAGS_GET(s, x) ((s)->hw_flags & (1<<x))
#define SENSOR_HW_FLAGS_SET(s, x, v) ((s)->hw_flags |= (v<<x))
#define SENSOR_HW_FLAGS_CLR(s, x) ((s)->hw_flags &= ~(1<<x))
typedef enum {
SENSOR_ERROR_NO_ERROR = 0,
SENSOR_ERROR_CTL_FAILED = -1,
SENSOR_ERROR_CTL_UNSUPPORTED = -2,
SENSOR_ERROR_ISC_UNDETECTED = -3,
SENSOR_ERROR_ISC_UNSUPPORTED = -4,
SENSOR_ERROR_ISC_INIT_FAILED = -5,
SENSOR_ERROR_TIM_INIT_FAILED = -6,
SENSOR_ERROR_DMA_INIT_FAILED = -7,
SENSOR_ERROR_DCMI_INIT_FAILED = -8,
SENSOR_ERROR_IO_ERROR = -9,
SENSOR_ERROR_CAPTURE_FAILED = -10,
SENSOR_ERROR_CAPTURE_TIMEOUT = -11,
SENSOR_ERROR_INVALID_FRAMESIZE = -12,
SENSOR_ERROR_INVALID_PIXFORMAT = -13,
SENSOR_ERROR_INVALID_WINDOW = -14,
SENSOR_ERROR_INVALID_FRAMERATE = -15,
SENSOR_ERROR_INVALID_ARGUMENT = -16,
SENSOR_ERROR_PIXFORMAT_UNSUPPORTED = -17,
SENSOR_ERROR_FRAMEBUFFER_ERROR = -18,
SENSOR_ERROR_FRAMEBUFFER_OVERFLOW = -19,
SENSOR_ERROR_JPEG_OVERFLOW = -20,
} sensor_error_t;
#define SENSOR_HW_FLAGS_VSYNC (0) // vertical sync polarity.
#define SENSOR_HW_FLAGS_HSYNC (1) // horizontal sync polarity.
#define SENSOR_HW_FLAGS_PIXCK (2) // pixel clock edge.
#define SENSOR_HW_FLAGS_FSYNC (3) // hardware frame sync.
#define SENSOR_HW_FLAGS_JPEGE (4) // hardware JPEG encoder.
#define SENSOR_HW_FLAGS_RGB565_REV (5) // byte reverse rgb565.
#define SENSOR_HW_FLAGS_GET(s, x) ((s)->hw_flags & (1<<x))
#define SENSOR_HW_FLAGS_SET(s, x, v) ((s)->hw_flags |= (v<<x))
#define SENSOR_HW_FLAGS_CLR(s, x) ((s)->hw_flags &= ~(1<<x))
typedef void (*vsync_cb_t)(uint32_t vsync);
typedef void (*frame_cb_t)();
@ -385,4 +409,6 @@ int sensor_auto_crop_framebuffer();
// Default snapshot function.
int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags);
// Convert sensor error codes to strings.
const char *sensor_strerror(int error);
#endif /* __SENSOR_H__ */

View File

@ -97,16 +97,17 @@ __weak int sensor_init()
{
// Reset the sesnor state
memset(&sensor, 0, sizeof(sensor_t));
return -1;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
__weak int sensor_abort()
{
return -1;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
__weak int sensor_reset()
{
// Disable any ongoing frame capture.
sensor_abort();
// Reset the sensor state
@ -146,15 +147,22 @@ __weak int sensor_reset()
mp_hal_delay_ms(10);
DCMI_RESET_HIGH();
}
mp_hal_delay_ms(20);
// Check if the control is supported.
if (sensor.reset == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call sensor-specific reset function
if (sensor.reset(&sensor) != 0) {
return -1;
return SENSOR_ERROR_CTL_FAILED;
}
// Reset framebuffers
framebuffer_reset_buffers();
return 0;
}
@ -216,7 +224,7 @@ int sensor_probe_init()
sensor.slv_addr = cambus_scan(&sensor.bus);
#ifndef OMV_ENABLE_NONI2CIS
if (sensor.slv_addr == 0) {
return -2;
return SENSOR_ERROR_ISC_UNDETECTED;
}
#endif
}
@ -281,12 +289,11 @@ int sensor_probe_init()
sensor.reset_pol = ACTIVE_LOW;
break;
}
// No sensors detected.
return -2;
return SENSOR_ERROR_ISC_UNDETECTED;
#endif
default:
return -3;
return SENSOR_ERROR_ISC_UNSUPPORTED;
break;
}
@ -294,7 +301,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_OV2640 == 1)
case OV2640_ID:
if (sensor_set_xclk_frequency(OV2640_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = ov2640_init(&sensor);
break;
@ -303,7 +310,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_OV5640 == 1)
case OV5640_ID:
if (sensor_set_xclk_frequency(OV5640_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = ov5640_init(&sensor);
break;
@ -312,7 +319,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_OV7670 == 1)
case OV7670_ID:
if (sensor_set_xclk_frequency(OV7670_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = ov7670_init(&sensor);
break;
@ -321,7 +328,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_OV7690 == 1)
case OV7690_ID:
if (sensor_set_xclk_frequency(OV7690_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = ov7690_init(&sensor);
break;
@ -342,7 +349,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_MT9V034 == 1)
case MT9V034_ID:
if (sensor_set_xclk_frequency(MT9V034_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = mt9v034_init(&sensor);
break;
@ -351,7 +358,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_MT9M114 == 1)
case MT9M114_ID:
if (sensor_set_xclk_frequency(MT9M114_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = mt9m114_init(&sensor);
break;
@ -360,7 +367,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_LEPTON == 1)
case LEPTON_ID:
if (sensor_set_xclk_frequency(LEPTON_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = lepton_init(&sensor);
break;
@ -375,7 +382,7 @@ int sensor_probe_init()
#if (OMV_ENABLE_GC2145 == 1)
case GC2145_ID:
if (sensor_set_xclk_frequency(GC2145_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = gc2145_init(&sensor);
break;
@ -384,20 +391,20 @@ int sensor_probe_init()
#if (OMV_ENABLE_PAJ6100 == 1)
case PAJ6100_ID:
if (sensor_set_xclk_frequency(PAJ6100_XCLK_FREQ) != 0) {
return -3;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
init_ret = paj6100_init(&sensor);
break;
#endif // (OMV_ENABLE_PAJ6100 == 1)
default:
return -3;
return SENSOR_ERROR_ISC_UNSUPPORTED;
break;
}
if (init_ret != 0 ) {
// Sensor init failed.
return -4;
return SENSOR_ERROR_ISC_INIT_FAILED;
}
return 0;
@ -410,12 +417,12 @@ __weak int sensor_get_id()
__weak uint32_t sensor_get_xclk_frequency()
{
return 0;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
__weak int sensor_set_xclk_frequency(uint32_t frequency)
{
return -1;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
__weak bool sensor_is_detected()
@ -425,19 +432,27 @@ __weak bool sensor_is_detected()
__weak int sensor_sleep(int enable)
{
// Disable any ongoing frame capture.
sensor_abort();
if (sensor.sleep == NULL
|| sensor.sleep(&sensor, enable) != 0) {
// Operation not supported
return -1;
// Check if the control is supported.
if (sensor.sleep == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.sleep(&sensor, enable) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_shutdown(int enable)
{
int ret = 0;
// Disable any ongoing frame capture.
sensor_abort();
if (enable) {
@ -455,31 +470,44 @@ __weak int sensor_shutdown(int enable)
}
mp_hal_delay_ms(10);
return ret;
}
__weak int sensor_read_reg(uint16_t reg_addr)
{
// Check if the control is supported.
if (sensor.read_reg == NULL) {
// Operation not supported
return -1;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
return sensor.read_reg(&sensor, reg_addr);
// Call the sensor specific function.
if (sensor.read_reg(&sensor, reg_addr) == -1) {
return SENSOR_ERROR_IO_ERROR;
}
return 0;
}
__weak int sensor_write_reg(uint16_t reg_addr, uint16_t reg_data)
{
// Check if the control is supported.
if (sensor.write_reg == NULL) {
// Operation not supported
return -1;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
return sensor.write_reg(&sensor, reg_addr, reg_data);
// Call the sensor specific function.
if (sensor.write_reg(&sensor, reg_addr, reg_data) == -1) {
return SENSOR_ERROR_IO_ERROR;
}
return 0;
}
__weak int sensor_set_pixformat(pixformat_t pixformat)
{
// Check if the value has changed.
if (sensor.pixformat == pixformat) {
// No change
return 0;
}
@ -491,25 +519,29 @@ __weak int sensor_set_pixformat(pixformat_t pixformat)
&& (pixformat == PIXFORMAT_RGB565)
&& (MAIN_FB()->u * MAIN_FB()->v * 2 > size)
&& (MAIN_FB()->u * MAIN_FB()->v * 1 <= size)) {
// No change
return 0;
}
// Cropping and transposing (and thus auto rotation) don't work in JPEG mode.
if ((pixformat == PIXFORMAT_JPEG)
&& (sensor_get_cropped() || sensor.transpose || sensor.auto_rotation)) {
return -1;
return SENSOR_ERROR_PIXFORMAT_UNSUPPORTED;
}
// Disable any ongoing frame capture.
sensor_abort();
// Flush previous frame.
framebuffer_update_jpeg_buffer();
if (sensor.set_pixformat == NULL
|| sensor.set_pixformat(&sensor, pixformat) != 0) {
// Operation not supported
return -1;
// Check if the control is supported.
if (sensor.set_pixformat == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_pixformat(&sensor, pixformat) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
mp_hal_delay_ms(100); // wait for the camera to settle
@ -534,16 +566,19 @@ __weak int sensor_set_framesize(framesize_t framesize)
return 0;
}
// Disable any ongoing frame capture.
sensor_abort();
// Flush previous frame.
framebuffer_update_jpeg_buffer();
// Call the sensor specific function
if (sensor.set_framesize == NULL
|| sensor.set_framesize(&sensor, framesize) != 0) {
// Operation not supported
return -1;
if (sensor.set_framesize == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
if (sensor.set_framesize(&sensor, framesize) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
mp_hal_delay_ms(100); // wait for the camera to settle
@ -574,15 +609,16 @@ __weak int sensor_set_framerate(int framerate)
}
if (framerate < 0) {
return -1;
return SENSOR_ERROR_INVALID_ARGUMENT;
}
// Call the sensor specific function (does not fail if function is not set)
if (sensor.set_framerate != NULL) {
if (sensor.set_framerate(&sensor, framerate) != 0) {
// Operation not supported
return -1;
}
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
if (sensor.set_framerate(&sensor, framerate) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
// Set framerate
@ -634,16 +670,17 @@ __weak uint32_t sensor_get_dst_bpp()
__weak int sensor_set_windowing(int x, int y, int w, int h)
{
// Check if the value has changed.
if ((MAIN_FB()->x == x) && (MAIN_FB()->y == y) &&
(MAIN_FB()->u == w) && (MAIN_FB()->v == h)) {
// No change
return 0;
}
if (sensor.pixformat == PIXFORMAT_JPEG) {
return -1;
return SENSOR_ERROR_PIXFORMAT_UNSUPPORTED;
}
// Disable any ongoing frame capture.
sensor_abort();
// Flush previous frame.
@ -665,151 +702,218 @@ __weak int sensor_set_windowing(int x, int y, int w, int h)
__weak int sensor_set_contrast(int level)
{
if (sensor.set_contrast != NULL) {
return sensor.set_contrast(&sensor, level);
// Check if the control is supported.
if (sensor.set_contrast == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
return -1;
// Call the sensor specific function.
if (sensor.set_contrast(&sensor, level) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_brightness(int level)
{
if (sensor.set_brightness != NULL) {
return sensor.set_brightness(&sensor, level);
// Check if the control is supported.
if (sensor.set_brightness == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
return -1;
// Call the sensor specific function.
if (sensor.set_brightness(&sensor, level) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_saturation(int level)
{
if (sensor.set_saturation != NULL) {
return sensor.set_saturation(&sensor, level);
// Check if the control is supported.
if (sensor.set_saturation == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
return -1;
// Call the sensor specific function.
if (sensor.set_saturation(&sensor, level) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_gainceiling(gainceiling_t gainceiling)
{
// Check if the value has changed.
if (sensor.gainceiling == gainceiling) {
/* no change */
return 0;
}
/* call the sensor specific function */
if (sensor.set_gainceiling == NULL
|| sensor.set_gainceiling(&sensor, gainceiling) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_gainceiling == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_gainceiling(&sensor, gainceiling) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
// Set the new control value.
sensor.gainceiling = gainceiling;
return 0;
}
__weak int sensor_set_quality(int qs)
{
/* call the sensor specific function */
if (sensor.set_quality == NULL
|| sensor.set_quality(&sensor, qs) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_quality == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_quality(&sensor, qs) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_colorbar(int enable)
{
/* call the sensor specific function */
if (sensor.set_colorbar == NULL
|| sensor.set_colorbar(&sensor, enable) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_colorbar == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_colorbar(&sensor, enable) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_auto_gain(int enable, float gain_db, float gain_db_ceiling)
{
/* call the sensor specific function */
if (sensor.set_auto_gain == NULL
|| sensor.set_auto_gain(&sensor, enable, gain_db, gain_db_ceiling) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_auto_gain == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_auto_gain(&sensor, enable, gain_db, gain_db_ceiling) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_get_gain_db(float *gain_db)
{
/* call the sensor specific function */
if (sensor.get_gain_db == NULL
|| sensor.get_gain_db(&sensor, gain_db) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.get_gain_db == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.get_gain_db(&sensor, gain_db) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_auto_exposure(int enable, int exposure_us)
{
/* call the sensor specific function */
if (sensor.set_auto_exposure == NULL
|| sensor.set_auto_exposure(&sensor, enable, exposure_us) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_auto_exposure == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_auto_exposure(&sensor, enable, exposure_us) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_get_exposure_us(int *exposure_us)
{
/* call the sensor specific function */
if (sensor.get_exposure_us == NULL
|| sensor.get_exposure_us(&sensor, exposure_us) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.get_exposure_us == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.get_exposure_us(&sensor, exposure_us) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_auto_whitebal(int enable, float r_gain_db, float g_gain_db, float b_gain_db)
{
/* call the sensor specific function */
if (sensor.set_auto_whitebal == NULL
|| sensor.set_auto_whitebal(&sensor, enable, r_gain_db, g_gain_db, b_gain_db) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_auto_whitebal == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_auto_whitebal(&sensor, enable, r_gain_db, g_gain_db, b_gain_db) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_get_rgb_gain_db(float *r_gain_db, float *g_gain_db, float *b_gain_db)
{
/* call the sensor specific function */
if (sensor.get_rgb_gain_db == NULL
|| sensor.get_rgb_gain_db(&sensor, r_gain_db, g_gain_db, b_gain_db) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.get_rgb_gain_db == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.get_rgb_gain_db(&sensor, r_gain_db, g_gain_db, b_gain_db) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
}
__weak int sensor_set_hmirror(int enable)
{
// Check if the value has changed.
if (sensor.hmirror == ((bool) enable)) {
/* no change */
return 0;
}
// Disable any ongoing frame capture.
sensor_abort();
/* call the sensor specific function */
if (sensor.set_hmirror == NULL
|| sensor.set_hmirror(&sensor, enable) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_hmirror == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_hmirror(&sensor, enable) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
// Set the new control value.
sensor.hmirror = enable;
mp_hal_delay_ms(100); // wait for the camera to settle
// Wait for the camera to settle
mp_hal_delay_ms(100);
return 0;
}
@ -820,21 +924,30 @@ __weak bool sensor_get_hmirror()
__weak int sensor_set_vflip(int enable)
{
// Check if the value has changed.
if (sensor.vflip == ((bool) enable)) {
/* no change */
return 0;
}
// Disable any ongoing frame capture.
sensor_abort();
/* call the sensor specific function */
if (sensor.set_vflip == NULL
|| sensor.set_vflip(&sensor, enable) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_vflip == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_vflip(&sensor, enable) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
// Set the new control value.
sensor.vflip = enable;
mp_hal_delay_ms(100); // wait for the camera to settle
// Wait for the camera to settle
mp_hal_delay_ms(100);
return 0;
}
@ -845,18 +958,21 @@ __weak bool sensor_get_vflip()
__weak int sensor_set_transpose(bool enable)
{
// Check if the value has changed.
if (sensor.transpose == enable) {
/* no change */
return 0;
}
if (sensor.pixformat == PIXFORMAT_JPEG) {
return -1;
}
// Disable any ongoing frame capture.
sensor_abort();
if (sensor.pixformat == PIXFORMAT_JPEG) {
return SENSOR_ERROR_PIXFORMAT_UNSUPPORTED;
}
// Set the new control value.
sensor.transpose = enable;
return 0;
}
@ -867,17 +983,20 @@ __weak bool sensor_get_transpose()
__weak int sensor_set_auto_rotation(bool enable)
{
// Check if the value has changed.
if (sensor.auto_rotation == enable) {
/* no change */
return 0;
}
if (sensor.pixformat == PIXFORMAT_JPEG) {
return -1;
}
// Disable any ongoing frame capture.
sensor_abort();
// Operation not supported on JPEG images.
if (sensor.pixformat == PIXFORMAT_JPEG) {
return SENSOR_ERROR_PIXFORMAT_UNSUPPORTED;
}
// Set the new control value.
sensor.auto_rotation = enable;
return 0;
}
@ -889,6 +1008,7 @@ __weak bool sensor_get_auto_rotation()
__weak int sensor_set_framebuffers(int count)
{
// Disable any ongoing frame capture.
sensor_abort();
// Flush previous frame.
@ -899,29 +1019,37 @@ __weak int sensor_set_framebuffers(int count)
__weak int sensor_set_special_effect(sde_t sde)
{
// Check if the value has changed.
if (sensor.sde == sde) {
/* no change */
return 0;
}
/* call the sensor specific function */
if (sensor.set_special_effect == NULL
|| sensor.set_special_effect(&sensor, sde) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_special_effect == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_special_effect(&sensor, sde) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
// Set the new control value.
sensor.sde = sde;
return 0;
}
__weak int sensor_set_lens_correction(int enable, int radi, int coef)
{
/* call the sensor specific function */
if (sensor.set_lens_correction == NULL
|| sensor.set_lens_correction(&sensor, enable, radi, coef) != 0) {
/* operation not supported */
return -1;
// Check if the control is supported.
if (sensor.set_lens_correction == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// Call the sensor specific function.
if (sensor.set_lens_correction(&sensor, enable, radi, coef) != 0) {
return SENSOR_ERROR_CTL_FAILED;
}
return 0;
@ -929,19 +1057,21 @@ __weak int sensor_set_lens_correction(int enable, int radi, int coef)
__weak int sensor_ioctl(int request, ... /* arg */)
{
int ret = -1;
// Disable any ongoing frame capture.
sensor_abort();
if (sensor.ioctl != NULL) {
va_list ap;
va_start(ap, request);
/* call the sensor specific function */
ret = sensor.ioctl(&sensor, request, ap);
va_end(ap);
// Check if the control is supported.
if (sensor.ioctl == NULL) {
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
return ret;
va_list ap;
va_start(ap, request);
// Call the sensor specific function.
int ret = sensor.ioctl(&sensor, request, ap);
va_end(ap);
return ((ret != 0) ? SENSOR_ERROR_CTL_FAILED : 0);
}
__weak int sensor_set_vsync_callback(vsync_cb_t vsync_cb)
@ -1063,6 +1193,41 @@ __weak int sensor_auto_crop_framebuffer()
return 0;
}
mp_rom_error_text_t sensor_strerror(int error)
{
static mp_rom_error_text_t sensor_errors[] = {
MP_ERROR_TEXT("No error."),
MP_ERROR_TEXT("Sensor control failed."),
MP_ERROR_TEXT("The requested operation is not supported by the image sensor."),
MP_ERROR_TEXT("Failed to detect the image sensor or image sensor is detached."),
MP_ERROR_TEXT("The detected image sensor is not supported."),
MP_ERROR_TEXT("Failed to initialize the image sensor."),
MP_ERROR_TEXT("Failed to initialize the image sensor clock."),
MP_ERROR_TEXT("Failed to initialize the image sensor DMA."),
MP_ERROR_TEXT("Failed to initialize the image sensor DCMI."),
MP_ERROR_TEXT("An low level I/O error has occurred."),
MP_ERROR_TEXT("Frame capture has failed."),
MP_ERROR_TEXT("Frame capture has timed out."),
MP_ERROR_TEXT("Frame size is not supported or is not set."),
MP_ERROR_TEXT("Pixel format is not supported or is not set."),
MP_ERROR_TEXT("Window is not supported or is not set."),
MP_ERROR_TEXT("An invalid argument is used."),
MP_ERROR_TEXT("The requested operation is not supported on the current pixel format."),
MP_ERROR_TEXT("Frame buffer error."),
MP_ERROR_TEXT("Frame buffer overflow, try reducing the frame size."),
MP_ERROR_TEXT("JPEG frame buffer overflow."),
};
// Sensor errors are negative.
error = ((error < 0) ? (error * -1) : error);
if (error > (sizeof(sensor_errors) / sizeof(sensor_errors[0]))) {
return "Unknown error.";
} else {
return sensor_errors[error];
}
}
__weak int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
{
return -1;

View File

@ -69,7 +69,7 @@ int sensor_init()
// Configure the sensor external clock (XCLK).
if (sensor_set_xclk_frequency(OMV_XCLK_FREQUENCY) != 0) {
// Failed to initialize the sensor clock.
return -1;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
// Detect and initialize the image sensor.
@ -82,7 +82,7 @@ int sensor_init()
// Configure the DCMI interface.
if (sensor_dcmi_config(PIXFORMAT_INVALID) != 0){
// DCMI config failed
return -6;
return SENSOR_ERROR_DCMI_INIT_FAILED;
}
// Clear fb_enabled flag
@ -162,7 +162,7 @@ int sensor_set_xclk_frequency(uint32_t frequency)
int sensor_set_windowing(int x, int y, int w, int h)
{
return -1;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
// This is the default snapshot function, which can be replaced in sensor_init functions.
@ -179,14 +179,14 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
}
if (sensor_check_framebuffer_size() != 0) {
return -1;
return SENSOR_ERROR_FRAMEBUFFER_OVERFLOW;
}
framebuffer_free_current_buffer();
vbuffer_t *buffer = framebuffer_get_tail(FB_NO_FLAGS);
if (!buffer) {
return -1;
return SENSOR_ERROR_FRAMEBUFFER_ERROR;
}
uint8_t *b = buffer->data;

View File

@ -95,7 +95,7 @@ int sensor_init()
// Configure the sensor external clock (XCLK).
if (sensor_set_xclk_frequency(OMV_XCLK_FREQUENCY) != 0) {
// Failed to initialize the sensor clock.
return -1;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
// Detect and initialize the image sensor.
@ -183,7 +183,7 @@ int sensor_set_xclk_frequency(uint32_t frequency)
int sensor_set_windowing(int x, int y, int w, int h)
{
return -1;
return SENSOR_ERROR_CTL_UNSUPPORTED;
}
static void dma_irq_handler()
@ -214,7 +214,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
framebuffer_update_jpeg_buffer();
if (sensor_check_framebuffer_size() != 0) {
return -1;
return SENSOR_ERROR_FRAMEBUFFER_OVERFLOW;
}
// Free the current FB head.
@ -230,7 +230,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
MAIN_FB()->bpp = 2;
break;
default:
return -1;
return SENSOR_ERROR_INVALID_PIXFORMAT;
}
vbuffer_t *buffer = framebuffer_get_head(FB_NO_FLAGS);
@ -240,7 +240,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
if (buffer == NULL && !dma_channel_is_busy(DCMI_DMA_CHANNEL)) {
buffer = framebuffer_get_tail(FB_PEEK);
if (buffer == NULL) {
return -1;
return SENSOR_ERROR_FRAMEBUFFER_ERROR;
}
// Configure the DMA on the first frame, for later frames only the write is changed.
@ -262,7 +262,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
buffer = framebuffer_get_head(FB_NO_FLAGS);
if ((mp_hal_ticks_ms() - ticks) > 3000) {
sensor_abort();
return -1;
return SENSOR_ERROR_CAPTURE_TIMEOUT;
}
}

View File

@ -130,7 +130,7 @@ int sensor_init()
// Configure the sensor external clock (XCLK).
if (sensor_set_xclk_frequency(OMV_XCLK_FREQUENCY) != 0) {
// Failed to initialize the sensor clock.
return -1;
return SENSOR_ERROR_TIM_INIT_FAILED;
}
// Detect and initialize the image sensor.
@ -142,13 +142,13 @@ int sensor_init()
// Configure the DCMI DMA Stream
if (sensor_dma_config() != 0) {
// DMA problem
return -5;
return SENSOR_ERROR_DMA_INIT_FAILED;
}
// Configure the DCMI interface.
if (sensor_dcmi_config(PIXFORMAT_INVALID) != 0){
// DCMI config failed
return -6;
return SENSOR_ERROR_DCMI_INIT_FAILED;
}
// Clear fb_enabled flag
@ -751,7 +751,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
// Error out if the pixformat is not set.
if (!bytes_per_pixel) {
return -1;
return SENSOR_ERROR_INVALID_PIXFORMAT;
}
uint32_t x_crop = get_dcmi_hw_crop(bytes_per_pixel);
@ -770,14 +770,14 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
|| (dma_line_width_bytes > (OMV_LINE_BUF_SIZE / 2))
|| (!length)
|| (length % DMA_LENGTH_ALIGNMENT)) {
return -2;
return SENSOR_ERROR_INVALID_FRAMESIZE;
}
// Get the destination buffer address.
vbuffer_t *buffer = framebuffer_get_tail(FB_PEEK);
if ((sensor->pixformat == PIXFORMAT_JPEG) && (sensor->chip_id == OV2640_ID) && (!buffer)) {
return -3;
return SENSOR_ERROR_FRAMEBUFFER_ERROR;
}
#if (OMV_ENABLE_SENSOR_MDMA == 1)
@ -901,7 +901,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
}
#endif
return -4;
return SENSOR_ERROR_CAPTURE_TIMEOUT;
}
}
@ -921,7 +921,7 @@ int sensor_snapshot(sensor_t *sensor, image_t *image, uint32_t flags)
// The JPEG in the frame buffer is actually invalid.
if (buffer->jpeg_buffer_overflow) {
return -5;
return SENSOR_ERROR_JPEG_OVERFLOW;
}
// Prepare the frame buffer w/h/bpp values given the image type.