mirror of
https://github.com/marqs85/ossc.git
synced 2025-04-13 07:37:01 +00:00
Add auto input switching
Cycle through inputs until sync is found or limit has been reached. RGsB or YPbPr defaults can be set per input. Stay on current physical input for a short time when sync is lost. Press right button on the remote for next input.
This commit is contained in:
parent
0905620b4d
commit
4e4f5749ea
software/sys_controller/ossc
@ -41,6 +41,7 @@
|
||||
#include "HDMI_TX.h"
|
||||
#include "hdmitx.h"
|
||||
#include "sd_io.h"
|
||||
#include "sys/alt_timestamp.h"
|
||||
|
||||
#define STABLE_THOLD 1
|
||||
#define MIN_LINES_PROGRESSIVE 200
|
||||
@ -69,6 +70,7 @@ alt_u8 stable_frames;
|
||||
alt_u8 update_cur_vm;
|
||||
|
||||
alt_u8 vm_sel, vm_edit, profile_sel, profile_sel_menu, input_profiles[AV_LAST], lt_sel, def_input, profile_link, lcd_bl_timeout;
|
||||
alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr = 1, auto_av3_ypbpr;
|
||||
alt_u16 tc_h_samplerate, tc_h_synclen, tc_h_bporch, tc_h_active, tc_v_synclen, tc_v_bporch, tc_v_active;
|
||||
|
||||
char row1[LCD_ROW_LEN+1], row2[LCD_ROW_LEN+1], menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
|
||||
@ -785,6 +787,12 @@ int main()
|
||||
|
||||
alt_u32 input_vec;
|
||||
|
||||
alt_u32 auto_input_timestamp = 300 * (alt_timestamp_freq() >> 10);
|
||||
alt_u8 auto_input_changed = 0;
|
||||
alt_u8 auto_input_ctr = 0;
|
||||
alt_u8 auto_input_current_ctr = AUTO_CURRENT_MAX_COUNT;
|
||||
alt_u8 auto_input_keep_current = 0;
|
||||
|
||||
int init_stat, man_input_change;
|
||||
|
||||
init_stat = init_hw();
|
||||
@ -806,6 +814,9 @@ int main()
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
// start timer for auto input
|
||||
alt_timestamp_start();
|
||||
|
||||
// Mainloop
|
||||
while(1) {
|
||||
// Read remote control and PCB button status
|
||||
@ -826,11 +837,68 @@ int main()
|
||||
btn_code = 0;
|
||||
}
|
||||
|
||||
// Auto input switching
|
||||
if (auto_input != AUTO_OFF && cm.avinput != AV_TESTPAT && !cm.sync_active && !menu_active
|
||||
&& alt_timestamp() >= auto_input_timestamp && auto_input_ctr < AUTO_MAX_COUNT) {
|
||||
|
||||
// Keep switching on the same physical input when set to Current input or a short time after losing sync.
|
||||
auto_input_keep_current = (auto_input == AUTO_CURRENT_INPUT || auto_input_current_ctr < AUTO_CURRENT_MAX_COUNT);
|
||||
|
||||
switch(cm.avinput) {
|
||||
case AV1_RGBs:
|
||||
target_input = auto_av1_ypbpr ? AV1_YPBPR : AV1_RGsB;
|
||||
break;
|
||||
case AV1_RGsB:
|
||||
case AV1_YPBPR:
|
||||
target_input = auto_input_keep_current ? AV1_RGBs : (auto_av2_ypbpr ? AV2_YPBPR : AV2_RGsB);
|
||||
break;
|
||||
case AV2_YPBPR:
|
||||
case AV2_RGsB:
|
||||
target_input = auto_input_keep_current ? target_input : AV3_RGBHV;
|
||||
break;
|
||||
case AV3_RGBHV:
|
||||
target_input = AV3_RGBs;
|
||||
break;
|
||||
case AV3_RGBs:
|
||||
target_input = auto_av3_ypbpr ? AV3_YPBPR : AV3_RGsB;
|
||||
break;
|
||||
case AV3_RGsB:
|
||||
case AV3_YPBPR:
|
||||
target_input = auto_input_keep_current ? AV3_RGBHV : AV1_RGBs;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auto_input_ctr++;
|
||||
|
||||
if (auto_input_current_ctr < AUTO_CURRENT_MAX_COUNT)
|
||||
auto_input_current_ctr++;
|
||||
|
||||
// For input linked profile loading below
|
||||
auto_input_changed = 1;
|
||||
|
||||
// reset timer
|
||||
alt_timestamp_start();
|
||||
}
|
||||
|
||||
man_input_change = parse_control();
|
||||
|
||||
if (menu_active)
|
||||
display_menu(0);
|
||||
|
||||
// Only auto load profile when input is manually changed or when sync is active after automatic switch.
|
||||
if ((target_input != cm.avinput && man_input_change) || (auto_input_changed && cm.sync_active)) {
|
||||
// The input changed, so load the appropriate profile if
|
||||
// input->profile link is enabled
|
||||
if (profile_link && (profile_sel != input_profiles[target_input])) {
|
||||
profile_sel = input_profiles[target_input];
|
||||
read_userdata(profile_sel);
|
||||
}
|
||||
|
||||
auto_input_changed = 0;
|
||||
}
|
||||
|
||||
if (target_input != cm.avinput) {
|
||||
|
||||
target_tvp = TVP_INPUT1;
|
||||
@ -873,13 +941,6 @@ int main()
|
||||
|
||||
printf("### SWITCH MODE TO %s ###\n", avinput_str[target_input]);
|
||||
|
||||
// The input changed, so load the appropriate profile if
|
||||
// input->profile link is enabled
|
||||
if (profile_link && (profile_sel != input_profiles[target_input])) {
|
||||
profile_sel = input_profiles[target_input];
|
||||
read_userdata(profile_sel);
|
||||
}
|
||||
|
||||
cm.avinput = target_input;
|
||||
cm.sync_active = 0;
|
||||
ths_source_sel(target_ths, (cm.cc.video_lpf > 1) ? (VIDEO_LPF_MAX-cm.cc.video_lpf) : THS_LPF_BYPASS);
|
||||
@ -895,9 +956,14 @@ int main()
|
||||
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
|
||||
if (!menu_active)
|
||||
lcd_write_status();
|
||||
// record last input if it was selected manually
|
||||
if ((def_input == AV_LAST) && man_input_change)
|
||||
write_userdata(INIT_CONFIG_SLOT);
|
||||
if (man_input_change) {
|
||||
// record last input if it was selected manually
|
||||
if (def_input == AV_LAST)
|
||||
write_userdata(INIT_CONFIG_SLOT);
|
||||
// Reset auto input timer when input is manually changed
|
||||
auto_input_ctr = 0;
|
||||
alt_timestamp_start();
|
||||
}
|
||||
}
|
||||
|
||||
// Check here to enable regardless of input
|
||||
@ -933,6 +999,9 @@ int main()
|
||||
strncpy(row2, " NO SYNC", LCD_ROW_LEN+1);
|
||||
if (!menu_active)
|
||||
lcd_write_status();
|
||||
alt_timestamp_start();// reset auto input timer
|
||||
auto_input_ctr = 0;
|
||||
auto_input_current_ctr = 0;
|
||||
}
|
||||
break;
|
||||
case MODE_CHANGE:
|
||||
|
@ -61,6 +61,11 @@
|
||||
#define FPGA_SCANLINEMODE_V 2
|
||||
#define FPGA_SCANLINEMODE_ALT 3
|
||||
|
||||
#define AUTO_OFF 0
|
||||
#define AUTO_CURRENT_INPUT 1
|
||||
#define AUTO_MAX_COUNT 100
|
||||
#define AUTO_CURRENT_MAX_COUNT 6
|
||||
|
||||
// In reverse order of importance
|
||||
typedef enum {
|
||||
NO_CHANGE = 0,
|
||||
|
@ -119,6 +119,8 @@ int parse_control()
|
||||
alt_u8* pmcfg_ptr[] = { &pt_only, &tc.pm_240p, &tc.pm_384p, &tc.pm_480i, &tc.pm_480p, &tc.pm_480p, &tc.pm_1080i };
|
||||
alt_u8 valid_pm[] = { 0x1, 0x1f, 0x3, 0xf, 0x3, 0x3, 0x3 };
|
||||
|
||||
avinput_t next_input = (cm.avinput == AV3_YPBPR) ? AV1_RGBs : (cm.avinput+1);
|
||||
|
||||
if (remote_code)
|
||||
printf("RCODE: 0x%.4lx, %d\n", remote_code, remote_rpt);
|
||||
|
||||
@ -239,6 +241,10 @@ int parse_control()
|
||||
lcd_write_status();
|
||||
menu_active = 0;
|
||||
break;
|
||||
case RC_RIGHT:
|
||||
if (!menu_active)
|
||||
man_target_input = next_input;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -246,7 +252,7 @@ int parse_control()
|
||||
|
||||
Button_Check:
|
||||
if (btn_code & PB0_BIT)
|
||||
man_target_input = (cm.avinput == AV3_YPBPR) ? AV1_RGBs : (cm.avinput+1);
|
||||
man_target_input = next_input;
|
||||
if (btn_code & PB1_BIT)
|
||||
tc.sl_mode = tc.sl_mode < SL_MODE_MAX ? tc.sl_mode + 1 : 0;
|
||||
|
||||
|
@ -42,6 +42,7 @@ extern alt_u16 tc_h_samplerate, tc_h_synclen, tc_h_bporch, tc_h_active, tc_v_syn
|
||||
extern alt_u32 remote_code;
|
||||
extern alt_u16 rc_keymap[REMOTE_MAX_KEYS];
|
||||
extern alt_u8 vm_sel, profile_sel_menu, lt_sel, def_input, profile_link, lcd_bl_timeout;
|
||||
extern alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
|
||||
|
||||
alt_u8 menu_active;
|
||||
|
||||
@ -66,6 +67,8 @@ static const char *sl_id_desc[] = { LNG("Top","ウエ"), LNG("Bottom","シタ")
|
||||
static const char *audio_dw_sampl_desc[] = { LNG("Off (fs = 96kHz)","オフ (fs = 96kHz)"), "2x (fs = 48kHz)" };
|
||||
static const char *lt_desc[] = { "Top-left", "Center", "Bottom-right" };
|
||||
static const char *lcd_bl_timeout_desc[] = { "Off", "3s", "10s", "30s" };
|
||||
static const char *rgsb_ypbpr_desc[] = { "RGsB", "YPbPr" };
|
||||
static const char *auto_input_desc[] = { "Off", "Current input", "All inputs" };
|
||||
|
||||
static void sampler_phase_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, LNG("%d deg","%d ド"), (v*1125)/100); }
|
||||
static void sync_vth_disp(alt_u8 v) { sniprintf(menu_row2, LCD_ROW_LEN+1, "%d mV", (v*1127)/100); }
|
||||
@ -181,6 +184,10 @@ MENU(menu_settings, P99_PROTECT({ \
|
||||
{ LNG("Link input->prof","Link input->prof"), OPT_AVCONFIG_SELECTION, { .sel = { &profile_link, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
|
||||
{ "<Import sett. >", OPT_FUNC_CALL, { .fun = { import_userdata, NULL } } },
|
||||
{ LNG("Initial input","ショキニュウリョク"), OPT_AVCONFIG_SELECTION, { .sel = { &def_input, OPT_WRAP, SETTING_ITEM(avinput_str) } } },
|
||||
{ "Autodetect input", OPT_AVCONFIG_SELECTION, { .sel = { &auto_input, OPT_WRAP, SETTING_ITEM(auto_input_desc) } } },
|
||||
{ "Auto AV1 Y/Gs", OPT_AVCONFIG_SELECTION, { .sel = { &auto_av1_ypbpr, OPT_WRAP, SETTING_ITEM(rgsb_ypbpr_desc) } } },
|
||||
{ "Auto AV2 Y/Gs", OPT_AVCONFIG_SELECTION, { .sel = { &auto_av2_ypbpr, OPT_WRAP, SETTING_ITEM(rgsb_ypbpr_desc) } } },
|
||||
{ "Auto AV3 Y/Gs", OPT_AVCONFIG_SELECTION, { .sel = { &auto_av3_ypbpr, OPT_WRAP, SETTING_ITEM(rgsb_ypbpr_desc) } } },
|
||||
{ "LCD BL timeout", OPT_AVCONFIG_SELECTION, { .sel = { &lcd_bl_timeout, OPT_WRAP, SETTING_ITEM(lcd_bl_timeout_desc) } } },
|
||||
{ LNG("<Fw. update >","<ファームウェアアップデート>"), OPT_FUNC_CALL, { .fun = { fw_update, NULL } } },
|
||||
}))
|
||||
|
@ -38,6 +38,7 @@ extern alt_u8 input_profiles[AV_LAST];
|
||||
extern alt_u8 profile_sel;
|
||||
extern alt_u8 def_input, profile_link;
|
||||
extern alt_u8 lcd_bl_timeout;
|
||||
extern alt_u8 auto_input, auto_av1_ypbpr, auto_av2_ypbpr, auto_av3_ypbpr;
|
||||
extern SD_DEV sdcard_dev;
|
||||
extern char menu_row1[LCD_ROW_LEN+1], menu_row2[LCD_ROW_LEN+1];
|
||||
|
||||
@ -68,6 +69,10 @@ int write_userdata(alt_u8 entry)
|
||||
((ude_initcfg*)databuf)->def_input = def_input;
|
||||
((ude_initcfg*)databuf)->profile_link = profile_link;
|
||||
((ude_initcfg*)databuf)->lcd_bl_timeout = lcd_bl_timeout;
|
||||
((ude_initcfg*)databuf)->auto_input = auto_input;
|
||||
((ude_initcfg*)databuf)->auto_av1_ypbpr = auto_av1_ypbpr;
|
||||
((ude_initcfg*)databuf)->auto_av2_ypbpr = auto_av2_ypbpr;
|
||||
((ude_initcfg*)databuf)->auto_av3_ypbpr = auto_av3_ypbpr;
|
||||
memcpy(((ude_initcfg*)databuf)->keys, rc_keymap, sizeof(rc_keymap));
|
||||
retval = write_flash_page(databuf, sizeof(ude_initcfg), (USERDATA_OFFSET+entry*SECTORSIZE)/PAGESIZE);
|
||||
if (retval != 0)
|
||||
@ -145,6 +150,10 @@ int read_userdata(alt_u8 entry)
|
||||
target_input = def_input;
|
||||
else if (((ude_initcfg*)databuf)->last_input < AV_LAST)
|
||||
target_input = ((ude_initcfg*)databuf)->last_input;
|
||||
auto_input = ((ude_initcfg*)databuf)->auto_input;
|
||||
auto_av1_ypbpr = ((ude_initcfg*)databuf)->auto_av1_ypbpr;
|
||||
auto_av2_ypbpr = ((ude_initcfg*)databuf)->auto_av2_ypbpr;
|
||||
auto_av3_ypbpr = ((ude_initcfg*)databuf)->auto_av3_ypbpr;
|
||||
profile_link = ((ude_initcfg*)databuf)->profile_link;
|
||||
profile_sel = input_profiles[AV_TESTPAT]; // Global profile
|
||||
lcd_bl_timeout = ((ude_initcfg*)databuf)->lcd_bl_timeout;
|
||||
|
@ -53,6 +53,10 @@ typedef struct {
|
||||
avinput_t last_input;
|
||||
avinput_t def_input;
|
||||
alt_u8 lcd_bl_timeout;
|
||||
alt_u8 auto_input;
|
||||
alt_u8 auto_av1_ypbpr;
|
||||
alt_u8 auto_av2_ypbpr;
|
||||
alt_u8 auto_av3_ypbpr;
|
||||
alt_u16 keys[REMOTE_MAX_KEYS];
|
||||
} __attribute__((packed, __may_alias__)) ude_initcfg;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user