Skip to content

Commit e71e619

Browse files
authored
Merge pull request #249 from hd-zero/support-HDZGCS
support HDZero Camera Switcher 3
2 parents 3791a1c + 038a26e commit e71e619

7 files changed

Lines changed: 158 additions & 57 deletions

File tree

src/camera.c

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,18 @@ extern uint8_t g_camera_switch;
3333
void camera_type_detect(void) {
3434
camera_type = CAMERA_TYPE_UNKNOWN;
3535

36-
runcam_type_detect();
37-
if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V1 ||
38-
camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2 ||
39-
camera_type == CAMERA_TYPE_RUNCAM_NANO_90 ||
40-
camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) {
41-
camera_mfr = CAMERA_MFR_RUNCAM;
42-
return;
36+
if (g_camera_switch == SWITCH_TYPE_HDZCS && g_camera_id == 3) {
37+
camera_type = CAMERA_TYPE_HDZCS_CVBS;
38+
camera_mfr = CAMERA_MFR_HDZERO;
39+
} else {
40+
runcam_type_detect();
41+
if (camera_type == CAMERA_TYPE_RUNCAM_MICRO_V1 ||
42+
camera_type == CAMERA_TYPE_RUNCAM_MICRO_V2 ||
43+
camera_type == CAMERA_TYPE_RUNCAM_NANO_90 ||
44+
camera_type == CAMERA_TYPE_RUNCAM_MICRO_V3) {
45+
camera_mfr = CAMERA_MFR_RUNCAM;
46+
return;
47+
}
4348
}
4449
}
4550

