From f2a40fea7f6d2657423150e89e7761f1e02126a4 Mon Sep 17 00:00:00 2001 From: ligenxxxx <59721724+ligenxxxx@users.noreply.github.com> Date: Fri, 13 Oct 2023 19:00:53 +0800 Subject: [PATCH] support micro v3 camera --- src/camera.c | 28 ++++++++++++------- src/camera.h | 4 ++- src/hardware.c | 3 +- src/runcam.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 93 insertions(+), 18 deletions(-) diff --git a/src/camera.c b/src/camera.c index 16199be..8cf3ecc 100644 --- a/src/camera.c +++ b/src/camera.c @@ -30,7 +30,8 @@ void camera_type_detect(void) { runcam_type_detect(); if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V1 || camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2 || - camera_type == CAMERA_TYPE_RUNCAM_NANO_90) { + camera_type == CAMERA_TYPE_RUNCAM_NANO_90 || + camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) { camera_mfr = CAMERA_MFR_RUNCAM; #ifdef _DEBUG_CAMERA debugf("\r\ncamera mfr : RUNCAM"); @@ -41,17 +42,21 @@ void camera_type_detect(void) { } void camera_ratio_detect(void) { - if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V1) { + switch (camera_type) { + case CAMERA_TYPE_RUNCAM_MICRO_V1: camRatio = 0; - } else if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2) { - if (camera_setting_reg_set[11] == 0) - camRatio = 1; - else - camRatio = 0; - } else if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) { + break; + case CAMERA_TYPE_RUNCAM_MICRO_V2: + case CAMERA_TYPE_RUNCAM_MICRO_V3: + camRatio = (camera_setting_reg_set[11] == 0); + break; + case CAMERA_TYPE_RUNCAM_NANO_90: camRatio = 1; - } else + break; + default: camRatio = 0; + break; + } } void camera_mode_detect(uint8_t init) { @@ -84,7 +89,7 @@ void camera_mode_detect(uint8_t init) { Init_TC3587(0); video_format = VDO_FMT_720P60; I2C_Write16(ADDR_TC3587, 0x0058, 0x00e0); - } else if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2) { + } else if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2 || camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) { if (camera_setting_reg_set[11] == 3) { Set_1080P30(IS_RX); video_format = VDO_FMT_1080P30; @@ -349,6 +354,7 @@ void camera_menu_draw_value(void) { const char *switch_str[] = {" OFF", " ON"}; const char *resolution_runcam_micro_v2[] = {" 4:3 ", " 16:9CROP ", " 16:9FULL ", " 1080@30 "}; const char *resolution_runcam_nano_90[] = {" 540P@90", "540@90CROP", " 540P@60", "960X720@60"}; + const char *resolution_runcam_micro_v3[] = {" 4:3 ", " 16:9CROP ", " 16:9FULL ", " 1080@30 "}; uint8_t str[4]; uint8_t i; @@ -429,6 +435,8 @@ void camera_menu_draw_value(void) { strcpy(&osd_buf[i][osd_menu_offset + 19], resolution_runcam_micro_v2[camera_setting_reg_menu[i - 1]]); } else if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) { strcpy(&osd_buf[i][osd_menu_offset + 19], resolution_runcam_nano_90[camera_setting_reg_menu[i - 1]]); + } else if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) { + strcpy(&osd_buf[i][osd_menu_offset + 19], resolution_runcam_micro_v3[camera_setting_reg_menu[i - 1]]); } osd_buf[i][osd_menu_offset + 29] = '>'; break; diff --git a/src/camera.h b/src/camera.h index 994e9c3..d4409ac 100644 --- a/src/camera.h +++ b/src/camera.h @@ -10,6 +10,7 @@ #define RUNCAM_MICRO_V1 0x42 #define RUNCAM_MICRO_V2 0x44 #define RUNCAM_NANO_90 0x46 +#define RUNCAM_MICRO_V3 0x48 #define CAMERA_SETTING_NUM 16 #define CAMERA_PROFILE_NUM 3 @@ -25,7 +26,7 @@ typedef enum { CAMERA_MFR_UNKNOW, CAMERA_MFR_FOXEER, CAMERA_MFR_RUNCAM, -} camera_manufacturer_e; +} camera_manufacture_e; typedef enum { CAMERA_TYPE_UNKNOW, @@ -34,6 +35,7 @@ typedef enum { CAMERA_TYPE_RUNCAM_MICRO_V1, // include hdz nano v1 CAMERA_TYPE_RUNCAM_MICRO_V2, // include hzd nano v2 / hdz nano lite CAMERA_TYPE_RUNCAM_NANO_90, + CAMERA_TYPE_RUNCAM_MICRO_V3, } camera_type_e; typedef enum { diff --git a/src/hardware.c b/src/hardware.c index 267d082..9135190 100644 --- a/src/hardware.c +++ b/src/hardware.c @@ -1083,7 +1083,8 @@ void video_detect(void) { if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V1 || camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2 || - camera_type == CAMERA_TYPE_RUNCAM_NANO_90) { + camera_type == CAMERA_TYPE_RUNCAM_NANO_90 || + camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) { val |= I2C_Read16(ADDR_TC3587, 0x006A); val |= I2C_Read16(ADDR_TC3587, 0x006E); if (val) diff --git a/src/runcam.c b/src/runcam.c index 54a936f..a49d5bb 100644 --- a/src/runcam.c +++ b/src/runcam.c @@ -101,6 +101,38 @@ const uint8_t runcam_nano_90_attribute[CAMERA_SETTING_NUM][4] = { {0, 0x00, 0x00, 0x00}, }; +const uint8_t runcam_micro_v3_attribute[CAMERA_SETTING_NUM][4] = { + // brightness + {1, 0x40, 0xC0, 0x80}, + // sharpness + {1, 0x00, 0x02, 0x01}, + // contrast + {1, 0x00, 0x02, 0x01}, + // saturation + {1, 0x00, 0x06, 0x05}, + // shutter speed + {1, 0x00, 0x20, 0x00}, + // wb mode + {1, 0x00, 0x01, 0x00}, + // wb red + {1, 0x00, 0xff, 0xc7}, + // wb blue + {1, 0x00, 0xff, 0xca}, + // hv flip + {1, 0x00, 0x01, 0x00}, + // night mode + {1, 0x00, 0x01, 0x01}, + // led mode + {1, 0x00, 0x01, 0x00}, + // video fmt + {1, 0x00, 0x03, 0x02}, + + {0, 0x00, 0x00, 0x00}, + {0, 0x00, 0x00, 0x00}, + {0, 0x00, 0x00, 0x00}, + {0, 0x00, 0x00, 0x00}, +}; + void runcam_type_detect(void) { uint8_t i, j; uint32_t rdat; @@ -132,6 +164,17 @@ void runcam_type_detect(void) { for (j = 0; j < 4; j++) camera_attribute[i][j] = runcam_nano_90_attribute[i][j]; } + return; + } + + rdat = RUNCAM_Read(RUNCAM_MICRO_V3, 0x50); + if (rdat != 0x00000000 && rdat != 0xffffffff) { + camera_type = CAMERA_TYPE_RUNCAM_MICRO_V3; + camera_device = RUNCAM_MICRO_V3; + for (i = 0; i < CAMERA_SETTING_NUM; i++) { + for (j = 0; j < 4; j++) + camera_attribute[i][j] = runcam_micro_v3_attribute[i][j]; + } } } } @@ -166,6 +209,8 @@ void runcam_brightness(uint8_t val, uint8_t led_mode) { d = 0x0452004e; else if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2) d = 0x04500050; + else if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) + d = 0x04500050; else // if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) d = 0x04480048; @@ -303,7 +348,7 @@ void runcam_wb(uint8_t wbMode, uint8_t wbRed, uint8_t wbBlue) { } void runcam_hv_flip(uint8_t val) { - if (camera_type != CAMERA_TYPE_RUNCAM_MICRO_V2 && camera_type != CAMERA_TYPE_RUNCAM_NANO_90) + if (camera_type != CAMERA_TYPE_RUNCAM_MICRO_V2 && camera_type != CAMERA_TYPE_RUNCAM_NANO_90 && camera_type != CAMERA_TYPE_RUNCAM_MICRO_V3) return; camera_setting_reg_set[8] = val; @@ -322,16 +367,22 @@ void runcam_night_mode(uint8_t val) { 0: night mode off 1: night mode on */ - if (camera_type != CAMERA_TYPE_RUNCAM_MICRO_V2 && camera_type != CAMERA_TYPE_RUNCAM_NANO_90) + if (camera_type != CAMERA_TYPE_RUNCAM_MICRO_V2 && camera_type != CAMERA_TYPE_RUNCAM_NANO_90 && camera_type != CAMERA_TYPE_RUNCAM_MICRO_V3) return; camera_setting_reg_set[9] = val; if (val == 0) { // Max gain off RUNCAM_Read_Write(camera_device, 0x000070, 0x10000040); - RUNCAM_Read_Write(camera_device, 0x000718, 0x30002900); - RUNCAM_Read_Write(camera_device, 0x00071c, 0x32003100); - RUNCAM_Read_Write(camera_device, 0x000720, 0x34003300); + if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) { + RUNCAM_Read_Write(camera_device, 0x000718, 0x30003000); + RUNCAM_Read_Write(camera_device, 0x00071c, 0x32003200); + RUNCAM_Read_Write(camera_device, 0x000720, 0x34003400); + } else { + RUNCAM_Read_Write(camera_device, 0x000718, 0x30002900); + RUNCAM_Read_Write(camera_device, 0x00071c, 0x32003100); + RUNCAM_Read_Write(camera_device, 0x000720, 0x34003300); + } } else if (val == 1) { // Max gain on RUNCAM_Read_Write(camera_device, 0x000070, 0x10000040); RUNCAM_Read_Write(camera_device, 0x000718, 0x28002700); @@ -377,7 +428,20 @@ uint8_t runcam_video_format(uint8_t val) { ret |= RUNCAM_Read_Write(camera_device, 0x000034, 0x00014441); else ret |= RUNCAM_Read_Write(camera_device, 0x000034, 0x00012941); + } else if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) { + if (val == 0) + ret |= RUNCAM_Read_Write(camera_device, 0x000008, 0x8208910B); + else if (val == 1) + ret |= RUNCAM_Read_Write(camera_device, 0x000008, 0x82089102); + else if (val == 2) + ret |= RUNCAM_Read_Write(camera_device, 0x000008, 0x82089110); + else if (val == 3) + ret |= RUNCAM_Read_Write(camera_device, 0x000008, 0x81089106); + if (val == 3) // 1080p30 + ret |= RUNCAM_Read_Write(camera_device, 0x000034, 0x00014441); + else + ret |= RUNCAM_Read_Write(camera_device, 0x000034, 0x00012941); } else if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) { if (val == 0) ret |= RUNCAM_Read_Write(camera_device, 0x000008, 0x8008811d); @@ -412,7 +476,7 @@ void runcam_shutter(uint8_t val) { return; } else { if (val == 0) { // auto - if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2) + if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2 || camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) dat = 0x460; else if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) dat = 0x447;