Merge borti4938's diy-audio code and fix audio format.

This commit is contained in:
marqs 2016-11-06 15:24:26 +02:00
parent d548d53272
commit fac88b348e
12 changed files with 1225 additions and 1039 deletions

View File

@ -120,6 +120,7 @@
<PreBuild/>
<PostBuild/>
<CustomBuild Enabled="yes">
<Target Name="diy-audio-debug">make APP_CFLAGS_DEFINED_SYMBOLS="-DDEBUG -DDIY_AUDIO"</Target>
<RebuildCommand/>
<CleanCommand>make clean</CleanCommand>
<BuildCommand>make APP_CFLAGS_DEFINED_SYMBOLS="-DDEBUG"</BuildCommand>
@ -159,6 +160,7 @@
<PreBuild/>
<PostBuild/>
<CustomBuild Enabled="yes">
<Target Name="diy-audio">make APP_CFLAGS_DEFINED_SYMBOLS="-DDIY_AUDIO"</Target>
<Target Name="compile_image">make mem_init_generate</Target>
<Target Name="Build_jp">iconv -f UTF-8 -t SHIFT-JIS ossc/menu.c &gt; ossc/menu_sjis.c; make OSDLANG=JP</Target>
<RebuildCommand/>

View File

@ -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);
}

View File

@ -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_*/

View File

@ -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)<<O_MCLK_SAMP) | B_EXT_256FS | ((bExtMCLK&0x1)<<O_MCLK4CTS));
//HDMITX_AndREG_Byte(REG_TX_SW_RST,~M_AUD_DIV);
if (bAudioDwSampl == 0x1)
HDMITX_OrREG_Byte(REG_TX_CLK_CTRL1,B_AUD_DIV2);
// set audio format
Instance[0].TMDSClock = VideoPixelClock;
BYTE fs = bAudioDwSampl == 0x1 ? AUDFS_48KHz : AUDFS_96KHz;
Instance[0].bAudFs = fs;
Instance[0].bOutputAudioMode = B_AUDFMT_32BIT_I2S;
Instance[0].bAudioChannelSwap = bAudioSwapLR == 0x1 ? 0xf : 0x0; // swap channels
BYTE AudioEnable = (0x1 & ~(M_AUD_SWL|B_SPDIFTC)) | M_AUD_24BIT;
HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0,AudioEnable & 0xF0);
HDMITX_AndREG_Byte(REG_TX_SW_RST,~(B_AUD_RST|B_AREF_RST));
HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL1,Instance[0].bOutputAudioMode);
HDMITX_WriteI2C_Byte(REG_TX_AUDIO_FIFOMAP,0xE4); // default mapping.
HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL3,(Instance[0].bAudioChannelSwap&0xF)|(AudioEnable&B_AUD_SPDIF));
HDMITX_WriteI2C_Byte(REG_TX_AUD_SRCVALID_FLAT,B_AUD_SPXFLAT_SRC3|B_AUD_SPXFLAT_SRC2|B_AUD_SPXFLAT_SRC1|B_AUD_ERR2FLAT); // only two channels
Switch_HDMITX_Bank(1) ;
HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_MODE,0); // 2 audio channel without pre-emphasis
HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CAT,0);
HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_SRCNUM,1);
HDMITX_WriteI2C_Byte(REG_TX_AUD0CHST_CHTNUM,0);
HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_CA_FS,0xC0|fs); // choose clock
fs = ~fs; // OFS is the one's complement of FS
HDMITX_WriteI2C_Byte(REG_TX_AUDCHST_OFS_WL,(fs<<4)|AUD_SWL_24); // 24 bit Audio
Switch_HDMITX_Bank(0);
HDMITX_WriteI2C_Byte(REG_TX_AUDIO_CTRL0,AudioEnable);
Instance[0].bAudioChannelEnable = AudioEnable;
return TRUE;
}
BOOL
GetEDIDData(int EDIDBlockID,BYTE *pEDIDData)

View File

