//------------------------------------------------------------------------------ // 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) }
// Affected Register(s): CEC_CAPTURE_ID // Document Reference : CEC Promgramming Interface (CPI) Programmer's Reference // Warning: Only a single CEC device can be select with this interface even though // the all 16 devices can be selected. //------------------------------------------------------------------------------ // uint8_t CEC_CAPTURE_ID_Set( uint8_t logical_address ) { uint8_t error = FALSE; uint8_t capture_address[2]; uint8_t capture_addr_sel = 0x01; capture_address[0] = 0; capture_address[1] = 0; if( logical_address < 8 ) { capture_addr_sel = capture_addr_sel << logical_address; capture_address[0] = capture_addr_sel; } else { capture_addr_sel = capture_addr_sel << ( logical_address - 8 ); capture_address[1] = capture_addr_sel; } // Set Capture Address RegisterWriteBlock(REG__CEC_CAPTURE_ID0,capture_address,2); RegisterWrite(REG__CEC_TX_INIT, logical_address); return 0; }
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: 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: SetupInterruptMasks // Description: Configure interrupt mask registers. // Any unmasked interrupt causes the hardware interrupt pin to be set when pendng. //------------------------------------------------------------------------------ void SetupInterruptMasks(void) { uint8_t abIntrMasks[8]; abIntrMasks[0] = 0; abIntrMasks[1] = BIT__SCDT_CHG; abIntrMasks[2] = 0; abIntrMasks[3] = 0; abIntrMasks[4] = BIT__VRCHG | BIT__HRCHG; abIntrMasks[5] = BIT__NEW_ACP_PKT; //check ACP type2 packet abIntrMasks[6] = BIT__VIDEO_READY; abIntrMasks[7] = BIT__NO_ACP_INF; #if (CONF__ODCK_LIMITED==ENABLE) abIntrMasks[6] |= BIT__PCLK_STOP; #endif //(CONF__ODCK_LIMITED==ENABLE) RegisterWriteBlock(REG__INTR1_UNMASK, &abIntrMasks[0], 4); RegisterWriteBlock(REG__INTR5_UNMASK, &abIntrMasks[4], 2); RegisterWriteBlock(REG__INTR7_UNMASK, &abIntrMasks[6], 2); }
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; }
//------------------------------------------------------------------------------ // 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); }
static void InterruptHandler(void) { uint8_t abIntrStatus[8]; uint8_t bNewInfoFrm = 0; uint8_t bNoInfoFrm = 0; //read all interrupt registers RegisterReadBlock(REG__INTR1, &abIntrStatus[0], 4); RegisterReadBlock(REG__INTR5, &abIntrStatus[4], 2); RegisterReadBlock(REG__INTR7, &abIntrStatus[6], 2); #if 0 DEBUG_PRINT(("i: %02X %02X %02X %02X %02X %02X %02X %02X\n", (int)abIntrStatus[0],(int)abIntrStatus[1],(int)abIntrStatus[2],(int)abIntrStatus[3], (int)abIntrStatus[4],(int)abIntrStatus[5],(int)abIntrStatus[6],(int)abIntrStatus[7])); #endif //clear all pending interrupts RegisterWriteBlock(REG__INTR1, &abIntrStatus[0], 4); RegisterWriteBlock(REG__INTR5, &abIntrStatus[4], 2); RegisterWriteBlock(REG__INTR7, &abIntrStatus[6], 2); #if (CONF__ODCK_LIMITED==ENABLE) if (abIntrStatus[6] & BIT__PCLK_STOP) //ODCK stopped { DEBUG_PRINT(("ODCK stopped\n")); ProcessOdckStop(); } #endif //#if (CONF__ODCK_LIMITED==ENABLED) // process pending interrupts if (abIntrStatus[1] & BIT__SCDT_CHG) //if SCDT change ProcessScdtModeChange(); if (abIntrStatus[4] & BIT__AACDONE) //if soft mute done { TurnAudioMute(ON); CurrentStatus.AudioState = STATE_AUDIO__REQUEST_AUDIO; } #if (CONF__VSYNC_OVERFLOW == ENABLE) if (abIntrStatus[4] & BIT__HRCHG ) //if H res change #else if (abIntrStatus[4] & (BIT__HRCHG|BIT__VRCHG)) //if H/V res change #endif { #if (PEBBLES_ES1_FF_WORKAROUND == ENABLE) if (!ProcessVhResolutionChange()) #endif ConfigureDeepColor(); } if (abIntrStatus[5] & BIT__NEW_ACP_PKT) AcpPacketHandler(ON); if (abIntrStatus[6] & BIT__VIDEO_READY) //video ready for unmute { DEBUG_PRINT(("Video rdy\n")); TurnVideoMute(OFF); } if (abIntrStatus[7] & BIT__NO_ACP_INF) // no ACP pkt AcpPacketHandler(OFF); #if (CONF__SUPPORT_3D == ENABLE) /***** Processing info frame interrupts ***********************/ bNewInfoFrm = abIntrStatus[INTR3_NEW_INFOFR] & INTR3_NEW_INFOFR_SEL; bNoInfoFrm = abIntrStatus[INTR8_NEW_GMT_NO_INFOFR] & INTR8_NO_INFOFR_SEL; if( abIntrStatus[INTR4_NO_AVI] & INTR4_NO_AVI_SEL ){ bNoInfoFrm |= BIT__VIRT_NO_AVI_INF; } if ( abIntrStatus[INTR8_NEW_GMT_NO_INFOFR] & BIT__NEW_GDB_INF ){ bNewInfoFrm |= BIT__VIRT_NEW_GDB_INF; } if ( abIntrStatus[INTR5_NEW_ACP] & BIT__NEW_ACP_PKT ){ bNewInfoFrm |= BIT__VIRT_NEW_ACP_INF; } /* Check if any of info frame interrupts has occured */ if( bNewInfoFrm || bNoInfoFrm ){ InterInfoFrmProc ( bNewInfoFrm, bNoInfoFrm ); } #endif //#if (CONF__SUPPORT_3D == ENABLE) /***** End Processing info frame interrupts ***********************/ }
//------------------------------------------------------------------------------ // 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; }