1284neg.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 544 行 · 第 1/2 页

C
544
字号
    else
    {
        // All other modes.
        P1284Terminate(PortObj->ulBase, FALSE);
    }    
        
    if (PortObj->wHost == HOST_HAS_ECP)
    {
        WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_STD_MODE);
    }
        
    PortObj->bCurrentMode = LPT_MODE;
    PortObj->bCurrentPhase = FORWARD_IDLE;
    PortObj->dwDevId = 0;
    PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
    PortObj->pPortData.dwCommError = 0;
    return;
}
//---------------------------------------------------------------------------
DWORD
Nibble_Connect
(
    PPortInformation  PortObj,
    BYTE              bExtenByte
)
// PURPOSE
//  Negotiate channel to nibble mode.  Stay at reverse idle phase to return.
//
// ASSUMPTIONS & ASSERTIONS
//  1) This code ASSUMES a ISA parallel port implementation.
//  2) current mode and phase are lpt/elpt mode, forward idle phase.
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// RETURNS
//  1)PD_SUCCESS -> success
//  2)PD_NOTP1284
//  3)PD_UNSUPPORTED
//---------------------------------------------------------------------------
{
    DWORD dwError;
    ULONG uDCR_reg;
    ULONG uDSR_reg;

    DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect]: entry\r\n")));
    if (bExtenByte & PN_REQ_DEVID)
    {
        // We'll use this flag to determine the correct
        // method for terminating from nibble mode.
        PortObj->dwDevId = PN_REQ_DEVID;
    }

    if ((dwError = P1284Negotiate(PortObj->ulBase, bExtenByte)) != PD_SUCCESS)
    {
        DEBUGMSG(ZONE_ERROR,(TEXT("[Nibble_Connect]:Got error back from P1284Negotiate\r\n")));
        PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
        PortObj->pPortData.dwCommError = CE_MODE;

        return (dwError);
    }

    DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect]: Successfully negotiated into Nibble mode.\r\n")));

    // Set the port status to reflect successful revese negotiation
    PortObj->bCurrentMode = NIBBLE_MODE;
    PortObj->bCurrentPhase = NB_REVERSE_IDLE;   // Go into REV_IDLE state.
    PortObj->bRevProtocol = ID_NIBBLE;


    uDSR_reg = PortObj->ulBase + 1;
    if (!ChecknFault(uDSR_reg))
    {
        DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect] data available.\r\n")));
        PortObj->bCurrentPhase = NB_DATA_AVAILABLE;
    }
    else
    {
        DEBUGMSG(ZONE_IO,(TEXT("[Nibble_Connect] data not available.\r\n")));
        //switch to reverse idle mode, drop HostBusy low to wait for interrupt
        uDCR_reg = PortObj->ulBase + 2;
        //be carefule for PS/2 Type3 machine, avoid to touch AutoStrobe (b7)
        WRITE_PORT_UCHAR((PUCHAR)uDCR_reg,(BYTE)(READ_PORT_UCHAR((PUCHAR)uDCR_reg) | NAUTOFD_LOW));
        WRITE_PORT_UCHAR((PUCHAR)uDCR_reg,(BYTE)(READ_PORT_UCHAR((PUCHAR)uDCR_reg) | NAUTOFD_LOW));
        PortObj->bCurrentPhase = NB_REVERSE_IDLE;
    }
    PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
    PortObj->pPortData.dwCommError = 0;
    return (PD_SUCCESS);
}

/*  *** this was my attempt at ECP_Connect [a-jsouth] ***
DWORD
ECP_Connect
(
    PPortInformation  PortObj,
    BYTE              bExtenByte
)
{
    DWORD dwError;
    //ULONG uDCR_reg;
    //ULONG uDSR_reg;

    DEBUGMSG(ZONE_IO,(TEXT("[ECP_Connect]: entry\r\n")));

    if ((dwError = P1284Negotiate(PortObj->ulBase, bExtenByte)) != PD_SUCCESS)
    {
        RETAILMSG(1,(TEXT("[ECP_Connect]: Got error back from P1284Negotiate\r\n")));
        PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
        PortObj->pPortData.dwCommError = CE_MODE;

        return (dwError);
    }

    if( bExtenByte == ECP_MODE || (bExtenByte == (ECP_MODE|PN_REQ_DEVID)) )
    {
        PortObj->bCurrentMode = ECP_MODE;
        PortObj->bCurrentPhase = NB_REVERSE_IDLE;   // Go into REV_IDLE state.
        PortObj->bRevProtocol = ID_NIBBLE;
        //InterruptDone( PortObj->IORefData );

        return(PD_SUCCESS);
    }


    PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
    PortObj->pPortData.dwCommError = 0;
    
    return( dwError );
}
*/

