1
0
mirror of https://github.com/marqs85/ossc.git synced 2026-04-20 13:16:50 +00:00

Initial public release (FW 0.64)

This commit is contained in:
marqs
2016-02-23 01:03:50 +02:00
commit 388c464f63
264 changed files with 66416 additions and 0 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+196
View File
@@ -0,0 +1,196 @@
#include "hdmitx.h"
#include "edid.h"
#ifdef SUPPORT_EDID
static SYS_STATUS EDIDCheckSum(BYTE *pEDID) ;
static SYS_STATUS
EDIDCheckSum(BYTE *pEDID)
{
BYTE CheckSum ;
int i ;
if( !pEDID )
{
return ER_FAIL ;
}
for( i = 0, CheckSum = 0 ; i < 128 ; i++ )
{
CheckSum += pEDID[i] ; CheckSum &= 0xFF ;
}
return (CheckSum == 0)?ER_SUCCESS:ER_FAIL ;
}
SYS_STATUS
ParseVESAEDID(BYTE *pEDID)
{
if( ER_SUCCESS != EDIDCheckSum(pEDID) ) return ER_FAIL ;
if( pEDID[0] != 0 ||
pEDID[7] != 0 ||
pEDID[1] != 0xFF ||
pEDID[2] != 0xFF ||
pEDID[3] != 0xFF ||
pEDID[4] != 0xFF ||
pEDID[5] != 0xFF ||
pEDID[6] != 0xFF )
{
return ER_FAIL ; // not a EDID 1.3 standard block.
}
/////////////////////////////////////////////////////////
// if need to parse EDID property , put here.
/////////////////////////////////////////////////////////
return ER_SUCCESS ;
}
SYS_STATUS
ParseCEAEDID(BYTE *pCEAEDID, RX_CAP *pRxCap)
{
BYTE offset,End ;
BYTE count ;
BYTE tag ;
int i ;
if( !pCEAEDID || !pRxCap ) return ER_FAIL ;
pRxCap->ValidCEA = FALSE ;
if( ER_SUCCESS != EDIDCheckSum(pCEAEDID) ) return ER_FAIL ;
if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) return ER_SUCCESS ; // not a CEA BLOCK.
End = pCEAEDID[2] ; // CEA description.
pRxCap->VideoMode = pCEAEDID[3] ;
if (pRxCap->VideoMode & CEA_SUPPORT_YUV444)
OS_PRINTF("Support Color: YUV444\n");
if (pRxCap->VideoMode & CEA_SUPPORT_YUV422)
OS_PRINTF("Support Color: YUV422\n");
for( offset = 0 ; offset < 0x80 ; offset ++ )
{
if( (offset % 0x10) == 0 )
{
ErrorF("[%02X]", offset ) ;
}
else if((offset%0x10)==0x08)
{
ErrorF( " -" ) ;
}
ErrorF(" %02X",pCEAEDID[offset]) ;
if((offset%0x10)==0x0f)
{
ErrorF("\n") ;
}
}
pRxCap->VDOModeCount = 0 ;
pRxCap->idxNativeVDOMode = 0xff ;
for( offset = 4 ; offset < End ; )
{
tag = pCEAEDID[offset] >> 5 ;
count = pCEAEDID[offset] & 0x1f ;
switch( tag )
{
case 0x01: // Audio Data Block ;
pRxCap->AUDDesCount = count/3 ;
offset++ ;
for( i = 0 ; i < pRxCap->AUDDesCount ; i++ )
{
pRxCap->AUDDes[i].uc[0] = pCEAEDID[offset++] ;
pRxCap->AUDDes[i].uc[1] = pCEAEDID[offset++] ;
pRxCap->AUDDes[i].uc[2] = pCEAEDID[offset++] ;
}
break ;
case 0x02: // Video Data Block ;
//pRxCap->VDOModeCount = 0 ;
offset ++ ;
for( i = 0,pRxCap->idxNativeVDOMode = 0xff ; i < count ; i++, offset++ )
{
BYTE VIC ;
VIC = pCEAEDID[offset] & (~0x80) ;
OS_PRINTF("HDMI Sink VIC(Video Identify Code)=%d\n", VIC);
// if( FindModeTableEntryByVIC(VIC) != -1 )
{
pRxCap->VDOMode[pRxCap->VDOModeCount] = VIC ;
if( pCEAEDID[offset] & 0x80 )
{
pRxCap->idxNativeVDOMode = (BYTE)pRxCap->VDOModeCount ;
// iVideoModeSelect = pRxCap->VDOModeCount ;
}
pRxCap->VDOModeCount++ ;
}
}
break ;
case 0x03: // Vendor Specific Data Block ;
offset ++ ;
pRxCap->IEEEOUI = (ULONG)pCEAEDID[offset+2] ;
pRxCap->IEEEOUI <<= 8 ;
pRxCap->IEEEOUI += (ULONG)pCEAEDID[offset+1] ;
pRxCap->IEEEOUI <<= 8 ;
pRxCap->IEEEOUI += (ULONG)pCEAEDID[offset] ;
///////////////////////////////////////////////////////////
// For HDMI 1.3 extension handling.
///////////////////////////////////////////////////////////
pRxCap->dc.uc = 0 ;
pRxCap->MaxTMDSClock = 0 ;
pRxCap->lsupport.uc = 0 ;
pRxCap->ValidHDMI = (pRxCap->IEEEOUI==HDMI_IEEEOUI)? TRUE:FALSE ;
if( (pRxCap->ValidHDMI) && (count > 5 ))
{
// HDMI 1.3 extension
pRxCap->dc.uc = pCEAEDID[offset+5] ;
pRxCap->MaxTMDSClock = pCEAEDID[offset+6] ;
pRxCap->lsupport.uc = pCEAEDID[offset+7] ;
if(pRxCap->lsupport.info.Latency_Present)
{
pRxCap->V_Latency = pCEAEDID[offset+9] ;
pRxCap->A_Latency = pCEAEDID[offset+10] ;
}
if(pRxCap->lsupport.info.I_Latency_Present)
{
pRxCap->V_I_Latency = pCEAEDID[offset+11] ;
pRxCap->A_I_Latency = pCEAEDID[offset+12] ;
}
}
offset += count ; // ignore the remaind.
break ;
case 0x04: // Speaker Data Block ;
offset ++ ;
pRxCap->SpeakerAllocBlk.uc[0] = pCEAEDID[offset] ;
pRxCap->SpeakerAllocBlk.uc[1] = pCEAEDID[offset+1] ;
pRxCap->SpeakerAllocBlk.uc[2] = pCEAEDID[offset+2] ;
offset += 3 ;
break ;
case 0x05: // VESA Data Block ;
offset += count+1 ;
break ;
case 0x07: // Extended Data Block ;
offset += count+1 ; //ignore
break ;
default:
offset += count+1 ; // ignore
}
}
pRxCap->ValidCEA = TRUE ;
return ER_SUCCESS ;
}
#endif // SUPPORT_EDID
@@ -0,0 +1,11 @@
#ifndef HDMI_COMMON_H_
#define HDMI_COMMON_H_
typedef enum{
COLOR_RGB444 = 0,
COLOR_YUV422,
COLOR_YUV444,
COLOR_MODE_NUM
}COLOR_TYPE;
#endif /*HDMI_COMMON_H_*/
+314
View File
@@ -0,0 +1,314 @@
//#include "terasic_includes.h"
//#include "mcu.h"
#include "it6613_sys.h"
#include "hdmitx.h"
#include "HDMI_TX.h"
#include "edid.h"
int TX_HDP = FALSE;
extern BYTE bOutputColorMode;
extern BYTE bInputColorMode;
extern BOOL bChangeMode;
extern RX_CAP RxCapability;
extern BOOL bHDMIMode;
extern BOOL bAudioEnable;
BOOL ParseEDID();
INSTANCE InitInstanceData =
{
0,0, //I2C_DEV, I2C_ADDR
0, //bIntType (TxCLK active, Push-Pull Mode, INT active low)
0,/* | T_MODE_CCIR656 | T_MODE_SYNCEMB | T_MODE_INDDR */ // bInputVideoSignalType
B_AUDFMT_STD_I2S, // bOutputAudioMode, 0x00, standard i2s, rising edge to sample ws/i2s, not full packet mode REG[0xE1]
0,// bAudioChannelSwap
B_AUD_EN_I2S0 | B_AUD_I2S | M_AUD_16BIT, // bAudioChannelEnable, 0x01, REG[0xE0], defined in it6613_drv.h
AUDFS_48KHz, //0, //bAudFs,
0, // TMDSClock
TRUE,//bAuthenticated
TRUE,// bHDMIMode
FALSE,// bIntPOL
FALSE // bHPD
} ;
bool HDMITX_ChipVerify(void){
bool bPass = FALSE;
alt_u8 szID[4];
int i;
for(i=0;i<4;i++)
szID[i] = HDMITX_ReadI2C_Byte(i);
// if (szID[0] == 0x00 && szID[1] == 0xCA && szID[1] == 0x13 && szID[1] == 0x06) szID[0] ???
if ((szID[1] == 0xCA && szID[2] == 0x13 && szID[3] == 0x06) || (szID[1] == 0xCA && szID[2] == 0x13 && szID[3] == 0x16)){
bPass = TRUE;
printf("TX Chip Revision ID: %d\n", szID[0]);
}else{
printf("NG, Read TX Chip ID:%02X%02X%02X%02Xh (expected:00CA1306h)\n", szID[0], szID[1], szID[2], szID[3]);
}
return bPass;
}
bool HDMITX_Init(void){
bool bSuccess = TRUE;
HDMITX_Reset();
usleep(500*1000);
if (!HDMITX_ChipVerify()){
OS_PRINTF("Failed to find IT6613 HDMI-TX Chip.\n");
bSuccess = FALSE;
//return 0;
}
HDMITX_InitInstance(&InitInstanceData) ;
InitIT6613() ;
return bSuccess;
}
bool HDMITX_HPD(void){
if (TX_HDP)
return TRUE;
return FALSE;
}
void HDMITX_SetAVIInfoFrame(alt_u8 VIC, alt_u8 OutputColorMode, bool b16x9, bool ITU709)
{
AVI_InfoFrame AviInfo;
alt_u8 pixelrep = 0;
OS_PRINTF("HDMITX_SetAVIInfoFrame, VIC=%d, ColorMode=%d, Aspect-Ratio=%s, ITU709=%s\n",
VIC, OutputColorMode, b16x9?"16:9":"4:3", ITU709?"Yes":"No");
AviInfo.pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ;
AviInfo.pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ;
AviInfo.pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ;
switch(OutputColorMode)
{
case F_MODE_YUV444:
// AviInfo.info.ColorMode = 2 ;
AviInfo.pktbyte.AVI_DB[0] = (2<<5)|(1<<4) ;
break ;
case F_MODE_YUV422:
// AviInfo.info.ColorMode = 1 ;
AviInfo.pktbyte.AVI_DB[0] = (1<<5)|(1<<4) ;
break ;
case F_MODE_RGB444:
default:
// AviInfo.info.ColorMode = 0 ;
AviInfo.pktbyte.AVI_DB[0] = (0<<5)|(1<<4) ;
break ;
}
AviInfo.pktbyte.AVI_DB[0] |= 2; // indicate "no overscan"
AviInfo.pktbyte.AVI_DB[1] = 8 ;
AviInfo.pktbyte.AVI_DB[1] |= (!b16x9)?(1<<4):(2<<4) ; // 4:3 or 16:9
AviInfo.pktbyte.AVI_DB[1] |= (!ITU709)?(1<<6):(2<<6) ; // ITU709 or ITU601
AviInfo.pktbyte.AVI_DB[2] = (1<<3) ; // indicate "full-range RGB"
AviInfo.pktbyte.AVI_DB[3] = VIC ;
AviInfo.pktbyte.AVI_DB[4] = pixelrep & 3 ;
AviInfo.pktbyte.AVI_DB[5] = 0 ;
AviInfo.pktbyte.AVI_DB[6] = 0 ;
AviInfo.pktbyte.AVI_DB[7] = 0 ;
AviInfo.pktbyte.AVI_DB[8] = 0 ;
AviInfo.pktbyte.AVI_DB[9] = 0 ;
AviInfo.pktbyte.AVI_DB[10] = 0 ;
AviInfo.pktbyte.AVI_DB[11] = 0 ;
AviInfo.pktbyte.AVI_DB[12] = 0 ;
EnableAVIInfoFrame(TRUE, (unsigned char *)&AviInfo) ;
}
void HDMITX_ChangeVideoTiming(int VIC){
int OutputVideoTiming = VIC;
int HdmiColorMode;
switch(bOutputColorMode)
{
case F_MODE_YUV444:
HdmiColorMode = HDMI_YUV444;
break ;
case F_MODE_YUV422:
HdmiColorMode = HDMI_YUV422;
break ;
case F_MODE_RGB444:
default:
HdmiColorMode = HDMI_RGB444;
break ;
}
HDMITX_ChangeDisplayOption(OutputVideoTiming, HdmiColorMode); // just modify variable. Take effect when HDMITX_SetOutput is called in HDMITX_DevLoopProc
}
void HDMITX_ChangeVideoTimingAndColor(int VIC, COLOR_TYPE Color){
int OutputVideoTiming = VIC;
int HdmiColorMode;
switch(Color)
{
case COLOR_YUV444:
HdmiColorMode = HDMI_YUV444;
break ;
case COLOR_YUV422:
HdmiColorMode = HDMI_YUV422;
break ;
case COLOR_RGB444:
default:
HdmiColorMode = HDMI_RGB444;
break ;
}
HDMITX_ChangeDisplayOption(OutputVideoTiming, HdmiColorMode);
}
void HDMITX_DisableVideoOutput(void){
DisableVideoOutput();
}
void HDMITX_EnableVideoOutput(void){
HDMITX_SetOutput();
}
void HDMITX_SetColorSpace(COLOR_TYPE InputColor, COLOR_TYPE OutputColor){
// DisableVideoOutput();
bInputColorMode = InputColor;
bOutputColorMode = OutputColor;
// HDMITX_SetOutput();
}
bool HDMITX_IsSinkSupportYUV444(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
(RxCapability.VideoMode & CEA_SUPPORT_YUV444))
bSupport = TRUE;
return bSupport;
}
bool HDMITX_IsSinkSupportYUV422(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
(RxCapability.VideoMode & CEA_SUPPORT_YUV422))
bSupport = TRUE;
return bSupport;
}
bool HDMITX_IsSinkSupportColorDepth36(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
RxCapability.dc.info.DC_36Bit)
bSupport = TRUE;
return bSupport;
}
bool HDMITX_IsSinkSupportColorDepth30(void){
bool bSupport = FALSE;
if (RxCapability.Valid && RxCapability.ValidHDMI && RxCapability.ValidCEA &&
RxCapability.dc.info.DC_30Bit)
bSupport = TRUE;
return bSupport;
}
void HDMITX_SetOutputColorDepth(int ColorDepth){
SetOutputColorDepthPhase(ColorDepth, 0);
}
bool HDMITX_DevLoopProc()
{
static BYTE PreHPDChange = 0;
static BYTE PreHPD = 0;
BYTE HPD, HPDChange ;
// Richard CheckHDMI(&HPD,&HPDChange) ;
CheckHDMITX(&HPD,&HPDChange) ;
if (HPD == PreHPD && HPDChange) // richard add
return FALSE;
TX_HDP = HPD;
PreHPD = HPD;
PreHPDChange = HPDChange;
if( HPDChange )
{
OS_PRINTF("HPDChange\n");
if( HPD )
{
OS_PRINTF("HPD=ON\n");
RxCapability.Valid = ParseEDID() ;
//bOutputColorMode = F_MODE_YUV444; //F_MODE_RGB444; // richard node. users can change color space here according to HDMI sink
if( RxCapability.Valid && RxCapability.ValidHDMI )
{
OS_PRINTF("HDMI Display found\n");
bHDMIMode = TRUE ;
if(RxCapability.VideoMode & (1<<6))
{
bAudioEnable = TRUE ;
}
#if 0 // richard, don't care edid, the output always RGB444
if( RxCapability.VideoMode & (1<<5))
{
bOutputColorMode &= ~F_MODE_CLRMOD_MASK ;
bOutputColorMode |= F_MODE_YUV444;
}
else if (RxCapability.VideoMode & (1<<4))
{
bOutputColorMode &= ~F_MODE_CLRMOD_MASK ;
bOutputColorMode |= F_MODE_YUV422 ;
}
#endif
}
else if (!RxCapability.Valid)
{
OS_PRINTF("Failed to read EDID\n");
// enable it when edid fail
bHDMIMode = TRUE ;
bAudioEnable = TRUE ;
}
else
{
OS_PRINTF("Invalid HDMI Display\n");
bHDMIMode = FALSE ;
bAudioEnable = FALSE ;
}
OS_PRINTF("HDMITX_SetOutput\n");
//HDMITX_SetOutput() ;
}
else
{
OS_PRINTF("HPD=OFF\n");
// unplug mode, ...
OS_PRINTF("DisableVideoOutput\n");
//DisableVideoOutput() ;
RxCapability.Valid = FALSE; // richard add
RxCapability.ValidHDMI = FALSE; // richard add
RxCapability.ValidCEA = FALSE; // richard add
}
}
else // no stable but need to process mode change procedure
{
if(bChangeMode && HPD)
{
OS_PRINTF("HDMITX_SetOutput\n");
HDMITX_SetOutput() ;
}
}
return HPDChange;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef HDMI_TX_H_
#define HDMI_TX_H_
#include "HDMI_COMMON.h"
#include "alt_types.h"
#include "hdmitx.h"
bool HDMITX_Init(void);
bool HDMITX_ChipVerify(void);
bool HDMITX_HPD(void);
void HDMITX_ChangeVideoTiming(int VIC);
void HDMITX_ChangeVideoTimingAndColor(int VIC, COLOR_TYPE Color);
void HDMITX_SetAVIInfoFrame(alt_u8 VIC, alt_u8 OutputColorMode, bool b16x9, bool ITU709);
void HDMITX_DisableVideoOutput(void);
void HDMITX_EnableVideoOutput(void);
void HDMITX_SetColorSpace(COLOR_TYPE InputColor, COLOR_TYPE OutputColor);
bool HDMITX_DevLoopProc(void);
bool HDMITX_IsSinkSupportYUV444(void);
bool HDMITX_IsSinkSupportYUV422(void);
bool HDMITX_IsSinkSupportColorDepth36(void);
bool HDMITX_IsSinkSupportColorDepth30(void);
void HDMITX_SetOutputColorDepth(int ColorDepth);
#endif /*HDMI_TX_H_*/
+129
View File
@@ -0,0 +1,129 @@
#ifndef _EDID_H_
#define _EDID_H_
#include "hdmitx.h"
#ifdef SUPPORT_EDID
/////////////////////////////////////////
// RX Capability.
/////////////////////////////////////////
typedef struct {
BYTE b16bit:1 ;
BYTE b20bit:1 ;
BYTE b24bit:1 ;
BYTE Rsrv:5 ;
} LPCM_BitWidth ;
typedef enum {
AUD_RESERVED_0 = 0 ,
AUD_LPCM,
AUD_AC3,
AUD_MPEG1,
AUD_MP3,
AUD_MPEG2,
AUD_AAC,
AUD_DTS,
AUD_ATRAC,
AUD_ONE_BIT_AUDIO,
AUD_DOLBY_DIGITAL_PLUS,
AUD_DTS_HD,
AUD_MAT_MLP,
AUD_DST,
AUD_WMA_PRO,
AUD_RESERVED_15
} AUDIO_FORMAT_CODE ;
typedef union {
struct {
BYTE channel:3 ;
BYTE AudioFormatCode:4 ;
BYTE Rsrv1:1 ;
BYTE b32KHz:1 ;
BYTE b44_1KHz:1 ;
BYTE b48KHz:1 ;
BYTE b88_2KHz:1 ;
BYTE b96KHz:1 ;
BYTE b176_4KHz:1 ;
BYTE b192KHz:1 ;
BYTE Rsrv2:1 ;
BYTE ucCode ;
} s ;
BYTE uc[3] ;
} AUDDESCRIPTOR ;
typedef union {
struct {
BYTE FL_FR:1 ;
BYTE LFE:1 ;
BYTE FC:1 ;
BYTE RL_RR:1 ;
BYTE RC:1 ;
BYTE FLC_FRC:1 ;
BYTE RLC_RRC:1 ;
BYTE Reserve:1 ;
BYTE Unuse[2] ;
} s ;
BYTE uc[3] ;
} SPK_ALLOC ;
#define CEA_SUPPORT_UNDERSCAN (1<<7)
#define CEA_SUPPORT_AUDIO (1<<6)
#define CEA_SUPPORT_YUV444 (1<<5)
#define CEA_SUPPORT_YUV422 (1<<4)
#define CEA_NATIVE_MASK 0xF
typedef union _tag_DCSUPPORT {
struct {
BYTE DVI_Dual:1 ;
BYTE Rsvd:2 ;
BYTE DC_Y444:1 ;
BYTE DC_30Bit:1 ;
BYTE DC_36Bit:1 ;
BYTE DC_48Bit:1 ;
BYTE SUPPORT_AI:1 ;
} info ;
BYTE uc ;
} DCSUPPORT ; // Richard Note: Color Depth
typedef union _LATENCY_SUPPORT{
struct {
BYTE Rsvd:6 ;
BYTE I_Latency_Present:1 ;
BYTE Latency_Present:1 ;
} info ;
BYTE uc ;
} LATENCY_SUPPORT ;
#define HDMI_IEEEOUI 0x0c03
typedef struct _RX_CAP{
BYTE Valid; // richard add
BYTE VideoMode ;
BYTE VDOModeCount ;
BYTE idxNativeVDOMode ;
BYTE VDOMode[128] ;
BYTE AUDDesCount ;
AUDDESCRIPTOR AUDDes[32] ;
ULONG IEEEOUI ;
DCSUPPORT dc ;
BYTE MaxTMDSClock ;
LATENCY_SUPPORT lsupport ;
BYTE V_Latency ;
BYTE A_Latency ;
BYTE V_I_Latency ;
BYTE A_I_Latency ;
SPK_ALLOC SpeakerAllocBlk ;
BYTE ValidCEA:1 ;
BYTE ValidHDMI:1 ;
} RX_CAP ;
SYS_STATUS ParseVESAEDID(BYTE *pEDID) ;
SYS_STATUS ParseCEAEDID(BYTE *pCEAEDID, RX_CAP *pRxCap) ;
#endif // SUPPORT_EDID
#endif // _EDID_H_
+119
View File
@@ -0,0 +1,119 @@
#ifndef _HDMITX_H_
#define _HDMITX_H_
#ifdef EXTERN_HDCPROM
#pragma message("Defined EXTERN_HDCPROM")
#endif // EXTERN_HDCPROM
#define SUPPORT_EDID
//#define SUPPORT_HDCP
#define SUPPORT_INPUTRGB
//#define SUPPORT_INPUTYUV444
//#define SUPPORT_INPUTYUV422
//#define SUPPORT_SYNCEMBEDDED
//#define SUPPORT_DEGEN
//#define SUPPORT_INPUTYUV // richard add
//#define INVERT_VID_LATCHEDGE //latch at falling edge
#ifdef SUPPORT_SYNCEMBEDDED
#pragma message("defined SUPPORT_SYNCEMBEDDED for Sync Embedded timing input or CCIR656 input.")
#endif
#ifndef _MCU_ // DSSSHA need large computation data rather than 8051 supported.
#define SUPPORT_DSSSHA
#endif
#if defined(SUPPORT_INPUTYUV444) || defined(SUPPORT_INPUTYUV422)
#define SUPPORT_INPUTYUV
#endif
/*#ifdef _MCU_
#include "mcu.h"
#else // not MCU
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "ioaccess.h"
#include "install.h"
#include "pc.h"
#endif // MCU*/
#include "typedef.h"
#include "HDMI_COMMON.h"
/*typedef unsigned char BYTE;
#define _CODE const
#define SYS_STATUS unsigned int
#define TRUE 1
#define FALSE 0*/
//#define NULL 0
//typedef unsigned char bool;
#include "Altera_UP_SD_Card_Avalon_Interface_mod.h"
#include "sysconfig.h"
// Hardwired to CPU reset
#define HDMITX_Reset(x)
#ifndef SUPPORT_HDCP
static SYS_STATUS
HDCP_Authenticate()
{
return ER_SUCCESS;
}
static void
HDCP_ResetAuth()
{
return;
}
static void
HDCP_ResumeAuthentication()
{
return;
}
#endif
//#include "edid.h"
// #include "dss_sha.h"
#include "it6613_drv.h"
#define HDMITX_INSTANCE_MAX 1
#define SIZEOF_CSCMTX 18
#define SIZEOF_CSCGAIN 6
#define SIZEOF_CSCOFFSET 3
///////////////////////////////////////////////////////////////////////
// Output Mode Type
///////////////////////////////////////////////////////////////////////
#define RES_ASPEC_4x3 0
#define RES_ASPEC_16x9 1
#define F_MODE_REPT_NO 0
#define F_MODE_REPT_TWICE 1
#define F_MODE_REPT_QUATRO 3
#define F_MODE_CSC_ITU601 0
#define F_MODE_CSC_ITU709 1
///////////////////////////////////////////////////////////////////////
// ROM OFFSET
///////////////////////////////////////////////////////////////////////
#define ROMOFF_INT_TYPE 0
#define ROMOFF_INPUT_VIDEO_TYPE 1
#define ROMOFF_OUTPUT_AUDIO_MODE 8
#define ROMOFF_AUDIO_CH_SWAP 9
#define TIMER_LOOP_LEN 10
#define MS(x) (((x)+(TIMER_LOOP_LEN-1))/TIMER_LOOP_LEN) ; // for timer loop
#endif // _HDMITX_H_
@@ -0,0 +1,82 @@
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "i2c_opencores.h"
#include "hdmitx.h"
#include "it6613.h"
inline alt_u32 read_it2(alt_u32 regaddr) {
I2C_start(I2CA_BASE, IT_BASE, 0);
I2C_write(I2CA_BASE, regaddr, 0);
I2C_start(I2CA_BASE, IT_BASE, 1);
return I2C_read(I2CA_BASE,1);
}
inline void write_it2(alt_u32 regaddr, alt_u8 data) {
I2C_start(I2CA_BASE, IT_BASE, 0);
I2C_write(I2CA_BASE, regaddr, 0);
I2C_write(I2CA_BASE, data, 1);
}
BYTE I2C_Read_Byte(BYTE Addr,BYTE RegAddr) {
I2C_start(I2CA_BASE, Addr, 0);
I2C_write(I2CA_BASE, RegAddr, 0);
I2C_start(I2CA_BASE, Addr, 1);
return I2C_read(I2CA_BASE,1);
}
SYS_STATUS I2C_Write_Byte(BYTE Addr,BYTE RegAddr,BYTE Data) {
I2C_start(I2CA_BASE, Addr, 0);
I2C_write(I2CA_BASE, RegAddr, 0);
I2C_write(I2CA_BASE, Data, 1);
return 0;
}
SYS_STATUS I2C_Read_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) {
int i;
for (i=0; i<N; i++)
pData[i] = I2C_Read_Byte(Addr, RegAddr+i);
return 0;
}
SYS_STATUS I2C_Write_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) {
int i;
for (i=0; i<N; i++)
I2C_Write_Byte(Addr, RegAddr+i, pData[i]);
return 0;
}
BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr) {
return read_it2(RegAddr);
}
SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr,BYTE val) {
write_it2(RegAddr, val);
return 0;
}
SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr,BYTE *pData,int N) {
int i;
for (i=0; i<N; i++)
pData[i] = HDMITX_ReadI2C_Byte(RegAddr+i);
return 0;
}
SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr,BYTE *pData,int N) {
int i;
for (i=0; i<N; i++)
HDMITX_WriteI2C_Byte(RegAddr+i, pData[i]);
return 0;
}
void DelayMS(unsigned int ms) {
usleep(1000*ms);
}
+83
View File
@@ -0,0 +1,83 @@
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "i2c_opencores.h"
#include "it6613.h"
volatile alt_u8 cur_bank;
inline void select_bank_it(alt_u8 bank) {
cur_bank = bank;
I2C_start(I2CA_BASE, IT_BASE, 0);
I2C_write(I2CA_BASE, IT_CURBANK, 0);
I2C_write(I2CA_BASE, cur_bank, 1);
}
inline alt_u32 read_it(alt_u32 regaddr) {
if ((regaddr > 0xFF) && (cur_bank == 0))
select_bank_it(1);
else if ((regaddr <= 0xFF) && (cur_bank == 1))
select_bank_it(0);
I2C_start(I2CA_BASE, IT_BASE, 0);
I2C_write(I2CA_BASE, (regaddr & 0xFF), 1);
I2C_start(I2CA_BASE, IT_BASE, 1);
return I2C_read(I2CA_BASE,1);
}
inline void write_it(alt_u32 regaddr, alt_u8 data) {
if ((regaddr > 0xFF) && (cur_bank == 0))
select_bank_it(1);
else if ((regaddr <= 0xFF) && (cur_bank == 1))
select_bank_it(0);
I2C_start(I2CA_BASE, IT_BASE, 0);
I2C_write(I2CA_BASE, (regaddr & 0xFF), 0);
I2C_write(I2CA_BASE, data, 1);
}
/*inline void reset_it() {
usleep(100000);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x00);
usleep(100000);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x01);
usleep(100000);
}*/
int init_it() {
alt_u32 vendor_id, device_id;
alt_u32 i;
cur_bank = 0;
select_bank_it(cur_bank);
vendor_id = read_it(IT_VENDORID);
device_id = read_it(IT_DEVICEID);
printf("VEN: 0x%.2X, DEV: 0x%.2X\n", vendor_id, device_id);
if (!((vendor_id == IT6613_VENDORID) && (device_id == IT6613_DEVICEID)))
return -1;
write_it(REG_TX_SW_RST,B_REF_RST|B_VID_RST|B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
usleep(1000);
write_it(REG_TX_SW_RST,B_VID_RST|B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
write_it(IT_DRIVECTRL, 0x10);
write_it(IT_HDMIMODE, 0);
for (i=0xC1; i<=0xD0; i++)
write_it(i, 0);
write_it(IT_OUTCOLOR, 0);
// enable video
//HDMITX_WriteI2C_Byte(REG_TX_SW_RST,B_VID_RST|B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
write_it(REG_TX_SW_RST, B_AUD_RST|B_AREF_RST|B_HDCP_RST) ;
usleep(1000);
return 0;
}
+29
View File
@@ -0,0 +1,29 @@
#ifndef IT6613_H_
#define IT6613_H_
//#define I2C_DEBUG
//#define I2CA_HDMI_BASE I2C_OPENCORES_1_BASE
#define I2CA_BASE I2C_OPENCORES_0_BASE
#define IT6613_VENDORID 0xCA
#define IT6613_DEVICEID 0x13
#define IT_BASE (0x98>>1)
#define IT_VENDORID 0x01
#define IT_DEVICEID 0x02
#define IT_RESET 0x04
#define IT_CURBANK 0x0F
#define IT_DRIVECTRL 0x61
#define IT_HDMIMODE 0xC0
#define IT_OUTCOLOR 0x158
#define REG_TX_SW_RST 0x04
#define B_ENTEST (1<<7)
#define B_REF_RST (1<<5)
#define B_AREF_RST (1<<4)
#define B_VID_RST (1<<3)
#define B_AUD_RST (1<<2)
#define B_HDMI_RST (1<<1)
#define B_HDCP_RST (1<<0)
#endif /* IT6613_H_ */
File diff suppressed because it is too large Load Diff
+844
View File
@@ -0,0 +1,844 @@
#ifndef _IT6613_H_
#define _IT6613_H_
//#define EXTERN_HDCPROM
/////////////////////////////////////////
// DDC Address
/////////////////////////////////////////
#define DDC_HDCP_ADDRESS 0x74
#define DDC_EDID_ADDRESS 0xA0
#define DDC_FIFO_MAXREQ 0x20
// I2C address
#define _80MHz 80000000
#define HDMI_TX_I2C_SLAVE_ADDR 0x98 // PCADR is ground, if PCADR=1, address=0x9A
///////////////////////////////////////////////////////////////////////
// Register offset
///////////////////////////////////////////////////////////////////////
#define REG_TX_VENDOR_ID0 0x00
#define REG_TX_VENDOR_ID1 0x01
#define REG_TX_DEVICE_ID0 0x02
#define REG_TX_DEVICE_ID1 0x03
#define O_DEVID 0
#define M_DEVID 0xF
#define O_REVID 4
#define M_REVID 0xF
#define REG_TX_SW_RST 0x04
#define B_ENTEST (1<<7)
#define B_REF_RST (1<<5)
#define B_AREF_RST (1<<4)
#define B_VID_RST (1<<3)
#define B_AUD_RST (1<<2)
#define B_HDMI_RST (1<<1)
#define B_HDCP_RST (1<<0)
#define REG_TX_INT_CTRL 0x05
#define B_INTPOL_ACTL 0
#define B_INTPOL_ACTH (1<<7)
#define B_INT_PUSHPULL 0
#define B_INT_OPENDRAIN (1<<6)
#define REG_TX_INT_STAT1 0x06
#define B_INT_AUD_OVERFLOW (1<<7)
#define B_INT_ROMACQ_NOACK (1<<6)
#define B_INT_RDDC_NOACK (1<<5)
#define B_INT_DDCFIFO_ERR (1<<4)
#define B_INT_ROMACQ_BUS_HANG (1<<3)
#define B_INT_DDC_BUS_HANG (1<<2)
#define B_INT_RX_SENSE (1<<1)
#define B_INT_HPD_PLUG (1<<0)
#define REG_TX_INT_STAT2 0x07
#define B_INT_HDCP_SYNC_DET_FAIL (1<<7)
#define B_INT_VID_UNSTABLE (1<<6)
#define B_INT_PKTACP (1<<5)
#define B_INT_PKTNULL (1<<4)
#define B_INT_PKTGENERAL (1<<3)
#define B_INT_KSVLIST_CHK (1<<2)
#define B_INT_AUTH_DONE (1<<1)
#define B_INT_AUTH_FAIL (1<<0)
#define REG_TX_INT_STAT3 0x08
#define B_INT_AUD_CTS (1<<6)
#define B_INT_VSYNC (1<<5)
#define B_INT_VIDSTABLE (1<<4)
#define B_INT_PKTMPG (1<<3)
#define B_INT_PKTSPD (1<<2)
#define B_INT_PKTAUD (1<<1)
#define B_INT_PKTAVI (1<<0)
#define REG_TX_INT_MASK1 0x09
#define B_AUDIO_OVFLW_MASK (1<<7)
#define B_DDC_NOACK_MASK (1<<5)
#define B_DDC_FIFO_ERR_MASK (1<<4)
#define B_DDC_BUS_HANG_MASK (1<<2)
#define B_RXSEN_MASK (1<<1)
#define B_HPD_MASK (1<<0)
#define REG_TX_INT_MASK2 0x0A
#define B_PKT_AVI_MASK (1<<7)
#define B_PKT_VID_UNSTABLE_MASK (1<<6)
#define B_PKT_ACP_MASK (1<<5)
#define B_PKT_NULL_MASK (1<<4)
#define B_PKT_GEN_MASK (1<<3)
#define B_KSVLISTCHK_MASK (1<<2)
#define B_T_AUTH_DONE_MASK (1<<1)
#define B_AUTH_FAIL_MASK (1<<0)
#define REG_TX_INT_MASK3 0x0B
#define B_HDCP_SYNC_DET_FAIL_MASK (1<<6)
#define B_AUDCTS_MASK (1<<5)
#define B_VSYNC_MASK (1<<4)
#define B_VIDSTABLE_MASK (1<<3)
#define B_PKT_MPG_MASK (1<<2)
#define B_PKT_SPD_MASK (1<<1)
#define B_PKT_AUD_MASK (1<<0)
#define REG_TX_INT_CLR0 0x0C
#define B_CLR_PKTACP (1<<7)
#define B_CLR_PKTNULL (1<<6)
#define B_CLR_PKTGENERAL (1<<5)
#define B_CLR_KSVLISTCHK (1<<4)
#define B_CLR_AUTH_DONE (1<<3)
#define B_CLR_AUTH_FAIL (1<<2)
#define B_CLR_RXSENSE (1<<1)
#define B_CLR_HPD (1<<0)
#define REG_TX_INT_CLR1 0x0D
#define B_CLR_VSYNC (1<<7)
#define B_CLR_VIDSTABLE (1<<6)
#define B_CLR_PKTMPG (1<<5)
#define B_CLR_PKTSPD (1<<4)
#define B_CLR_PKTAUD (1<<3)
#define B_CLR_PKTAVI (1<<2)
#define B_CLR_HDCP_SYNC_DET_FAIL (1<<1)
#define B_CLR_VID_UNSTABLE (1<<0)
#define REG_TX_SYS_STATUS 0x0E
// readonly
#define B_INT_ACTIVE (1<<7)
#define B_HPDETECT (1<<6)
#define B_RXSENDETECT (1<<5)
#define B_TXVIDSTABLE (1<<4)
// read/write
#define O_CTSINTSTEP 2
#define M_CTSINTSTEP (3<<2)
#define B_CLR_AUD_CTS (1<<1)
#define B_INTACTDONE (1<<0)
#define REG_TX_BANK_CTRL 0x0F
#define B_BANK0 0
#define B_BANK1 1
// DDC
#define REG_TX_DDC_MASTER_CTRL 0x10
#define B_MASTERROM (1<<1)
#define B_MASTERDDC (0<<1)
#define B_MASTERHOST (1<<0)
#define B_MASTERHDCP (0<<0)
#define REG_TX_DDC_HEADER 0x11
#define REG_TX_DDC_REQOFF 0x12
#define REG_TX_DDC_REQCOUNT 0x13
#define REG_TX_DDC_EDIDSEG 0x14
#define REG_TX_DDC_CMD 0x15
#define CMD_DDC_SEQ_BURSTREAD 0
#define CMD_LINK_CHKREAD 2
#define CMD_EDID_READ 3
#define CMD_FIFO_CLR 9
#define CMD_GEN_SCLCLK 0xA
#define CMD_DDC_ABORT 0xF
#define REG_TX_DDC_STATUS 0x16
#define B_DDC_DONE (1<<7)
#define B_DDC_ACT (1<<6)
#define B_DDC_NOACK (1<<5)
#define B_DDC_WAITBUS (1<<4)
#define B_DDC_ARBILOSE (1<<3)
#define B_DDC_ERROR (B_DDC_NOACK|B_DDC_WAITBUS|B_DDC_ARBILOSE)
#define B_DDC_FIFOFULL (1<<2)
#define B_DDC_FIFOEMPTY (1<<1)
#define REG_TX_DDC_READFIFO 0x17
#define REG_TX_ROM_STARTADDR 0x18
#define REG_TX_HDCP_HEADER 0x19
#define REG_TX_ROM_HEADER 0x1A
#define REG_TX_BUSHOLD_T 0x1B
#define REG_TX_ROM_STAT 0x1C
#define B_ROM_DONE (1<<7)
#define B_ROM_ACTIVE (1<<6)
#define B_ROM_NOACK (1<<5)
#define B_ROM_WAITBUS (1<<4)
#define B_ROM_ARBILOSE (1<<3)
#define B_ROM_BUSHANG (1<<2)
// HDCP
#define REG_TX_AN_GENERATE 0x1F
#define B_START_CIPHER_GEN 1
#define B_STOP_CIPHER_GEN 0
#define REG_TX_HDCP_DESIRE 0x20
#define B_ENABLE_HDPC11 (1<<1)
#define B_CPDESIRE (1<<0)
#define REG_TX_AUTHFIRE 0x21
#define REG_TX_LISTCTRL 0x22
#define B_LISTFAIL (1<<1)
#define B_LISTDONE (1<<0)
#define REG_TX_AKSV 0x23
#define REG_TX_AKSV0 0x23
#define REG_TX_AKSV1 0x24
#define REG_TX_AKSV2 0x25
#define REG_TX_AKSV3 0x26
#define REG_TX_AKSV4 0x27
#define REG_TX_AN 0x28
#define REG_TX_AN_GEN 0x30
#define REG_TX_ARI 0x38
#define REG_TX_ARI0 0x38
#define REG_TX_ARI1 0x39
#define REG_TX_APJ 0x3A
#define REG_TX_BKSV 0x3B
#define REG_TX_BRI 0x40
#define REG_TX_BRI0 0x40
#define REG_TX_BRI1 0x41
#define REG_TX_BPJ 0x42
#define REG_TX_BCAP 0x43
#define B_CAP_HDMI_REPEATER (1<<6)
#define B_CAP_KSV_FIFO_RDY (1<<5)
#define B_CAP_HDMI_FAST_MODE (1<<4)
#define B_CAP_HDCP_1p1 (1<<1)
#define B_CAP_FAST_REAUTH (1<<0)
#define REG_TX_BSTAT 0x44
#define REG_TX_BSTAT0 0x44
#define REG_TX_BSTAT1 0x45
#define B_CAP_HDMI_MODE (1<<12)
#define B_CAP_DVI_MODE (0<<12)
#define B_MAX_CASCADE_EXCEEDED (1<<11)
#define M_REPEATER_DEPTH (0x7<<8)
#define O_REPEATER_DEPTH 8
#define B_DOWNSTREAM_OVER (1<<7)
#define M_DOWNSTREAM_COUNT 0x7F
#define REG_TX_AUTH_STAT 0x46
#define B_T_AUTH_DONE (1<<7)
#define REG_TX_CLK_CTRL0 0x58
#define O_OSCLK_SEL 5
#define M_OSCLK_SEL 3
#define B_AUTO_OVER_SAMPLING_CLOCK (1<<4)
#define O_EXT_MCLK_SEL 2
#define M_EXT_MCLK_SEL (3<<O_EXT_MCLK_SEL)
#define B_EXT_128FS (0<<O_EXT_MCLK_SEL)
#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 REG_TX_SHA_SEL 0x50
#define REG_TX_SHA_RD_BYTE1 0x51
#define REG_TX_SHA_RD_BYTE2 0x52
#define REG_TX_SHA_RD_BYTE3 0x53
#define REG_TX_SHA_RD_BYTE4 0x54
#define REG_TX_AKSV_RD_BYTE5 0x55
#define REG_TX_CLK_CTRL1 0x59
#define B_EN_TXCLK_COUNT (1<<5)
#define B_VDO_LATCH_EDGE (1<<3)
#define M_AUD_DIV 3
#define B_AUD_NODIV 0
#define B_AUD_DIV2 1
#define B_AUD_DIV4 3
#define B_AUD_NODEF 2
#define REG_TX_CLK_STATUS1 0x5E
#define REG_TX_CLK_STATUS2 0x5F
#define B_IP_LOCK (1<<7)
#define B_XP_LOCK (1<<6)
#define B_OSF_LOCK (1<<5)
#define REG_TX_AFE_DRV_CTRL 0x61
#define B_AFE_DRV_PWD (1<<5)
#define B_AFE_DRV_RST (1<<4)
#define B_AFE_DRV_PDRXDET (1<<2)
#define B_AFE_DRV_TERMON (1<<1)
#define B_AFE_DRV_ENCAL (1<<0)
#define REG_TX_AFE_XP_CTRL 0x62
#define B_AFE_XP_GAINBIT (1<<7)
#define B_AFE_XP_PWDPLL (1<<6)
#define B_AFE_XP_ENI (1<<5)
#define B_AFE_XP_ER0 (1<<4)
#define B_AFE_XP_RESETB (1<<3)
#define B_AFE_XP_PWDI (1<<2)
#define B_AFE_XP_DEI (1<<1)
#define B_AFE_XP_DER (1<<0)
#define REG_TX_AFE_ISW_CTRL 0x63
#define B_AFE_RTERM_SEL (1<<7)
#define B_AFE_IP_BYPASS (1<<6)
#define M_AFE_DRV_ISW (7<<3)
#define O_AFE_DRV_ISW 3
#define B_AFE_DRV_ISWK 7
#define REG_TX_AFE_IP_CTRL 0x64
#define B_AFE_IP_GAINBIT (1<<7)
#define B_AFE_IP_PWDPLL (1<<6)
#define M_AFE_IP_CKSEL (3<<4)
#define O_AFE_IP_CKSEL 4
#define B_AFE_IP_ER0 (1<<3)
#define B_AFE_IP_RESETB (1<<2)
#define B_AFE_IP_ENC (1<<1)
#define B_AFE_IP_EC1 (1<<0)
#define REG_TX_AFE_RING 0x65
#define B_AFE_CAL_UPDATE (1<<7)
#define B_AFE_CAL_MANUAL (1<<6)
#define M_AFE_CAL_CLK_MODE (3<<4)
#define O_AFE_CAL_CLK_MODE 4
#define O_AFE_DRV_VSW 2
#define M_AFE_DRV_VSW (3<<2)
#define B_AFE_RING_SLOW (1<<1)
#define B_AFE_RING_FAST (1<<0)
#define REG_TX_AFE_TEST 0x66
#define B_AFE_AFE_ENTEST (1<<6)
#define B_AFE_AFE_ENBIST (1<<5)
#define M_AFE_CAL_RTERM_MANUAL 0x1F
#define REG_TX_AFE_LFSR 0x67
#define B_AFE_AFELFSR_VAL (1<<7)
#define B_AFE_DIS_AFELFSR (1<<6)
#define M_AFE_RTERM_VAOUE 0xF
//
//#define REG_TX_AFE_DRV_CTRL 0x61
// #define M_AFE_DRV_SR (3<<2)
// #define O_AFE_DRV_SR 2
// #define B_AFE_DRV_RST (1<<4)
// #define B_AFE_DRV_PWD (1<<5)
// #define B_AFE_DRV_ENBIST (1<<6)
//
//#define REG_TX_AFE_XP_CTRL1 0x62
// #define B_AFE_XP_GAINBIT (1<<7)
// #define B_AFE_XP_PWDPLL (1<<6)
// #define B_AFE_XP_ENI (1<<5)
// #define B_AFE_XP_ER0 (1<<4)
// #define B_AFE_XP_RESETB (1<<3)
// #define B_AFE_XP_PWDI (1<<2)
// #define B_AFE_XP_DEI (1<<1)
// #define B_AFE_XP_BYPASS (1<<0)
//
//#define REG_TX_AFE_XP_CTRL2 0x63
// #define B_XP_ENCLKX5 (1<<3)
// #define M_XP_CLKSEL 3
// #define B_XP_CLKSEL_HALF_PCLKHV 0
// #define B_XP_CLKSEL_1_PCLKHV 1
// #define B_XP_CLKSEL_2_PCLKHV 2
// #define B_XP_CLKSEL_4_PCLKHV 3
//
//
//#define REG_TX_AFE_IP_CTRL 0x64
// #define B_AFE_IP_GAINBIT (1<<6)
// #define B_AFE_IP_PWDPLL (1<<5)
// #define B_AFE_IP_SEDB (1<<4)
// #define B_AFE_IP_ER0 (1<<3)
// #define B_AFE_IP_RESETB (1<<2)
// #define B_AFE_IP_PDIV1 (1<<1)
// #define B_AFE_IP_ENCB (1<<0)
//
//#define REG_TX_AFE_RING 0x65
// #define B_AFE_RING_FAST (1<<0)
// #define B_AFE_RING_SLOW (1<<1)
// #define M_AFE_DRV_VSW (3<<2)
// #define B_AFE_VSW_NOENH 0
// #define B_AFE_VSW_12ENH (1<<2)
// #define B_AFE_VSW_24ENH (2<<2)
// #define B_AFE_VSW_35ENH (3<<2)
// Input Data Format Register
#define REG_TX_INPUT_MODE 0x70
#define O_INCLKDLY 0
#define M_INCLKDLY 3
#define B_INDDR (1<<2)
#define B_SYNCEMB (1<<3)
#define B_2X656CLK (1<<4)
#define B_PCLKDIV2 (1<<5)
#define M_INCOLMOD (3<<6)
#define B_IN_RGB 0
#define B_IN_YUV422 (1<<6)
#define B_IN_YUV444 (2<<6)
#define REG_TX_TXFIFO_RST 0x71
#define B_ENAVMUTERST 1
#define B_TXFFRST (1<<1)
#define REG_TX_CSC_CTRL 0x72
#define B_CSC_BYPASS 0
#define B_CSC_RGB2YUV 2
#define B_CSC_YUV2RGB 3
#define M_CSC_SEL 3
#define B_TX_EN_DITHER (1<<7)
#define B_TX_EN_UDFILTER (1<<6)
#define B_TX_DNFREE_GO (1<<5)
#define REG_TX_CSC_YOFF 0x73
#define REG_TX_CSC_COFF 0x74
#define REG_TX_CSC_RGBOFF 0x75
#define REG_TX_CSC_MTX11_L 0x76
#define REG_TX_CSC_MTX11_H 0x77
#define REG_TX_CSC_MTX12_L 0x78
#define REG_TX_CSC_MTX12_H 0x79
#define REG_TX_CSC_MTX13_L 0x7A
#define REG_TX_CSC_MTX13_H 0x7B
#define REG_TX_CSC_MTX21_L 0x7C
#define REG_TX_CSC_MTX21_H 0x7D
#define REG_TX_CSC_MTX22_L 0x7E
#define REG_TX_CSC_MTX22_H 0x7F
#define REG_TX_CSC_MTX23_L 0x80
#define REG_TX_CSC_MTX23_H 0x81
#define REG_TX_CSC_MTX31_L 0x82
#define REG_TX_CSC_MTX31_H 0x83
#define REG_TX_CSC_MTX32_L 0x84
#define REG_TX_CSC_MTX32_H 0x85
#define REG_TX_CSC_MTX33_L 0x86
#define REG_TX_CSC_MTX33_H 0x87
#define REG_TX_CSC_GAIN1V_L 0x88
#define REG_TX_CSC_GAIN1V_H 0x89
#define REG_TX_CSC_GAIN2V_L 0x8A
#define REG_TX_CSC_GAIN2V_H 0x8B
#define REG_TX_CSC_GAIN3V_L 0x8C
#define REG_TX_CSC_GAIN3V_H 0x8D
#define REG_TX_HVPol 0x90
#define REG_TX_HfPixel 0x91
#define REG_TX_HSSL 0x95
#define REG_TX_HSEL 0x96
#define REG_TX_HSH 0x97
#define REG_TX_VSS1 0xA0
#define REG_TX_VSE1 0xA1
#define REG_TX_VSS2 0xA2
#define REG_TX_VSE2 0xA3
// HDMI General Control Registers
#define REG_TX_HDMI_MODE 0xC0
#define B_TX_HDMI_MODE 1
#define B_TX_DVI_MODE 0
#define REG_TX_AV_MUTE 0xC1
#define REG_TX_GCP 0xC1
#define B_CLR_AVMUTE 0
#define B_SET_AVMUTE 1
#define B_TX_SETAVMUTE (1<<0)
#define B_BLUE_SCR_MUTE (1<<1)
#define B_NODEF_PHASE (1<<2)
#define B_PHASE_RESYNC (1<<3)
#define O_COLOR_DEPTH 4
#define M_COLOR_DEPTH 7
#define B_COLOR_DEPTH_MASK (M_COLOR_DEPTH<<O_COLOR_DEPTH)
#define B_CD_NODEF 0
#define B_CD_24 (4<<4)
#define B_CD_30 (5<<4)
#define B_CD_36 (6<<4)
#define B_CD_48 (7<<4)
#define REG_TX_OESS_CYCLE 0xC3
#define REG_TX_ENCRYPTION 0xC4
#define B_DISABLE_ENCRYPTION 1
#define B_ENABLE_ENCRYPTION 0
#define REG_TX_PKT_SINGLE_CTRL 0xC5
#define B_SINGLE_PKT 1
#define B_BURST_PKT
#define B_SW_CTS (1<<1)
#define REG_TX_PKT_GENERAL_CTRL 0xC6
#define REG_TX_NULL_CTRL 0xC9
#define REG_TX_ACP_CTRL 0xCA
#define REG_TX_ISRC1_CTRL 0xCB
#define REG_TX_ISRC2_CTRL 0xCC
#define REG_TX_AVI_INFOFRM_CTRL 0xCD
#define REG_TX_AUD_INFOFRM_CTRL 0xCE
#define REG_TX_SPD_INFOFRM_CTRL 0xCF
#define REG_TX_MPG_INFOFRM_CTRL 0xD0
#define B_ENABLE_PKT 1
#define B_REPEAT_PKT (1<<1)
// Audio Channel Control
#define REG_TX_AUDIO_CTRL0 0xE0
#define M_AUD_SWL (3<<6)
#define M_AUD_16BIT (0<<6)
#define M_AUD_18BIT (1<<6)
#define M_AUD_20BIT (2<<6)
#define M_AUD_24BIT (3<<6)
#define B_SPDIFTC (1<<5)
#define B_AUD_SPDIF (1<<4)
#define B_AUD_I2S (0<<4)
#define B_AUD_EN_I2S3 (1<<3)
#define B_AUD_EN_I2S2 (1<<2)
#define B_AUD_EN_I2S1 (1<<1)
#define B_AUD_EN_I2S0 (1<<0)
#define REG_TX_AUDIO_CTRL1 0xE1
#define B_AUD_FULLPKT (1<<6)
#define B_AUDFMT_STD_I2S (0<<0)
#define B_AUDFMT_32BIT_I2S (1<<0)
#define B_AUDFMT_LEFT_JUSTIFY (0<<1)
#define B_AUDFMT_RIGHT_JUSTIFY (1<<1)
#define B_AUDFMT_DELAY_1T_TO_WS (0<<2)
#define B_AUDFMT_NO_DELAY_TO_WS (1<<2)
#define B_AUDFMT_WS0_LEFT (0<<3)
#define B_AUDFMT_WS0_RIGHT (1<<3)
#define B_AUDFMT_MSB_SHIFT_FIRST (0<<4)
#define B_AUDFMT_LSB_SHIFT_FIRST (1<<4)
#define B_AUDFMT_RISE_EDGE_SAMPLE_WS (0<<5)
#define B_AUDFMT_FALL_EDGE_SAMPLE_WS (0<<5)
#define REG_TX_AUDIO_FIFOMAP 0xE2
#define O_FIFO3SEL 6
#define O_FIFO2SEL 4
#define O_FIFO1SEL 2
#define O_FIFO0SEL 0
#define B_SELSRC3 3
#define B_SELSRC2 2
#define B_SELSRC1 1
#define B_SELSRC0 0
#define REG_TX_AUDIO_CTRL3 0xE3
#define B_AUD_MULCH (1<<7)
#define B_EN_ZERO_CTS (1<<6)
#define B_CHSTSEL (1<<4)
#define B_S3RLCHG (1<<3)
#define B_S2RLCHG (1<<2)
#define B_S1RLCHG (1<<1)
#define B_S0RLCHG (1<<0)
#define REG_TX_AUD_SRCVALID_FLAT 0xE4
#define B_AUD_SPXFLAT_SRC3 (1<<7)
#define B_AUD_SPXFLAT_SRC2 (1<<6)
#define B_AUD_SPXFLAT_SRC1 (1<<5)
#define B_AUD_SPXFLAT_SRC0 (1<<4)
#define B_AUD_ERR2FLAT (1<<3)
#define B_AUD_S3VALID (1<<2)
#define B_AUD_S2VALID (1<<1)
#define B_AUD_S1VALID (1<<0)
//////////////////////////////////////////
// Bank 1
//////////////////////////////////////////
#define REGPktAudCTS0 0x30 // 7:0
#define REGPktAudCTS1 0x31 // 15:8
#define REGPktAudCTS2 0x32 // 19:16
#define REGPktAudN0 0x33 // 7:0
#define REGPktAudN1 0x34 // 15:8
#define REGPktAudN2 0x35 // 19:16
#define REGPktAudCTSCnt0 0xA0 // 7:0
#define REGPktAudCTSCnt1 0xA1 // 15:8
#define REGPktAudCTSCnt2 0xA2 // 19:16
//////////////////////////////////////////
// COMMON PACKET for NULL,ISRC1,ISRC2,SPD
//////////////////////////////////////////
#define REG_TX_PKT_HB00 0x38
#define REG_TX_PKT_HB01 0x39
#define REG_TX_PKT_HB02 0x3A
#define REG_TX_PKT_PB00 0x3B
#define REG_TX_PKT_PB01 0x3C
#define REG_TX_PKT_PB02 0x3D
#define REG_TX_PKT_PB03 0x3E
#define REG_TX_PKT_PB04 0x3F
#define REG_TX_PKT_PB05 0x40
#define REG_TX_PKT_PB06 0x41
#define REG_TX_PKT_PB07 0x42
#define REG_TX_PKT_PB08 0x43
#define REG_TX_PKT_PB09 0x44
#define REG_TX_PKT_PB10 0x45
#define REG_TX_PKT_PB11 0x46
#define REG_TX_PKT_PB12 0x47
#define REG_TX_PKT_PB13 0x48
#define REG_TX_PKT_PB14 0x49
#define REG_TX_PKT_PB15 0x4A
#define REG_TX_PKT_PB16 0x4B
#define REG_TX_PKT_PB17 0x4C
#define REG_TX_PKT_PB18 0x4D
#define REG_TX_PKT_PB19 0x4E
#define REG_TX_PKT_PB20 0x4F
#define REG_TX_PKT_PB21 0x50
#define REG_TX_PKT_PB22 0x51
#define REG_TX_PKT_PB23 0x52
#define REG_TX_PKT_PB24 0x53
#define REG_TX_PKT_PB25 0x54
#define REG_TX_PKT_PB26 0x55
#define REG_TX_PKT_PB27 0x56
#define REG_TX_AVIINFO_DB1 0x58
#define REG_TX_AVIINFO_DB2 0x59
#define REG_TX_AVIINFO_DB3 0x5A
#define REG_TX_AVIINFO_DB4 0x5B
#define REG_TX_AVIINFO_DB5 0x5C
#define REG_TX_AVIINFO_DB6 0x5E
#define REG_TX_AVIINFO_DB7 0x5F
#define REG_TX_AVIINFO_DB8 0x60
#define REG_TX_AVIINFO_DB9 0x61
#define REG_TX_AVIINFO_DB10 0x62
#define REG_TX_AVIINFO_DB11 0x63
#define REG_TX_AVIINFO_DB12 0x64
#define REG_TX_AVIINFO_DB13 0x65
#define REG_TX_AVIINFO_SUM 0x5D
#define REG_TX_PKT_AUDINFO_CC 0x68 // [2:0]
#define REG_TX_PKT_AUDINFO_SF 0x69 // [4:2]
#define REG_TX_PKT_AUDINFO_CA 0x6B // [7:0]
#define REG_TX_PKT_AUDINFO_DM_LSV 0x6C // [7][6:3]
#define REG_TX_PKT_AUDINFO_SUM 0x6D // [7:0]
// Source Product Description Info Frame
#define REG_TX_PKT_SPDINFO_SUM 0x70
#define REG_TX_PKT_SPDINFO_PB1 0x71
#define REG_TX_PKT_SPDINFO_PB2 0x72
#define REG_TX_PKT_SPDINFO_PB3 0x73
#define REG_TX_PKT_SPDINFO_PB4 0x74
#define REG_TX_PKT_SPDINFO_PB5 0x75
#define REG_TX_PKT_SPDINFO_PB6 0x76
#define REG_TX_PKT_SPDINFO_PB7 0x77
#define REG_TX_PKT_SPDINFO_PB8 0x78
#define REG_TX_PKT_SPDINFO_PB9 0x79
#define REG_TX_PKT_SPDINFO_PB10 0x7A
#define REG_TX_PKT_SPDINFO_PB11 0x7B
#define REG_TX_PKT_SPDINFO_PB12 0x7C
#define REG_TX_PKT_SPDINFO_PB13 0x7D
#define REG_TX_PKT_SPDINFO_PB14 0x7E
#define REG_TX_PKT_SPDINFO_PB15 0x7F
#define REG_TX_PKT_SPDINFO_PB16 0x80
#define REG_TX_PKT_SPDINFO_PB17 0x81
#define REG_TX_PKT_SPDINFO_PB18 0x82
#define REG_TX_PKT_SPDINFO_PB19 0x83
#define REG_TX_PKT_SPDINFO_PB20 0x84
#define REG_TX_PKT_SPDINFO_PB21 0x85
#define REG_TX_PKT_SPDINFO_PB22 0x86
#define REG_TX_PKT_SPDINFO_PB23 0x87
#define REG_TX_PKT_SPDINFO_PB24 0x88
#define REG_TX_PKT_SPDINFO_PB25 0x89
#define REG_TX_PKT_MPGINFO_FMT 0x8A
#define B_MPG_FR 1
#define B_MPG_MF_I (1<<1)
#define B_MPG_MF_B (2<<1)
#define B_MPG_MF_P (3<<1)
#define B_MPG_MF_MASK (3<<1)
#define REG_TX_PKG_MPGINFO_DB0 0x8B
#define REG_TX_PKG_MPGINFO_DB1 0x8C
#define REG_TX_PKG_MPGINFO_DB2 0x8D
#define REG_TX_PKG_MPGINFO_DB3 0x8E
#define REG_TX_PKG_MPGINFO_SUM 0x8F
#define REG_TX_AUDCHST_MODE 0x91 // 191 REG_TX_AUD_CHSTD[2:0] 6:4
// REG_TX_AUD_CHSTC 3
// REG_TX_AUD_NLPCM 2
// REG_TX_AUD_MONO 0
#define REG_TX_AUDCHST_CAT 0x92 // 192 REG_TX_AUD_CHSTCAT 7:0
#define REG_TX_AUDCHST_SRCNUM 0x93 // 193 REG_TX_AUD_CHSTSRC 3:0
#define REG_TX_AUD0CHST_CHTNUM 0x94 // 194 REG_TX_AUD0_CHSTCHR 7:4
// REG_TX_AUD0_CHSTCHL 3:0
#define REG_TX_AUD1CHST_CHTNUM 0x95 // 195 REG_TX_AUD1_CHSTCHR 7:4
// REG_TX_AUD1_CHSTCHL 3:0
#define REG_TX_AUD2CHST_CHTNUM 0x96 // 196 REG_TX_AUD2_CHSTCHR 7:4
// REG_TX_AUD2_CHSTCHL 3:0
#define REG_TX_AUD3CHST_CHTNUM 0x97 // 197 REG_TX_AUD3_CHSTCHR 7:4
// REG_TX_AUD3_CHSTCHL 3:0
#define REG_TX_AUDCHST_CA_FS 0x98 // 198 REG_TX_AUD_CHSTCA 5:4
// REG_TX_AUD_CHSTFS 3:0
#define REG_TX_AUDCHST_OFS_WL 0x99 // 199 REG_TX_AUD_CHSTOFS 7:4
// REG_TX_AUD_CHSTWL 3:0
/////////////////////////////////////////////////////////////////////
// Macro
/////////////////////////////////////////////////////////////////////
#define Switch_HDMITX_Bank(x) HDMITX_WriteI2C_Byte(0x0f,(x)&1)
#define HDMI_OrREG_TX_Byte(reg,ormask) HDMITX_WriteI2C_Byte(reg,(HDMITX_ReadI2C_Byte(reg) | (ormask)))
#define HDMI_AndREG_TX_Byte(reg,andmask) HDMITX_WriteI2C_Byte(reg,(HDMITX_ReadI2C_Byte(reg) & (andmask)))
#define HDMI_SetREG_TX_Byte(reg,andmask,ormask) HDMITX_WriteI2C_Byte(reg,((HDMITX_ReadI2C_Byte(reg) & (andmask))|(ormask)))
/////////////////////////////////////////////////////////////////////
// data structure
/////////////////////////////////////////////////////////////////////
typedef struct _INSTANCE_STRUCT {
BYTE I2C_DEV ;
BYTE I2C_ADDR ;
/////////////////////////////////////////////////
// Interrupt Type
/////////////////////////////////////////////////
BYTE bIntType ; // = 0 ;
/////////////////////////////////////////////////
// Video Property
/////////////////////////////////////////////////
BYTE bInputVideoSignalType ; // for Sync Embedded,CCIR656,InputDDR
/////////////////////////////////////////////////
// Audio Property
/////////////////////////////////////////////////
BYTE bOutputAudioMode ; // = 0 ;
BYTE bAudioChannelSwap ; // = 0 ;
BYTE bAudioChannelEnable ;
BYTE bAudFs ;
unsigned long TMDSClock ;
BYTE bAuthenticated:1 ;
BYTE bHDMIMode: 1;
BYTE bIntPOL:1 ; // 0 = Low Active
BYTE bHPD:1 ;
} INSTANCE ;
// 2008/02/27 added by jj_tseng@chipadvanced.com
typedef enum _mode_id {
UNKNOWN_MODE=0,
CEA_640x480p60,
CEA_720x480p60,
CEA_1280x720p60,
CEA_1920x1080i60,
CEA_720x480i60,
CEA_720x240p60,
CEA_1440x480i60,
CEA_1440x240p60,
CEA_2880x480i60,
CEA_2880x240p60,
CEA_1440x480p60,
CEA_1920x1080p60,
CEA_720x576p50,
CEA_1280x720p50,
CEA_1920x1080i50,
CEA_720x576i50,
CEA_1440x576i50,
CEA_720x288p50,
CEA_1440x288p50,
CEA_2880x576i50,
CEA_2880x288p50,
CEA_1440x576p50,
CEA_1920x1080p50,
CEA_1920x1080p24,
CEA_1920x1080p25,
CEA_1920x1080p30,
VESA_640x350p85,
VESA_640x400p85,
VESA_720x400p85,
VESA_640x480p60,
VESA_640x480p72,
VESA_640x480p75,
VESA_640x480p85,
VESA_800x600p56,
VESA_800x600p60,
VESA_800x600p72,
VESA_800x600p75,
VESA_800X600p85,
VESA_840X480p60,
VESA_1024x768p60,
VESA_1024x768p70,
VESA_1024x768p75,
VESA_1024x768p85,
VESA_1152x864p75,
VESA_1280x768p60R,
VESA_1280x768p60,
VESA_1280x768p75,
VESA_1280x768p85,
VESA_1280x960p60,
VESA_1280x960p85,
VESA_1280x1024p60,
VESA_1280x1024p75,
VESA_1280X1024p85,
VESA_1360X768p60,
VESA_1400x768p60R,
VESA_1400x768p60,
VESA_1400x1050p75,
VESA_1400x1050p85,
VESA_1440x900p60R,
VESA_1440x900p60,
VESA_1440x900p75,
VESA_1440x900p85,
VESA_1600x1200p60,
VESA_1600x1200p65,
VESA_1600x1200p70,
VESA_1600x1200p75,
VESA_1600x1200p85,
VESA_1680x1050p60R,
VESA_1680x1050p60,
VESA_1680x1050p75,
VESA_1680x1050p85,
VESA_1792x1344p60,
VESA_1792x1344p75,
VESA_1856x1392p60,
VESA_1856x1392p75,
VESA_1920x1200p60R,
VESA_1920x1200p60,
VESA_1920x1200p75,
VESA_1920x1200p85,
VESA_1920x1440p60,
VESA_1920x1440p75,
} MODE_ID ;
//~jj_tseng@chipadvanced.com
//////////////////////////////////////////////////////////////////////
// External Interface
//////////////////////////////////////////////////////////////////////
void InitIT6613();
void HDMITX_InitInstance(INSTANCE *pInstance) ;
BOOL EnableVideoOutput(VIDEOPCLKLEVEL level,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) ;
BOOL SetupVideoInputSignal(BYTE inputSignalType) ;
#ifdef SUPPORT_DEGEN
BOOL ProgramDEGenModeByID(MODE_ID id,BYTE bInputSignalType) ;
#endif // SUPPORT_DEGEN
#ifdef SUPPORT_SYNCEMBEDDED
BOOL ProgramSyncEmbeddedVideoMode(BYTE VIC,BYTE bInputType) ;
#endif
BOOL EnableAudioOutput(unsigned long VideoPixelClock,BYTE bAudioSampleFreq,BYTE ChannelNumber,BYTE bAudSWL,BYTE bSPDIF) ;
void DisableIT6613() ;
void DisableVideoOutput() ;
void DisableAudioOutput() ;
BOOL GetEDIDData(int EDIDBlockID,BYTE *pEDIDData);
BOOL CheckHDMITX(BYTE *pHPD,BYTE *pHPDChange) ;
BOOL EnableHDCP(BYTE bEnable) ;
BOOL EnableAVIInfoFrame(BYTE bEnable,BYTE *pAVIInfoFrame);
BOOL EnableAudioInfoFrame(BYTE bEnable,BYTE *pAudioInfoFrame);
// BOOL EnableVideoOutputIndirect(BYTE xCnt,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) ;
void SetAVMute(BYTE bEnable) ;
void SetOutputColorDepthPhase(BYTE ColorDepth,BYTE bPhase) ;
void Get6613Reg(BYTE *pReg) ;
////////////////////////////////////////////////////////////////////
// Required Interfance
////////////////////////////////////////////////////////////////////
BYTE I2C_Read_Byte(BYTE Addr,BYTE RegAddr);
SYS_STATUS I2C_Write_Byte(BYTE Addr,BYTE RegAddr,BYTE Data);
SYS_STATUS I2C_Read_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) ;
SYS_STATUS I2C_Write_ByteN(BYTE Addr,BYTE RegAddr,BYTE *pData,int N) ;
BYTE HDMITX_ReadI2C_Byte(BYTE RegAddr);
SYS_STATUS HDMITX_WriteI2C_Byte(BYTE RegAddr,BYTE val);
SYS_STATUS HDMITX_ReadI2C_ByteN(BYTE RegAddr,BYTE *pData,int N);
SYS_STATUS HDMITX_WriteI2C_ByteN(BYTE RegAddr,BYTE *pData,int N);
#endif // _IT6613_H_
+550
View File
@@ -0,0 +1,550 @@
///////////////////////////////////////////////////////////////////////////////
// This is the sample program for CAT6611 driver usage.
///////////////////////////////////////////////////////////////////////////////
#include "hdmitx.h"
#include "it6613_sys.h" // richard add
#include "edid.h" // richard add
extern int TX_HDP; // richard add
int gEnableColorDepth = 1; //richard add
////////////////////////////////////////////////////////////////////////////////
// EDID
////////////////////////////////////////////////////////////////////////////////
static _XDATA unsigned char EDID_Buf[128] ;
// richard static RX_CAP _XDATA RxCapability ;
RX_CAP _XDATA RxCapability ;
// richard static BOOL bChangeMode = FALSE ;
BOOL bChangeMode = FALSE ;
_XDATA AVI_InfoFrame AviInfo;
_XDATA Audio_InfoFrame AudioInfo ;
////////////////////////////////////////////////////////////////////////////////
// Program utility.
////////////////////////////////////////////////////////////////////////////////
// move to .h BOOL ParseEDID() ;
// richard static BOOL ParseCEAEDID(BYTE *pCEAEDID) ;
void ConfigAVIInfoFrame(BYTE VIC, BYTE pixelrep) ;
void ConfigAudioInfoFrm() ;
#ifndef SUPPORT_SYNCEMB
_IDATA BYTE bInputColorMode = F_MODE_RGB444; //F_MODE_RGB444;
_IDATA BYTE bInputSignalType = 0 ;
// BYTE bInputSignalType = T_MODE_INDDR ; // for DDR mode input
#else
// BYTE bInputSignalType = T_MODE_SYNCEMB ; // for 16 bit sync embedded
_IDATA BYTE bInputColorMode = F_MODE_YUV422 ;
_IDATA BYTE bInputSignalType = T_MODE_SYNCEMB | T_MODE_CCIR656 ; // for 16 bit sync embedded
#endif // SUPPORT_SYNCEMB
_IDATA BYTE iVideoModeSelect=0 ;
_IDATA BYTE bOutputColorMode = F_MODE_RGB444; //F_MODE_RGB444 ;
_XDATA ULONG VideoPixelClock ;
_XDATA BYTE VIC ; // 480p60
_XDATA BYTE pixelrep ; // no pixelrepeating
_XDATA HDMI_Aspec aspec ;
_XDATA HDMI_Colorimetry Colorimetry ;
BOOL bHDMIMode, bAudioEnable ;
////////////////////////////////////////////////////////////////////////////////
// Function Body.
////////////////////////////////////////////////////////////////////////////////
//richard, move to .h void HDMITX_ChangeDisplayOption(HDMI_Video_Type VideoMode, HDMI_OutputColorMode OutputColorMode) ;
//richard, move to .hvoid HDMITX_SetOutput() ;
//richard richard, move to .h void HDMITX_DevLoopProc() ;
void
HDMITX_SetOutput()
{
VIDEOPCLKLEVEL level ;
unsigned long TMDSClock = VideoPixelClock*(pixelrep+1);
#ifdef SUPPORT_SYNCEMB
ProgramSyncEmbeddedVideoMode(VIC, bInputSignalType) ; // inf CCIR656 input
#endif
//TMDSClock = 745000000; //????? richard
if( TMDSClock>80000000 )
{
level = PCLK_HIGH ;
}
else if(TMDSClock>20000000)
{
level = PCLK_MEDIUM ;
}
else
{
level = PCLK_LOW ;
}
//BOOL EnableVideoOutput(VIDEOPCLKLEVEL level,BYTE inputColorMode,BYTE outputColorMode,BYTE bHDMI) ;
//EnableVideoOutput(level,bInputColorMode, bInputSignalType, bOutputColorMode,bHDMIMode) ;
EnableVideoOutput(level,bInputColorMode, bOutputColorMode,bHDMIMode) ; // richard modify
if( bHDMIMode )
{
OS_PRINTF("ConfigAVIInfoFrame, VIC=%d\n", VIC);
ConfigAVIInfoFrame(VIC, pixelrep) ;
EnableHDCP(TRUE) ;
if( bAudioEnable )
{
//BOOL EnableAudioOutput(ULONG VideoPixelClock,BYTE bAudioSampleFreq,BYTE ChannelNumber,BYTE bAudSWL,BYTE bSPDIF)
//EnableAudioOutput(TMDSClock,48000, 2, FALSE);
bool bSPDIF = FALSE;
EnableAudioOutput(TMDSClock,AUDFS_48KHz, 2, 16, bSPDIF); // richard modify
ConfigAudioInfoFrm() ;
}
}
SetAVMute(FALSE) ;
bChangeMode = FALSE ;
}
void
HDMITX_ChangeDisplayOption(HDMI_Video_Type OutputVideoTiming, HDMI_OutputColorMode OutputColorMode)
{
//HDMI_Video_Type t=HDMI_480i60_16x9;
switch(OutputVideoTiming)
{
case HDMI_640x480p60:
VIC = 1 ;
VideoPixelClock = 25000000 ;
pixelrep = 0 ;
aspec = HDMI_4x3 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_480p60:
VIC = 2 ;
VideoPixelClock = 27000000 ;
pixelrep = 0 ;
aspec = HDMI_4x3 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_480p60_16x9:
VIC = 3 ;
VideoPixelClock = 27000000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_720p60:
VIC = 4 ;
VideoPixelClock = 74250000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_1080i60:
VIC = 5 ;
VideoPixelClock = 74250000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_480i60:
VIC = 6 ;
VideoPixelClock = 13500000 ;
pixelrep = 1 ;
aspec = HDMI_4x3 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_480i60_16x9:
VIC = 7 ;
VideoPixelClock = 13500000 ;
pixelrep = 1 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_1080p60:
VIC = 16 ;
VideoPixelClock = 148500000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_576p50:
VIC = 17 ;
VideoPixelClock = 27000000 ;
pixelrep = 0 ;
aspec = HDMI_4x3 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_576p50_16x9:
VIC = 18 ;
VideoPixelClock = 27000000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_720p50:
VIC = 19 ;
VideoPixelClock = 74250000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_1080i50:
VIC = 20 ;
VideoPixelClock = 74250000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_576i50:
VIC = 21 ;
VideoPixelClock = 13500000 ;
pixelrep = 1 ;
aspec = HDMI_4x3 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_576i50_16x9:
VIC = 22 ;
VideoPixelClock = 13500000 ;
pixelrep = 1 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU601 ;
break ;
case HDMI_1080p50:
VIC = 31 ;
VideoPixelClock = 148500000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_1080p24:
VIC = 32 ;
VideoPixelClock = 74250000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_1080p25:
VIC = 33 ;
VideoPixelClock = 74250000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_1080p30:
VIC = 34 ;
VideoPixelClock = 74250000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU709 ;
break ;
case HDMI_1080i120:// richard add
VIC = 46 ;
VideoPixelClock = 148500000 ;
pixelrep = 0 ;
aspec = HDMI_16x9 ;
Colorimetry = HDMI_ITU601 ;
break ;
default:
VIC = 0; // richard add
bChangeMode = FALSE ;
return ;
}
switch(OutputColorMode)
{
case HDMI_YUV444:
bOutputColorMode = F_MODE_YUV444 ;
break ;
case HDMI_YUV422:
bOutputColorMode = F_MODE_YUV422 ;
break ;
case HDMI_RGB444:
default:
bOutputColorMode = F_MODE_RGB444 ;
break ;
}
if( Colorimetry == HDMI_ITU709 )
{
bInputColorMode |= F_VIDMODE_ITU709 ;
}
else
{
bInputColorMode &= ~F_VIDMODE_ITU709 ;
}
if( Colorimetry != HDMI_640x480p60)
{
bInputColorMode |= F_VIDMODE_16_235 ;
}
else
{
bInputColorMode &= ~F_VIDMODE_16_235 ;
}
bChangeMode = TRUE ;
}
void
ConfigAVIInfoFrame(BYTE VIC, BYTE pixelrep)
{
// AVI_InfoFrame AviInfo;
AviInfo.pktbyte.AVI_HB[0] = AVI_INFOFRAME_TYPE|0x80 ;
AviInfo.pktbyte.AVI_HB[1] = AVI_INFOFRAME_VER ;
AviInfo.pktbyte.AVI_HB[2] = AVI_INFOFRAME_LEN ;
switch(bOutputColorMode)
{
case F_MODE_YUV444:
// AviInfo.info.ColorMode = 2 ;
AviInfo.pktbyte.AVI_DB[0] = (2<<5)|(1<<4) ;
break ;
case F_MODE_YUV422:
// AviInfo.info.ColorMode = 1 ;
AviInfo.pktbyte.AVI_DB[0] = (1<<5)|(1<<4) ;
break ;
case F_MODE_RGB444:
default:
// AviInfo.info.ColorMode = 0 ;
AviInfo.pktbyte.AVI_DB[0] = (0<<5)|(1<<4) ;
break ;
}
AviInfo.pktbyte.AVI_DB[1] = 8 ;
AviInfo.pktbyte.AVI_DB[1] |= (aspec != HDMI_16x9)?(1<<4):(2<<4) ; // 4:3 or 16:9
AviInfo.pktbyte.AVI_DB[1] |= (Colorimetry != HDMI_ITU709)?(1<<6):(2<<6) ; // 4:3 or 16:9
AviInfo.pktbyte.AVI_DB[2] = 0 ;
AviInfo.pktbyte.AVI_DB[3] = VIC ;
AviInfo.pktbyte.AVI_DB[4] = pixelrep & 3 ;
AviInfo.pktbyte.AVI_DB[5] = 0 ;
AviInfo.pktbyte.AVI_DB[6] = 0 ;
AviInfo.pktbyte.AVI_DB[7] = 0 ;
AviInfo.pktbyte.AVI_DB[8] = 0 ;
AviInfo.pktbyte.AVI_DB[9] = 0 ;
AviInfo.pktbyte.AVI_DB[10] = 0 ;
AviInfo.pktbyte.AVI_DB[11] = 0 ;
AviInfo.pktbyte.AVI_DB[12] = 0 ;
EnableAVIInfoFrame(TRUE, (unsigned char *)&AviInfo) ;
}
////////////////////////////////////////////////////////////////////////////////
// Function: ConfigAudioInfoFrm
// Parameter: NumChannel, number from 1 to 8
// Return: ER_SUCCESS for successfull.
// Remark: Evaluate. The speakerplacement is only for reference.
// For production, the caller of SetAudioInfoFrame should program
// Speaker placement by actual status.
// Side-Effect:
////////////////////////////////////////////////////////////////////////////////
void
ConfigAudioInfoFrm()
{
int i ;
ErrorF("ConfigAudioInfoFrm(%d)\n",2) ;
AudioInfo.pktbyte.AUD_HB[0] = AUDIO_INFOFRAME_TYPE ;
AudioInfo.pktbyte.AUD_HB[1] = 1 ;
AudioInfo.pktbyte.AUD_HB[2] = AUDIO_INFOFRAME_LEN ;
AudioInfo.pktbyte.AUD_DB[0] = 1 ;
for( i = 1 ;i < AUDIO_INFOFRAME_LEN ; i++ )
{
AudioInfo.pktbyte.AUD_DB[i] = 0 ;
}
EnableAudioInfoFrame(TRUE, (unsigned char *)&AudioInfo) ;
}
/////////////////////////////////////////////////////////////////////
// ParseEDID()
// Check EDID check sum and EDID 1.3 extended segment.
/////////////////////////////////////////////////////////////////////
BOOL
ParseEDID()
{
// collect the EDID ucdata of segment 0
BYTE CheckSum ;
BYTE BlockCount ;
BOOL err ;
BOOL bValidCEA = FALSE ;
int i ;
RxCapability.ValidCEA = FALSE ;
// richard GetEDIDData(0, EDID_Buf);
if (!GetEDIDData(0, EDID_Buf))
return FALSE;
for( i = 0, CheckSum = 0 ; i < 128 ; i++ )
{
CheckSum += EDID_Buf[i] ; CheckSum &= 0xFF ;
}
//Eep_Write(0x80, 0x80, EDID_Buf) ;
if( CheckSum != 0 ) // 128-byte EDID sum shall equal zero
{
return FALSE ;
}
// check EDID Header
if( EDID_Buf[0] != 0x00 ||
EDID_Buf[1] != 0xFF ||
EDID_Buf[2] != 0xFF ||
EDID_Buf[3] != 0xFF ||
EDID_Buf[4] != 0xFF ||
EDID_Buf[5] != 0xFF ||
EDID_Buf[6] != 0xFF ||
EDID_Buf[7] != 0x00)
{
return FALSE ;
}
BlockCount = EDID_Buf[0x7E] ; // Extention Flash: Number of 128-byte EDID extesion blocks to follow
if( BlockCount == 0 )
{
return TRUE ; // do nothing.
}
else if ( BlockCount > 4 )
{
BlockCount = 4 ;
}
// read all segment for test
for( i = 1 ; i <= BlockCount ; i++ )
{
err = GetEDIDData(i, EDID_Buf) ;
if( err )
{
if( !bValidCEA && EDID_Buf[0] == 0x2 && EDID_Buf[1] == 0x3 ) //EDID_Buf[0] == 0x2 ==> Additional timing data type 2
{
// richard change
//err = ParseCEAEDID(EDID_Buf) ;
err = ParseCEAEDID(EDID_Buf, &RxCapability);
if( err )
{
if(RxCapability.IEEEOUI==0x0c03)
{
RxCapability.ValidHDMI = TRUE ;
bValidCEA = TRUE ;
}
else
{
RxCapability.ValidHDMI = FALSE ;
}
}
}
}
}
return err?FALSE:TRUE ; // richard modify
}
/* richard: use the one defined edid.c
static BOOL
ParseCEAEDID(BYTE *pCEAEDID)
{
BYTE offset,End ;
BYTE count ;
BYTE tag ;
int i ;
// richard if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) return ER_SUCCESS ; // not a CEA BLOCK.
if( pCEAEDID[0] != 0x02 || pCEAEDID[1] != 0x03 ) // not a CEA BLOCK.
return FALSE;
End = pCEAEDID[2] ; // CEA description.
RxCapability.VideoMode = pCEAEDID[3] ;
RxCapability.VDOModeCount = 0 ;
RxCapability.idxNativeVDOMode = 0xff ;
for( offset = 4 ; offset < End ; )
{
tag = pCEAEDID[offset] >> 5 ;
count = pCEAEDID[offset] & 0x1f ;
switch( tag )
{
case 0x01: // Audio Data Block ;
RxCapability.AUDDesCount = count/3 ;
offset++ ;
for( i = 0 ; i < RxCapability.AUDDesCount ; i++ )
{
RxCapability.AUDDes[i].uc[0] = pCEAEDID[offset++] ;
RxCapability.AUDDes[i].uc[1] = pCEAEDID[offset++] ;
RxCapability.AUDDes[i].uc[2] = pCEAEDID[offset++] ;
}
break ;
case 0x02: // Video Data Block ;
//RxCapability.VDOModeCount = 0 ;
offset ++ ;
for( i = 0,RxCapability.idxNativeVDOMode = 0xff ; i < count ; i++, offset++ )
{
BYTE VIC ;
VIC = pCEAEDID[offset] & (~0x80) ;
// if( FindModeTableEntryByVIC(VIC) != -1 )
{
RxCapability.VDOMode[RxCapability.VDOModeCount] = VIC ;
if( pCEAEDID[offset] & 0x80 )
{
RxCapability.idxNativeVDOMode = (BYTE)RxCapability.VDOModeCount ;
iVideoModeSelect = RxCapability.VDOModeCount ;
}
RxCapability.VDOModeCount++ ;
}
}
break ;
case 0x03: // Vendor Specific Data Block ;
offset ++ ;
RxCapability.IEEEOUI = (ULONG)pCEAEDID[offset+2] ;
RxCapability.IEEEOUI <<= 8 ;
RxCapability.IEEEOUI += (ULONG)pCEAEDID[offset+1] ;
RxCapability.IEEEOUI <<= 8 ;
RxCapability.IEEEOUI += (ULONG)pCEAEDID[offset] ;
offset += count ; // ignore the remaind.
break ;
case 0x04: // Speaker Data Block ;
offset ++ ;
RxCapability.SpeakerAllocBlk.uc[0] = pCEAEDID[offset] ;
RxCapability.SpeakerAllocBlk.uc[1] = pCEAEDID[offset+1] ;
RxCapability.SpeakerAllocBlk.uc[2] = pCEAEDID[offset+2] ;
offset += 3 ;
break ;
case 0x05: // VESA Data Block ;
offset += count+1 ;
break ;
case 0x07: // Extended Data Block ;
offset += count+1 ; //ignore
break ;
default:
offset += count+1 ; // ignore
}
}
RxCapability.ValidCEA = TRUE ;
return TRUE ;
}
*/
@@ -0,0 +1,63 @@
#ifndef _CAT6611_SYS_H_
#define _CAT6611_SYS_H_
////////////////////////////////////////////////////////////////////////////////
// Internal Data Type
////////////////////////////////////////////////////////////////////////////////
typedef enum tagHDMI_Video_Type {
HDMI_Unkown = 0 ,
HDMI_640x480p60 = 1 ,
HDMI_480p60,
HDMI_480p60_16x9,
HDMI_720p60,
HDMI_1080i60,
HDMI_480i60,
HDMI_480i60_16x9,
HDMI_1080p60 = 16,
HDMI_576p50,
HDMI_576p50_16x9,
HDMI_720p50 = 19,
HDMI_1080i50,
HDMI_576i50,
HDMI_576i50_16x9,
HDMI_1080p50 = 31,
HDMI_1080p24,
HDMI_1080p25,
HDMI_1080p30,
HDMI_1080i120 = 46, // richard add
} HDMI_Video_Type ;
typedef enum tagHDMI_Aspec {
HDMI_4x3 ,
HDMI_16x9
} HDMI_Aspec;
typedef enum tagHDMI_OutputColorMode {
HDMI_RGB444,
HDMI_YUV444,
HDMI_YUV422
} HDMI_OutputColorMode ;
typedef enum tagHDMI_Colorimetry {
HDMI_ITU601,
HDMI_ITU709
} HDMI_Colorimetry ;
///////////////////////////////////////////////////////////////////////
// Output Mode Type
///////////////////////////////////////////////////////////////////////
#define RES_ASPEC_4x3 0
#define RES_ASPEC_16x9 1
#define F_MODE_REPT_NO 0
#define F_MODE_REPT_TWICE 1
#define F_MODE_REPT_QUATRO 3
#define F_MODE_CSC_ITU601 0
#define F_MODE_CSC_ITU709 1
void HDMITX_ChangeDisplayOption(HDMI_Video_Type VideoMode, HDMI_OutputColorMode OutputColorMode);
void HDMITX_SetOutput();
#endif // _CAT6611_SYS_H_
+329
View File
@@ -0,0 +1,329 @@
#ifndef _TYPEDEF_H_
#define _TYPEDEF_H_
//////////////////////////////////////////////////
// data type
//////////////////////////////////////////////////
#ifdef _MCU_
typedef bit BOOL ;
#define _CODE //richard code
#define _IDATA //richard idata
#define _XDATA //richard xdata
#else
typedef int BOOL ;
#define _CODE
#define _IDATA
#define _XDATA
#endif // _MCU_
typedef char CHAR,*PCHAR ;
typedef unsigned char uchar,*puchar ;
typedef unsigned char UCHAR,*PUCHAR ;
typedef unsigned char byte,*pbyte ;
typedef unsigned char BYTE,*PBYTE ;
typedef short SHORT,*PSHORT ;
typedef unsigned short ushort,*pushort ;
typedef unsigned short USHORT,*PUSHORT ;
typedef unsigned short word,*pword ;
typedef unsigned short WORD,*PWORD ;
typedef long LONG,*PLONG ;
typedef unsigned long ulong,*pulong ;
typedef unsigned long ULONG,*PULONG ;
typedef unsigned long dword,*pdword ;
typedef unsigned long DWORD,*PDWORD ;
#define FALSE 0
#define TRUE 1
#define SUCCESS 0
#define FAIL -1
#define ON 1
#define OFF 0
typedef enum _SYS_STATUS {
ER_SUCCESS = 0,
ER_FAIL,
ER_RESERVED
} SYS_STATUS ;
#define abs(x) (((x)>=0)?(x):(-(x)))
typedef enum _Video_State_Type {
VSTATE_PwrOff = 0,
VSTATE_SyncWait ,
VSTATE_SWReset,
VSTATE_SyncChecking,
VSTATE_HDCPSet,
VSTATE_HDCP_Reset,
VSTATE_ModeDetecting,
VSTATE_VideoOn,
VSTATE_Reserved
} Video_State_Type ;
typedef enum _Audio_State_Type {
ASTATE_AudioOff = 0,
ASTATE_RequestAudio ,
ASTATE_ResetAudio,
ASTATE_WaitForReady,
ASTATE_AudioOn ,
ASTATE_Reserved
} Audio_State_Type ;
typedef enum _TXVideo_State_Type {
TXVSTATE_Unplug = 0,
TXVSTATE_HPD,
TXVSTATE_WaitForMode,
TXVSTATE_WaitForVStable,
TXVSTATE_VideoInit,
TXVSTATE_VideoSetup,
TXVSTATE_VideoOn,
TXVSTATE_Reserved
} TXVideo_State_Type ;
typedef enum _TXAudio_State_Type {
TXASTATE_AudioOff = 0,
TXASTATE_AudioPrepare,
TXASTATE_AudioOn,
TXASTATE_AudioFIFOFail,
TXASTATE_Reserved
} TXAudio_State_Type ;
typedef enum {
PCLK_LOW = 0 ,
PCLK_MEDIUM,
PCLK_HIGH
} VIDEOPCLKLEVEL ;
///////////////////////////////////////////////////////////////////////
// Video Data Type
///////////////////////////////////////////////////////////////////////
#define F_MODE_RGB24 0
#define F_MODE_RGB444 0
#define F_MODE_YUV422 1
#define F_MODE_YUV444 2
#define F_MODE_CLRMOD_MASK 3
#define F_MODE_INTERLACE 1
#define F_MODE_ITU709 (1<<4)
#define F_MODE_ITU601 0
#define F_MODE_0_255 0
#define F_MODE_16_235 (1<<5)
#define F_MODE_EN_UDFILT (1<<6) // output mode only,and loaded from EEPROM
#define F_MODE_EN_DITHER (1<<7) // output mode only,and loaded from EEPROM
#define F_VIDMODE_ITU709 F_MODE_ITU709 // richard add
#define F_VIDMODE_16_235 F_MODE_16_235 // richard add
typedef union _VideoFormatCode
{
struct _VFC
{
BYTE colorfmt:2 ;
BYTE interlace:1 ;
BYTE Colorimetry:1 ;
BYTE Quantization:1 ;
BYTE UpDownFilter:1 ;
BYTE Dither:1 ;
} VFCCode ;
unsigned char VFCByte ;
} VideoFormatCode ;
#define T_MODE_CCIR656 (1<<0)
#define T_MODE_SYNCEMB (1<<1)
#define T_MODE_INDDR (1<<2)
#define T_MODE_PCLKDIV2 (1<<3)
#define T_MODE_DEGEN (1<<4)
#define T_MODE_SYNCGEN (1<<5)
//////////////////////////////////////////////////////////////////
// Audio relate definition and macro.
//////////////////////////////////////////////////////////////////
// for sample clock
#define AUDFS_22p05KHz 4
#define AUDFS_44p1KHz 0
#define AUDFS_88p2KHz 8
#define AUDFS_176p4KHz 12
#define AUDFS_24KHz 6
#define AUDFS_48KHz 2
#define AUDFS_96KHz 10
#define AUDFS_192KHz 14
#define AUDFS_32KHz 3
#define AUDFS_OTHER 1
// Audio Enable
#define ENABLE_SPDIF (1<<4)
#define ENABLE_I2S_SRC3 (1<<3)
#define ENABLE_I2S_SRC2 (1<<2)
#define ENABLE_I2S_SRC1 (1<<1)
#define ENABLE_I2S_SRC0 (1<<0)
#define AUD_SWL_NOINDICATE 0x0
#define AUD_SWL_16 0x2
#define AUD_SWL_17 0xC
#define AUD_SWL_18 0x4
#define AUD_SWL_20 0xA // for maximum 20 bit
#define AUD_SWL_21 0xD
#define AUD_SWL_22 0x5
#define AUD_SWL_23 0x9
#define AUD_SWL_24 0xB
/////////////////////////////////////////////////////////////////////
// Packet and Info Frame definition and datastructure.
/////////////////////////////////////////////////////////////////////
#define VENDORSPEC_INFOFRAME_TYPE 0x01
#define AVI_INFOFRAME_TYPE 0x02
#define SPD_INFOFRAME_TYPE 0x03
#define AUDIO_INFOFRAME_TYPE 0x04
#define MPEG_INFOFRAME_TYPE 0x05
#define VENDORSPEC_INFOFRAME_VER 0x01
#define AVI_INFOFRAME_VER 0x02
#define SPD_INFOFRAME_VER 0x01
#define AUDIO_INFOFRAME_VER 0x01
#define MPEG_INFOFRAME_VER 0x01
#define VENDORSPEC_INFOFRAME_LEN 8
#define AVI_INFOFRAME_LEN 13
#define SPD_INFOFRAME_LEN 25
#define AUDIO_INFOFRAME_LEN 10
#define MPEG_INFOFRAME_LEN 10
#define ACP_PKT_LEN 9
#define ISRC1_PKT_LEN 16
#define ISRC2_PKT_LEN 16
typedef union _AVI_InfoFrame
{
struct {
BYTE Type ;
BYTE Ver ;
BYTE Len ;
BYTE Scan:2 ;
BYTE BarInfo:2 ;
BYTE ActiveFmtInfoPresent:1 ;
BYTE ColorMode:2 ;
BYTE FU1:1 ;
BYTE ActiveFormatAspectRatio:4 ;
BYTE PictureAspectRatio:2 ;
BYTE Colorimetry:2 ;
BYTE Scaling:2 ;
BYTE FU2:6 ;
BYTE VIC:7 ;
BYTE FU3:1 ;
BYTE PixelRepetition:4 ;
BYTE FU4:4 ;
SHORT Ln_End_Top ;
SHORT Ln_Start_Bottom ;
SHORT Pix_End_Left ;
SHORT Pix_Start_Right ;
} info ;
struct {
BYTE AVI_HB[3] ;
BYTE AVI_DB[AVI_INFOFRAME_LEN] ;
} pktbyte ;
} AVI_InfoFrame ;
typedef union _Audio_InfoFrame {
struct {
BYTE Type ;
BYTE Ver ;
BYTE Len ;
BYTE AudioChannelCount:3 ;
BYTE RSVD1:1 ;
BYTE AudioCodingType:4 ;
BYTE SampleSize:2 ;
BYTE SampleFreq:3 ;
BYTE Rsvd2:3 ;
BYTE FmtCoding ;
BYTE SpeakerPlacement ;
BYTE Rsvd3:3 ;
BYTE LevelShiftValue:4 ;
BYTE DM_INH:1 ;
} info ;
struct {
BYTE AUD_HB[3] ;
BYTE AUD_DB[AUDIO_INFOFRAME_LEN] ;
} pktbyte ;
} Audio_InfoFrame ;
typedef union _MPEG_InfoFrame {
struct {
BYTE Type ;
BYTE Ver ;
BYTE Len ;
ULONG MpegBitRate ;
BYTE MpegFrame:2 ;
BYTE Rvsd1:2 ;
BYTE FieldRepeat:1 ;
BYTE Rvsd2:3 ;
} info ;
struct {
BYTE MPG_HB[3] ;
BYTE MPG_DB[MPEG_INFOFRAME_LEN] ;
} pktbyte ;
} MPEG_InfoFrame ;
// Source Product Description
typedef union _SPD_InfoFrame {
struct {
BYTE Type ;
BYTE Ver ;
BYTE Len ;
char VN[8] ; // vendor name character in 7bit ascii characters
char PD[16] ; // product description character in 7bit ascii characters
BYTE SourceDeviceInfomation ;
} info ;
struct {
BYTE SPD_HB[3] ;
BYTE SPD_DB[SPD_INFOFRAME_LEN] ;
} pktbyte ;
} SPD_InfoFrame ;
///////////////////////////////////////////////////////////////////////////
// Using for interface.
///////////////////////////////////////////////////////////////////////////
struct VideoTiming {
ULONG VideoPixelClock ;
BYTE VIC ;
BYTE pixelrep ;
BYTE outputVideoMode ;
} ;
#endif // _TYPEDEF_H_
@@ -0,0 +1 @@
:00000001FF
@@ -0,0 +1 @@
set_global_assignment -name SEARCH_PATH $::quartus(qip_path)
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<simPackage>
<file path="hdl_sim/sys_onchip_memory2_0.dat" type="DAT" initParamName="INIT_FILE" memoryPath="onchip_memory2_0" />
<file path="epcq_controller_0.hex" type="HEX" memoryPath="epcq_controller_0" />
<file path="sys_onchip_memory2_0.hex" type="HEX" initParamName="INIT_FILE" memoryPath="onchip_memory2_0" />
</simPackage>
File diff suppressed because it is too large Load Diff
+108
View File
@@ -0,0 +1,108 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include "lcd.h"
#include "alt_types.h"
#include "altera_avalon_pio_regs.h"
#define LCD_CMD 0x00
#define LCD_DATA 0x40
#define WRDELAY 20
#define CLEARDELAY 800
void lcd_init() {
alt_u8 lcd_ctrl = 0x00;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x38); // function set
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x39); // function set, select extended table (IS=1)
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x14); // osc freq
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x71); // contrast set
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x5E); // power/icon/cont
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x6D); // follower control
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x0C); // display on
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x01); // clear display
usleep(CLEARDELAY);
SPI_write(I2CA_BASE, 0x06); // entry mode set
usleep(WRDELAY);
SPI_write(I2CA_BASE, 0x02); // return home
usleep(CLEARDELAY);
lcd_ctrl |= LCD_CS_N;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
}
void lcd_write(char *row1, char *row2) {
alt_u8 i, rowlen;
alt_u8 lcd_ctrl = 0x00;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
SPI_write(I2CA_BASE, 0x01); // clear display
usleep(CLEARDELAY);
// Set RS to enter data write mode
lcd_ctrl |= LCD_RS;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
//ensure no empty row
rowlen = strnlen(row1, LCD_ROW_LEN);
if (rowlen == 0) {
strncpy(row1, " ", LCD_ROW_LEN+1);
rowlen++;
}
for (i=0; i<rowlen; i++) {
SPI_write(I2CA_BASE, row1[i]);
usleep(WRDELAY);
}
// second row
lcd_ctrl &= ~LCD_RS;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
SPI_write(I2CA_BASE, (1<<7)|0x40);
usleep(WRDELAY);
lcd_ctrl |= LCD_RS;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
//ensure no empty row
rowlen = strnlen(row2, LCD_ROW_LEN);
if (rowlen == 0) {
strncpy(row2, " ", LCD_ROW_LEN+1);
rowlen++;
}
for (i=0; i<rowlen; i++) {
SPI_write(I2CA_BASE, row2[i]);
usleep(WRDELAY);
}
lcd_ctrl |= LCD_CS_N;
IOWR_ALTERA_AVALON_PIO_DATA(PIO_5_BASE, lcd_ctrl);
}
+39
View File
@@ -0,0 +1,39 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef LCD_H_
#define LCD_H_
#include "system.h"
#include <stdio.h>
#include "sysconfig.h"
#define LCD_ROW_LEN 16
//#define I2C_DEBUG
#define I2CA_BASE I2C_OPENCORES_0_BASE
#define LCD_CS_N (1<<0)
#define LCD_RS (1<<1)
void lcd_init();
void lcd_write(char *row1, char *row2);
#endif /* LCD_H_ */
+34
View File
@@ -0,0 +1,34 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef SYSCONFIG_H_
#define SYSCONFIG_H_
#ifndef DEBUG
#define OS_PRINTF(...)
#define ErrorF(...)
#define printf(...)
#else
#define OS_PRINTF printf
#define ErrorF printf
// use reduced printf
//#define printf alt_printf
#endif
#endif /* SYSCONFIG_H_ */
+81
View File
@@ -0,0 +1,81 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "i2c_opencores.h"
#include "ths7353.h"
inline alt_u32 ths_readreg(alt_u8 channel) {
//Phase 1
I2C_start(I2CA_BASE, THS_BASE, 0);
I2C_write(I2CA_BASE, channel, 1);
//Phase 2
I2C_start(I2CA_BASE, THS_BASE, 1);
return I2C_read(I2CA_BASE,1);
}
inline void ths_writereg(alt_u8 channel, alt_u8 data) {
I2C_start(I2CA_BASE, THS_BASE, 0);
I2C_write(I2CA_BASE, channel, 0);
I2C_write(I2CA_BASE, data, 1);
}
int ths_init() {
//Avoid random FIFO state (see datasheet p.37)
I2C_write(I2CA_BASE, 0x00, 0);
usleep(10);
//Initialize all channels
ths_writereg(THS_CH1, (THS_LPF_DEFAULT<<THS_LPF_OFFS));
ths_writereg(THS_CH2, (THS_LPF_DEFAULT<<THS_LPF_OFFS));
ths_writereg(THS_CH3, (THS_LPF_DEFAULT<<THS_LPF_OFFS));
return (ths_readreg(THS_CH1) == (THS_LPF_DEFAULT<<THS_LPF_OFFS));
}
void ths_set_lpf(alt_u8 val) {
alt_u8 status = ths_readreg(THS_CH1) & ~THS_LPF_MASK;
status |= (val<<THS_LPF_OFFS);
ths_writereg(THS_CH1, status);
ths_writereg(THS_CH2, status);
ths_writereg(THS_CH3, status);
printf("THS LPF value set to 0x%x\n", val);
}
void ths_source_sel(ths_input_t input, alt_u8 lpf) {
alt_u8 status = ths_readreg(THS_CH1) & ~(THS_SRC_MASK|THS_MODE_MASK);
//alt_u8 status = 0x00;
if (input == THS_STANDBY)
status |= (THS_MODE_AVMUTE<<THS_MODE_OFFS);
else
status |= (THS_MODE_AC_BIAS | (input<<THS_SRC_OFFS));
//status |= (lpf<<THS_LPF_OFFS);
ths_writereg(THS_CH1, status);
ths_writereg(THS_CH2, status);
ths_writereg(THS_CH3, status);
printf("THS source set to %u\n", input);
}
+63
View File
@@ -0,0 +1,63 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef THS7353_H_
#define THS7353_H_
#include "sysconfig.h"
#define THS_BASE (0x58>>1)
#define THS_CH1 0x01
#define THS_CH2 0x02
#define THS_CH3 0x03
typedef enum {
THS_INPUT_A = 0,
THS_INPUT_B = 1,
THS_STANDBY = 2
} ths_input_t;
#define THS_LPF_DEFAULT 0x3
#define THS_LPF_MASK 0x18
#define THS_LPF_OFFS 3
#define THS_SRC_MASK 0x20
#define THS_SRC_OFFS 5
#define THS_MODE_MASK 0x7
#define THS_MODE_OFFS 0
#define THS_MODE_DISABLE 0
#define THS_MODE_AVMUTE 1
#define THS_MODE_AC_BIAS 4
#define THS_MODE_STC 6 //mid bias
#define THS_LPF_BYPASS 0x03
//#define I2C_DEBUG
#define I2CA_BASE I2C_OPENCORES_0_BASE
int ths_init();
void ths_set_lpf(alt_u8 val);
void ths_source_sel(ths_input_t input, alt_u8 lpf);
#endif /* THS7353_H_ */
+401
View File
@@ -0,0 +1,401 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "i2c_opencores.h"
#include "tvp7002.h"
//#define SYNCBYPASS // Bypass VGA syncs (for debug - needed for interlace?)
//#define EXTADCCLK // Use external ADC clock (external osc)
//#define ADCPOWERDOWN // Power-down ADCs
//#define PLLPOSTDIV // Double-rate PLL with div-by-2 (decrease jitter?)
/* Y'Pb'Pr' to R'G'B' CSC coefficients.
*
* Coefficients from "Colour Space Conversions" (http://www.poynton.com/PDFs/coloureq.pdf).
*/
const ypbpr_to_rgb_csc_t csc_coeffs[] = {
{ "Rec. 601", 0x2000, 0x0000, 0x2CE5, 0x2000, 0xF4FD, 0xE926, 0x2000, 0x38BC, 0x0000 }, // eq. 101
{ "Rec. 709", 0x2000, 0x0000, 0x323E, 0x2000, 0xFA04, 0xF113, 0x2000, 0x3B61, 0x0000 }, // eq. 105
};
extern mode_data_t video_modes[];
static inline void tvp_set_hpllcoast(alt_u8 pre, alt_u8 post) {
tvp_writereg(TVP_HPLLPRECOAST, pre);
tvp_writereg(TVP_HPLLPOSTCOAST, post);
}
static inline void tvp_set_ssthold(alt_u8 vsdetect_thold) {
tvp_writereg(TVP_SSTHOLD, vsdetect_thold);
}
static void tvp_set_clamp(video_format fmt) {
switch (fmt) {
case FORMAT_RGBS:
case FORMAT_RGBHV:
case FORMAT_RGsB:
//select bottom clamp (RGB)
tvp_writereg(TVP_SOGTHOLD, 0x58);
break;
case FORMAT_YPbPr:
//select mid clamp for Pb & Pr
tvp_writereg(TVP_SOGTHOLD, 0x5D);
break;
default:
break;
}
}
static void tvp_set_clamp_position(video_type type) {
switch (type) {
case VIDEO_LDTV:
tvp_writereg(TVP_CLAMPSTART, 0x2);
tvp_writereg(TVP_CLAMPWIDTH, 0x6);
break;
case VIDEO_SDTV:
case VIDEO_EDTV:
case VIDEO_PC:
tvp_writereg(TVP_CLAMPSTART, 0x6);
tvp_writereg(TVP_CLAMPWIDTH, 0x10);
break;
case VIDEO_HDTV:
tvp_writereg(TVP_CLAMPSTART, 0x32);
tvp_writereg(TVP_CLAMPWIDTH, 0x20);
break;
default:
break;
}
}
static void tvp_set_alc(video_type type) {
//disable ALC
//tvp_writereg(TVP_ALCEN, 0x00);
//tvp_writereg(TVP_ALCEN, 0x80);
//set analog (coarse) gain to max recommended value (-> 91% of the ADC range with 0.7Vpp input)
tvp_writereg(TVP_BG_CGAIN, 0x88);
tvp_writereg(TVP_R_CGAIN, 0x08);
//set rest of the gain digitally (fine) to utilize 100% of the range at the output (0.91*(1+(26/256)) = 1)
tvp_writereg(TVP_R_FGAIN, 26);
tvp_writereg(TVP_G_FGAIN, 26);
tvp_writereg(TVP_B_FGAIN, 26);
//select ALC placement
switch (type) {
case VIDEO_LDTV:
tvp_writereg(TVP_ALCPLACE, 0x9);
break;
case VIDEO_SDTV:
case VIDEO_EDTV:
case VIDEO_PC:
tvp_writereg(TVP_ALCPLACE, 0x18);
break;
case VIDEO_HDTV:
tvp_writereg(TVP_ALCPLACE, 0x5A);
break;
default:
break;
}
}
inline alt_u32 tvp_readreg(alt_u32 regaddr) {
I2C_start(I2CA_BASE, TVP_BASE, 0);
I2C_write(I2CA_BASE, regaddr, 1); //don't use repeated start as it seems unreliable at 400kHz
I2C_start(I2CA_BASE, TVP_BASE, 1);
return I2C_read(I2CA_BASE,1);
}
inline void tvp_writereg(alt_u32 regaddr, alt_u8 data) {
I2C_start(I2CA_BASE, TVP_BASE, 0);
I2C_write(I2CA_BASE, regaddr, 0);
I2C_write(I2CA_BASE, data, 1);
}
inline void tvp_reset() {
usleep(10000);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x00);
usleep(10000);
IOWR_ALTERA_AVALON_PIO_DATA(PIO_0_BASE, 0x01);
usleep(10000);
}
inline void tvp_disable_output() {
usleep(10000);
tvp_writereg(TVP_MISCCTRL1, 0x13);
usleep(10000);
tvp_writereg(TVP_MISCCTRL2, 0x03);
usleep(10000);
}
inline void tvp_enable_output() {
usleep(10000);
tvp_writereg(TVP_MISCCTRL1, 0x11);
usleep(10000);
tvp_writereg(TVP_MISCCTRL2, 0x02);
usleep(10000);
}
void tvp_init() {
// disable output
tvp_disable_output();
//Set global defaults
// Hsync input->output delay (horizontal shift)
// Default is 13, which maintains alignment of RGB and hsync at output
//tvp_writereg(TVP_HSOUTSTART, 0);
// Hsync edge->Vsync edge delay
tvp_writereg(TVP_VSOUTALIGN, 0);
// Set default CSC coeffs.
tvp_sel_csc(&csc_coeffs[0]);
// Set default phase
tvp_set_hpll_phase(0x10);
// Set min LPF
tvp_set_lpf(0);
tvp_set_sync_lpf(0);
// Increase line length tolerance
tvp_writereg(TVP_LINELENTOL, 0x06);
// Common sync separator threshold
// Some arcade games need more that the default 0x40
tvp_set_ssthold(0x44);
}
// Configure H-PLL (sampling rate, VCO gain and charge pump current)
void tvp_setup_hpll(alt_u16 h_samplerate, alt_u16 v_lines, alt_u8 hz, alt_u8 plldivby2) {
alt_u32 pclk_est;
alt_u8 vco_range;
alt_u8 cp_current;
alt_u8 status = tvp_readreg(TVP_HPLLPHASE) & 0xF8;
// Enable PLL post-div-by-2 with double samplerate
if (plldivby2) {
tvp_writereg(TVP_HPLLPHASE, status|1);
h_samplerate = 2*h_samplerate;
} else {
tvp_writereg(TVP_HPLLPHASE, status);
}
tvp_writereg(TVP_HPLLDIV_MSB, (h_samplerate >> 4));
tvp_writereg(TVP_HPLLDIV_LSB, ((h_samplerate & 0xf) << 4));
printf("Horizontal samplerate set to %u\n", h_samplerate);
pclk_est = ((alt_u32)h_samplerate * v_lines * hz) / 1000; //in kHz
printf("Estimated PCLK: %u.%.3u MHz\n", pclk_est/1000, pclk_est%1000);
if (pclk_est < 36000) {
vco_range = 0;
} else if (pclk_est < 70000) {
vco_range = 1;
} else if (pclk_est < 135000) {
vco_range = 2;
} else {
vco_range = 3;
}
cp_current = (40*Kvco[vco_range]+h_samplerate/2) / h_samplerate; //"+h_samplerate/2" for fast rounding
printf("VCO range: %s\nCPC: %u\n", Kvco_str[vco_range], cp_current);
tvp_writereg(TVP_HPLLCTRL, ((vco_range << 6) | (cp_current << 3)));
}
void tvp_sel_clk(alt_u8 refclk) {
alt_u8 status = tvp_readreg(TVP_INPMUX2) & 0xFA;
//TODO: set SOG and CLP LPF based on mode
if (refclk == REFCLK_INTCLK) {
tvp_writereg(TVP_INPMUX2, status|0x2);
} else {
#ifdef EXTADCCLK
tvp_writereg(TVP_INPMUX2, status|0x8);
#else
tvp_writereg(TVP_INPMUX2, status|0xA);
#endif
}
}
void tvp_sel_csc(ypbpr_to_rgb_csc_t *csc) {
tvp_writereg(TVP_CSC1HI, (csc->G_Y >> 8));
tvp_writereg(TVP_CSC1LO, (csc->G_Y & 0xff));
tvp_writereg(TVP_CSC2HI, (csc->G_Pb >> 8));
tvp_writereg(TVP_CSC2LO, (csc->G_Pb & 0xff));
tvp_writereg(TVP_CSC3HI, (csc->G_Pr >> 8));
tvp_writereg(TVP_CSC3LO, (csc->G_Pr & 0xff));
tvp_writereg(TVP_CSC4HI, (csc->R_Y >> 8));
tvp_writereg(TVP_CSC4LO, (csc->R_Y & 0xff));
tvp_writereg(TVP_CSC5HI, (csc->R_Pb >> 8));
tvp_writereg(TVP_CSC5LO, (csc->R_Pb & 0xff));
tvp_writereg(TVP_CSC6HI, (csc->R_Pr >> 8));
tvp_writereg(TVP_CSC6LO, (csc->R_Pr & 0xff));
tvp_writereg(TVP_CSC7HI, (csc->B_Y >> 8));
tvp_writereg(TVP_CSC7LO, (csc->B_Y & 0xff));
tvp_writereg(TVP_CSC8HI, (csc->B_Pb >> 8));
tvp_writereg(TVP_CSC8LO, (csc->B_Pb & 0xff));
tvp_writereg(TVP_CSC9HI, (csc->B_Pr >> 8));
tvp_writereg(TVP_CSC9LO, (csc->B_Pr & 0xff));
}
void tvp_set_lpf(alt_u8 val) {
alt_u8 status = tvp_readreg(TVP_VIDEOBWLIM) & 0xF0;
tvp_writereg(TVP_VIDEOBWLIM, status|val);
printf("TVP LPF value set to 0x%x\n", val);
}
void tvp_set_sync_lpf(alt_u8 val) {
alt_u8 status = tvp_readreg(TVP_INPMUX2) & 0x3F;
tvp_writereg(TVP_INPMUX2, status|((3-val)<<6));
printf("Sync LPF value set to 0x%x\n", (3-val));
}
void tvp_set_hpll_phase(alt_u8 val) {
alt_u8 status = tvp_readreg(TVP_HPLLPHASE) & 0x07;
tvp_writereg(TVP_HPLLPHASE, (val<<3)|status);
printf("Phase value set to 0x%x\n", val);
}
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 refclk) {
// Configure clock settings
tvp_sel_clk(refclk);
// Clamp position and ALC
tvp_set_clamp_position(type);
tvp_set_alc(type);
// Macrovision enable/disable, coast disable for RGBHV.
// Coast needs to be enabled when HSYNC is missing during VSYNC. Valid only for RGBHV?
// Macrovision should be enabled when serration pulses etc. present, so disable only for RGBHV.
switch (type) {
case VIDEO_PC:
//tvp_writereg(TVP_MISCCTRL4, 0x04);
tvp_writereg(TVP_MISCCTRL4, 0x0C);
tvp_writereg(TVP_MVSWIDTH, 0x03);
break;
case VIDEO_HDTV:
tvp_writereg(TVP_MISCCTRL4, 0x08);
tvp_writereg(TVP_MVSWIDTH, 0x0E);
break;
case VIDEO_LDTV:
case VIDEO_SDTV:
case VIDEO_EDTV:
tvp_writereg(TVP_MISCCTRL4, 0x08);
tvp_writereg(TVP_MVSWIDTH, 0x88); // TODO: check mode
break;
default:
break;
}
tvp_setup_hpll(video_modes[modeid].h_total, vlines, hz, !!(video_modes[modeid].flags & MODE_PLLDIVBY2));
//Long coast may lead to PLL frequency drift and sync loss (e.g. SNES)
/*if (video_modes[modeid].v_active < 720)
tvp_set_hpllcoast(3, 3);
else*/
tvp_set_hpllcoast(1, 0);
// Hsync output width
tvp_writereg(TVP_HSOUTWIDTH, video_modes[modeid].h_synclen);
}
void tvp_source_sel(tvp_input_t input, video_format fmt, alt_u8 refclk) {
alt_u8 sync_status;
alt_u8 sog_ch;
if ((fmt == FORMAT_RGsB) || (fmt == FORMAT_YPbPr))
sog_ch = (input == TVP_INPUT3) ? 2 : 0;
else if ((input == TVP_INPUT1) && (fmt == FORMAT_RGBS))
sog_ch = 1;
else
sog_ch = 2;
// RGB+SOG input select
tvp_writereg(TVP_INPMUX1, (sog_ch<<6) | (input<<4) | (input<<2) | input);
// Configure clock settings
tvp_sel_clk(refclk);
// Clamp setup
tvp_set_clamp(fmt);
// HV/SOG sync select
if ((input == TVP_INPUT3) && (fmt != FORMAT_RGsB)) {
if (fmt == FORMAT_RGBHV)
tvp_writereg(TVP_SYNCCTRL1, 0x52);
else // RGBS
tvp_writereg(TVP_SYNCCTRL1, 0x53);
sync_status = tvp_readreg(TVP_SYNCSTAT);
if (sync_status & (1<<7))
printf("%s detected, %s polarity\n", (sync_status & (1<<3)) ? "Csync" : "Hsync", (sync_status & (1<<5)) ? "pos" : "neg");
if (sync_status & (1<<4))
printf("Vsync detected, %s polarity\n", (sync_status & (1<<2)) ? "pos" : "neg");
} else {
tvp_writereg(TVP_SYNCCTRL1, 0x5B);
sync_status = tvp_readreg(TVP_SYNCSTAT);
if (sync_status & (1<<1))
printf("SOG detected\n");
else
printf("SOG not detected\n");
}
// Enable CSC for YPbPr
if (fmt == FORMAT_YPbPr)
tvp_writereg(TVP_MISCCTRL3, 0x10);
else
tvp_writereg(TVP_MISCCTRL3, 0x00);
#ifdef SYNCBYPASS
tvp_writereg(TVP_SYNCBYPASS, 0x03);
#else
tvp_writereg(TVP_SYNCBYPASS, 0x00);
#endif
//TODO:
//clamps
//TVP_ADCSETUP
printf("\n");
}
alt_u8 tvp_check_sync(tvp_input_t input) {
alt_u8 sync_status;
sync_status = tvp_readreg(TVP_SYNCSTAT);
if (input == TVP_INPUT3)
return !!((sync_status & 0x98) > 0x80);
//return !!((sync_status & 0x90) == 0x90);
else
return !!(sync_status & (1<<1));
}
+90
View File
@@ -0,0 +1,90 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef TVP7002_H_
#define TVP7002_H_
#include "tvp7002_regs.h"
#include "video_modes.h"
#include "sysconfig.h"
//#define I2C_DEBUG
#define I2CA_BASE I2C_OPENCORES_0_BASE
typedef enum {
TVP_INPUT1 = 0,
TVP_INPUT2 = 1,
TVP_INPUT3 = 2
} tvp_input_t;
static const alt_u8 Kvco[] = {75, 85, 150, 200};
static const char *Kvco_str[] = { "Ultra low", "Low", "Medium", "High" };
typedef enum {
REFCLK_EXT27 = 0,
REFCLK_INTCLK = 1
} tvp_refclk_t;
typedef struct {
const char *name;
alt_u16 R_Y;
alt_u16 R_Pb;
alt_u16 R_Pr;
alt_u16 G_Y;
alt_u16 G_Pb;
alt_u16 G_Pr;
alt_u16 B_Y;
alt_u16 B_Pb;
alt_u16 B_Pr;
} ypbpr_to_rgb_csc_t;
static const alt_u32 clkrate[] = {27000000, 6500000}; //in MHz
inline alt_u32 tvp_readreg(alt_u32 regaddr);
inline void tvp_writereg(alt_u32 regaddr, alt_u8 data);
inline void tvp_reset();
inline void tvp_disable_output();
inline void tvp_enable_output();
void tvp_init();
void tvp_setup_hpll(alt_u16 h_samplerate, alt_u16 v_lines, alt_u8 hz, alt_u8 plldivby2);
void tvp_sel_clk(alt_u8 refclk);
void tvp_sel_csc(ypbpr_to_rgb_csc_t *csc);
void tvp_set_lpf(alt_u8 val);
void tvp_set_sync_lpf(alt_u8 val);
void tvp_set_hpll_phase(alt_u8 val);
void tvp_source_setup(alt_8 modeid, video_type type, alt_u32 vlines, alt_u8 hz, alt_u8 refclk);
void tvp_source_sel(tvp_input_t input, video_format fmt, alt_u8 refclk);
alt_u8 tvp_check_sync(tvp_input_t input);
#endif /* TVP7002_H_ */
@@ -0,0 +1,117 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef TVP7002_REGS_H_
#define TVP7002_REGS_H_
#define TVP_BASE (0xB8>>1)
#define TVP_CHIPREV 0x00
#define TVP_HPLLDIV_MSB 0x01
#define TVP_HPLLDIV_LSB 0x02
#define TVP_HPLLCTRL 0x03
#define TVP_HPLLPHASE 0x04
#define TVP_CLAMPSTART 0x05
#define TVP_CLAMPWIDTH 0x06
#define TVP_HSOUTWIDTH 0x07
#define TVP_B_FGAIN 0x08
#define TVP_G_FGAIN 0x09
#define TVP_R_FGAIN 0x0A
#define TVP_B_FOFFSET_MSB 0x0B
#define TVP_G_FOFFSET_MSB 0x0C
#define TVP_R_FOFFSET_MSB 0x0D
#define TVP_SYNCCTRL1 0x0E
#define TVP_HPLLCTRL2 0x0F
#define TVP_SOGTHOLD 0x10
#define TVP_SSTHOLD 0x11
#define TVP_HPLLPRECOAST 0x12
#define TVP_HPLLPOSTCOAST 0x13
#define TVP_SYNCSTAT 0x14
#define TVP_OUTFORMAT 0x15
#define TVP_MISCCTRL1 0x16
#define TVP_MISCCTRL2 0x17
#define TVP_MISCCTRL3 0x18
#define TVP_INPMUX1 0x19
#define TVP_INPMUX2 0x1A
#define TVP_BG_CGAIN 0x1B
#define TVP_R_CGAIN 0x1C
#define TVP_FOFFSET_LSB 0x1D
#define TVP_B_COFFSET 0x1E
#define TVP_G_COFFSET 0x1F
#define TVP_R_COFFSET 0x20
#define TVP_HSOUTSTART 0x21
#define TVP_MISCCTRL4 0x22
#define TVP_B_ALCOUT_LSB 0x23
#define TVP_G_ALCOUT_LSB 0x24
#define TVP_R_ALCOUT_LSB 0x25
#define TVP_ALCEN 0x26
#define TVP_ALCOUT_MSB 0x27
#define TVP_ALCFILT 0x28
#define TVP_FCLAMPCTRL 0x2A
#define TVP_POWERCTRL 0x2B
#define TVP_ADCSETUP 0x2C
#define TVP_CCLAMPCTRL 0x2D
#define TVP_SOGCLAMP 0x2E
#define TVP_RGBCCLAMPCTRL 0x2F
#define TVP_SOGCCLAMPCTRL 0x30
#define TVP_ALCPLACE 0x31
#define TVP_MVSWIDTH 0x34
#define TVP_VSOUTALIGN 0x35
#define TVP_SYNCBYPASS 0x36
#define TVP_LINECNT1 0x37
#define TVP_LINECNT2 0x38
#define TVP_CLKCNT1 0x39
#define TVP_CLKCNT2 0x3A
#define TVP_HSINWIDTH 0x3B
#define TVP_VSINWIDTH 0x3C
#define TVP_LINELENTOL 0x3D
#define TVP_VIDEOBWLIM 0x3F
#define TVP_AVIDSTART1 0x40
#define TVP_AVIDSTART2 0x41
#define TVP_AVIDSTOP1 0x42
#define TVP_AVIDSTOP2 0x43
#define TVP_VB0OFF 0x44
#define TVP_VB1OFF 0x45
#define TVP_VB0DUR 0x46
#define TVP_VB1DUR 0x47
#define TVP_CSC1LO 0x4A
#define TVP_CSC1HI 0x4B
#define TVP_CSC2LO 0x4C
#define TVP_CSC2HI 0x4D
#define TVP_CSC3LO 0x4E
#define TVP_CSC3HI 0x4F
#define TVP_CSC4LO 0x50
#define TVP_CSC4HI 0x51
#define TVP_CSC5LO 0x52
#define TVP_CSC5HI 0x53
#define TVP_CSC6LO 0x54
#define TVP_CSC6HI 0x55
#define TVP_CSC7LO 0x56
#define TVP_CSC7HI 0x57
#define TVP_CSC8LO 0x58
#define TVP_CSC8HI 0x59
#define TVP_CSC9LO 0x5A
#define TVP_CSC9HI 0x5B
#endif /* TVP7002_REGS_H_ */
@@ -0,0 +1,85 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#include <stdio.h>
#include <unistd.h>
#include "system.h"
#include "video_modes.h"
#define LINECNT_MAX_TOLERANCE 30
const mode_data_t video_modes[] = {
{ "240p_L3M0", 1280, 240, 6000, 1704, 262, 196, 16, 124, 3, (VIDEO_SDTV|VIDEO_PC), MODE_L3_MODE0 },
{ "240p_L3M1", 960, 240, 6000, 1278, 262, 147, 16, 93, 3, (VIDEO_SDTV|VIDEO_PC), MODE_L3_MODE1 },
{ "240p_L3M2", 320, 240, 6000, 426, 262, 49, 16, 31, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE2|MODE_PLLDIVBY2) },
{ "240p_L3M3", 256, 240, 6000, 341, 262, 39, 16, 25, 3, (VIDEO_LDTV|VIDEO_PC), (MODE_L3_MODE3|MODE_PLLDIVBY2) },
{ "240p", 720, 240, 6000, 858, 262, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE) },
{ "288p", 720, 288, 5000, 864, 312, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE) },
{ "384p", 496, 384, 5766, 640, 423, 50, 29, 62, 3, VIDEO_EDTV, (MODE_L2ENABLE) }, //Sega Model 2
{ "640x384", 640, 384, 5500, 800, 492, 48, 63, 96, 2, VIDEO_PC, (MODE_L2ENABLE) }, //X68k @ 24kHz
{ "480i", 720, 240, 5994, 858, 525, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE|MODE_INTERLACED) },
{ "480p", 720, 480, 5994, 858, 525, 60, 30, 62, 6, (VIDEO_EDTV|VIDEO_PC), (MODE_DTV480P) },
{ "640x480", 640, 480, 6000, 800, 525, 48, 33, 96, 2, (VIDEO_PC|VIDEO_EDTV), (MODE_VGA480P) },
{ "640x512", 640, 512, 6000, 800, 568, 48, 28, 96, 2, VIDEO_PC, 0 }, //X68k @ 31kHz
{ "576i", 720, 288, 5000, 864, 625, 65, 16, 60, 3, (VIDEO_SDTV|VIDEO_PC), (MODE_L2ENABLE|MODE_INTERLACED) },
{ "576p", 720, 576, 5000, 864, 625, 65, 32, 60, 6, VIDEO_EDTV, 0 },
{ "800x600", 800, 600, 6000, 1056, 628, 88, 23, 128, 4, VIDEO_PC, 0 },
{ "720p", 1280, 720, 5994, 1650, 750, 255, 20, 40, 5, VIDEO_HDTV, 0 },
{ "1280x720", 1280, 720, 6000, 1650, 750, 220, 20, 40, 5, VIDEO_PC, 0 },
{ "1024x768", 1024, 768, 6000, 1344, 806, 160, 29, 136, 6, VIDEO_PC, 0 },
{ "1280x1024", 1280, 1024, 6000, 1688, 1066, 248, 38, 112, 3, VIDEO_PC, 0 },
{ "1080i", 1920, 1080, 5994, 2200, 1125, 148, 16, 44, 5, VIDEO_HDTV, (MODE_L2ENABLE|MODE_INTERLACED) }, //Too high freq for L2 PLL
{ "1080p", 1920, 1080, 5994, 2200, 1125, 188, 36, 44, 5, VIDEO_HDTV, 0 },
{ "1920x1080", 1920, 1080, 6000, 2200, 1125, 148, 36, 44, 5, VIDEO_PC, 0 },
};
/* TODO: rewrite, check hz etc. */
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type typemask, alt_u8 linemult_target, alt_u8 l3_mode, alt_u8 s480p_mode) {
alt_8 i;
alt_u8 num_modes = sizeof(video_modes)/sizeof(mode_data_t);
video_type mode_type;
// TODO: a better check
for (i=0; i<num_modes; i++) {
mode_type = video_modes[i].type;
// disable particular 480p mode based on input and user preference
if (video_modes[i].flags & MODE_DTV480P) {
if (s480p_mode == 0) // auto
mode_type &= ~VIDEO_PC;
else if (s480p_mode == 2) // VGA 640x480
mode_type = 0;
} else if (video_modes[i].flags & MODE_VGA480P) {
if (s480p_mode == 0) // auto
mode_type &= ~VIDEO_EDTV;
else if (s480p_mode == 1) // DTV 480P
mode_type = 0;
}
if ((typemask & mode_type) && (progressive == !(video_modes[i].flags & MODE_INTERLACED)) && (totlines <= (video_modes[i].v_total+LINECNT_MAX_TOLERANCE))) {
if (linemult_target && (video_modes[i].flags & MODE_L3ENABLE_MASK) && ((video_modes[i].flags & MODE_L3ENABLE_MASK) == (1<<l3_mode))) {
return i;
} else if (!(video_modes[i].flags & MODE_L3ENABLE_MASK)) {
return i;
}
}
}
return -1;
}
@@ -0,0 +1,72 @@
//
// Copyright (C) 2015 Markus Hiienkari <mhiienka@niksula.hut.fi>
//
// This file is part of Open Source Scan Converter project.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
#ifndef VIDEO_MODES_H_
#define VIDEO_MODES_H_
#include <alt_types.h>
#include "sysconfig.h"
typedef enum {
FORMAT_RGBS = 0,
FORMAT_RGBHV = 1,
FORMAT_RGsB = 2,
FORMAT_YPbPr = 3
} video_format;
typedef enum {
VIDEO_LDTV = (1<<0),
VIDEO_SDTV = (1<<1),
VIDEO_EDTV = (1<<2),
VIDEO_HDTV = (1<<3),
VIDEO_PC = (1<<4)
} video_type;
#define MODE_L3ENABLE_MASK 0xf
typedef enum {
MODE_L3_MODE0 = (1<<0),
MODE_L3_MODE1 = (1<<1),
MODE_L3_MODE2 = (1<<2),
MODE_L3_MODE3 = (1<<3),
MODE_L2ENABLE = (1<<4),
MODE_INTERLACED = (1<<5),
MODE_PLLDIVBY2 = (1<<6),
MODE_DTV480P = (1<<7),
MODE_VGA480P = (1<<8)
} mode_flags;
typedef struct {
char name[10];
alt_u16 h_active;
alt_u16 v_active;
alt_u16 hz_x100;
alt_u16 h_total;
alt_u16 v_total;
alt_u8 h_backporch;
alt_u8 v_backporch;
alt_u8 h_synclen;
alt_u8 v_synclen;
video_type type;
mode_flags flags;
} mode_data_t;
alt_8 get_mode_id(alt_u32 totlines, alt_u8 progressive, alt_u32 hz, video_type typemask, alt_u8 linemult_target, alt_u8 l3_mode, alt_u8 s480p_mode);
#endif /* VIDEO_MODES_H_ */