unsigned char EP956Controller_Task(void) { // // Read from EP956 and Report Status // // Polling Interrupt Flag and updat the internal information EP956Controller_Interrupt(); // Polling Hot-Plug (MHL Link) / RSEN every 55ms EP956Control_Link_Task(); // // Update some controls from the user any time // // Power Control if(pEP956C_Registers->Power_Control & (EP956E_Power_Control__PD_HDMI | EP956E_Power_Control__PD_TOT) ) { is_Source_Ready = 0; pEP956C_Registers->Power_Control |= EP956E_Power_Control__PD_HDMI; #ifndef MHL_CODE EP956_Reg_Set_Bit(EP956_TX_PHY_Control_1, EP956_TX_PHY_Control_1__RSEN_DIS); #endif } else { #ifndef MHL_CODE EP956_Reg_Clear_Bit(EP956_TX_PHY_Control_1, EP956_TX_PHY_Control_1__RSEN_DIS); #endif if( is_VideoChanging || is_AudioChanging || (pEP956C_Registers->Video_Input_Format[0] == 0) ) { is_Source_Ready = 0; // if(ConnectionState == CBUS_LINK_STATE__Connected) { // MHL_MSC_Cmd_MSC_MSG(MSC_RAP, RAP_CONTENT_OFF); // } } else { is_Source_Ready = 1; // if(ConnectionState == CBUS_LINK_STATE__Connected) { // MHL_MSC_Cmd_MSC_MSG(MSC_RAP, RAP_CONTENT_ON); // } } } // Mute Control if( (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__AUDIO_DIS) || (TX_State < TXS_Stream) ) { HDMI_Tx_AMute_Enable(); } else { HDMI_Tx_AMute_Disable(); } if( (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__VIDEO_DIS) || (TX_State < TXS_Stream) ) { HDMI_Tx_VMute_Enable(); } else { HDMI_Tx_VMute_Disable(); } // Auto Handle AVMute Handle_AVMute(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__AVMUTE_EN); // // Handle the main HDMI Link State and HDCP Authentication State // The state transition: [Search_EDID] => [Wait_Upstream] => [Stream] => [HDCP] // switch(TX_State) { case TXS_Search_EDID: if(is_Connected && is_PATH_EN) { //if(ReadEDID_TimeCount > 200/EP956C_TIMER_PERIOD) //EP_DEV_DBG("delay 200ms+\n"); delay_100ms(2); //EP_DEV_DBG("delay 200ms-\n"); { unsigned char EDID_DDC_Status; static BYTE detectCount = 0; // Confirm Hot-Plug (time-out after 1s) if(!is_Hot_Plug) { //if(ReadEDID_TimeCount <= 1000/EP956C_TIMER_PERIOD) break; if(detectCount++ < 5) break; detectCount = 0; EP_DEV_DBG("Err: EDID detected without Hot-Plug for 1s\n"); } // Read EDID EP_DEV_DBG("State Transist: Read EDID -> [TXS_Wait_Upstream]\n"); memset(pEP956C_Registers->Readed_EDID, 0xFF, 256); EDID_DDC_Status = Downstream_Rx_read_EDID(pEP956C_Registers->Readed_EDID); if(EDID_DDC_Status) { static BYTE failCount = 0; EP_DEV_DBG("Err: EDID read failed 0x%02X\n", (int)EDID_DDC_Status); //if(ReadEDID_TimeCount <= 500/EP956C_TIMER_PERIOD) break; if(failCount++ < 3) break; failCount = 0; } //ReadEDID_TimeCount = 0; // Set Output if(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__FORCE_HDMI_CAP) { is_Cap_HDMI = 1; } else { is_Cap_HDMI = EDID_GetHDMICap(pEP956C_Registers->Readed_EDID); } if(is_Cap_HDMI) { EP_DEV_DBG("Support HDMI"); // Default Capability is_Cap_YCC444 = is_Cap_YCC422 = 0; pEP956C_Registers->EDID_ASFreq = 0x07; pEP956C_Registers->EDID_AChannel_PCM = 1; pEP956C_Registers->EDID_VideoDataAddr = 0x00; pEP956C_Registers->EDID_AudioDataAddr = 0x00; pEP956C_Registers->EDID_SpeakerDataAddr = 0x00; pEP956C_Registers->EDID_VendorDataAddr = 0x00; if(!EDID_DDC_Status) { if(pEP956C_Registers->Readed_EDID[131] & 0x20) { // Support YCC444 is_Cap_YCC444 = 1; EP_DEV_DBG(" YCC444"); } if(pEP956C_Registers->Readed_EDID[131] & 0x10) { // Support YCC422 is_Cap_YCC422 = 1; EP_DEV_DBG(" YCC422"); } EP_DEV_DBG("\n"); pEP956C_Registers->EDID_ASFreq = EDID_GetPCMFreqCap(pEP956C_Registers->Readed_EDID); pEP956C_Registers->EDID_AChannel_PCM = EDID_GetChannelCap(pEP956C_Registers->Readed_EDID, 1); // Get PCM Max Channel pEP956C_Registers->EDID_AChannel_DSD = EDID_GetChannelCap(pEP956C_Registers->Readed_EDID, 9); // Get DSD Max Channel pEP956C_Registers->EDID_VideoDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x40); pEP956C_Registers->EDID_AudioDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x20); pEP956C_Registers->EDID_SpeakerDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x80); pEP956C_Registers->EDID_VendorDataAddr = EDID_GetDataBlockAddr(pEP956C_Registers->Readed_EDID, 0x60); } } else { EP_DEV_DBG("Support DVI RGB only\n"); is_Cap_YCC444 = is_Cap_YCC422 = 0; pEP956C_Registers->EDID_ASFreq = pEP956C_Registers->EDID_AChannel_PCM = 0; } if(is_Cap_HDMI) pEP956C_Registers->EDID_Status = EDID_DDC_Status | EP956E_EDID_Status__HDMI; else pEP956C_Registers->EDID_Status = EDID_DDC_Status; EP_DEV_DBG("Support Max PCM Audio Channel %d\n", (int)pEP956C_Registers->EDID_AChannel_PCM+1); EP_DEV_DBG("Support Audio Freq 0x%02X\n", (int)pEP956C_Registers->EDID_ASFreq); // Report EDID Change pEP956C_Registers->Interrupt_Flags |= EP956E_Interrupt_Flags__EDID_CHG; if(EP956C_GenerateInt && (pEP956C_Registers->Interrupt_Enable & EP956E_Interrupt_Enable__EDID_CHG) ) EP956C_GenerateInt(); TX_State = TXS_Wait_Upstream; } } else { pEP956C_Registers->EDID_Status = EDID_STATUS_NoAct; //ReadEDID_TimeCount = 0; } break; case TXS_Wait_Upstream: if(!is_Connected || !is_PATH_EN) { TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(is_Source_Ready && is_ReceiverSense) { // EP956 can detect RSEN in power down mode EP_DEV_DBG("State Transist: Power Up -> [TXS_Stream]\n"); // Set to DVI mode HDMI_Tx_DVI(); // Power Up HDMI_Tx_Power_Up(); is_HDMI_Mode_Set = 1; //HDMI_Mode_Set_TimeCount = 0; TX_State = TXS_Stream; } else { // Check Force HDMI BOOL if(!is_Cap_HDMI) { if(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__FORCE_HDMI_CAP) { TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } } } break; case TXS_Stream: //if(HDMI_Mode_Set_TimeCount > 10/EP956C_TIMER_PERIOD) //EP_DEV_DBG("delay 10ms+\n"); //EP_DEV_DBG("delay 10ms-\n"); if(is_HDMI_Mode_Set) { delay_1ms(10); //HDMI_Mode_Set_TimeCount = 0; is_HDMI_Mode_Set = 0; // HDMI Mode if(!is_Cap_HDMI || (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDMI_DIS) ) { HDMI_Tx_DVI(); // Set to DVI mode (The Info Frame and Audio Packets would not be send) } else { HDMI_Tx_HDMI(); // Set to HDMI mode } #ifdef MHL_CODE if(EP956_VDO_Settings[Video_Params.VideoSettingIndex].Pix_Freq_Type > PIX_FREQ_74250KHz) { is_PackedPixelMode = 1; if(is_PATH_EN) MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__PacketPixel | PATH_EN); else MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__PacketPixel); MHL_Clock_Mode(1); } else { is_PackedPixelMode = 0; if(is_PATH_EN) MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__Normal | PATH_EN); else MHL_MSC_Cmd_WRITE_STATE(MSC_STATUS_LINK_MODE, CLK_MODE__Normal); MHL_Clock_Mode(0); } #endif } if(!is_Connected || !is_PATH_EN) { TXS_RollBack_Stream(); TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(!is_Source_Ready || !is_ReceiverSense) { TXS_RollBack_Stream(); TX_State = TXS_Wait_Upstream; } else if(!(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDCP_DIS)) { if(is_HDMI_Mode_Set == 0) { EP_DEV_DBG("State Transist: Start HDCP -> [TXS_HDCP]\n"); // Enable mute for transmiter video and audio HDMI_Tx_Mute_Enable(); TX_State = TXS_HDCP; } } if(Dump_Timer++ > 2000/EP956C_TIMER_PERIOD) { Dump_Timer = 0; EP956_Reg_Read(EP956_CTS, Temp_Byte, 3); EP_DEV_DBG("CTS %02X %02X %02X\n", Temp_Byte[0], Temp_Byte[1], Temp_Byte[2]); EP956_Reg_Read(EP956_N, Temp_Byte, 3); EP_DEV_DBG("N %02X %02X %02X\n", Temp_Byte[0], Temp_Byte[1], Temp_Byte[2]); EP956_Reg_Read(EP956_Color_Space_Control, Temp_Byte, 1); EP_DEV_DBG("EP956_Color_Space_Control %X\n", Temp_Byte[0]); EP956_Reg_Read(EP956_General_Control_8, Temp_Byte, 1); EP_DEV_DBG("EP956_General_Control_8 %X\n", Temp_Byte[0]); EP956_Reg_Read(EP956_IIS_Control, Temp_Byte, 1); EP_DEV_DBG("EP956_IIS_Control %X\n", Temp_Byte[0]); HDMI_Dump_Status(); } break; case TXS_HDCP: if(!is_Connected || !is_PATH_EN) { TXS_RollBack_HDCP(); TXS_RollBack_Stream(); TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(!is_Source_Ready || !is_ReceiverSense) { TXS_RollBack_HDCP(); TXS_RollBack_Stream(); TX_State = TXS_Wait_Upstream; } else if(pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDCP_DIS) { TXS_RollBack_HDCP(); TX_State = TXS_Stream; } else if(!is_Hot_Plug || is_VideoChanging || (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__VIDEO_DIS) ) { // Enable mute for transmiter video and audio HDMI_Tx_Mute_Enable(); HDCP_Stop(); } else { pEP956C_Registers->HDCP_State = HDCP_Authentication_Task(); pEP956C_Registers->HDCP_Status = HDCP_Get_Status(); } break; } // // Combine the EDID capability and the source information to set the EP956 video/audio settings // // // Update Video Params // // Video Interface Video_Params.Interface = pEP956C_Registers->Video_Interface[0]; // Video Timing if(pEP956C_Registers->Video_Input_Format[0]) { // Semi Auto Detect Video Timing if(pEP956C_Registers->Video_Input_Format[0] < 128) { if(pEP956C_Registers->Video_Input_Format[0] < 112) { Video_Params.VideoSettingIndex = pEP956C_Registers->Video_Input_Format[0]; } else { Video_Params.VideoSettingIndex = pEP956C_Registers->Video_Input_Format[0] - (112 - EP956_VDO_Settings_Rep_Start); } } else { Video_Params.VideoSettingIndex = pEP956C_Registers->Video_Input_Format[0] - (128 - EP956_VDO_Settings_IT_Start); } } // Select Sync Mode Video_Params.SyncMode = (pEP956C_Registers->Video_Interface[1] & EP956E_Video_Interface_Setting_1__SYNC) >> 2; // Select Color Space switch(pEP956C_Registers->Video_Interface[1] & EP956E_Video_Interface_Setting_1__COLOR) { default: case EP956E_Video_Interface_Setting_1__COLOR__Auto: switch(Video_Params.VideoSettingIndex) { case 4: case 5: case 16: case 19: case 20: case 31: case 32: case 33: case 34: case 39: case 40: case 41: case 46: case 47: // HD Timing Video_Params.ColorSpace = COLORSPACE_709; break; default: if(Video_Params.VideoSettingIndex && Video_Params.VideoSettingIndex < EP956_VDO_Settings_IT_Start) { // SD Timing Video_Params.ColorSpace = COLORSPACE_601; } else { // IT Timing Video_Params.ColorSpace = COLORSPACE_709; } } break; case EP956E_Video_Interface_Setting_1__COLOR__601: Video_Params.ColorSpace = COLORSPACE_601; break; case EP956E_Video_Interface_Setting_1__COLOR__709: Video_Params.ColorSpace = COLORSPACE_709; break; } // Set Input Format switch(pEP956C_Registers->Video_Interface[1] & EP956E_Video_Interface_Setting_1__VIN_FMT) { default: case EP956E_Video_Interface_Setting_1__VIN_FMT__RGB: Video_Params.FormatIn = COLORFORMAT_RGB; break; case EP956E_Video_Interface_Setting_1__VIN_FMT__YCC444: Video_Params.FormatIn = COLORFORMAT_YCC444; break; case EP956E_Video_Interface_Setting_1__VIN_FMT__YCC422: Video_Params.FormatIn = COLORFORMAT_YCC422; break; } // Set Output Format switch(pEP956C_Registers->Video_Input_Format[2] & EP956E_Video_Output_Format_2__VOUT_FMT) { default: case EP956E_Video_Output_Format_2__VOUT_FMT__Auto: if(is_Cap_YCC444) { Video_Params.FormatOut = COLORFORMAT_YCC444; } else if(is_Cap_YCC422) { Video_Params.FormatOut = COLORFORMAT_YCC422; } else { Video_Params.FormatOut = COLORFORMAT_RGB; } break; case EP956E_Video_Output_Format_2__VOUT_FMT__YCC444: Video_Params.FormatOut = COLORFORMAT_YCC444; break; case EP956E_Video_Output_Format_2__VOUT_FMT__YCC422: Video_Params.FormatOut = COLORFORMAT_YCC422; break; case EP956E_Video_Output_Format_2__VOUT_FMT__RGB: Video_Params.FormatOut = COLORFORMAT_RGB; break; } #ifdef MHL_CODE // Pack Pixel Mode if(EP956_VDO_Settings[Video_Params.VideoSettingIndex].Pix_Freq_Type > PIX_FREQ_74250KHz) { // Force to YCC422 Video_Params.FormatOut = COLORFORMAT_YCC422; } #endif // DVI mode settings overwrite if(!is_Cap_HDMI || (pEP956C_Registers->System_Configuration & EP956E_System_Configuration__HDMI_DIS) ) { Video_Params.FormatOut = COLORFORMAT_RGB; } // AFAR Video_Params.AFARate = ((pEP956C_Registers->Video_Input_Format[1] & EP956E_Video_Output_Format_1__AFAR) >> 4) | 0x08; // Video Change if(memcmp(&Video_Params, &pEP956C_Registers->Video_Params_Backup, 4) != 0) { // Timing change that AVMute is needed pEP956C_Registers->Video_Params_Backup = Video_Params; //VideoChg_TimeCount = 0; is_VideoChanging = 1; EP_DEV_DBG("Video Changing......\n"); } else if(memcmp(&Video_Params, &pEP956C_Registers->Video_Params_Backup, sizeof(VDO_PARAMS)) != 0) { // Format change which can by applied immediately pEP956C_Registers->Video_Params_Backup = Video_Params; HDMI_Tx_VideoFMT_Config(&Video_Params); } // Video Change Debouncing if(is_VideoChanging) { //if(VideoChg_TimeCount > AV_STABLE_TIME/EP956C_TIMER_PERIOD) //EP_DEV_DBG("delay 500ms+\n"); delay_100ms(5); //EP_DEV_DBG("delay 500ms-\n"); { HDMI_Tx_Video_Config(&Video_Params); is_VideoChanging = 0; //VideoChg_TimeCount = 0; // Report Video Change pEP956C_Registers->Interrupt_Flags |= EP956E_Interrupt_Flags__VIDEO_CHG; if(EP956C_GenerateInt && (pEP956C_Registers->Interrupt_Enable & EP956E_Interrupt_Enable__VIDEO_CHG) ) EP956C_GenerateInt(); } } // // Update Audio Params // Audio_Params.Interface = pEP956C_Registers->Audio_Interface & 0x8F; // DSDCK_POL, ..., SD_DIR, WS_M, WS_POL, SCK_POL Audio_Params.VideoSettingIndex = Video_Params.VideoSettingIndex; // Update Audio Type Audio_Params.AudioType = (pEP956C_Registers->Audio_Input_Format[0] & EP956E_Audio_Output_Format__AUDIO_TYPE) >> 6; // Update Audio Channel Number if(Audio_Params.AudioType == AUDIO_TYPE_IIS) { if(EP956_VDO_Settings[Video_Params.VideoSettingIndex].Pix_Freq_Type <= PIX_FREQ_27027KHz) { Audio_Params.ChannelNumber = 1; } else { Audio_Params.ChannelNumber = min(((pEP956C_Registers->Audio_Interface & 0x70) >> 4), pEP956C_Registers->EDID_AChannel_PCM); } } else if(Audio_Params.AudioType == AUDIO_TYPE_DSD) {
unsigned char EP932Controller_Task(void) { //DBG_printf(("EP932 EP932Controller_Task \r\n")); // Read Interrupt Flag and updat the internal information ReadInterruptFlags(); // Polling Hot-Plug every 80ms if(HTP_TimeCount > 80/EP932C_TIMER_PERIOD) { HTP_TimeCount = 0; ConnectionState = HDMI_Tx_HTPLG(); HTPLG_NOW = ConnectionState; if(HTPLG_LAST != HTPLG_NOW) { HTPLG_LAST = HTPLG_NOW; if(HTPLG_NOW == 0) { DBG_printf(("Without HotPlug\r\n")); EP_HDMI_DumpMessage(); } else { DBG_printf(("Detect HotPlug \r\n")); } } is_Hot_Plug = (ConnectionState == 1)? 1:0; if(is_Connected != ((ConnectionState)?1:0) ) { if(HP_ChangeCount++ >= 1) { // Accept continuous 1 error = 1*80 ms = 80 ms (Skip when low period < 80 ms) HP_ChangeCount = 0; is_Connected = ((ConnectionState)?1:0); } } else { HP_ChangeCount = 0; } if(is_Hot_Plug) { pEP932C_Registers->System_Status |= EP932E_System_Status__HTPLG; } else { pEP932C_Registers->System_Status &= ~EP932E_System_Status__HTPLG; } is_ReceiverSense = HDMI_Tx_RSEN(); // Only valid when TX is powered on if(TX_State > TXS_Wait_Upstream) { // Powered Up and have Input // Update RSEN if(is_ReceiverSense) { pEP932C_Registers->System_Status |= EP932E_System_Status__RSEN; } else { pEP932C_Registers->System_Status &= ~EP932E_System_Status__RSEN; } RSEN_ChangeCount = 0; // Read HSO VSO POL information EP932_Reg_Read(EP932_General_Control_4, DDC_Data, 1); Video_Params.HVPol = 0;//DDC_Data[0] & (EP932_DE_Control__VSO_POL | EP932_DE_Control__HSO_POL); } else { if(RSEN_ChangeCount++ >= 8) { // Accept continuous 8 error = 8*80 ms = 640 ms (Skip when low period < 640 ms) RSEN_ChangeCount = 0; pEP932C_Registers->System_Status &= ~EP932E_System_Status__RSEN; } } } // // Update EP932 Registers according to the System Process // //DBG_printf(("TX_State=%d \n",TX_State)); switch(TX_State) { case TXS_Search_EDID: if(is_Connected) { if(ReadEDID_TimeCount > 200/EP932C_TIMER_PERIOD) { unsigned char EDID_DDC_Status = 0; // Confirm Hot-Plug (time-out after 1s) if(!is_Hot_Plug) { if(ReadEDID_TimeCount <= 1000/EP932C_TIMER_PERIOD) break; DBG_printf(("WARNING: EDID detected without Hot-Plug for 1s\r\n")); } // Read EDID DBG_printf(("\r\nState Transist: Read EDID -> [TXS_Wait_Upstream] 0x%x\r\n",pEP932C_Registers->System_Configuration)); memset(pEP932C_Registers->Readed_EDID, 0xFF, 256); if(!(pEP932C_Registers->System_Configuration & EP932E_System_Configuration__FORCE_HDMI_CAP)){ EDID_DDC_Status = Downstream_Rx_read_EDID(pEP932C_Registers->Readed_EDID); if(EDID_DDC_Status) { //if(EDID_DDC_Status == EDID_STATUS_NoAct) { if(EDID_DDC_Status != EDID_STATUS_ChecksumError) { DBG_printf(("WARNING: EDID read failed 0x%02X\r\n", (int)EDID_DDC_Status)); if(ReadEDID_TimeCount <= 500/EP932C_TIMER_PERIOD) break; } } } ReadEDID_TimeCount = 0; // Set Output if(pEP932C_Registers->System_Configuration & EP932E_System_Configuration__FORCE_HDMI_CAP) { is_Cap_HDMI = 1; } else { is_Cap_HDMI = EDID_GetHDMICap(pEP932C_Registers->Readed_EDID); } if(is_Cap_HDMI) { DBG_printf(("Support HDMI")); // Default Capability is_Cap_YCC444 = is_Cap_YCC422 = 0; pEP932C_Registers->EDID_ASFreq = 0x07; pEP932C_Registers->EDID_AChannel = 1; pEP932C_Registers->EDID_VideoDataAddr = 0x00; pEP932C_Registers->EDID_AudioDataAddr = 0x00; pEP932C_Registers->EDID_SpeakerDataAddr = 0x00; pEP932C_Registers->EDID_VendorDataAddr = 0x00; if(!EDID_DDC_Status) { if(pEP932C_Registers->Readed_EDID[131] & 0x20) { // Support YCC444 is_Cap_YCC444 = 1; DBG_printf((" YCC444")); } if(pEP932C_Registers->Readed_EDID[131] & 0x10) { // Support YCC422 is_Cap_YCC422 = 1; DBG_printf((" YCC422")); } DBG_printf(("\r\n")); pEP932C_Registers->EDID_ASFreq = EDID_GetPCMFreqCap(pEP932C_Registers->Readed_EDID); DBG_printf(("EDID ASFreq = 0x%02X\r\n",(int)pEP932C_Registers->EDID_ASFreq)); pEP932C_Registers->EDID_AChannel = EDID_GetPCMChannelCap(pEP932C_Registers->Readed_EDID); DBG_printf(("EDID AChannel = 0x%02X\r\n",(int)pEP932C_Registers->EDID_AChannel)); pEP932C_Registers->EDID_VideoDataAddr = EDID_GetDataBlockAddr(pEP932C_Registers->Readed_EDID, 0x40); pEP932C_Registers->EDID_AudioDataAddr = EDID_GetDataBlockAddr(pEP932C_Registers->Readed_EDID, 0x20); pEP932C_Registers->EDID_SpeakerDataAddr = EDID_GetDataBlockAddr(pEP932C_Registers->Readed_EDID, 0x80); pEP932C_Registers->EDID_VendorDataAddr = EDID_GetDataBlockAddr(pEP932C_Registers->Readed_EDID, 0x60); } } else { DBG_printf(("Support DVI RGB only\r\n")); is_Cap_YCC444 = is_Cap_YCC422 = 0; pEP932C_Registers->EDID_ASFreq = pEP932C_Registers->EDID_AChannel = 0; } if(is_Cap_HDMI) pEP932C_Registers->EDID_Status = EDID_DDC_Status | EP932E_EDID_Status__HDMI; else pEP932C_Registers->EDID_Status = EDID_DDC_Status; DBG_printf(("Support Max Audio Channel %d\r\n", (int)pEP932C_Registers->EDID_AChannel+1)); DBG_printf(("Support Audio Freq 0x%02X\r\n", (int)pEP932C_Registers->EDID_ASFreq)); // Report EDID Change pEP932C_Registers->Interrupt_Flags |= EP932E_Interrupt_Flags__EDID_CHG; if(EP932C_GenerateInt && (pEP932C_Registers->Interrupt_Enable & EP932E_Interrupt_Enable__EDID_CHG) ) EP932C_GenerateInt(); TX_State = TXS_Wait_Upstream; } } else { pEP932C_Registers->EDID_Status = EDID_STATUS_NoAct; ReadEDID_TimeCount = 0; } break; case TXS_Wait_Upstream: if(!is_Connected) { TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(!(pEP932C_Registers->Power_Control & (EP932E_Power_Control__PD_HDMI | EP932E_Power_Control__PD_TOT)) ) { DBG_printf(("\r\nState Transist: Power Up -> [TXS_Stream]\r\n")); // Power Up HDMI_Tx_Power_Up(); TX_State = TXS_Stream; } else { // Check Force HDMI bit if(!is_Cap_HDMI) { if(pEP932C_Registers->System_Configuration & EP932E_System_Configuration__FORCE_HDMI_CAP) { TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } } } break; case TXS_Stream: #if defined(Enable_HDCP) if(!is_HDCP_Info_BKSV_Rdy && is_ReceiverSense && is_Hot_Plug) { // Get HDCP Info if(!Downstream_Rx_read_BKSV(pEP932C_Registers->HDCP_BKSV)) { pEP932C_Registers->HDCP_Status = EP932E_HDCP_Status__BKSV; } pEP932C_Registers->HDCP_BCAPS3[0] = Downstream_Rx_BCAPS(); is_HDCP_Info_BKSV_Rdy = 1; } #endif if(!is_Connected) { TXS_RollBack_Stream(); TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(pEP932C_Registers->Power_Control & (EP932E_Power_Control__PD_HDMI | EP932E_Power_Control__PD_TOT) ) { pEP932C_Registers->Power_Control |= EP932E_Power_Control__PD_HDMI; TXS_RollBack_Stream(); TX_State = TXS_Wait_Upstream; } #if defined(Enable_HDCP) else if(!((pEP932C_Registers->System_Configuration & EP932E_System_Configuration__HDCP_DIS) || is_VideoChanging) && is_ReceiverSense) { // Enable mute for transmiter video and audio HDMI_Tx_Mute_Enable(); DBG_printf(("\r\nState Transist: Start HDCP -> [TXS_HDCP]\r\n")); TX_State = TXS_HDCP; } #endif break; #if defined(Enable_HDCP) case TXS_HDCP: if(!is_Connected || !is_Hot_Plug) { TXS_RollBack_HDCP(); TXS_RollBack_Stream(); TXS_RollBack_Wait_Upstream(); TX_State = TXS_Search_EDID; } else if(pEP932C_Registers->Power_Control & (EP932E_Power_Control__PD_HDMI | EP932E_Power_Control__PD_TOT) ) { pEP932C_Registers->Power_Control |= EP932E_Power_Control__PD_HDMI; TXS_RollBack_HDCP(); TXS_RollBack_Stream(); TX_State = TXS_Wait_Upstream; } else if((pEP932C_Registers->System_Configuration & EP932E_System_Configuration__HDCP_DIS) || is_VideoChanging) { TXS_RollBack_HDCP(); TX_State = TXS_Stream; } else { pEP932C_Registers->HDCP_State = HDCP_Authentication_Task(is_ReceiverSense && is_Hot_Plug); pEP932C_Registers->HDCP_Status = HDCP_Get_Status(); } break; #endif } // // Update EP932 Registers for any time // // Mute Control if( (pEP932C_Registers->System_Configuration & EP932E_System_Configuration__AUDIO_DIS) || (TX_State < TXS_Stream) || is_VideoChanging || is_AudioChanging ) { HDMI_Tx_AMute_Enable(); } else { HDMI_Tx_AMute_Disable(); } if( (pEP932C_Registers->System_Configuration & EP932E_System_Configuration__VIDEO_DIS) || (TX_State < TXS_Stream) || is_VideoChanging ) { HDMI_Tx_VMute_Enable(); } else { HDMI_Tx_VMute_Disable(); } // HDMI Mode if(!is_Cap_HDMI || (pEP932C_Registers->System_Configuration & EP932E_System_Configuration__HDMI_DIS) ) { HDMI_Tx_DVI(); // Set to DVI mode (The Info Frame and Audio Packets would not be send) } else { HDMI_Tx_HDMI(); // Set to HDMI mode } ++Process_Dispatch_ID; if(Process_Dispatch_ID > 2) Process_Dispatch_ID = 0; switch(Process_Dispatch_ID) { case 0: // // Update Video Params // // Video Interface Video_Params.Interface = pEP932C_Registers->Video_Interface[0]; // Video Timing if(pEP932C_Registers->Video_Input_Format[0]) { // Manul set the Video Timing if(pEP932C_Registers->Video_Input_Format[0] < 128) { Video_Params.VideoSettingIndex = pEP932C_Registers->Video_Input_Format[0]; } else { Video_Params.VideoSettingIndex = pEP932C_Registers->Video_Input_Format[0] - (128 - EP932_VDO_Settings_IT_Start); } } // Select Sync Mode Video_Params.SyncMode = (pEP932C_Registers->Video_Interface[1] & EP932E_Video_Interface_Setting_1__SYNC) >> 2; // Select Color Space switch(pEP932C_Registers->Video_Interface[1] & EP932E_Video_Interface_Setting_1__COLOR) { default: case EP932E_Video_Interface_Setting_1__COLOR__Auto: switch(Video_Params.VideoSettingIndex) { case 4: case 5: case 16: case 19: case 20: case 31: case 32: case 33: case 34: case 39: case 40: case 41: case 46: case 47: // HD Timing Video_Params.ColorSpace = COLORSPACE_709; break; default: if(Video_Params.VideoSettingIndex && Video_Params.VideoSettingIndex < EP932_VDO_Settings_IT_Start) { // SD Timing Video_Params.ColorSpace = COLORSPACE_601; } else { // IT Timing Video_Params.ColorSpace = COLORSPACE_709; } } break; case EP932E_Video_Interface_Setting_1__COLOR__601: Video_Params.ColorSpace = COLORSPACE_601; break; case EP932E_Video_Interface_Setting_1__COLOR__709: Video_Params.ColorSpace = COLORSPACE_709; break; } // Set Input Format switch(pEP932C_Registers->Video_Interface[1] & EP932E_Video_Interface_Setting_1__VIN_FMT) { default: case EP932E_Video_Interface_Setting_1__VIN_FMT__RGB: Video_Params.FormatIn = COLORFORMAT_RGB; Video_Params.FormatOut = COLORFORMAT_RGB; break; case EP932E_Video_Interface_Setting_1__VIN_FMT__YCC444: Video_Params.FormatIn = COLORFORMAT_YCC444; if(is_Cap_YCC444) { Video_Params.FormatOut = COLORFORMAT_YCC444; } else if(is_Cap_YCC422) { Video_Params.FormatOut = COLORFORMAT_YCC422; } else { Video_Params.FormatOut = COLORFORMAT_RGB; } break; case EP932E_Video_Interface_Setting_1__VIN_FMT__YCC422: Video_Params.FormatIn = COLORFORMAT_YCC422; if(is_Cap_YCC444) { Video_Params.FormatOut = COLORFORMAT_YCC444; } else if(is_Cap_YCC422) { Video_Params.FormatOut = COLORFORMAT_YCC422; } else { Video_Params.FormatOut = COLORFORMAT_RGB; } break; } //add by eric.lu // Set Output Format switch(pEP932C_Registers->Video_Output_Format) { default: case 0: // Auto, don't need change setting. break; case 1: // Force to YUV444 output format Video_Params.FormatOut = COLORFORMAT_YCC444; break; case 2: // Force to YUV422 output format Video_Params.FormatOut = COLORFORMAT_YCC422; break; case 3: // Force to RGB444 output format Video_Params.FormatOut = COLORFORMAT_RGB; break; } // end of add // DVI mode settings overwrite if(!is_Cap_HDMI || (pEP932C_Registers->System_Configuration & EP932E_System_Configuration__HDMI_DIS) ) { Video_Params.FormatOut = COLORFORMAT_RGB; } // AFAR Video_Params.AFARate = ((pEP932C_Registers->Video_Input_Format[1] & EP932E_Video_Input_Format_1__AFAR) >> 4) | 0x08; // add by eric.lu // SCAN Video_Params.SCAN = (pEP932C_Registers->Video_Input_Format[1] & EP932E_Video_Input_Format_1__SCAN); // end of add // Video Change if(memcmp(&Video_Params, &pEP932C_Registers->Video_Params_Backup, sizeof(VDO_PARAMS)) != 0) { if(memcmp(&Video_Params, &pEP932C_Registers->Video_Params_Backup, 6) != 0) { is_TimingChanging = 1; } // DBG_printf(("Video_Params new: interface 0x%02X, Vindex 0x%02X, HV 0x%02X, mode 0x%02X, Fin 0x%02X, Fout 0x%02X, color 0x%02X, AFAR 0x%02X\r\n",(int)Video_Params.Interface, (int)Video_Params.VideoSettingIndex, (int)Video_Params.HVPol ,(int)Video_Params.SyncMode, (int)Video_Params.FormatIn, (int)Video_Params.FormatOut, (int)Video_Params.ColorSpace, (int)Video_Params.AFARate)); // DBG_printf(("Video_Params old: interface 0x%02X, Vindex 0x%02X, HV 0x%02X, mode 0x%02X, Fin 0x%02X, Fout 0x%02X, color 0x%02X, AFAR 0x%02X\r\n",(int)pEP932C_Registers->Video_Params_Backup.Interface, (int)pEP932C_Registers->Video_Params_Backup.VideoSettingIndex, (int)pEP932C_Registers->Video_Params_Backup.HVPol ,(int)pEP932C_Registers->Video_Params_Backup.SyncMode, (int)pEP932C_Registers->Video_Params_Backup.FormatIn, (int)pEP932C_Registers->Video_Params_Backup.FormatOut, (int)pEP932C_Registers->Video_Params_Backup.ColorSpace, (int)pEP932C_Registers->Video_Params_Backup.AFARate)); pEP932C_Registers->Video_Params_Backup = Video_Params; VideoChg_TimeCount = 0; is_VideoChanging = 1; } // Video Change Debouncing if(is_VideoChanging) { if(VideoChg_TimeCount > AV_STABLE_TIME/EP932C_TIMER_PERIOD) { DBG_printf(("### VideoChanging \r\n")); if(is_TimingChanging) EP932Controller_Reset(); HDMI_Tx_Video_Config(&Video_Params); if(is_TimingChanging) { if(!is_AudioChanging) HDMI_Tx_Audio_Config(&Audio_Params); } is_TimingChanging = 0; is_VideoChanging = 0; VideoChg_TimeCount = 0; // Report Video Change pEP932C_Registers->Interrupt_Flags |= EP932E_Interrupt_Flags__VIDEO_CHG; if(EP932C_GenerateInt && (pEP932C_Registers->Interrupt_Enable & EP932E_Interrupt_Enable__VIDEO_CHG) ) EP932C_GenerateInt(); } } break; case 1: // // Update Audio Params // Audio_Params.Interface = pEP932C_Registers->Audio_Interface & 0x0F; // IIS, WS_M, WS_POL, SCK_POL Audio_Params.VideoSettingIndex = Video_Params.VideoSettingIndex; // Update Audio Channel Number if(EP932_VDO_Settings[Video_Params.VideoSettingIndex].Pix_Freq_Type <= PIX_FREQ_27027KHz) { Audio_Params.ChannelNumber = 1; } else { Audio_Params.ChannelNumber = min(((pEP932C_Registers->Audio_Interface & 0x70) >> 4), pEP932C_Registers->EDID_AChannel); } // Update VFS if(Audio_Params.VideoSettingIndex < EP932_VDO_Settings_IT_Start) { // Pixel Clock Type shift (59.94/60) Audio_Params.VFS = (pEP932C_Registers->Video_Input_Format[1] & EP932E_Video_Input_Format_1__VIF)? 1:0; } else { Audio_Params.VFS = 0; } Audio_Params.NoCopyRight = (pEP932C_Registers->Audio_Input_Format & EP932E_Audio_Input_Format__NoCopyRight)?1:0; // Write Frequency info (Use ADO_FREQ or Auto) switch( pEP932C_Registers->Audio_Input_Format & EP932E_Audio_Input_Format__ADO_FREQ ) { case EP932E_Audio_Input_Format__ADO_FREQ__32000Hz: Audio_Params.InputFrequency = ADSFREQ_32000Hz; // Disable Down Sample Audio_Params.ADSRate = 0; break; default: case EP932E_Audio_Input_Format__ADO_FREQ__44100Hz: Audio_Params.InputFrequency = ADSFREQ_44100Hz; // Disable Down Sample Audio_Params.ADSRate = 0; break; case EP932E_Audio_Input_Format__ADO_FREQ__48000Hz: Audio_Params.InputFrequency = ADSFREQ_48000Hz; // Disable Down Sample Audio_Params.ADSRate = 0; break; case EP932E_Audio_Input_Format__ADO_FREQ__88200Hz: Audio_Params.InputFrequency = ADSFREQ_88200Hz; if(pEP932C_Registers->EDID_ASFreq & 0x08) { // 88.2kHz // Disable Down Sample Audio_Params.ADSRate = 0; } else { // Enable Down Sample 1/2 Audio_Params.ADSRate = 1; } break; case EP932E_Audio_Input_Format__ADO_FREQ__96000Hz: Audio_Params.InputFrequency = ADSFREQ_96000Hz; if(pEP932C_Registers->EDID_ASFreq & 0x10) { // 96kHz // Disable Down Sample Audio_Params.ADSRate = 0; } else { if(pEP932C_Registers->EDID_ASFreq & 0x04) { // 48kHz // Enable Down Sample 1/2 Audio_Params.ADSRate = 1; } else { // Enable Down Sample 1/3 Audio_Params.ADSRate = 2; } } break; case EP932E_Audio_Input_Format__ADO_FREQ__176400Hz: Audio_Params.InputFrequency = ADSFREQ_176400Hz; if(pEP932C_Registers->EDID_ASFreq & 0x20) { // 176kHz // Disable Down Sample Audio_Params.ADSRate = 0; } else { if(pEP932C_Registers->EDID_ASFreq & 0x08) { // 88.2kHz // Enable Down Sample 1/2 Audio_Params.ADSRate = 1; } else { // Enable Down Sample 1/4 Audio_Params.ADSRate = 3; } } break; case EP932E_Audio_Input_Format__ADO_FREQ__192000Hz: Audio_Params.InputFrequency = ADSFREQ_192000Hz; if(pEP932C_Registers->EDID_ASFreq & 0x40) { // 192kHz // Disable Down Sample Audio_Params.ADSRate = 0; } else { if(pEP932C_Registers->EDID_ASFreq & 0x10) { // 96kHz // Enable Down Sample 1/2 Audio_Params.ADSRate = 1; } else { // Enable Down Sample 1/4 Audio_Params.ADSRate = 3; } } break; } // Audio Change if(memcmp(&Audio_Params, &pEP932C_Registers->Audio_Params_Backup, sizeof(ADO_PARAMS)) != 0) { pEP932C_Registers->Audio_Params_Backup = Audio_Params; AudioChg_TimeCount = 0; is_AudioChanging = 1; } // Audio Change Debouncing if(is_AudioChanging) { if(AudioChg_TimeCount > AV_STABLE_TIME/EP932C_TIMER_PERIOD) { HDMI_Tx_Audio_Config(&Audio_Params); is_AudioChanging = 0; AudioChg_TimeCount = 0; // Report Audio Change pEP932C_Registers->Interrupt_Flags |= EP932E_Interrupt_Flags__AUDIO_CHG; if(EP932C_GenerateInt && (pEP932C_Registers->Interrupt_Enable & EP932E_Interrupt_Enable__AUDIO_CHG) ) EP932C_GenerateInt(); } } break; case 2: // Update TREG if(pEP932C_Registers->Analog_Test_Control != Backup_Analog_Test_Control) { Backup_Analog_Test_Control = pEP932C_Registers->Analog_Test_Control; if(pEP932C_Registers->Analog_Test_Control & 0x01) { EP932_Reg_Set_Bit(EP932_Color_Space_Control, 0x01); } else { EP932_Reg_Clear_Bit(EP932_Color_Space_Control, 0x01); } if(pEP932C_Registers->Analog_Test_Control & 0x02) { EP932_Reg_Set_Bit(EP932_Color_Space_Control, 0x02); } else { EP932_Reg_Clear_Bit(EP932_Color_Space_Control, 0x02); } } break; } // Return the status if(pEP932C_Registers->Power_Control & (EP932E_Power_Control__PD_HDMI | EP932E_Power_Control__PD_TOT)) { return EP932C_TASK_Idle; } else { return EP932C_TASK_Pending; } }