Exemplo n.º 1
0
static byte CBusCheckInterruptStatus ( byte channel )
{
	byte 	intStatus, result;
	byte     vs_cmd, vs_data;
	byte 	writeBurstLen 	= 0;

	/* Read CBUS interrupt status.  */
	intStatus = SiIRegioCbusRead( REG_CBUS_INTR_STATUS, channel );
	if( intStatus & BIT_MSC_MSG_RCV )
	{
		printk("( intStatus & BIT_MSC_MSG_RCV )\n");
		vs_cmd  = SiIRegioCbusRead( REG_CBUS_PRI_VS_CMD, channel );
		vs_data = SiIRegioCbusRead( REG_CBUS_PRI_VS_DATA, channel );
	}
	SiIRegioCbusWrite( REG_CBUS_INTR_STATUS, channel, intStatus );

	/* Check for interrupts.  */

	result = STATUS_SUCCESS;
	intStatus &= (~BIT_HEARTBEAT_TIMEOUT);	 //don't check heartbeat
	if( intStatus != 0 )
	{
		if( intStatus & BIT_CONNECT_CHG )
		{
			printk("( intStatus & BIT_CONNECT_CHG )\n");
			/* The connection change interrupt has been received.   */
			result = CBusProcessConnectionChange( channel );
			SiIRegioCbusWrite( REG_CBUS_BUS_STATUS, channel, BIT_CONNECT_CHG );
		}

		if( intStatus & BIT_MSC_XFR_DONE )
		{
			printk("( intStatus & BIT_MSC_XFR_DONE )\n");
			/* A previous MSC sub-command has been acknowledged by the responder.   */
			/* Does not include MSC MSG commands.                                   */

			l_cbus[ channel].state = CBUS_XFR_DONE;

			/* Save any response data in the channel request structure to be returned    */
			/* to the upper level.                                                      */

			msc_return_cmd = l_cbus[ channel].request[ l_cbus[ channel].activeIndex ].msgData[0] =
				SiIRegioCbusRead( REG_CBUS_PRI_RD_DATA_1ST, channel );
			msc_return_value = l_cbus[ channel].request[ l_cbus[ channel].activeIndex ].msgData[1] =
				SiIRegioCbusRead( REG_CBUS_PRI_RD_DATA_2ND, channel );

			printk ( "\nCBUS:: Transfer Done \n" );
			printk ("Response data Received:: %02X\n\n", (int)l_cbus[ channel].request[l_cbus[channel].activeIndex].msgData[0]);

			result = STATUS_SUCCESS;

			// Check if we received NACK from Peer
			writeBurstLen = SiIRegioCbusRead( REG_MSC_WRITE_BURST_LEN, channel );
			if( writeBurstLen & MSC_REQUESTOR_DONE_NACK )
			{
				result = ERROR_NACK_FROM_PEER;
				printk( "NACK received!!! :: %02X\n", (int)writeBurstLen) ;
			}
			result = CBusProcessFailureInterrupts( channel, intStatus, result );
		}

		if( intStatus & BIT_MSC_MSG_RCV )
		{
			printk("( intStatus & BIT_MSC_MSG_RCV )\n");
			/* Receiving a sub-command, either an actual command or */
			/* the response to a command we sent.                   */
			result = CBusProcessSubCommand( channel, vs_cmd, vs_data );
		}
	}
	return( result );
}
Exemplo n.º 2
0
//------------------------------------------------------------------------------
// Function:    CBusCheckInterruptStatus
// Description: If any interrupts on the specified channel are set, process them.
// Returns:     SUCCESS or CBUS_SOFTWARE_ERRORS_t error code.
//------------------------------------------------------------------------------
static uint8_t CBusCheckInterruptStatus ( void )
{
    uint8_t result;
    uint8_t busStatus;
    uint8_t	temp;
    uint8_t cbusData[2];

    result = SUCCESS;

    if ( SiiDrvCbusIntrFlagGet() )
    {
        //CBUS connction change
        if ( SiiDrvCbusBusStatusGet( &busStatus ) )
        {
        	/* The connection change interrupt has been received.   */
			pCbus->chState.connected = busStatus ? true : false;
        	DEBUG_PRINT( MSG_DBG, "CBUS:: ----Connection Change---- %s \n", pCbus->chState.connected ? "Connected" : "Disconnected" );
			if( pCbus->chState.connected )
			{
				SiiDrvCbusTermCtrl( true );
                if ( SiiCbusSendDcapRdy())
                {
                    //set DCAP_CHG bit
                    if(SiiMhlRxSendDcapChange())
                    {
                        // send set_hpd and set path_en bit too
                        SiMhlRxHpdSet(true);
                    }
                }
#if defined(__KERNEL__)
                SiiOsTimerStart(pCbus->chState.dcapTimer, CBUS_DCAP_READY_TIMER);
#else
                pCbus->chState.dcapTimer = SiiTimerTotalElapsed();
#endif
			}
			else
			{
				SiiDrvCbusTermCtrl( false );       
				//set the cbus to idle
				CBusResetToIdle();
			}

			SiiMhlRxConnNtfy(pCbus->chState.connected);
        }

        // Receive CBUS messages
        if ( SiiDrvCbusVsDataGet( &cbusData[0] ) )
        {
            CBusProcessSubCommand( &cbusData[0] );
        }

        //Cbus message transfer done
        if ( SiiDrvCbusCmdRetDataGet( &pCbus->chState.request[ CH_ACTIVE_INDEX ].retData[0] ) )
        {
            if (pCbus->chState.state == CBUS_SENT)
                pCbus->chState.state = CBUS_XFR_DONE;
        }

        //Cbus Devcap ready
        if (SiiDrvCbusDevCapReadyGet ())
        {
            if (!pCbus->chState.dcap_ready)
            {
                DEBUG_PRINT( MSG_DBG, "CBUS:: DCap Ready received!\n");
#if defined(__KERNEL__)
                SiiOsTimerStop(pCbus->chState.dcapTimer);
#endif
                pCbus->chState.dcap_ready = true;
                // Read Dcap
                SiiMhlRxReadDevCapReg(0x00);
                pCbus->chState.dcap_ongoing = true;
            }
        }

        if (SiiDrvCbusDevCapChangedGet ())
        {
            DEBUG_PRINT( MSG_DBG, "CBUS:: DCap Change received!\n");
            if (pCbus->chState.dcap_ready)
            {
                // Read Dcap
                if (!pCbus->chState.dcap_ongoing)
                {
                    SiiMhlRxReadDevCapReg(0x00);
                    pCbus->chState.dcap_ongoing = true;
                }
            }
        }

    	// request received from peer to write into scratchpad
    	if ( SiiDrvCbusReqWrtGet() )
    	{
    		DEBUG_PRINT( MSG_DBG, "Grant peer's request to write scratchpad\n");
    		SiiCbusGrtWrt();
	    }

    	// scratchpad write notification received from peer
    	if ( SiiDrvCbusScratchpadWrtnGet() )
    	{
    		// send it to app layer
    		SiiMhlRxScratchpadWrittenNtfy();
    	}

    	// request to write into peer's scratchpad is granted
    	if ( SiiDrvCbusGrtWrtGet() && pCbus->chState.burstWaitState )
    	{
    		DEBUG_PRINT( MSG_DBG, "Peer sent grant write\n");
            SiiCbusWriteBurst();
            //Recieve grt, stop burst timer.
            pCbus->chState.burst [CH_ACTIVE_BURST].burstStatus = CBUS_BURST_IDLE;
            pCbus->chState.burstWaitState = false;
#if defined(__KERNEL__)
            SiiOsTimerStop(pCbus->chState.burstTimer);
#else
            pCbus->chState.burstTimer = 0;
#endif
        }


    	if ( SiiDrvCbus3DReqGet() )
    	{
            DEBUG_PRINT( MSG_DBG, "Peer request 3D infomation\n");
            SiiDrvCbusBuild3DData();
            SiiDrv3DWriteBurst();
        }

        if( SiiDrvCbusNackFromPeerGet() )
        {
            DEBUG_PRINT( MSG_ERR,( "NACK received from peer\n" ));
            result |= ERROR_NACK_FROM_PEER;
        }

        if( SiiDrvCbusDdcAbortReasonGet( &temp ) )
        {
            DEBUG_PRINT( MSG_DBG, "CBUS DDC ABORT happened, reason: %02X\n", (int)temp );
            if (temp & BIT_MSC_ABORT_BY_PEER)    //Abort by peer
            {
                result |= ERROR_CBUS_ABORT;
            }
            else if(temp)
            {
                result |= ERROR_CBUS_OTHER;
            }
        }


        if ( SiiDrvCbusMscAbortReasonGet( &temp ) )
        {
            DEBUG_PRINT( MSG_DBG, "MSC CMD aborted, reason: %02X\n", (int)temp );
            if (temp & BIT_MSC_ABORT_BY_PEER)    //Abort by peer
            {
                result |= ERROR_CBUS_ABORT;
            }
            if (temp & (BIT_MSC_MAX_RETRY|BIT_MSC_TIMEOUT))
            {
                result |= ERROR_CBUS_TIMEOUT;
            }
            if ((temp & ~(ERROR_CBUS_ABORT|BIT_MSC_MAX_RETRY|BIT_MSC_TIMEOUT)) != 0)
            {
                result |= ERROR_CBUS_ABORT_OTHER;
            }
        }

        if ( SiiDrvCbusMscAbortResReasonGet( &temp ) )
        {
            DEBUG_PRINT( MSG_DBG, "MSC CMD aborted as Responder , reason: %02X\n", (int)temp );
            if (temp & BIT_MSC_ABORT_BY_PEER)    //Abort by peer
            {
                result |= ERROR_CBUS_ABORT;;
            }
            else if(temp)
            {
                result |= ERROR_CBUS_OTHER;
            }
        }
    }

    SiiDrvCbusIntrFlagSet();
    return( result );
}