static void MhlCbusIsr( void ) { uint8_t cbusInt; uint8_t gotData[4]; uint8_t i; cbusInt = SiiRegRead(REG_CBUS_MSC_INT2_STATUS); if(cbusInt == 0xFF) { return; } if( cbusInt ) { if ( BIT0 & cbusInt) { SiiMhlTxMscWriteBurstDone( cbusInt ); } if(cbusInt & BIT2) { uint8_t intr[4]={0}; TX_DEBUG_PRINT(("MHL INTR Received\n")); SiiRegReadBlock(REG_CBUS_SET_INT_0, intr, 4); SiiMhlTxGotMhlIntr( intr[0], intr[1] ); SiiRegWriteBlock(REG_CBUS_SET_INT_0, intr, 4); } if(cbusInt & BIT3) { uint8_t status[4]={0}; TX_DEBUG_PRINT(("MHL STATUS Received\n")); for (i = 0; i < 4;++i) { status[i] = SiiRegRead(REG_CBUS_WRITE_STAT_0 + i); SiiRegWrite((REG_CBUS_WRITE_STAT_0 + i), 0xFF ); } SiiMhlTxGotMhlStatus( status[0], status[1] ); } SiiRegWrite(REG_CBUS_MSC_INT2_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_2: %02X\n", (int) cbusInt)); } cbusInt = SiiRegRead(REG_CBUS_INTR_STATUS); if (cbusInt) { SiiRegWrite(REG_CBUS_INTR_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_1: %02X\n", (int) cbusInt)); } if((cbusInt & BIT3)) { uint8_t mscMsg[2]; TX_DEBUG_PRINT(("MSC_MSG Received\n")); mscMsg[0] = SiiRegRead(REG_CBUS_PRI_VS_CMD); mscMsg[1] = SiiRegRead(REG_CBUS_PRI_VS_DATA); TX_DEBUG_PRINT(("MSC MSG: %02X %02X\n", (int)mscMsg[0], (int)mscMsg[1] )); SiiMhlTxGotMhlMscMsg( mscMsg[0], mscMsg[1] ); } if (cbusInt & (BIT_MSC_ABORT | BIT_MSC_XFR_ABORT | BIT_DDC_ABORT)) { gotData[0] = CBusProcessErrors(cbusInt); mscCmdInProgress = false; } if(cbusInt & BIT4) { TX_DEBUG_PRINT(("MSC_REQ_DONE\n")); mscCmdInProgress = false; SiiMhlTxMscCommandDone( SiiRegRead(REG_CBUS_PRI_RD_DATA_1ST) ); } if (cbusInt & BIT7) { TX_DEBUG_PRINT(("Parity error count reaches 15\n")); SiiRegWrite(REG_CBUS_STAT2, 0x00); } }
/////////////////////////////////////////////////////////////////////////// // // MhlCbusIsr // // Only when MHL connection has been established. This is where we have the // first looks on the CBUS incoming commands or returned data bytes for the // previous outgoing command. // // It simply stores the event and allows application to pick up the event // and respond at leisure. // // Look for interrupts on CBUS:CBUS_INTR_STATUS [0xC8:0x08] // 7 = RSVD (reserved) // 6 = MSC_RESP_ABORT (interested) // 5 = MSC_REQ_ABORT (interested) // 4 = MSC_REQ_DONE (interested) // 3 = MSC_MSG_RCVD (interested) // 2 = DDC_ABORT (interested) // 1 = RSVD (reserved) // 0 = rsvd (reserved) /////////////////////////////////////////////////////////////////////////// static void MhlCbusIsr (void) { uint8_t cbusInt; uint8_t gotData[4]; // Max four status and int registers. // // Main CBUS interrupts on CBUS_INTR_STATUS // cbusInt = SiiRegRead(REG_CBUS_INTR_STATUS); // When I2C is inoperational (D3) and a previous interrupt brought us here, do nothing. if(cbusInt == 0xFF) { return; } if( cbusInt ) { // // Clear all interrupts that were raised even if we did not process // SiiRegWrite(REG_CBUS_INTR_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_1: %02X\n", (int) cbusInt)); } // MSC_MSG (RCP/RAP) if ((cbusInt & BIT_CBUS_MSC_MR_MSC_MSG)) { uint8_t mscMsg[2]; TX_DEBUG_PRINT(("Drv: MSC_MSG Received\n")); // // Two bytes arrive at registers 0x18 and 0x19 // mscMsg[0] = SiiRegRead(REG_CBUS_PRI_VS_CMD); mscMsg[1] = SiiRegRead(REG_CBUS_PRI_VS_DATA); TX_DEBUG_PRINT(("Drv: MSC MSG: %02X %02X\n", (int)mscMsg[0], (int)mscMsg[1] )); SiiMhlTxGotMhlMscMsg( mscMsg[0], mscMsg[1] ); } if (cbusInt & (BIT_MSC_ABORT | BIT_MSC_XFR_ABORT | BIT_DDC_ABORT)) { gotData[0] = CBusProcessErrors(cbusInt); mscCmdInProgress = false; } // MSC_REQ_DONE received. if (cbusInt & BIT_CBUS_MSC_MT_DONE) { TX_DEBUG_PRINT(("Drv: MSC_REQ_DONE\n")); mscCmdInProgress = false; // only do this after cBusInt interrupts are cleared above SiiMhlTxMscCommandDone( SiiRegRead(REG_CBUS_PRI_RD_DATA_1ST) ); } // // Clear all interrupts that were raised even if we did not process // // // Now look for interrupts on register 0x1E. CBUS_MSC_INT2 // 7:4 = Reserved // 3 = msc_mr_write_state = We got a WRITE_STAT // 2 = msc_mr_set_int. We got a SET_INT // 1 = reserved // 0 = msc_mr_write_burst. We received WRITE_BURST // cbusInt = SiiRegRead(REG_CBUS_MSC_INT2_STATUS); if(cbusInt) { // // Clear all interrupts that were raised even if we did not process // SiiRegWrite(REG_CBUS_MSC_INT2_STATUS, cbusInt); TX_DEBUG_PRINT(("Drv: Clear CBUS INTR_2: %02X\n", (int) cbusInt)); } if ( BIT_CBUS_MSC_MR_WRITE_BURST & cbusInt) { // WRITE_BURST complete SiiMhlTxMscWriteBurstDone( cbusInt ); } if(cbusInt & BIT_CBUS_MSC_MR_SET_INT) { uint8_t intr[4]; TX_DEBUG_PRINT(("Drv: MHL INTR Received\n")); SiiRegReadBlock(REG_CBUS_SET_INT_0, intr, 4); SiiRegWriteBlock(REG_CBUS_SET_INT_0, intr, 4); // We are interested only in first two bytes. SiiMhlTxGotMhlIntr( intr[0], intr[1] ); } if (cbusInt & BIT_CBUS_MSC_MR_WRITE_STATE) { uint8_t status[4]; uint8_t clear[4]={0xff,0xff,0xff,0xff};// must write 0xFF to clear regardless! // don't put debug output here, it just creates confusion. SiiRegReadBlock(REG_CBUS_WRITE_STAT_0, status, 4); SiiRegWriteBlock(REG_CBUS_WRITE_STAT_0, clear, 4); SiiMhlTxGotMhlStatus( status[0], status[1] ); } }