diff --git a/software/ossc_sw.project b/software/ossc_sw.project
index 245e670..284e606 100644
--- a/software/ossc_sw.project
+++ b/software/ossc_sw.project
@@ -120,6 +120,7 @@
+ make APP_CFLAGS_DEFINED_SYMBOLS="-DDEBUG -DDIY_AUDIO"
make clean
make APP_CFLAGS_DEFINED_SYMBOLS="-DDEBUG"
@@ -159,6 +160,7 @@
+ make APP_CFLAGS_DEFINED_SYMBOLS="-DDIY_AUDIO"
make mem_init_generate
iconv -f UTF-8 -t SHIFT-JIS ossc/menu.c > ossc/menu_sjis.c; make OSDLANG=JP
diff --git a/software/sys_controller/it6613/HDMI_TX.c b/software/sys_controller/it6613/HDMI_TX.c
index 747662a..f96ced0 100644
--- a/software/sys_controller/it6613/HDMI_TX.c
+++ b/software/sys_controller/it6613/HDMI_TX.c
@@ -312,4 +312,21 @@ bool HDMITX_DevLoopProc()
return HPDChange;
}
-
+void HDMITX_SetAudioInfoFrame(BYTE bAudioDwSampling)
+{
+ Audio_InfoFrame AudioInfo;
+
+ AudioInfo.info.Type = AUDIO_INFOFRAME_TYPE;
+ AudioInfo.info.Ver = AUDIO_INFOFRAME_VER;
+ AudioInfo.info.Len = AUDIO_INFOFRAME_LEN;
+
+ AudioInfo.info.AudioChannelCount = 1; // 2 channels
+ AudioInfo.info.AudioCodingType = 1; // PCM
+ AudioInfo.info.SampleSize = 3; // 24bit
+ AudioInfo.info.SampleFreq = bAudioDwSampling ? 3 : 5; //48kHz or 96kHz
+ AudioInfo.info.SpeakerPlacement = 0; // Front left and front right
+ AudioInfo.info.LevelShiftValue = 0;
+ AudioInfo.info.DM_INH = 0; // Down-mix Inhibit Flag; 0=Permitted or no information about any assertion of this
+
+ EnableAudioInfoFrame(TRUE, (BYTE *) &AudioInfo);
+}
diff --git a/software/sys_controller/it6613/HDMI_TX.h b/software/sys_controller/it6613/HDMI_TX.h
index 65b9ad9..061e7e6 100644
--- a/software/sys_controller/it6613/HDMI_TX.h
+++ b/software/sys_controller/it6613/HDMI_TX.h
@@ -26,4 +26,6 @@ bool HDMITX_IsSinkSupportColorDepth36(void);
bool HDMITX_IsSinkSupportColorDepth30(void);
void HDMITX_SetOutputColorDepth(int ColorDepth);
+void HDMITX_SetAudioInfoFrame(BYTE bAudioDwSampling);
+
#endif /*HDMI_TX_H_*/
diff --git a/software/sys_controller/it6613/it6613_drv.c b/software/sys_controller/it6613/it6613_drv.c
index 482caa8..2e46d94 100644
--- a/software/sys_controller/it6613/it6613_drv.c
+++ b/software/sys_controller/it6613/it6613_drv.c
@@ -523,6 +523,73 @@ BOOL EnableAudioOutput(ULONG VideoPixelClock,BYTE bAudioSampleFreq,BYTE ChannelN
return TRUE ;
}
+BOOL EnableAudioOutput4OSSC(ULONG VideoPixelClock,BYTE bExtMCLK,BYTE bAudioDwSampl,BYTE bAudioSwapLR)
+{
+ // set N and CTS
+ ULONG n = 12288;
+ ULONG cts = VideoPixelClock/1000;
+
+ if (bAudioDwSampl == 0x1)
+ n = n>>1;
+
+ //program N
+ Switch_HDMITX_Bank(1);
+ HDMITX_WriteI2C_Byte(REGPktAudN0,(BYTE)((n)&0xFF));
+ HDMITX_WriteI2C_Byte(REGPktAudN1,(BYTE)((n>>8)&0xFF));
+ HDMITX_WriteI2C_Byte(REGPktAudN2,(BYTE)((n>>16)&0xF));
+ //program CTS
+ HDMITX_WriteI2C_Byte(REGPktAudCTS0, cts & 0xff);
+ HDMITX_WriteI2C_Byte(REGPktAudCTS1,(cts>>8) & 0xff);
+ HDMITX_WriteI2C_Byte(REGPktAudCTS2,(cts>>16) & 0xff);
+ Switch_HDMITX_Bank(0);
+
+#ifdef MANUAL_CTS
+ HDMITX_WriteI2C_Byte(0xF8, 0xC3);
+ HDMITX_WriteI2C_Byte(0xF8, 0xA5);
+ HDMITX_WriteI2C_Byte(REG_TX_PKT_SINGLE_CTRL,B_SW_CTS);
+ HDMITX_WriteI2C_Byte(0xF8, 0xFF);
+#else
+ HDMITX_WriteI2C_Byte(REG_TX_PKT_SINGLE_CTRL,0); // D[1] = 0,HW auto count CTS
+#endif
+
+ // define internal/external MCLK and audio down-sampling
+ HDMITX_SetREG_Byte(REG_TX_CLK_CTRL0,~(M_EXT_MCLK_SEL|B_EXT_MCLK_SAMP|B_EXT_MCLK4CTS),((bExtMCLK&0x1)<> 4;
+ cts |= read_it2(0x36) << 4;
+ cts |= read_it2(0x37) << 12;
+ printf("CTS: %lu\n", cts);
+#endif
+ }
+}
+#endif
+
inline void TX_enable(tx_mode_t mode)
{
// shut down TX before setting new config
@@ -93,8 +125,12 @@ inline void TX_enable(tx_mode_t mode)
// re-setup
EnableVideoOutput(PCLK_MEDIUM, COLOR_RGB444, COLOR_RGB444, !mode);
//TODO: set correct VID based on mode
- if (mode == TX_HDMI)
+ if (mode == TX_HDMI) {
HDMITX_SetAVIInfoFrame(HDMI_480p60, F_MODE_RGB444, 0, 0);
+#ifdef DIY_AUDIO
+ SetupAudio(mode);
+#endif
+ }
// start TX
SetAVMute(FALSE);
@@ -289,6 +325,18 @@ status_t get_status(tvp_input_t input, video_format format)
if (!memcmp(&tc.col, &cm.cc.col, sizeof(color_setup_t)))
tvp_set_fine_gain_offset(&cm.cc.col);
+#ifdef DIY_AUDIO
+ if ((tc.audio_dw_sampl != cm.cc.audio_dw_sampl) ||
+ (tc.audio_swap_lr != cm.cc.audio_swap_lr) ||
+#ifdef MANUAL_CTS
+ (tc.edtv_l2x != cm.cc.edtv_l2x) ||
+ (tc.interlace_pt != cm.cc.interlace_pt) ||
+ update_cur_vm ||
+#endif
+ (tc.audio_ext_mclk != cm.cc.audio_ext_mclk))
+ SetupAudio(tc.tx_mode);
+#endif
+
cm.cc = tc;
update_cur_vm = 0;
@@ -391,6 +439,12 @@ void program_mode()
tvp_source_setup(cm.id, target_type, (cm.progressive ? cm.totlines : cm.totlines/2), v_hz_x100/100, (alt_u8)h_synclen_px, cm.cc.pre_coast, cm.cc.post_coast, cm.cc.vsync_thold);
set_lpf(cm.cc.video_lpf);
set_videoinfo();
+
+#ifdef DIY_AUDIO
+#ifdef MANUAL_CTS
+ SetupAudio(cm.cc.tx_mode);
+#endif
+#endif
}
void vm_display(alt_u8 code) {
@@ -538,7 +592,7 @@ int main()
if (init_stat >= 0) {
printf("### DIY VIDEO DIGITIZER / SCANCONVERTER INIT OK ###\n\n");
- sniprintf(row1, LCD_ROW_LEN+1, "OSSC fw. %u.%.2u", FW_VER_MAJOR, FW_VER_MINOR);
+ sniprintf(row1, LCD_ROW_LEN+1, "OSSC fw. %u.%.2u" FW_SUFFIX1 FW_SUFFIX2, FW_VER_MAJOR, FW_VER_MINOR);
#ifndef DEBUG
strncpy(row2, "2014-2016 marqs", LCD_ROW_LEN+1);
#else
@@ -639,6 +693,9 @@ int main()
cm.sync_active = 0;
ths_source_sel(target_ths, (cm.cc.video_lpf > 1) ? (VIDEO_LPF_MAX-cm.cc.video_lpf) : THS_LPF_BYPASS);
tvp_disable_output();
+#ifdef DIY_AUDIO
+ DisableAudioOutput();
+#endif
tvp_source_sel(target_input, target_format);
cm.clkcnt = 0; //TODO: proper invalidate
strncpy(row1, avinput_str[cm.avinput], LCD_ROW_LEN+1);
diff --git a/software/sys_controller/ossc/avconfig.c b/software/sys_controller/ossc/avconfig.c
index cfa7812..5634cd7 100644
--- a/software/sys_controller/ossc/avconfig.c
+++ b/software/sys_controller/ossc/avconfig.c
@@ -24,6 +24,7 @@
#include "altera_avalon_pio_regs.h"
#include "tvp7002.h"
+#define DEFAULT_ON 1
#define DEFAULT_PRE_COAST 1
#define DEFAULT_POST_COAST 0
#define DEFAULT_SAMPLER_PHASE 16
@@ -46,6 +47,9 @@ const avconfig_t tc_default = {
.vsync_thold = DEFAULT_VSYNC_THOLD,
.pre_coast = DEFAULT_PRE_COAST,
.post_coast = DEFAULT_POST_COAST,
+#ifdef DIY_AUDIO
+ .audio_dw_sampl = DEFAULT_ON,
+#endif
.col = {
.r_f_gain = DEFAULT_FINE_GAIN,
.g_f_gain = DEFAULT_FINE_GAIN,
diff --git a/software/sys_controller/ossc/avconfig.h b/software/sys_controller/ossc/avconfig.h
index 49d0b57..6894cfd 100644
--- a/software/sys_controller/ossc/avconfig.h
+++ b/software/sys_controller/ossc/avconfig.h
@@ -57,6 +57,11 @@ typedef struct {
alt_u8 video_lpf;
alt_u8 pre_coast;
alt_u8 post_coast;
+#ifdef DIY_AUDIO
+ alt_u8 audio_dw_sampl;
+ alt_u8 audio_swap_lr;
+ alt_u8 audio_ext_mclk;
+#endif
alt_u8 edtv_l2x;
alt_u8 interlace_pt;
alt_u8 def_input;
diff --git a/software/sys_controller/ossc/firmware.h b/software/sys_controller/ossc/firmware.h
index 4dd3332..89bc706 100644
--- a/software/sys_controller/ossc/firmware.h
+++ b/software/sys_controller/ossc/firmware.h
@@ -26,6 +26,18 @@
#define FW_VER_MAJOR 0
#define FW_VER_MINOR 74
+#ifdef DIY_AUDIO
+#define FW_SUFFIX1 "a"
+#else
+#define FW_SUFFIX1 ""
+#endif
+
+#ifdef OSDLANG_JP
+#define FW_SUFFIX2 "j"
+#else
+#define FW_SUFFIX2 ""
+#endif
+
#define FW_UPDATE_RETRIES 3
typedef struct {
diff --git a/software/sys_controller/ossc/menu.c b/software/sys_controller/ossc/menu.c
index 068863d..d7aaa10 100644
--- a/software/sys_controller/ossc/menu.c
+++ b/software/sys_controller/ossc/menu.c
@@ -53,6 +53,7 @@ static const char *tx_mode_desc[] = { "HDMI", "DVI" };
static const char *sl_mode_desc[] = { LNG("Off","オフ"), LNG("Auto","ジドウ"), LNG("Manual","シュドウ") };
static const char *sl_type_desc[] = { LNG("Horizontal","スイヘイ"), LNG("Vertical","スイチョク"), LNG("Alternating","コウゴ") };
static const char *sl_id_desc[] = { LNG("Top","ウエ"), LNG("Bottom","シタ") };
+static const char *audio_dw_sampl_desc[] = { "Off (fs = 96kHz)", "2x (fs = 48kHz)" };
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); }
@@ -117,6 +118,17 @@ MENU(menu_postproc, P99_PROTECT({ \
{ LNG("Vertical mask","スイチョクマスク"), OPT_AVCONFIG_NUMVALUE, { .num = { &tc.v_mask, OPT_NOWRAP, 0, HV_MASK_MAX, pixels_disp } } },
}))
+#ifdef DIY_AUDIO
+MENU(menu_audio, P99_PROTECT({ \
+ { "Down-sampling", OPT_AVCONFIG_SELECTION, { .sel = { &tc.audio_dw_sampl, OPT_WRAP, SETTING_ITEM(audio_dw_sampl_desc) } } },
+ { "Swap left/right", OPT_AVCONFIG_SELECTION, { .sel = { &tc.audio_swap_lr, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
+ { "Use ext. MCLK", OPT_AVCONFIG_SELECTION, { .sel = { &tc.audio_ext_mclk, OPT_WRAP, SETTING_ITEM(off_on_desc) } } },
+}))
+#define AUDIO_MENU { "Audio options >", OPT_SUBMENU, { .sub = { &menu_audio, NULL } } },
+#else
+#define AUDIO_MENU
+#endif
+
MENU(menu_main, P99_PROTECT({ \
{ LNG("Video in proc >","タイオウエイゾウ >"), OPT_SUBMENU, { .sub = { &menu_vinputproc, NULL } } },
@@ -124,6 +136,7 @@ MENU(menu_main, P99_PROTECT({ \
{ LNG("Sync opt. >","ドウキオプション >"), OPT_SUBMENU, { .sub = { &menu_sync, NULL } } },
{ LNG("Output opt. >","シュツリョクオプション >"), OPT_SUBMENU, { .sub = { &menu_output, NULL } } },
{ LNG("Post-proc. >","アトショリ >"), OPT_SUBMENU, { .sub = { &menu_postproc, NULL } } },
+ AUDIO_MENU
{ LNG("","<ファームウェアアップ >"), OPT_FUNC_CALL, { .fun = { fw_update, LNG("OK - pls restart","OK - サイキドウシテクダサイ"), LNG("failed","シッパイ") } } },
{ LNG("","<セッテイオショキカ >"), OPT_FUNC_CALL, { .fun = { set_default_avconfig, LNG("Reset done","ショキカスミ"), "" } } },
{ LNG("","<セッテイオホゾン >"), OPT_FUNC_CALL, { .fun = { write_userdata, LNG("Saved","ホゾンスミ"), LNG("failed","シッパイ") } } },
diff --git a/software/sys_controller/tvp7002/tvp7002.c b/software/sys_controller/tvp7002/tvp7002.c
index 38143e3..ad57bc7 100644
--- a/software/sys_controller/tvp7002/tvp7002.c
+++ b/software/sys_controller/tvp7002/tvp7002.c
@@ -224,7 +224,7 @@ void tvp_setup_hpll(alt_u16 h_samplerate, alt_u16 v_lines, alt_u8 hz, alt_u8 pll
pclk_est = ((alt_u32)h_samplerate * v_lines * hz) / 1000; //in kHz
- printf("Estimated PCLK_out: %lu.%.3lu MHz\n", pclk_est/1000, pclk_est%1000);
+ printf("Estimated PCLK_HPLL: %lu.%.3lu MHz\n", pclk_est/1000, pclk_est%1000);
if (pclk_est < 36000) {
vco_range = 0;