@ -233,6 +233,9 @@
#define REG_TX_AUTH_STAT 0x46
#define B_T_AUTH_DONE (1<<7)
#define REG_TX_CLK_CTRL0 0x58
#define O_MCLK_SAMP 7
#define B_EXT_MCLK_SAMP (1<<O_MCLK_SAMP)
#define B_INT_MCLK_SAMP (0<<O_MCLK_SAMP)
#define O_OSCLK_SEL 5
#define M_OSCLK_SEL 3
#define B_AUTO_OVER_SAMPLING_CLOCK (1<<4)
@ -242,6 +245,9 @@
#define B_EXT_256FS (1<<O_EXT_MCLK_SEL)
#define B_EXT_512FS (2<<O_EXT_MCLK_SEL)
#define B_EXT_1024FS (3<<O_EXT_MCLK_SEL)
#define O_MCLK4CTS 1
#define B_EXT_MCLK4CTS (1<<O_MCLK4CTS)
#define B_INT_MCLK4CTS (0<<O_MCLK4CTS)
#define REG_TX_SHA_SEL 0x50
#define REG_TX_SHA_RD_BYTE1 0x51
@ -815,6 +821,7 @@ BOOL ProgramDEGenModeByID(MODE_ID id,BYTE bInputSignalType) ;
BOOL ProgramSyncEmbeddedVideoMode(BYTE VIC,BYTE bInputType) ;
#endif
BOOL EnableAudioOutput(unsigned long VideoPixelClock,BYTE bAudioSampleFreq,BYTE ChannelNumber,BYTE bAudSWL,BYTE bSPDIF) ;
BOOL EnableAudioOutput4OSSC(ULONG VideoPixelClock,BYTE bExtMCLK,BYTE bAudioDwSampl,BYTE bAudioSwapLR) ;
void DisableIT6613() ;
void DisableVideoOutput() ;
void DisableAudioOutput() ;

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,7 @@
#include "sdcard.h"
#include "menu.h"
#include "avconfig.h"
#include "sysconfig.h"
#include "firmware.h"
#include "userdata.h"
#include "it6613.h"
@ -83,6 +84,37 @@ inline void lcd_write_status() {
lcd_write((char*)&row1, (char*)&row2);
}
#ifdef DIY_AUDIO
inline void SetupAudio(tx_mode_t mode)
{
// shut down audio-tx before setting new config (recommended for changing audio-tx config)
DisableAudioOutput();
EnableAudioInfoFrame(FALSE, NULL);
if (tc.tx_mode == TX_HDMI) {
alt_u32 pclk_out = (TVP_EXTCLK_HZ/cm.clkcnt)*video_modes[cm.id].h_total;
// TODO: check pixel repetition
if (video_modes[cm.id].flags & MODE_L2ENABLE)
pclk_out *= 2;
else if (video_modes[cm.id].flags & (MODE_L3_MODE0|MODE_L3_MODE1|MODE_L3_MODE2|MODE_L3_MODE3))
pclk_out *= 3;
printf("PCLK_out: %luHz\n", pclk_out);
EnableAudioOutput4OSSC(pclk_out,tc.audio_ext_mclk,tc.audio_dw_sampl,tc.audio_swap_lr);
HDMITX_SetAudioInfoFrame((BYTE)tc.audio_dw_sampl);
#ifdef DEBUG
Switch_HDMITX_Bank(1);
usleep(1000);
alt_u32 cts = 0;
cts |= read_it2(0x35) >> 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);

View File

@ -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,

View File

@ -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;

View File

@ -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 {

View File

@ -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("<Fw. update >","<ファームウェアアップ >"), OPT_FUNC_CALL, { .fun = { fw_update, LNG("OK - pls restart","OK - サイキドウシテクダサイ"), LNG("failed","シッパイ") } } },
{ LNG("<Reset settings>","<セッテイオショキカ >"), OPT_FUNC_CALL, { .fun = { set_default_avconfig, LNG("Reset done","ショキカスミ"), "" } } },
{ LNG("<Save settings >","<セッテイオホゾン >"), OPT_FUNC_CALL, { .fun = { write_userdata, LNG("Saved","ホゾンスミ"), LNG("failed","シッパイ") } } },

View File

@ -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;