/** *** [a-jsouth] this is the real ECP_Connect, lifted from Memphis ***/
DWORD             
ECP_Connect
(
    PPortInformation  PortObj,
    BYTE              bExtenByte
)
// PURPOSE
//  Negotiate a ECP mode with request extension value
//  stay at forward idle phase to return.
//
// ASSUMPTIONS & ASSERTIONS
//  meanings of comments used,
//  1) dcr (nSelectIn, nInit, nAutoFd, nStrobe);
//  2) dsr (Busy, nAck, PError, Select, nFault);
//  device properties will be set after call,
//  1) PortObj->bCurrentMode
//  2) PortObj->bCurrentPhase
//  3) PortObj->bRevProtocol
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// RETURNS
//  1)PD_SUCCESS -> success
//  2)PD_NOTP1284
//  3)PD_UNSUPPORTED
//---------------------------------------------------------------------------
{
    unsigned    uDSR_reg; 
    unsigned    uDCR_reg; 
    unsigned    uECR_reg;
    BYTE        bData;
    DWORD       dwError;

    // Initialize the LPT Port variables
    uDSR_reg = PortObj->ulBase + ECP_DSR_Reg;
    uDCR_reg = PortObj->ulBase + ECP_DCR_Reg;
    uECR_reg = PortObj->ulBase + ECP_ECR_Reg;
   
    if (bExtenByte & PN_REQ_DEVID)
    {
        // We'll use this flag to determine the correct
        // method for terminating from nibble mode.
        PortObj->dwDevId = PN_REQ_DEVID;
    }
    
    //reset FIFO
    WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_PS2_MODE);
   
    if ((dwError = P1284Negotiate(PortObj->ulBase, bExtenByte)) != PD_SUCCESS)
    {    
        WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_STD_MODE);
        PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
        PortObj->pPortData.dwCommError = CE_MODE;
        return (dwError);
    }    

    // drop nAutoFd low in 1 sec, set dcr (0,1,1,0)
    bData = READ_PORT_UCHAR((PUCHAR)uDCR_reg);
    WRITE_PORT_UCHAR((PUCHAR)uDCR_reg, (BYTE)(bData | NAUTOFD_LOW));

    // Wait 35ms, get dsr (1,1,1,1,x)
    if (!CheckPort(uDSR_reg, PE_STATE31_MASK, PE_STATE31, P1284_TL_MS))
    {
      
        bData = READ_PORT_UCHAR((PUCHAR)uDSR_reg);
        DEBUGMSG(ZONE_IO,(TEXT("[ECP_Connect]: Timeout at E31 read, DSR = 0x%x"),bData));

        // Terminate the negotiation phase
        TerminateChannel(PortObj);
        PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
        PortObj->pPortData.dwCommError = CE_MODE;
        return (PD_UNSUPPORTED);
   }
                     
    DEBUGMSG(ZONE_IO,(TEXT("[ECP_Connect]:  Into ECP Forward Idle mode.\r\n")));

    // set dcr (x,x,0,0)
    bData = READ_PORT_UCHAR((PUCHAR)uDCR_reg);
    WRITE_PORT_UCHAR((PUCHAR)uDCR_reg, (BYTE)(bData & 0xFC));

    // Put ECP hardware into ECP forward, interrupt disabled.
    WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_PS2_MODE);      //clear fifo
    WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_ECP_MODE|~ECP_ECR_SERVICE_INT_BIT);

    PortObj->bCurrentMode = ECP_MODE;
    PortObj->bCurrentPhase = ECP_F_IDLE;
    PortObj->bRevProtocol = ID_ECP;
//    PortObj->pfnWrite = (PFN)ECP_Write;       // We don't really use these, we dispatch thru MDD
//    PortObj->pfnRead = (PFN)ECP_Read;
    PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
    PortObj->pPortData.dwCommError = 0;
    return (PD_SUCCESS);
}

BOOL
Reverse2Forward
(
    PPortInformation PortObj
)
{
    unsigned  uDCR_reg;
    unsigned  uDSR_reg;
    unsigned  uECR_reg;
    BYTE      bData;

    uECR_reg = PortObj->ulBase + ECP_ECR_Reg;
    uDCR_reg = PortObj->ulBase + ECP_DCR_Reg;
    uDSR_reg = PortObj->ulBase + ECP_DSR_Reg;


    // Switch back to PS/2 mode
    WRITE_PORT_UCHAR((PUCHAR)uECR_reg, ECP_PS2_MODE);
    
    // raise nInit high, (x,1,x,x)
    bData = READ_PORT_UCHAR((PUCHAR)uDCR_reg);
    bData |= NINIT_HIGH;
    WRITE_PORT_UCHAR((PUCHAR)uDCR_reg, bData);

    // wait for 35 ms, get dsr (1,1,1,x,x)
    if (!CheckPort(uDSR_reg, E_STATE49_MASK, E_STATE49_VALUE, P1284_TL_MS))
    {
        DEBUGMSG(ZONE_IO,(TEXT("[Reverse2Forward]: Failed at Event 49")));

        PortObj->pPortData.dwLastError = PortObj->pPortData.dwCommError;
        PortObj->pPortData.dwCommError = CE_MODE;
        return (FALSE);
    }
    
    // set nAutoFd high, default indicate 'data'    
    bData &= NAUTOFD_MASK;              //0xFD
    WRITE_PORT_UCHAR((PUCHAR)uDCR_reg, bData);
    PortObj->bCurrentPhase = ECP_F_IDLE;
   
    return (TRUE);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?