diff --git a/src/core/main.c b/src/core/main.c index 55d4db49..1573960c 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -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(); @@ -159,7 +160,6 @@ int main(int argc, char *argv[]) { elrs_init(); ht_init(); beep_init(); - vclk_phase_init(); // 4. Initilize UI lvgl_init(); diff --git a/src/driver/hardware.c b/src/driver/hardware.c index 082123cb..1f48f761 100644 --- a/src/driver/hardware.c +++ b/src/driver/hardware.c @@ -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" @@ -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]; @@ -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; } @@ -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"; @@ -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]); @@ -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() { diff --git a/src/driver/hardware.h b/src/driver/hardware.h index f6c033f7..7788e643 100644 --- a/src/driver/hardware.h +++ b/src/driver/hardware.h @@ -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; diff --git a/src/driver/it66121.c b/src/driver/it66121.c index 7fe70837..b76c4f20 100644 --- a/src/driver/it66121.c +++ b/src/driver/it66121.c @@ -2,11 +2,12 @@ #include "../core/common.hh" #include "dm5680.h" #include "i2c.h" -#include #include #include #include +uint8_t it66121_vi_phase = 0; + void IT66121_close() { DM5680_ResetHDMI_TX(0); } @@ -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))); + } +} \ No newline at end of file diff --git a/src/driver/it66121.h b/src/driver/it66121.h index 568c1a5d..849ab6d5 100644 --- a/src/driver/it66121.h +++ b/src/driver/it66121.h @@ -3,9 +3,11 @@ #ifdef __cplusplus extern "C" { #endif +#include void IT66121_close(); void IT66121_init(); +void IT66121_set_phase(uint8_t phase); #ifdef __cplusplus }