@@ -62,6 +67,9 @@ void camera_ratio_detect(void) {
6267
camRatio = 1;
6368
break;
6469
#endif
70+
case CAMERA_TYPE_HDZCS_CVBS:
71+
camRatio = 1;
72+
break;
6573
default:
6674
camRatio = 0;
6775
break;
@@ -169,8 +177,12 @@ void camera_mode_detect(uint8_t init) {
169177

170178
// init tc3587 and detect fps
171179
WriteReg(0, 0x8F, 0x91);
172-
173-
if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) {
180+
if (camera_type == CAMERA_TYPE_HDZCS_CVBS) {
181+
Init_TC3587(0);
182+
Set_720P60(IS_RX);
183+
video_format = VDO_FMT_720P60;
184+
I2C_Write16(ADDR_TC3587, 0x0058, 0x00e0);
185+
} else if (camera_type == CAMERA_TYPE_RUNCAM_NANO_90) {
174186
Init_TC3587(1);
175187
if (camera_setting_reg_set[11] == 0) {
176188
Set_540P90(0);
@@ -305,7 +317,7 @@ void camera_setting_profile_check(uint8_t profile) {
305317
}
306318
void camera_profile_read(void) {
307319
if (g_camera_switch) {
308-
camera_profile_eep = g_camera_id-1;
320+
camera_profile_eep = g_camera_id - 1;
309321
} else {
310322
camera_profile_eep = camera_reg_read_eep(EEP_ADDR_CAM_PROFILE);
311323
}
@@ -331,7 +343,8 @@ void camera_setting_read(void) {
331343

332344
if (camera_type == CAMERA_TYPE_UNKNOWN ||
333345
camera_type == CAMERA_TYPE_OUTDATED ||
334-
camera_type == CAMERA_TYPE_RESERVED)
346+
camera_type == CAMERA_TYPE_RESERVED ||
347+
camera_type == CAMERA_TYPE_HDZCS_CVBS)
335348
return;
336349

337350
camera_type_last = camera_reg_read_eep(EEP_ADDR_CAM_TYPE);
@@ -365,7 +378,7 @@ void camera_setting_reg_menu_update(void) {
365378
void camera_setting_reg_eep_update(void) {
366379
uint8_t i;
367380
for (i = 0; i < CAMERA_SETTING_NUM; i++) {
368-
if (g_camera_switch && i == (CAM_STATUS_VDO_FMT-1)) {
381+
if (g_camera_switch && i == (CAM_STATUS_VDO_FMT - 1)) {
369382
// Sync all cameras on the camera switch to the same video setting if changed
370383
uint8_t value = camera_setting_reg_menu[i];
371384
camera_setting_reg_eep[0][i] = value;
@@ -416,6 +429,13 @@ void camera_init(void) {
416429
camera_button_init();
417430
}
418431

432+
void camera_reinit(void) {
433+
camera_type_detect();
434+
camera_setting_read();
435+
camera_setting_reg_menu_update();
436+
camera_mode_detect(1);
437+
}
438+
419439
void camera_button_op(uint8_t op) {
420440
switch (op) {
421441
case BTN_UP:

src/camera.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef enum {
2828
CAMERA_MFR_UNKNOW,
2929
CAMERA_MFR_FOXEER,
3030
CAMERA_MFR_RUNCAM,
31+
CAMERA_MFR_HDZERO,
3132
} camera_manufacture_e;
3233

3334
typedef enum {
@@ -38,6 +39,8 @@ typedef enum {
3839
CAMERA_TYPE_RUNCAM_MICRO_V2, // include hzd nano v2 / hdz nano lite
3940
CAMERA_TYPE_RUNCAM_NANO_90,
4041
CAMERA_TYPE_RUNCAM_MICRO_V3,
42+
CAMERA_TYPE_HDZCS_CVBS,
43+
CAMERA_TYPE_NUM,
4144
} camera_type_e;
4245

4346
typedef enum {
@@ -92,6 +95,7 @@ typedef enum {
9295
} camera_select_e;
9396

9497
void camera_init(void);
98+
void camera_reinit(void);
9599
void camera_switch_profile(void);
96100
uint8_t camera_status_update(uint8_t op);
97101
void camera_menu_init(void);

src/hardware.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,10 +1029,14 @@ void video_detect(void) {
10291029
return;
10301030
}
10311031
#endif
1032+
if (camera_type == CAMERA_TYPE_HDZCS_CVBS) {
1033+
return;
1034+
}
10321035

1033-
if (sec == 3) {
1034-
sec = 0;
1035-
if (cameraLost) { // video loss
1036+
if (cameraLost) {
1037+
sec++;
1038+
if (sec == 3) { // video loss
1039+
sec = 0;
10361040
if (video_format == VDO_FMT_720P50) {
10371041
Set_720P60(IS_RX);
10381042
video_format = VDO_FMT_720P60;
@@ -1041,6 +1045,8 @@ void video_detect(void) {
10411045
video_format = VDO_FMT_720P50;
10421046
}
10431047
}
1048+
} else {
1049+
sec = 0;
10441050
}
10451051
}
10461052
}

src/i2c_device.c

Lines changed: 78 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
#include "global.h"
66
#include "hardware.h"
77
#include "i2c.h"
8+
#include "msp_displayport.h"
89
#include "print.h"
910

1011
uint8_t g_camera_switch = SWITCH_TYPE_NONE;
1112
uint8_t g_camera_id = 0;
1213
uint8_t g_max_camera = 0;
1314
uint8_t g_manual_camera_sel = 0;
15+
static uint8_t camera_list[3] = {255, 254, 253};
1416

1517
/////////////////////////////////////////////////////////////////
1618
// MAX7315
@@ -140,70 +142,95 @@ void pca9557_set(uint8_t reg, uint8_t val) {
140142
I2C_Write8(ADDR_PCA9557, reg, val);
141143
}
142144

145+
// Read from 3 camera switch
146+
uint8_t hdzcs_get(uint8_t reg) {
147+
return I2C_Read8(ADDR_HDZCS, reg);
148+
}
149+
150+
// Write to 3 camera switch
151+
void hdzcs_set(uint8_t reg, uint8_t val) {
152+
I2C_Write8_Wait(10, ADDR_HDZCS, reg, val);
153+
}
154+
143155
uint8_t get_camera_switch_type(void) {
144156
uint8_t camera_switch = SWITCH_TYPE_NONE;
145157

146158
if ((pi4io_get(0x01) & 0xE0) == 0xA0) { // device ID register
147159
camera_switch = SWITCH_TYPE_PI4IO;
148160
} else if (pca9557_get(0x02) == 0xF0) { // polarity inversion register defaults to 0xF0
149161
camera_switch = SWITCH_TYPE_PCA9557;
162+
} else if (hdzcs_get(0xff) == 0x01) {
163+
camera_switch = SWITCH_TYPE_HDZCS;
150164
}
151165

152166
return camera_switch;
153167
}
154168

155169
void select_camera(uint8_t camera_id) {
156-
if (g_camera_switch)
157-
{
170+
static uint8_t camera_last = 0x00;
171+
if (g_camera_switch) {
158172
// Check camera id is within range, else default to 1
159173
uint8_t camera = (camera_id == 0 || camera_id > g_max_camera) ? 1 : camera_id;
160174
if (g_camera_id != camera) {
161175
g_camera_id = camera;
162176

163177
uint8_t command;
164178
switch (g_camera_id) {
165-
case 1:
166-
default:
167-
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x1B;
168-
break;
169-
case 2:
170-
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x64 : 0x16;
171-
break;
172-
case 3:
173-
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x0D;
174-
break;
179+
case 1:
180+
default:
181+
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x1B;
182+
break;
183+
case 2:
184+
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x64 : 0x16;
185+
break;
186+
case 3:
187+
command = (g_camera_switch == SWITCH_TYPE_PI4IO) ? 0x11 : 0x0D;
188+
break;
175189
}
176190

177191
if (g_camera_switch == SWITCH_TYPE_PI4IO) {
178192
pi4io_set(0x05, command);
179-
}
180-
else { // SWITCH_TYPE_PCA9557
193+
} else if (g_camera_switch == SWITCH_TYPE_PCA9557) { // SWITCH_TYPE_PCA9557
181194
pca9557_set(0x01, command);
182-
WAIT(200); // wait for camera power up
195+
WAIT(200); // wait for camera power up
196+
} else if (g_camera_switch == SWITCH_TYPE_HDZCS) {
197+
hdzcs_set(0x00, g_camera_id);
183198
}
184-
camera_switch_profile();
199+
200+
if (camera_last != camera_list[g_camera_id - 1]) {
201+
if (camera_list[g_camera_id - 1] < CAMERA_TYPE_NUM) { // camera has inited
202+
camera_reinit();
203+
} else {
204+
camera_init();
205+
camera_list[g_camera_id - 1] = camera_type;
206+
}
207+
camera_last = camera_type;
208+
}
209+
210+
resync_vrx_vtmg();
185211
}
186212
}
187213
}
188214

189215
void camera_switch_init() {
190216
g_camera_switch = get_camera_switch_type();
191217
if (g_camera_switch == SWITCH_TYPE_PI4IO) {
192-
//pi4io_set(0x01, 0xFF); // reset
193-
pi4io_set(0x0B, 0xFF); // Disable pullup/pulldown resistors
194-
pi4io_set(0x11, 0xFF); // Disable interrupts on inputs
195-
pi4io_get(0x13); // De-assert the interrrupt
196-
pi4io_set(0x03, 0x77); // Set P3 and P7 as inputs
197-
pi4io_set(0x07, 0x00); // Set outputs to follow the output port register
198-
pi4io_set(0x05, 0x11); // camera 1 default
218+
// pi4io_set(0x01, 0xFF); // reset
219+
pi4io_set(0x0B, 0xFF); // Disable pullup/pulldown resistors
220+
pi4io_set(0x11, 0xFF); // Disable interrupts on inputs
221+
pi4io_get(0x13); // De-assert the interrrupt
222+
pi4io_set(0x03, 0x77); // Set P3 and P7 as inputs
223+
pi4io_set(0x07, 0x00); // Set outputs to follow the output port register
224+
pi4io_set(0x05, 0x11); // camera 1 default
199225
g_max_camera = PI4IO_CAMS;
200226
} else if (g_camera_switch == SWITCH_TYPE_PCA9557) {
201227
g_max_camera = PCA9557_CAMS;
202-
pca9557_set(0x03, 0x00); // all outputs
203-
pca9557_set(0x01, 0x1B); // camera 1 default
204-
WAIT(200); // wait for camera power up
205-
} else {
206-
g_camera_id = 1;
228+
pca9557_set(0x03, 0x00); // all outputs
229+
pca9557_set(0x01, 0x1B); // camera 1 default
230+
WAIT(200); // wait for camera power up
231+
} else if (g_camera_switch == SWITCH_TYPE_HDZCS) {
232+
g_max_camera = HDZCS_CAMS;
233+
hdzcs_set(0x00, 0x01); // camera 1 default
207234
}
208235
}
209236

@@ -217,5 +244,28 @@ void manual_select_camera(void) {
217244
uint8_t camera_id = ((command & 0x80) >> 7) + 1;
218245
select_camera(camera_id);
219246
}
247+
} else if (g_camera_switch == SWITCH_TYPE_HDZCS) {
248+
uint8_t command = hdzcs_get(0x01);
249+
switch (command) {
250+
case 0:
251+
g_manual_camera_sel = 3; // manual analog camera
252+
break;
253+
case 1:
254+
g_manual_camera_sel = 2; // manual mipi camera 2
255+
break;
256+
case 2:
257+
g_manual_camera_sel = 1; // manual mipi camera 1
258+
break;
259+
case 3:
260+
g_manual_camera_sel = 0;
261+
break; // assign by FC
262+
default:
263+
g_manual_camera_sel = 0;
264+
break;
265+
}
266+
267+
if (g_manual_camera_sel) {
268+
select_camera(g_manual_camera_sel);
269+
}
220270
}
221271
}

src/i2c_device.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@
1313
#define ADDR_RUNCAM 0x21
1414
#define ADDR_PI4IO 0x43 // 2 camera switch
1515
#define ADDR_PCA9557 0x18 // 3 camera switch
16+
#define ADDR_HDZCS 0x60
1617

1718
typedef enum {
1819
SWITCH_TYPE_NONE,
1920
SWITCH_TYPE_PI4IO,
20-
SWITCH_TYPE_PCA9557
21+
SWITCH_TYPE_PCA9557,
22+
SWITCH_TYPE_HDZCS,
2123
} switch_type_e;
2224

2325
typedef enum {
2426
PI4IO_CAMS = 2,
25-
PCA9557_CAMS = 3
27+
PCA9557_CAMS = 3,
28+
HDZCS_CAMS = 3,
2629
} switch_cams_e;
2730

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

3437
uint8_t pi4io_get(uint8_t reg);
3538
void pi4io_set(uint8_t reg, uint8_t val);
39+
uint8_t hdzcs_get(uint8_t reg);
3640
void camera_switch_init(void);
3741
void select_camera(uint8_t camera_id);
3842
void manual_select_camera(void);

0 commit comments

Comments
 (0)