//------------------------------------------------------------------------------ // Function: ProcessOdckStop // Description: handles the ODCK (internally pclk) stop interrupt //------------------------------------------------------------------------------ static void ProcessOdckStop(void) { RegisterModify(REG__DRIVE_CNTL, MSK__ODCK_STRENGTH,CLEAR); //clear the ODCK first RegisterModify(REG__SYS_PSTOP,BIT__PSTOP_EN, CLEAR); //disable PSTOP feature RegisterModify(REG__INTR7,BIT__PCLK_STOP,SET); //clear the interrupt }
//------------------------------------------------------------------------------ // Function: AutoVideoSetup // Description: Setup registers for Auto Video Mode // // Notes: Compile time configuration is done using CONF__* defines in config.h //------------------------------------------------------------------------------ static void AutoVideoSetup(void) { const uint8_t unmuteTimeConf[] = {0xFF,0x00,0x00,0xFF,0x00,0x00}; RegisterWriteBlock(REG__WAIT_CYCLE, (uint8_t *)&unmuteTimeConf[0],6); //video unmute wait RegisterWrite(REG__VID_CTRL, (BIT__IVS & CONF__VSYNC_INVERT) | (BIT__IHS & CONF__HSYNC_INVERT) ); //set HSYNC,VSNC polarity RegisterWrite(REG__RPI_AUTO_CONFIG, BIT__CHECKSUM_EN|BIT__V_UNMUTE_EN|BIT__HCDP_EN|BIT__TERM_EN); //auto config RegisterWrite(REG__SRST, BIT__SWRST_AUTO); //enable auto sw reset RegisterWrite(REG__VID_AOF, CONF__OUTPUT_VIDEO_FORMAT); //set output video format RegisterModify(REG__AEC_CTRL, BIT__AVC_EN, SET); //enable auto video configuration #if (CONF__ODCK_LIMITED == ENABLE) RegisterModify(REG__SYS_PSTOP, MSK__PCLK_MAX, CONF__PCLK_MAX_CNT); #endif //(CONF__ODCK_LIMITED==ENABLE) #if (PEBBLES_ES1_ZONE_WORKAROUND == ENABLE) RegisterWrite(REG__AVC_EN2, BIT__AUTO_DC_CONF); //mask out auto configure deep color clock RegisterWrite(REG__VIDA_XPCNT_EN, BIT__VIDA_XPCNT_EN); //en read xpcnt #endif //(PEBBLES_ES1_ZONE_WORKAROUND == ENABLE) #if (PEBBLES_STARTER_NO_CLK_DIVIDER == ENABLE) RegisterModify(REG__AVC_EN2, BIT__AUTO_CLK_DIVIDER,SET); //msk out auto clk divider #endif //(PEBBLES_STARTER_NO_CLK_DIVIDER == ENABLE) }
//------------------------------------------------------------------------------ // Function: TurnVideoMute // Description: Enable or disable Video Mute // Note: ON is to mute, OFF is to unmute //------------------------------------------------------------------------------ void TurnVideoMute(uint8_t qOn) { if (qOn) //mute { RegisterModify(REG__HDMI_MUTE, BIT__VIDM, SET); CurrentStatus.VideoState = STATE_VIDEO__MUTED; DEBUG_PRINT(("Video off\n")); } else //unmute { #if(PEBBLES_ES1_ZONE_WORKAROUND == ENABLE) if((RegisterRead(REG__STATE)& BIT__SCDT) //check sync status &&ConfigureZone()) #endif { #if (CONF__ODCK_LIMITED==ENABLE) RegisterModify(REG__SYS_PSTOP,BIT__PSTOP_EN, SET); //enable PSTOP feature RegisterModify(REG__DRIVE_CNTL, MSK__ODCK_STRENGTH,SET); //clear the ODCK first #endif// #if (CONF__ODCK_LIMITED==ENABLE) RegisterModify(REG__HDMI_MUTE, BIT__VIDM, CLEAR); CurrentStatus.VideoState = STATE_VIDEO__ON; DEBUG_PRINT(("Video on\n")); #if (PEBBLES_VIDEO_STATUS_2ND_CHECK==ENABLE) TIMER_Set(TIMER__VIDEO, VIDEO_STABLITY_CHECK_INTERVAL); // start the video timer CurrentStatus.VideoStabilityCheckCount = 0; #endif//#if (PEBBLES_VIDEO_STATUS_2ND_CHECK==ENABLE) } } }
//------------------------------------------------------------------------------ // Function: TurnPowerDown // Description: Enter or exit powerdown mode // Note: ON is to powerdown, OFF is to wakeup //------------------------------------------------------------------------------ void TurnPowerDown(uint8_t qOn) { if (qOn) //powerDown { RegisterModify(REG__SYS_CTRL1, BIT__PD, CLEAR); } else //wakeup { RegisterModify(REG__SYS_CTRL1, BIT__PD, SET); DEBUG_PRINT(("wake up\n")); } }
//------------------------------------------------------------------------------ // Function: System_Init // Description: One time initialization at statup //------------------------------------------------------------------------------ static void SystemInit(void) { const uint8_t EQTable[] = {0x8A,0xAA,0x1A,0x2A}; while( (RegisterRead(REG__BSM_STAT)& BIT__BOOT_DONE )== 0) //wait done DEBUG_PRINT(("BIT__BOOT_DONE = 0; \n")); if((RegisterRead(REG__BSM_STAT)& BIT__BOOT_ERROR)!=0) DEBUG_PRINT(("First Boot error! \n")); RegisterModify(REG__HPD_HW_CTRL,MSK__INVALIDATE_ALL, SET); //disable auto HPD conf at RESET TurnAudioMute(ON); TurnVideoMute(ON); #if(PEBBLES_ES1_STARTER_CONF==ENABLE) RegisterWrite(REG__TERMCTRL2, VAL__45OHM); //1.term default value RegisterWrite(REG__FACTORY_A87,0x43); //2.Set PLL mode to internal and set selcalrefg to F RegisterWrite(REG__FACTORY_A81,0x18); //Set PLL zone to auto and set Div20 to 1 RegisterWrite(REG__DRIVE_CNTL,0x64); //3.change output strength, RegisterWrite(REG__FACTORY_ABB,0x04); //4.desable DEC_CON RegisterWriteBlock(REG__FACTORY_A92,(uint8_t *)&EQTable[0],4);//5.Repgrogram EQ table RegisterWrite(REG__FACTORY_AB5,0x40); //EnableEQ RegisterWrite(REG__FACTORY_9E5, 0x02); //6. DLL by pass RegisterWrite(REG__FACTORY_A89,0x00); //7. configure the PLLbias RegisterWrite(REG__FACTORY_00E,0x40); //for ES1.1 conf only #endif CEC_Init(); //set recommended values RegisterWrite(REG__AACR_CFG1, CONF__AACR_CFG1_VALUE); //pll config #1 RegisterWrite(REG__CBUS_PAD_SC, VAL__SC_CONF); //CBUS slew rate RegisterWrite(REG__SRST, BIT__SWRST_AUTO); //enable auto sw reset RegisterWrite(REG__INFM_CLR,BIT__CLR_GBD|BIT__CLR_ACP); //clr GBD & ACP RegisterWrite(REG__ECC_HDCP_THRES, CONF__HDCPTHRESH & 0xff); //HDCP threshold low uint8_t RegisterWrite(REG__ECC_HDCP_THRES+1, (CONF__HDCPTHRESH>>8) & 0xff); //HDCP threshold high uint8_t AutoVideoSetup(); AutoAudioSetup(); SetupInterruptMasks(); InitializePortSwitch(); TurnPowerDown(OFF); RegisterModify(REG__HPD_HW_CTRL,MSK__INVALIDATE_ALL, CLEAR); //CLEAR disable auto HPD conf /* Inti Hdmi Info frame related chip registers and data */ HdmiInitIf (); }
//------------------------------------------------------------------------------ // Function Name: SiI_CEC_GetCommand // Function Description: This function gets data from CEC Reception // // Accepts: pSiI_CEC // Returns: none // Globals: none //------------------------------------------------------------------------------ uint8_t SiI_CEC_GetCommand( SiI_CEC_t * pSiI_CEC ) { uint8_t error = FALSE; uint8_t bCount; bCount = pSiI_CEC->bCount & 0x0f; // extract uint8_t counter, ignore frame counter if ( !(pSiI_CEC->bCount & BIT_MSG_ERROR) ) RegisterReadBlock(REG__CEC_RX_CMD_HEADER, &pSiI_CEC->bDestOrRXHeader , bCount + 2); else error = 1; // Clear CLR_RX_FIFO_CUR; // Clear current frame from Rx FIFO RegisterModify(REG__CEC_RX_CONTROL, BIT_CLR_RX_FIFO_CUR, BIT_CLR_RX_FIFO_CUR ); // Check if more frame in Rx FIFO, if yes get uint8_t count of next frame. pSiI_CEC->bRXNextCount = 0; if( pSiI_CEC->bCount & 0xF0 ) { pSiI_CEC->bRXNextCount = RegisterRead(REG__CEC_RX_COUNT); } return error; }
//------------------------------------------------------------------------------ // Function Name: SiI_918x_Start // Function Description: Intilize Stream Switch Device // CEC Software Connection #1 //------------------------------------------------------------------------------ //void SiI_918x_Start( void ) void CEC_Init( void ) { // uint8_t cec_phyAddr[2]; #if(CONF__CEC_ENABLE == ENABLE) DEBUG_PRINT(("\nStream switch start\n")); //CEC workaround for ES0 GPIO_ClearCecD(); RegisterModify(REG__CEC_CONFIG_CPI,BIT__CEC_PASS_THROUGH,CLEAR); if((RegisterRead(DEV_REV_RX)& 0x0F)==VAL__REV_1_2) //if rev1.2 CEC by default reset RegisterModify(REG__C0_SRST2, BIT__CEC_SRST, SET); //0 is reset, 1 is normal else RegisterBitToggle(REG__C0_SRST2,BIT__CEC_SRST); RegisterWrite(REG__SLAVE_ADDR_EDID,CONF__I2C_SLAVE_PAGE_9); RegisterWrite(REG__SLAVE_ADDR_CEC,CONF__I2C_SLAVE_PAGE_8); // Set CEC device type = TV and logical address to capture. InitiatorAddress = CEC_LOGADDR_UNREGORBC_MSG ; if( CEC_CAPTURE_ID_Set( InitiatorAddress ) ) { DEBUG_PRINT(("\n Cannot init CEC")); } // // 4. Initialize Event Descriptor // CEC_event_descriptor_clear(); // Enumirate as an TV bCECTask = SiI_CEC_Enumiration; bEnumType = SiI_EnumTV; #endif // #if(CONF__CEC_ENABLE == ENABLE) //==================== // 5. Program EDID and set port specific address space. // Program (a) EDID and (b) Physical address //==================== ProgramEDID(); }
static void ProcessScdtModeChange(void) { uint8_t bStateReg; static uint8_t current_scdt = 0; bStateReg = RegisterRead(REG__STATE); //read scdt off or on if (bStateReg & BIT__SCDT) //SCDT on { //mute the audio if it is still on, it happens when SCDT off and on in a very short time if(CurrentStatus.AudioState == STATE_AUDIO__ON) { TurnAudioMute(ON); CurrentStatus.AudioState = STATE_AUDIO__MUTED; } CurrentStatus.ColorDepth = 0; RegisterModify(REG__TMDS_CCTRL2, MSK__DC_CTL, VAL__DC_CTL_8BPP_1X); CurrentStatus.ResolutionChangeCount = 0; CurrentStatus.VideoStabilityCheckCount = 0; CurrentStatus.AudioState = STATE_AUDIO__REQUEST_AUDIO; RegisterModify(REG__ECC_CTRL, BIT__CAPCNT, SET); //clear the error cont CurrentStatus.VideoState = STATE_VIDEO__UNMUTE; TIMER_Set(TIMER__VIDEO, VIDEO_UNMUTE_TIMEOUT); // start the video timer HdmiInitIf(); //yma add for 3D packet support printk("sii9233a SCDT on!\n"); if( current_scdt == 0 ) { sii9233a_output_mode_trigger(1); current_scdt = 1; } } else //SCDT off { TurnVideoMute(ON); printk("sii9233a SCDT off!\n"); if( current_scdt == 1 ) { sii9233a_output_mode_trigger(0); current_scdt = 0; } } }
//------------------------------------------------------------------------------ // Function: ConfigureSelectedPort // Description: Setup new input port after port change //------------------------------------------------------------------------------ static void ConfigureSelectedPort(void) { switch (CurrentStatus.PortSelection) { case PORT_SELECT__PORT_0: { RegisterModify(REG__PORT_SWTCH2, MSK__PORT_EN,VAL__PORT0_EN); //select port 0 RegisterWrite(REG__PORT_SWTCH, BIT__DDC0_EN); //select DDC 0 HAL_VccEnable(ON); } break; case PORT_SELECT__PORT_1: { RegisterModify(REG__PORT_SWTCH2, MSK__PORT_EN,VAL__PORT1_EN); //select port 1 RegisterWrite(REG__PORT_SWTCH, BIT__DDC1_EN); //select DDC 1 HAL_VccEnable(ON); } break; case PORT_SELECT__PORT_2: { RegisterModify(REG__PORT_SWTCH2, MSK__PORT_EN,VAL__PORT2_EN); //select port 2 RegisterWrite(REG__PORT_SWTCH, BIT__DDC2_EN); //select DDC 2 HAL_VccEnable(ON); } break; case PORT_SELECT__PORT_3: { RegisterModify(REG__PORT_SWTCH2, MSK__PORT_EN,VAL__PORT3_EN); //select port 3 RegisterWrite(REG__PORT_SWTCH, BIT__DDC3_EN); //select DDC 3 HAL_VccEnable(ON); } break; case PORT_SELECT__PORT_7: { DEBUG_PRINT(("turn off 3V power! \n")); //power down HAL_VccEnable(OFF); } break; } //end of switch }
uint8_t SiI_CEC_SetSnoop ( uint8_t bSnoopAddr, bool_t qOn ) { uint8_t error = FALSE; if ( qOn ) { RegisterModify(REG__CEC_DEBUG_3,BIT_SNOOP_EN, BIT_SNOOP_EN); bSnoopAddr <<= 4; } else { RegisterModify(REG__CEC_DEBUG_3, BIT_SNOOP_EN, CLEAR); bSnoopAddr = 0; } RegisterWriteBlock(REG__CEC_DEBUG_2, &bSnoopAddr, 1); return error; }
void sii_set_hdmi_port(char port) { if( (port>=0) && (port<4) ) { RegisterWrite(REG__PORT_SWTCH, (1<<(port+4)) ); RegisterModify(REG__PORT_SWTCH2, MSK__PORT_EN, port); } return ; }
//------------------------------------------------------------------------------ // Function: TurnAudioMute // Description: // Note: ON is to mute, OFF is to unmute //------------------------------------------------------------------------------ void TurnAudioMute (uint8_t qOn) { if (qOn) //mute { //mute audio RegisterModify(REG__HDMI_MUTE, BIT__AUDM, SET); //AAC off RegisterModify(REG__AEC_CTRL, BIT__AAC_EN, CLEAR); RegisterModify(REG__INTR5_UNMASK, BIT__AACDONE, CLEAR); //AAC intr off //power down the audio DAC HAL_PowerDownAudioDAC(); DEBUG_PRINT(("Audio off\n")); } else //unmute { //AAC on RegisterModify(REG__INTR5_UNMASK, BIT__AACDONE, SET); //AAC intr on RegisterModify(REG__AEC_CTRL, (BIT__AAC_EN ), SET); //AAC enable //unmute audio RegisterModify(REG__HDMI_MUTE, BIT__AUDM, CLEAR); //power up the audio DAC if(CurrentStatus.AudioMode!=AUDIO_MODE__HBR) HAL_WakeUpAudioDAC(); DEBUG_PRINT(("Audio on\n")); } }
//------------------------------------------------------------------------------ // Function: AutoAudioSetup // Description: Setup registers for Auto Audio Mode //------------------------------------------------------------------------------ static void AutoAudioSetup(void) { uint8_t abAecEnables[3]; RegisterModify(REG__ACR_CTRL3, MSK__CTS_THRESH, VAL__CTS_THRESH( CONF__CTS_THRESH_VALUE )); abAecEnables[0] = (BIT__SYNC_DETECT | BIT__CKDT_DETECT | BIT__CABLE_UNPLUG ); abAecEnables[1] = (BIT__HDMI_MODE_CHANGED | BIT__CTS_REUSED | BIT__AUDIO_FIFO_UNDERUN | BIT__AUDIO_FIFO_OVERRUN | BIT__FS_CHANGED | BIT__H_RES_CHANGED ); #if (CONF__VSYNC_OVERFLOW != ENABLE) abAecEnables[2] = (BIT__V_RES_CHANGED ); #endif RegisterWriteBlock(REG__AEC_EN1, abAecEnables, 3); RegisterModify(REG__AEC_CTRL, BIT__CTRL_ACR_EN, SET); }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ // Function: SystemDataReset // Description: Re-initialize receiver state //------------------------------------------------------------------------------ void SystemDataReset(void) { TurnAudioMute(ON); TurnVideoMute(ON); CurrentStatus.ResolutionChangeCount = 0; CurrentStatus.ColorDepth = 0; CurrentStatus.AudioMode = AUDIO_MODE__NOT_INIT; RegisterModify(REG__TMDS_CCTRL2, MSK__DC_CTL, VAL__DC_CTL_8BPP_1X); ConfigureSelectedPort(); }
uint8_t SiI_CEC_SetCommand( SiI_CEC_t * pSiI_CEC ) { uint8_t error = FALSE; uint8_t cec_int_status_reg[2]; uint8_t sw_retry_counter = 0 ; // Clear Tx Buffer RegisterModify(REG__CEC_DEBUG_3, BIT_FLUSH_TX_FIFO, BIT_FLUSH_TX_FIFO); DEBUG_PRINT(("\n TX: HDR[0x%02X],OPC[0x%02X],OPR[0x%02X, %02X, %02X]", (int)pSiI_CEC->bDestOrRXHeader, (int)pSiI_CEC->bOpcode, (int)pSiI_CEC->bOperand[0], (int)pSiI_CEC->bOperand[1], (int)pSiI_CEC->bOperand[2])) ; #ifdef CEC_TX_AUTO_CALC_ENABLED // // Enable TX_AUTO_CALC // RegisterWrite(REG__CEC_TRANSMIT_DATA, BIT__TX_AUTO_CALC); #endif// CEC_TX_AUTO_CALC_ENABLED // // Clear Tx-related buffers; write 1 to bits to be clear directly; writing 0 has no effect on the status bit // cec_int_status_reg[0] = 0x64 ; // Clear Tx Transmit Buffer Full Bit, Tx msg Sent Event Bit, and Tx FIFO Empty Event Bit cec_int_status_reg[1] = 0x02 ; // Clear Tx Frame Retranmit Count Exceeded Bit. RegisterWriteBlock(REG__CEC_INT_STATUS_0, cec_int_status_reg, 2); // Write Source and Destination address RegisterWrite(REG__CEC_TX_DEST,pSiI_CEC->bDestOrRXHeader); // Send CEC Opcode AND up to 15 Operands RegisterWriteBlock( REG__CEC_TX_COMMAND, &pSiI_CEC->bOpcode, pSiI_CEC->bCount + 1); if( error ) { DEBUG_PRINT(("\n SiI_CEC_SetCommand(): Fail to write CEC opcode and operands\n")) ; } #ifndef CEC_TX_AUTO_CALC_ENABLED // // Write Operand count and activate send // RegisterWrite(REG__CEC_TRANSMIT_DATA, BIT_TRANSMIT_CMD | pSiI_CEC->bCount ); #endif // CEC_TX_AUTO_CALC_ENABLED return error; }//e.o. uint8_t SiI_CEC_SetCommand( SiI_CEC_t * pSiI_CEC )
//------------------------------------------------------------------------------ // Function: ResetVideoControl // Description: // Note: check pclk status to configure the zone //------------------------------------------------------------------------------ uint8_t ResetVideoControl(void) { if(RegisterRead(REG__HDMI_MUTE)&BIT__VIDM_STATUS) { DEBUG_PRINT(("reset video control\n")); TurnVideoMute(ON); CurrentStatus.ColorDepth = 0; RegisterModify(REG__TMDS_CCTRL2, MSK__DC_CTL, VAL__DC_CTL_8BPP_1X); ResetZoneControl(); return FALSE; } else //video unmute status OK { TurnVideoMute(OFF); return TRUE; } }
uint8_t PclkCheck(void) { uint8_t xpcnt0_0; uint8_t xpcnt1_0; uint8_t xpcnt0_1; uint8_t xpcnt1_1; uint8_t wrongzone = 0; if((RegisterRead(REG__STATE))&BIT__PCLK_STABLE) //pclk stable { xpcnt0_0 = RegisterRead(0x06E); xpcnt1_0 = RegisterRead(0x06F); RegisterWrite(0x069,0x80); //change base // DEBUG_PRINT(("full cnt=%02X %02X ",(int)xpcnt0_0, (int)xpcnt1_0)); xpcnt0_1 = RegisterRead(0x06E); xpcnt1_1 = RegisterRead(0x06F); // DEBUG_PRINT(("half cnt=%02X %02X\n",(int)xpcnt0_1, (int)xpcnt1_1)); RegisterWrite(0x069,0xFF); if((xpcnt0_0==xpcnt0_1)&&(xpcnt1_0 <= xpcnt1_1)) //if xpcnt changes wrongzone=1; else return TRUE; } else { wrongzone=1; } if(wrongzone==1) { DEBUG_PRINT(("pclk stopped")); TurnVideoMute(ON); CurrentStatus.ColorDepth = 0; RegisterModify(REG__TMDS_CCTRL2, MSK__DC_CTL, VAL__DC_CTL_8BPP_1X); } return FALSE; }
static void ConfigureDeepColor(void) { uint8_t abDcCtlVal1x[] = { VAL__DC_CTL_8BPP_1X, VAL__DC_CTL_10BPP_1X, VAL__DC_CTL_12BPP_1X, 0 }; uint8_t abDcCtlVal2x[] = { VAL__DC_CTL_8BPP_2X, VAL__DC_CTL_10BPP_2X, VAL__DC_CTL_12BPP_2X, 0 }; uint8_t bColorDepth; uint8_t bDcCtlValue; uint8_t vStatus; bColorDepth = RegisterRead(REG__DC_STAT) & MSK__PIXEL_DEPTH; if (bColorDepth != CurrentStatus.ColorDepth) { if(CurrentStatus.VideoState == STATE_VIDEO__ON) vStatus = ON; CurrentStatus.ColorDepth = bColorDepth; if(vStatus == ON) TurnVideoMute(ON); //value is 2x if muxYC output is enabled if (RegisterRead(REG__VID_AOF) & BIT__MUXYC) { bDcCtlValue = abDcCtlVal2x[ bColorDepth ]; } else { bDcCtlValue = abDcCtlVal1x[ bColorDepth ]; } RegisterModify(REG__TMDS_CCTRL2, MSK__DC_CTL, bDcCtlValue); RegisterBitToggle(REG__SRST2, BIT__DCFIFO_RST); //reset the deep color FIFO DEBUG_PRINT(("DC stat=%02X ctl=%02X\n", (int)bColorDepth, (int)bDcCtlValue)); if(vStatus == ON) TurnVideoMute(OFF); } }
//------------------------------------------------------------------------------ // Function Name: SiI_CEC_IntProcessing // Function Description: This function is called on interrupt events // it makes interrut service // Accepts: SiI_CEC_Int_t * pInt // Returns: none // Globals: none //------------------------------------------------------------------------------ uint8_t CEC_IntProcessing ( SiI_CEC_Int_t * pInt ) { uint8_t error = FALSE; uint8_t cec_int_status_reg[2]; // Get Interrupts pInt->bTXState = 0; pInt->bCECErrors = 0; pInt->bRXState = 0; RegisterReadBlock(REG__CEC_INT_STATUS_0,cec_int_status_reg,2); { // Poll Interrupt if( (cec_int_status_reg[0] & 0x7F) || cec_int_status_reg[1] ) { DEBUG_PRINT(("\nA6A7Reg: %02X %02X", (int) cec_int_status_reg[0], (int) cec_int_status_reg[1])); // Clear interrupts if ( cec_int_status_reg[1] & BIT_FRAME_RETRANSM_OV ) { DEBUG_PRINT(("\n!CEC_A7_TX_RETRY_EXCEEDED![%02X][%02X]",(int) cec_int_status_reg[0], (int) cec_int_status_reg[1])); // flash TX otherwise after writing clear interrupt // BIT_FRAME_RETRANSM_OV the TX command will be re-send RegisterModify(REG__CEC_DEBUG_3,BIT_FLUSH_TX_FIFO, BIT_FLUSH_TX_FIFO); } // // Clear set bits that are set // RegisterWriteBlock(REG__CEC_INT_STATUS_0,cec_int_status_reg,2); DEBUG_PRINT(("\nA6A7Reg: %02X %02X", (int) cec_int_status_reg[0], (int) cec_int_status_reg[1])); // RX Processing if ( cec_int_status_reg[0] & BIT_RX_MSG_RECEIVED ) { // Save number of frames in Rx Buffer pInt->bRXState = RegisterRead(REG__CEC_RX_COUNT); } // RX Errors processing if ( cec_int_status_reg[1] & BIT_SHORT_PULSE_DET ) { pInt->bCECErrors |= eSiI_CEC_ShortPulse; } if ( cec_int_status_reg[1] & BIT_START_IRREGULAR ) { pInt->bCECErrors |= eSiI_CEC_StartIrregular; } if ( cec_int_status_reg[1] & BIT_RX_FIFO_OVERRUN ) // fixed per Uematsu san { pInt->bCECErrors |= eSiI_CEC_RXOverFlow; } // TX Processing if ( cec_int_status_reg[0] & BIT_TX_FIFO_EMPTY ) //0x04 { pInt->bTXState = eSiI_TXWaitCmd; } if ( cec_int_status_reg[0] & BIT_TX_MESSAGE_SENT ) //0x20 { pInt->bTXState = eSiI_TXSendAcked; } if ( cec_int_status_reg[1] & BIT_FRAME_RETRANSM_OV ) //0x02 { pInt->bTXState = eSiI_TXFailedToSend; } } } return error; }
//------------------------------------------------------------------------------ // Function: AudioUnmuteHandler // Description: State machine for performing audio unmute in firmware. //------------------------------------------------------------------------------ void AudioUnmuteHandler(void) { uint8_t bIntrStatus2; uint8_t bIntrStatus4; RegisterModify(REG__ECC_CTRL, BIT__CAPCNT, SET); //clear the error cont switch (CurrentStatus.AudioState) { case STATE_AUDIO__REQUEST_AUDIO: { bIntrStatus2 = RegisterRead(REG__INTR2); bIntrStatus4 = RegisterRead(REG__INTR4); if ((bIntrStatus2 & BIT__GOTAUD) && (bIntrStatus2 & BIT__GOTCTS)) //audio stable { if(bIntrStatus4 & MSK__CTS_ERROR) // reset ACR RegisterBitToggle(REG__SRST, BIT__ACRRST); else { // init ACR RegisterWrite(REG__ACR_CTRL1, BIT__ACR_INIT); DEBUG_PRINT(("aud rdy\n")); SetUpAudioOutput(); CurrentStatus.AudioState = STATE_AUDIO__AUDIO_READY; } } // clear all the audio interrupts RegisterWrite(REG__INTR2, (BIT__GOTAUD | BIT__GOTCTS)); RegisterWrite(REG__INTR4, (MSK__CTS_ERROR | MSK__FIFO_ERROR)); TIMER_Set(TIMER__AUDIO, 20); // delay 20ms before request audio again } break; case STATE_AUDIO__AUDIO_READY: { bIntrStatus4 = RegisterRead(REG__INTR4); if(bIntrStatus4 & MSK__CTS_ERROR) CurrentStatus.AudioState = STATE_AUDIO__REQUEST_AUDIO; else if (!(bIntrStatus4 & MSK__FIFO_ERROR)) // no audio FIFO error { if ((CurrentStatus.VideoState == STATE_VIDEO__ON) ||(CurrentStatus.VideoState == STATE_VIDEO__CHECKED)) //||ResetVideoControl())//video unmute status ok { if(CurrentStatus.AudioMode==AUDIO_MODE__DSD) HAL_SetAudioDACMode(AUDIO_MODE__DSD); else HAL_SetAudioDACMode(AUDIO_MODE__PCM); RegisterWrite(REG__INTR5, MSK__AUDIO_INTR);// clear all audio interrupts CurrentStatus.AudioState = STATE_AUDIO__ON; TurnAudioMute(OFF); } } else { // reset audio FIFO RegisterBitToggle(REG__SRST, BIT__FIFORST); // clear audio FIFO interrupts RegisterWrite(REG__INTR4, MSK__FIFO_ERROR); TIMER_Set(TIMER__AUDIO, 20); // delay 20ms before ready audio again } } } }