Skip to content

Commit

Permalink
Merge pull request #419 from ligenxxxx/new-method-to-set-vclk
Browse files Browse the repository at this point in the history
New method to set vclk phase
  • Loading branch information
ligenxxxx authored Jun 19, 2024
2 parents 7ad5d4c + c407725 commit f44bb32
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 53 deletions.
2 changes: 1 addition & 1 deletion src/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ int main(int argc, char *argv[]) {
// 1. Recall configuration
settings_init();
settings_load();
vclk_phase_init();

// 2. Initialize communications.
rtc_init();
Expand All @@ -159,7 +160,6 @@ int main(int argc, char *argv[]) {
elrs_init();
ht_init();
beep_init();
vclk_phase_init();

// 4. Initilize UI
lvgl_init();
Expand Down
195 changes: 144 additions & 51 deletions src/driver/hardware.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "hardware.h"
#include "i2c.h"
#include "it66021.h"
#include "it66121.h"
#include "msp_displayport.h"
#include "oled.h"
#include "uart.h"
Expand All @@ -34,24 +35,25 @@ int fhd_req = 0;
// local
pthread_mutex_t hardware_mutex;

uint32_t vclk_phase[VIDEO_SOURCE_NUM] = {
// 0x8d_0, 0x8e, 0x14, 0x8d_1
uint32_t vclk_phase_default[VIDEO_SOURCE_NUM] = {
// 0x8d, 0x8e, 0x14, hdmi_out
0x00000001, // VIDEO_SOURCE_VERSION
0x14840000, // VIDEO_SOURCE_MENU_UI
0x14840000, // VIDEO_SOURCE_HDZERO_IN_720P60_50
0x14840000, // VIDEO_SOURCE_HDZERO_IN_720P90
0x14840000, // VIDEO_SOURCE_HDZERO_IN_1080P30
0x1C840000, // VIDEO_SOURCE_AV_IN
0x14840004, // VIDEO_SOURCE_HDMI_IN_1080P50
0x14840004, // VIDEO_SOURCE_HDMI_IN_1080P60
0x14840004, // VIDEO_SOURCE_HDMI_IN_1080PPOTHER
0x14840004, // VIDEO_SOURCE_HDMI_IN_720P50
0x14840004, // VIDEO_SOURCE_HDMI_IN_720P60
0x14840004, // VIDEO_SOURCE_HDMI_IN_720P100
0x14840000, // VIDEO_SOURCE_HDMI_IN_1080P50
0x14840000, // VIDEO_SOURCE_HDMI_IN_1080P60
0x14840000, // VIDEO_SOURCE_HDMI_IN_1080PPOTHER
0x14840000, // VIDEO_SOURCE_HDMI_IN_720P50
0x14840000, // VIDEO_SOURCE_HDMI_IN_720P60
0x14840000, // VIDEO_SOURCE_HDMI_IN_720P100
};
uint32_t vclk_phase_load[VIDEO_SOURCE_NUM];
uint32_t vclk_phase[VIDEO_SOURCE_NUM];

uint8_t vclk_phase_read_cfg_file(char *file_path) {
uint8_t vclk_phase_read_file(char *file_path) {
FILE *file;
char line[256];
char type_str[128];
Expand All @@ -60,7 +62,7 @@ uint8_t vclk_phase_read_cfg_file(char *file_path) {
uint32_t value;
uint8_t i = 0;

LOGI("vclk_phase_read_cfg_file: %s", file_path);
LOGI("vclk_phase_read_file: %s", file_path);
for (i = 0; i < VIDEO_SOURCE_NUM; i++) {
vclk_phase_load[i] = 0xffffffff;
}
Expand Down Expand Up @@ -110,64 +112,153 @@ uint8_t vclk_phase_read_cfg_file(char *file_path) {
return 0;
}

uint8_t vclk_phase_write_cfg_file(char *file_path) {
uint8_t vclk_phase_inv_read_file(char *file_path) {
FILE *file;
char line[256];
char type_str[128];
char value_str[16];
char *endptr;
uint8_t mode = 0;
uint32_t value;
uint8_t i = 0;

LOGI("vclk_phase_write_cfg_file %s", file_path);
LOGI("vclk_phase_inv_read_file: %s", file_path);

file = fopen(file_path, "w");
file = fopen(file_path, "r");
if (file == NULL) {
LOGI("%s open failed", file_path);
return 1;
}
} else {
while (fgets(line, sizeof(line), file)) {
sscanf(line, "%s %s", type_str, value_str);
value = strtoul(value_str, &endptr, 0);
if (*endptr != '\0') {
LOGI("vclk parse inv error: %s, %s", type_str, value_str);
break;
}

if (strcmp(type_str, "MODE1") == 0 || strcmp(type_str, "mode1") == 0)
mode = 1;
else if (strcmp(type_str, "MODE2") == 0 || strcmp(type_str, "mode2") == 0)
mode = 2;
else if (strcmp(type_str, "MODE3") == 0 || strcmp(type_str, "mode3") == 0)
mode = 3;
else if (strcmp(type_str, "MODE4") == 0 || strcmp(type_str, "mode4") == 0)
mode = 4;
else if (strcmp(type_str, "MODE5") == 0 || strcmp(type_str, "mode5") == 0)
mode = 5;
else if (strcmp(type_str, "MODE6") == 0 || strcmp(type_str, "mode6") == 0)
mode = 6;
else if (strcmp(type_str, "MODE7") == 0 || strcmp(type_str, "mode7") == 0)
mode = 7;
else if (strcmp(type_str, "MODE8") == 0 || strcmp(type_str, "mode8") == 0)
mode = 8;
else if (strcmp(type_str, "MODE9") == 0 || strcmp(type_str, "mode9") == 0)
mode = 9;
else if (strcmp(type_str, "MODE10") == 0 || strcmp(type_str, "mode10") == 0)
mode = 10;
else if (strcmp(type_str, "MODE11") == 0 || strcmp(type_str, "mode11") == 0)
mode = 11;
else
break;

LOGI("mode %d", mode);

vclk_phase[mode] = vclk_phase_default[mode];

if ((value >> 0) & 1) // 14[0]
vclk_phase[mode] ^= (1 << 8);

if ((value >> 1) & 1) // 8e[7]
vclk_phase[mode] ^= (1 << 23);

if ((value >> 2) & 1) // 8d[2]
vclk_phase[mode] ^= (1 << 26);

if ((value >> 3) & 1) // hdmi out_0
vclk_phase[mode] ^= (1 << 0);

if ((value >> 4) & 1) // hdmi out_1
vclk_phase[mode] ^= (1 << 1);

fprintf(file, "VIDEO_SOURCE_VERSION 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_VERSION]);
fprintf(file, "VIDEO_SOURCE_MENU_UI 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_MENU_UI]);
fprintf(file, "VIDEO_SOURCE_HDZERO_IN_720P60_50 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDZERO_IN_720P60_50]);
fprintf(file, "VIDEO_SOURCE_HDZERO_IN_720P90 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDZERO_IN_720P90]);
fprintf(file, "VIDEO_SOURCE_HDZERO_IN_1080P30 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDZERO_IN_1080P30]);
fprintf(file, "VIDEO_SOURCE_AV_IN 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_AV_IN]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_1080P50 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDMI_IN_1080P50]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_1080P60 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDMI_IN_1080P60]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_720P50 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDMI_IN_720P50]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_720P60 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDMI_IN_720P60]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_720P100 0x%08x\r\n", vclk_phase[VIDEO_SOURCE_HDMI_IN_720P100]);
if ((value >> 5) & 1) // 8d[4]
vclk_phase[mode] ^= (1 << 28);

if ((value >> 6) & 1) // 8d[3]
vclk_phase[mode] ^= (1 << 27);

if ((value >> 7) & 1) // 8e[2]
vclk_phase[mode] ^= (1 << 18);

LOGI("%s 0x%02x, ori:0x%08x new:0x%08x", type_str, value, vclk_phase_default[mode], vclk_phase[mode]);
}
}

fclose(file);
return 0;
}

void vclk_phase_update_cfg() {
uint8_t i;
for (i = 0; i < VIDEO_SOURCE_NUM; i++) {
if (vclk_phase_load[i] != 0xffffffff && vclk_phase_load[i] != vclk_phase[i])
vclk_phase[i] = vclk_phase_load[i];
uint8_t vclk_phase_write_file(char *file_path, uint32_t phase_p[]) {
FILE *file;

LOGI("vclk_phase_write_file %s", file_path);

file = fopen(file_path, "w");
if (file == NULL) {
LOGI("%s open failed", file_path);
return 1;
}

fprintf(file, "VIDEO_SOURCE_VERSION 0x%08x\r\n", phase_p[VIDEO_SOURCE_VERSION]);
fprintf(file, "VIDEO_SOURCE_MENU_UI 0x%08x\r\n", phase_p[VIDEO_SOURCE_MENU_UI]);
fprintf(file, "VIDEO_SOURCE_HDZERO_IN_720P60_50 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDZERO_IN_720P60_50]);
fprintf(file, "VIDEO_SOURCE_HDZERO_IN_720P90 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDZERO_IN_720P90]);
fprintf(file, "VIDEO_SOURCE_HDZERO_IN_1080P30 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDZERO_IN_1080P30]);
fprintf(file, "VIDEO_SOURCE_AV_IN 0x%08x\r\n", phase_p[VIDEO_SOURCE_AV_IN]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_1080P50 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDMI_IN_1080P50]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_1080P60 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDMI_IN_1080P60]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_720P50 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDMI_IN_720P50]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_720P60 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDMI_IN_720P60]);
fprintf(file, "VIDEO_SOURCE_HDMI_IN_720P100 0x%08x\r\n", phase_p[VIDEO_SOURCE_HDMI_IN_720P100]);

fclose(file);
}

void vclk_phase_load_system_cfg() {
if (vclk_phase_read_cfg_file("/etc/vclk_phase.cfg")) {
void vclk_phase_load_system() {
uint8_t i;
if (vclk_phase_read_file("/etc/vclk_phase.cfg")) {
// if no .cfg file, write it.
vclk_phase_write_cfg_file("/etc/vclk_phase.cfg");
} else if (vclk_phase_load[VIDEO_SOURCE_VERSION] != 0xffffffff && vclk_phase_load[VIDEO_SOURCE_VERSION] != vclk_phase[VIDEO_SOURCE_VERSION]) {
vclk_phase_write_file("/etc/vclk_phase.cfg", vclk_phase_default);

for (i = 0; i < VIDEO_SOURCE_NUM; i++) {
vclk_phase[i] = vclk_phase_default[i];
}
} else if (vclk_phase_load[VIDEO_SOURCE_VERSION] != 0xffffffff && vclk_phase_load[VIDEO_SOURCE_VERSION] != vclk_phase_default[VIDEO_SOURCE_VERSION]) {
// newer .cfg file version
vclk_phase_write_cfg_file("/etc/vclk_phase.cfg");
vclk_phase_write_file("/etc/vclk_phase.cfg", vclk_phase_default);

for (i = 0; i < VIDEO_SOURCE_NUM; i++) {
vclk_phase[i] = vclk_phase_default[i];
}
} else {
vclk_phase_update_cfg();
for (i = 0; i < VIDEO_SOURCE_NUM; i++) {
if (vclk_phase_load[i] != 0xffffffff)
vclk_phase[i] = vclk_phase_load[i];
}
}
}

void vclk_phase_load_sdcard_cfg() {
if (vclk_phase_read_cfg_file("/mnt/extsd/vclk_phase.cfg")) {
void vclk_phase_inv_load_sdcard() {
if (vclk_phase_inv_read_file("/mnt/extsd/vclk_phase_inv.txt")) {
return;
}

vclk_phase_update_cfg();
vclk_phase_write_cfg_file("/etc/vclk_phase.cfg");
vclk_phase_write_file("/etc/vclk_phase.cfg", vclk_phase);

system_exec("rm /mnt/extsd/vclk_phase.cfg");
system_exec("rm /mnt/extsd/vclk_phase_inv.txt");
}

void vclk_phase_dump_cfg() {
void vclk_phase_dump() {
FILE *file;
char *file_path = "/mnt/extsd/vclk_phase_dump.cfg";

Expand All @@ -176,13 +267,13 @@ void vclk_phase_dump_cfg() {
return;
fclose(file);

vclk_phase_write_cfg_file(file_path);
vclk_phase_write_file(file_path, vclk_phase);
}

void vclk_phase_init() {
vclk_phase_load_system_cfg();
vclk_phase_load_sdcard_cfg();
vclk_phase_dump_cfg();
vclk_phase_load_system();
vclk_phase_inv_load_sdcard();
vclk_phase_dump();

LOGI("vclk phase:");
LOGI("VIDEO_SOURCE_VERSION 0x%08x", vclk_phase[0]);
Expand All @@ -199,15 +290,17 @@ void vclk_phase_init() {
LOGI("VIDEO_SOURCE_HDMI_IN_720P100 0x%08x", vclk_phase[11]);
}

void vclk_phase_set(video_source_t vs, uint8_t reg_8d_sel) {
void vclk_phase_set(video_source_t source, uint8_t reg_8d_sel) {

if (reg_8d_sel)
I2C_Write(ADDR_FPGA, 0x8d, (vclk_phase[vs] >> 0) & 0xff);
I2C_Write(ADDR_FPGA, 0x8d, (((vclk_phase[source] >> 24) & 0xff) ^ (1 << 4)));
else
I2C_Write(ADDR_FPGA, 0x8d, (vclk_phase[vs] >> 24) & 0xff);
I2C_Write(ADDR_FPGA, 0x8d, (vclk_phase[source] >> 24) & 0xff);

I2C_Write(ADDR_FPGA, 0x8e, (vclk_phase[source] >> 16) & 0xff);
I2C_Write(ADDR_AL, 0x14, (vclk_phase[source] >> 8) & 0xff);

I2C_Write(ADDR_FPGA, 0x8e, (vclk_phase[vs] >> 16) & 0xff);
I2C_Write(ADDR_AL, 0x14, (vclk_phase[vs] >> 8) & 0xff);
IT66121_set_phase(vclk_phase[source] & 3);
}

void hw_stat_init() {
Expand Down
1 change: 1 addition & 0 deletions src/driver/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef enum {
VIDEO_SOURCE_HDMI_IN_720P50 = 9,
VIDEO_SOURCE_HDMI_IN_720P60 = 10,
VIDEO_SOURCE_HDMI_IN_720P100 = 11,
VIDEO_SOURCE_HDMI_OUT = 11,
VIDEO_SOURCE_NUM = 12,
} video_source_t;

Expand Down
14 changes: 13 additions & 1 deletion src/driver/it66121.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
#include "../core/common.hh"
#include "dm5680.h"
#include "i2c.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

uint8_t it66121_vi_phase = 0;

void IT66121_close() {
DM5680_ResetHDMI_TX(0);
}
Expand Down Expand Up @@ -118,3 +119,14 @@ void IT66121_init() {
I2C_R_Write(ADDR_IT66121, 0xc1, 0x00);
I2C_R_Write(ADDR_IT66121, 0xc6, 0x03);
}

void IT66121_set_phase(uint8_t phase) {
uint8_t rdat;

rdat = I2C_R_Read(ADDR_IT66121, 0x02);
if (rdat == 0x12) {
I2C_R_Write(ADDR_IT66121, 0x70, (0x48 | phase));
} else if (rdat == 0x22) {
I2C_R_Write(ADDR_IT66121, 0x72, (0x03 | (phase << 6)));
}
}
2 changes: 2 additions & 0 deletions src/driver/it66121.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>

void IT66121_close();
void IT66121_init();
void IT66121_set_phase(uint8_t phase);

#ifdef __cplusplus
}
Expand Down

0 comments on commit f44bb32

Please sign in to comment.