⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1284comm.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
    {
       // all other modes, expect (x,1,x,1,x) (nibble w/ ID)
       if (CheckPort(uStatusPort, P_STATE5_MASK, P_STATE5_VALUE, P1284_MS))
          return (PD_SUCCESS);
    }

    DEBUGMSG(ZONE_ERROR,(TEXT("[P1284Negotiate] Timeout at E5/E6 read\r\n")));

//  Terminate FAILed negotiation, inverted Boolean
    if (bExtenByte == NIBBLE_MODE)
        P1284Terminate(ulBase, FALSE);
    else
        P1284Terminate(ulBase, TRUE);

//    return (PD_UNSUPPORTED);
     return (PD_NOTP1284);
}

// The following values are used during nibble mode read opeations.
#define NM_CONTROL_MASK         0xF0    // 1111 0000
#define NM_INT_MASK             0x60    // 0110 0000
#define NM_INTERRUPT            0x40    // 0100 0000
#define NM_HOSTBUSY             0x02    // 0000 0010
#define NM_INIT                 0x04    // 0000 0100


#define NM_PTRCLK_MASK          0x40    // 0100 0000
#define NM_PTRCLK_HI            0x40    // 0100 0000
#define NM_PTRCLK_LO            0x00    // 0000 0000

//---------------------------------------------------------------------------
BYTE
AssembleNibbles
(
    BYTE bLoNib,
    BYTE bHiNib
)
// PURPOSE
//  Assemble nibbles into a byte.
//
// ASSUMPTIONS & ASSERTIONS
//  Status bits and nibble bits are mapped as follow,
//      x--- ----: Busy          : bit 3, 7
//      --x- ----: PError   : bit 2, 6
//      ---x ----: Select   : bit 1, 5
//      ---- x---: nFault   : bit 0, 4
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// RETURNS
//  a byte data.
//---------------------------------------------------------------------------
{
#if x86
   _asm {
        push ax
        mov  al, bLoNib
        rcl  al, 1
        jc   lo_set
        or   ax, 0x80
        jmp  lo_nib
   lo_set:
        and  ax, 0x7F
   lo_nib:
        shr  al, 4

        mov  ah, bHiNib
        rcl  ah, 1
        jc   hi_set
        or   ax, 0x8000
        jmp  hi_nib
   hi_set:
        and  ax, 0x7fff
   hi_nib:
        and  ah, 0xF0
        or   al, ah
        mov  bHiNib, al
        pop  ax
   }
#else
     unsigned int uLowNib, uHiNib;
     uLowNib= (unsigned int)bLoNib;
     uHiNib= (unsigned int)bHiNib;
     uLowNib<<=1;
     if (uLowNib & 0x100) {
          uLowNib&=0x0000007f;
     } else
          uLowNib|=0x00000080;
     uLowNib>>=4;
     uHiNib<<=1;
     if (uHiNib & 0x100) {
          uHiNib&=0x0000007f;
     } else
          uHiNib|=0x00000080;
     uHiNib&=0x000000f0;
     uHiNib|=uLowNib;
     bHiNib= (BYTE)uHiNib;
#endif
   DEBUGMSG(ZONE_MAXIO,(TEXT("[AssembleNibbles] byte = %Xh %c\r\n"),bHiNib, bHiNib));
   return (bHiNib);
}
//---------------------------------------------------------------------------
BOOL
NibbleRead
(
    ULONG             ulBase,
    char*             lpInBuffer,
    DWORD             dwInBufferSize,
    DWORD*            lpdwBytesReceived
)
// PURPOSE
//  Read a block of data from the parallel port.
//
// ASSUMPTIONS & ASSERTIONS
//  Data will be read using P1284 Nibble mode protocol.  The basic method is:
//  1)current phase is reverse idle,
//      Watch for nDataAvail low
//      Raise HostBusy high
//  2)current phase is host busy data avail
//      Drop HostBusy
//      Watch for  PtrClk
//      Latch Nibble 0 (Data bits 0-3)
//      Raise HostBusy
//      Watch for PtrClk
//      Drop HostBusy
//      Watch for PtrClk
//      Latch Nibble 1 (Data bits 4-7)
//      Raise HostBusy
//
//  Data will be read until the read buffer is full, there is a time out
//  on PtrClk, or the peripheral does not assert nDataAvail.
//  A timeout occurs if the host does not see PtrClk drop
//  within T(l) + T(p) after HostBusy is droped.  Currently T(l) is
//  defiend to be 35 ms MAX, and T(p) is defined to be .5 us MIN.
//  MAX for T(p) is undefinned, and will be passed as a parameter to P1284LPT.
//       Data is read from status port.
//
// INTERNAL STRUCTURES
//
// UNRESOLVED ISSUES
//
// RETURNS
//  TRUE: if some or all data are read
//  FALSE: if no data read
//---------------------------------------------------------------------------
{
    DWORD dwBytesRead = 0L;
    BYTE  bLoRawNibble, bHiRawNibble;
    BYTE  bData, bOldDCR;
    ULONG uDataPort, uStatusPort, uControlPort;

    // Initialize the LPT Port variables
    uDataPort = ulBase;
    uStatusPort = uDataPort + 1 * dwPrinterRegMultiplier;
    uControlPort = uDataPort + 2 * dwPrinterRegMultiplier;

    if (ChecknFault(uStatusPort))
    {
        DEBUGMSG(ZONE_ERROR,(TEXT("[NibbleRead] data not available.\r\n")));
        *lpdwBytesReceived = 0;  // No data, not error.
        return (FALSE);
    }

    // Check current phase via HostBusy
    // We can be in Idle phase or HBDA
    bOldDCR = READ_PORT_UCHAR((PUCHAR)uControlPort);
    if (bOldDCR & NM_HOSTBUSY)
    {
        DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] reverse idle.\r\n")));
        // now in reverse idle phase
        //verify interrupt, state 19
        //respond to raise HostBusy high (state 20) enter HBDA
        //be carefule for PS/2 Type3 machine, avoid to touch AutoStrobe (b7)
        bOldDCR &= NM_CONTROL_MASK;
        WRITE_PORT_UCHAR((PUCHAR)uControlPort, (BYTE)(bOldDCR | NM_INIT));

        //wait PE low & nAck Hi for 35ms
        if (!CheckPort(uStatusPort,NM_INT_MASK, NM_INTERRUPT, P1284_MS))
        {
            *lpdwBytesReceived = 0;
            return (FALSE);
        }
        DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] host busy data available and interrupt received.\r\n")));
    }
    else
    {
        //be carefule for PS/2 Type3 machine, avoid to touch AutoStrobe (b7)
        bOldDCR &= NM_CONTROL_MASK;
    }
    // Read until we fill the input buffer, time-out, or have no data
    // available
    DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] read data into %Xh\r\n"),lpInBuffer));
    do
    {
        // Data is available and peripheral is ready to send data,
        // so drop HostBusy
        // do not modify other bits except HostBusy, we may overried high byte on PS/2 machine
        WRITE_PORT_UCHAR((PUCHAR)uControlPort, (BYTE)(bOldDCR | NM_INIT | NM_HOSTBUSY));

        // wait PtrClk go low          //0x40          //0x00
        if (!CheckPort(uStatusPort,NM_PTRCLK_MASK, NM_PTRCLK_LO, P1284_MS))
        {
               DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] Time-out waiting for PtrClk to go LO first Nibble\r\n")));
            *lpdwBytesReceived = dwBytesRead;
            return (TRUE);
        }
        // Latch first nibble, bits <0:3>
        bLoRawNibble = READ_PORT_UCHAR((PUCHAR)uStatusPort);

        // Raise HostBusy
        WRITE_PORT_UCHAR((PUCHAR)uControlPort, (BYTE)(bOldDCR | NM_INIT));

        // Wait PtrClk go Hi             //0x40         //0x40
        if (!CheckPort(uStatusPort,NM_PTRCLK_MASK, NM_PTRCLK_HI, P1284_MS))
        {
            DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] Time-out waiting for PtrClk to go HI first Nibble\r\n")));
            *lpdwBytesReceived = dwBytesRead;
            return (TRUE);
        }

        // Ready to get the Second Nibble.  Drop HostBusy again
        WRITE_PORT_UCHAR((PUCHAR)uControlPort, (BYTE)(bOldDCR | NM_INIT | NM_HOSTBUSY));

        // Wait PtrClk go low
        if (!CheckPort(uStatusPort,NM_PTRCLK_MASK, NM_PTRCLK_LO, P1284_MS))
        {
               DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] Time-out waiting for PtrClk to go LO on Second Nibble\r\n")));
            *lpdwBytesReceived = dwBytesRead;
            return (TRUE);
        }
        // Latch second nibble
        bHiRawNibble = READ_PORT_UCHAR((PUCHAR)uStatusPort);

        // Raise HostBusy
        WRITE_PORT_UCHAR((PUCHAR)uControlPort, (BYTE)(bOldDCR | NM_INIT));

        // Assemble the received, encoded nibble, into a data byte,
        // store it in the output array, and update the counters.
        bData = AssembleNibbles (bLoRawNibble, bHiRawNibble);
        *lpInBuffer++ = bData;
        dwBytesRead ++;

        // Wait PtrClk go Hi             //0x40         //0x40
        if (!CheckPort(uStatusPort,NM_PTRCLK_MASK, NM_PTRCLK_HI, P1284_MS))
        {
            *lpdwBytesReceived = dwBytesRead;
            return (TRUE);
        }

        // check nDataAvail, if high no more data
        if (ChecknFault(uStatusPort))
        {
            DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] data not available.\r\n")));
            *lpdwBytesReceived = dwBytesRead;
            return (TRUE);
        }
    }
    while(dwBytesRead < dwInBufferSize);
    // if we get here, we filled the input buffer, se we can just return.
    *lpdwBytesReceived = dwBytesRead;
    DEBUGMSG(ZONE_IO,(TEXT("[NibbleRead] read #EAX bytes\r\n"),dwBytesRead));
    return (TRUE);
}

⌨️ 快捷键说明

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