Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 32 additions & 12 deletions src/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,18 @@ extern uint8_t g_camera_switch;
void camera_type_detect(void) {
camera_type = CAMERA_TYPE_UNKNOWN;

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_MICRO_V3) {
camera_mfr = CAMERA_MFR_RUNCAM;
return;
if (g_camera_switch == SWITCH_TYPE_HDZCS && g_camera_id == 3) {
camera_type = CAMERA_TYPE_HDZCS_CVBS;
camera_mfr = CAMERA_MFR_HDZERO;
} else {
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_MICRO_V3) {
camera_mfr = CAMERA_MFR_RUNCAM;
return;
}
}
}

Expand All @@ -62,6 +67,9 @@ void camera_ratio_detect(void) {
camRatio = 1;
break;
#endif
case CAMERA_TYPE_HDZCS_CVBS:
camRatio = 1;
break;
default:
camRatio = 0;
break;
Expand Down Expand Up @@ -169,8 +177,12 @@ void camera_mode_detect(uint8_t init) {

// init tc3587 and detect fps
WriteReg(0, 0x8F, 0x91);

if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) {
if (camera_type == CAMERA_TYPE_HDZCS_CVBS) {
Init_TC3587(0);
Set_720P60(IS_RX);
video_format = VDO_FMT_720P60;
I2C_Write16(ADDR_TC3587, 0x0058, 0x00e0);
} else if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) {
Init_TC3587(1);
if (camera_setting_reg_set[11] == 0) {
Set_540P90(0);
Expand Down Expand Up @@ -305,7 +317,7 @@ void camera_setting_profile_check(uint8_t profile) {
}
void camera_profile_read(void) {
if (g_camera_switch) {
camera_profile_eep = g_camera_id-1;
camera_profile_eep = g_camera_id - 1;
} else {
camera_profile_eep = camera_reg_read_eep(EEP_ADDR_CAM_PROFILE);
}
Expand All @@ -331,7 +343,8 @@ void camera_setting_read(void) {

if (camera_type == CAMERA_TYPE_UNKNOWN ||
camera_type == CAMERA_TYPE_OUTDATED ||
camera_type == CAMERA_TYPE_RESERVED)
camera_type == CAMERA_TYPE_RESERVED ||
camera_type == CAMERA_TYPE_HDZCS_CVBS)
return;

camera_type_last = camera_reg_read_eep(EEP_ADDR_CAM_TYPE);
Expand Down Expand Up @@ -365,7 +378,7 @@ void camera_setting_reg_menu_update(void) {
void camera_setting_reg_eep_update(void) {
uint8_t i;
for (i = 0; i < CAMERA_SETTING_NUM; i++) {
if (g_camera_switch && i == (CAM_STATUS_VDO_FMT-1)) {
if (g_camera_switch && i == (CAM_STATUS_VDO_FMT - 1)) {
// Sync all cameras on the camera switch to the same video setting if changed
uint8_t value = camera_setting_reg_menu[i];
camera_setting_reg_eep[0][i] = value;
Expand Down Expand Up @@ -416,6 +429,13 @@ void camera_init(void) {
camera_button_init();
}

void camera_reinit(void) {
camera_type_detect();
camera_setting_read();
camera_setting_reg_menu_update();
camera_mode_detect(1);
}

void camera_button_op(uint8_t op) {
switch (op) {
case BTN_UP:
Expand Down
4 changes: 4 additions & 0 deletions src/camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ typedef enum {
CAMERA_MFR_UNKNOW,
CAMERA_MFR_FOXEER,
CAMERA_MFR_RUNCAM,
CAMERA_MFR_HDZERO,
} camera_manufacture_e;

typedef enum {
Expand All @@ -38,6 +39,8 @@ typedef enum {
CAMERA_TYPE_RUNCAM_MICRO_V2, // include hzd nano v2 / hdz nano lite
CAMERA_TYPE_RUNCAM_NANO_90,
CAMERA_TYPE_RUNCAM_MICRO_V3,
CAMERA_TYPE_HDZCS_CVBS,
CAMERA_TYPE_NUM,
} camera_type_e;

typedef enum {
Expand Down Expand Up @@ -92,6 +95,7 @@ typedef enum {
} camera_select_e;

void camera_init(void);
void camera_reinit(void);
void camera_switch_profile(void);
uint8_t camera_status_update(uint8_t op);
void camera_menu_init(void);
Expand Down
12 changes: 9 additions & 3 deletions src/hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -1029,10 +1029,14 @@ void video_detect(void) {
return;
}
#endif
if (camera_type == CAMERA_TYPE_HDZCS_CVBS) {
return;
}

if (sec == 3) {
sec = 0;
if (cameraLost) { // video loss
if (cameraLost) {
sec++;
if (sec == 3) { // video loss
sec = 0;
if (video_format == VDO_FMT_720P50) {
Set_720P60(IS_RX);
video_format = VDO_FMT_720P60;
Expand All @@ -1041,6 +1045,8 @@ void video_detect(void) {
video_format = VDO_FMT_720P50;
}
}
} else {
sec = 0;
}
}
}
Expand Down
106 changes: 78 additions & 28 deletions src/i2c_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
#include "global.h"
#include "hardware.h"
#include "i2c.h"
#include "msp_displayport.h"
#include "print.h"

uint8_t g_camera_switch = SWITCH_TYPE_NONE;
uint8_t g_camera_id = 0;
uint8_t g_max_camera = 0;
uint8_t g_manual_camera_sel = 0;
static uint8_t camera_list[3] = {255, 254, 253};

/////////////////////////////////////////////////////////////////
// MAX7315
Expand Down Expand Up @@ -140,70 +142,95 @@ void pca9557_set(uint8_t reg, uint8_t val) {
I2C_Write8(ADDR_PCA9557, reg, val);
}

// Read from 3 camera switch
uint8_t hdzcs_get(uint8_t reg) {
return I2C_Read8(ADDR_HDZCS, reg);
}

// Write to 3 camera switch
void hdzcs_set(uint8_t reg, uint8_t val) {
I2C_Write8_Wait(10, ADDR_HDZCS, reg, val);
}

uint8_t get_camera_switch_type(void) {
uint8_t camera_switch = SWITCH_TYPE_NONE;

if ((pi4io_get(0x01) & 0xE0) == 0xA0) { // device ID register
camera_switch = SWITCH_TYPE_PI4IO;
} else if (pca9557_get(0x02) == 0xF0) { // polarity inversion register defaults to 0xF0
camera_switch = SWITCH_TYPE_PCA9557;
} else if (hdzcs_get(0xff) == 0x01) {
camera_switch = SWITCH_TYPE_HDZCS;
}

return camera_switch;
}

void select_camera(uint8_t camera_id) {
if (g_camera_switch)
{
static uint8_t camera_last = 0x00;
if (g_camera_switch) {
// Check camera id is within range, else default to 1
uint8_t camera = (camera_id == 0 || camera_id > g_max_camera) ? 1 : camera_id;
if (g_camera_id != camera) {
g_camera_id = camera;

uint8_t command;
switch (g_camera_id) {
case 1:
default:
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x1B;
break;
case 2:
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x64 : 0x16;
break;
case 3:
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x0D;
break;
case 1:
default:
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x1B;
break;
case 2:
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x64 : 0x16;
break;
case 3:
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x0D;
break;
}

if (g_camera_switch == SWITCH_TYPE_PI4IO) {
pi4io_set(0x05, command);
}
else { // SWITCH_TYPE_PCA9557
} else if (g_camera_switch == SWITCH_TYPE_PCA9557) { // SWITCH_TYPE_PCA9557
pca9557_set(0x01, command);
WAIT(200); // wait for camera power up
WAIT(200); // wait for camera power up
} else if (g_camera_switch == SWITCH_TYPE_HDZCS) {
hdzcs_set(0x00, g_camera_id);
}
camera_switch_profile();

if (camera_last != camera_list[g_camera_id - 1]) {
if (camera_list[g_camera_id - 1] < CAMERA_TYPE_NUM) { // camera has inited
camera_reinit();
} else {
camera_init();
camera_list[g_camera_id - 1] = camera_type;
}
camera_last = camera_type;
}

resync_vrx_vtmg();
}
}
}

void camera_switch_init() {
g_camera_switch = get_camera_switch_type();
if (g_camera_switch == SWITCH_TYPE_PI4IO) {
//pi4io_set(0x01, 0xFF); // reset
pi4io_set(0x0B, 0xFF); // Disable pullup/pulldown resistors
pi4io_set(0x11, 0xFF); // Disable interrupts on inputs
pi4io_get(0x13); // De-assert the interrrupt
pi4io_set(0x03, 0x77); // Set P3 and P7 as inputs
pi4io_set(0x07, 0x00); // Set outputs to follow the output port register
pi4io_set(0x05, 0x11); // camera 1 default
// pi4io_set(0x01, 0xFF); // reset
pi4io_set(0x0B, 0xFF); // Disable pullup/pulldown resistors
pi4io_set(0x11, 0xFF); // Disable interrupts on inputs
pi4io_get(0x13); // De-assert the interrrupt
pi4io_set(0x03, 0x77); // Set P3 and P7 as inputs
pi4io_set(0x07, 0x00); // Set outputs to follow the output port register
pi4io_set(0x05, 0x11); // camera 1 default
g_max_camera = PI4IO_CAMS;
} else if (g_camera_switch == SWITCH_TYPE_PCA9557) {
g_max_camera = PCA9557_CAMS;
pca9557_set(0x03, 0x00); // all outputs
pca9557_set(0x01, 0x1B); // camera 1 default
WAIT(200); // wait for camera power up
} else {
g_camera_id = 1;
pca9557_set(0x03, 0x00); // all outputs
pca9557_set(0x01, 0x1B); // camera 1 default
WAIT(200); // wait for camera power up
} else if (g_camera_switch == SWITCH_TYPE_HDZCS) {
g_max_camera = HDZCS_CAMS;
hdzcs_set(0x00, 0x01); // camera 1 default
}
}

Expand All @@ -217,5 +244,28 @@ void manual_select_camera(void) {
uint8_t camera_id = ((command & 0x80) >> 7) + 1;
select_camera(camera_id);
}
} else if (g_camera_switch == SWITCH_TYPE_HDZCS) {
uint8_t command = hdzcs_get(0x01);
switch (command) {
case 0:
g_manual_camera_sel = 3; // manual analog camera
break;
case 1:
g_manual_camera_sel = 2; // manual mipi camera 2
break;
case 2:
g_manual_camera_sel = 1; // manual mipi camera 1
break;
case 3:
g_manual_camera_sel = 0;
break; // assign by FC
default:
g_manual_camera_sel = 0;
break;
}

if (g_manual_camera_sel) {
select_camera(g_manual_camera_sel);
}
}
}
8 changes: 6 additions & 2 deletions src/i2c_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,19 @@
#define ADDR_RUNCAM 0x21
#define ADDR_PI4IO 0x43 // 2 camera switch
#define ADDR_PCA9557 0x18 // 3 camera switch
#define ADDR_HDZCS 0x60

typedef enum {
SWITCH_TYPE_NONE,
SWITCH_TYPE_PI4IO,
SWITCH_TYPE_PCA9557
SWITCH_TYPE_PCA9557,
SWITCH_TYPE_HDZCS,
} switch_type_e;

typedef enum {
PI4IO_CAMS = 2,
PCA9557_CAMS = 3
PCA9557_CAMS = 3,
HDZCS_CAMS = 3,
} switch_cams_e;

void set_segment(uint32_t val);
Expand All @@ -33,6 +36,7 @@ void Init_TC3587(uint8_t fmt);

uint8_t pi4io_get(uint8_t reg);
void pi4io_set(uint8_t reg, uint8_t val);
uint8_t hdzcs_get(uint8_t reg);
void camera_switch_init(void);
void select_camera(uint8_t camera_id);
void manual_select_camera(void);
Expand Down
Loading