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

📄 pl010ser.c

📁 EP931X系列的WinCE串口驱动源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_OPEN,
              (TEXT("-SL_Open 0x%Xr\n"), pHead));
}

//
// @doc OEM 
// @func PVOID | SL_Close | Does nothing except keep track of the
// open count so that other routines know what to do.
//
VOID
SL_Close(
        PVOID   pHead // @parm PVOID returned by HWinit.
        )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_CLOSE,
              (TEXT("+SL_Close 0x%X\r\n"), pHead));

    if ( pSer16550->OpenCount )
        pSer16550->OpenCount--;

    EnterCriticalSection(&(pSer16550->RegCritSec));
    try {
        // Disable all interrupts and clear MCR.

        OUTB(pSerAMBA, pUART_CR, (UCHAR)0); 

        // Clear modem control state.
        //
        SL_ClearDTR(pHead);
        SL_ClearRTS(pHead);

    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just get out of here.
    }
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_CLOSE,
              (TEXT("-SL_Close 0x%X\r\n"), pHead));
}

//
// @doc OEM 
// @func PVOID | SL_Init | Initializes 16550 device head.  
//
VOID
SL_Init2(
       PVOID   pHead, // @parm points to device head
       PUCHAR  pRegBase, // Pointer to 16550 register base
       EVENT_FUNC EventCallback, // This callback exists in MDD
       PVOID   pMddHead,   // This is the first parm to callback
       PLOOKUP_TBL   pBaudTable  // BaudRate Table
       )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_CLOSE,(TEXT("+SL_INIT, 0x%X\r\n"), pHead));

    // Set up pointers to UART registers
    pSerAMBA->pUART_DR    = pRegBase + AMBA_UARTDR;
    pSerAMBA->pUART_RSR   = pRegBase + AMBA_UARTRSR;
    pSerAMBA->pUART_ECR   = pRegBase + AMBA_UARTECR;
    pSerAMBA->pUART_LCR_H = pRegBase + AMBA_UARTLCR_H;
    pSerAMBA->pUART_LCR_M = pRegBase + AMBA_UARTLCR_M;
    pSerAMBA->pUART_LCR_L = pRegBase + AMBA_UARTLCR_L;
    pSerAMBA->pUART_CR    = pRegBase + AMBA_UARTCR;
    pSerAMBA->pUART_FR    = pRegBase + AMBA_UARTFR;
    pSerAMBA->pUART_IIR   = pRegBase + AMBA_UARTIIR;
    pSerAMBA->pUART_ICR   = pRegBase + AMBA_UARTICR;
    pSerAMBA->pUART_ILPR  = pRegBase + AMBA_UARTILPR;

    // Special registers: the AMBA UART doesn't implement DTR and RTS.  Instead,
    // these signals are implemented with general-purpose IO lines.
    //
    // We have to VirtualCopy the System Controller registers used for 
    // DTR and RTS signals.
    //
    //if (!(pSerAMBA->pSC_BASE = VirtualAlloc(NULL, (4 * sizeof(ULONG)), MEM_RESERVE, PAGE_NOACCESS)))
    //{
    //    DEBUGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("!SL_Init2: VirtualAlloc Failed\r\n")));
    //    DEBUGCHK(FALSE);
    //    return;
    //}
    //
    //if (!VirtualCopy((LPVOID)pSerAMBA->pSC_BASE, (LPVOID)(VA_SC_BASE), (4 * sizeof(ULONG)), PAGE_READWRITE | PAGE_NOCACHE))
    //{
    //    DEBUGMSG(ZONE_INIT | ZONE_ERROR, (TEXT("!SL_Init2: VirtualCopy Failed (%d)\r\n"), GetLastError()));
    //    DEBUGCHK(FALSE);
    //    VirtualFree (pSerAMBA->pSC_BASE, 0, MEM_RELEASE);
    //    return;
    //}

    if(((PSER_INFO)pHead)->dwDevIndex ==1)
    {
        pSerAMBA->pSC_MCR   = (volatile PULONG)UART1_MCR;
    }
    else
    {
        pSerAMBA->pSC_MCR   = 0;
    }


    // Store info for callback function
    pSer16550->EventCallback = EventCallback;
    pSer16550->pMddHead = pMddHead;

    pSer16550->FlushDone      = CreateEvent(0, FALSE, FALSE, NULL);

    pSer16550->OpenCount = 0;

    // Don't allow any interrupts till PostInit.
    OUTB(pSerAMBA, pUART_CR, (UCHAR)0);

    InitializeCriticalSection(&(pSer16550->TransmitCritSec));
    InitializeCriticalSection(&(pSer16550->RegCritSec));

    // Clear any interrupts which may be pending.  Normally only
    // happens if we were warm reset.
    ClearPendingInts( pHead );

    DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_INIT, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func void | SL_PostInit | This routine takes care of final initialization.
//
// @rdesc None.
//
BOOL
SL_PostInit(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_INIT,(TEXT("+SL_PostInit, 0x%X\r\n"), pHead));
    
    // Since we are just a library which might get used for 
    // builtin ports which init at boot, or by PCMCIA ports
    // which init at Open, we can't do anything too fancy.
    // Lets just make sure we cancel any pending interrupts so
    // that if we are being used with an edge triggered PIC, he
    // will see an edge after the MDD hooks the interrupt.
    ClearPendingInts( pHead );
    
    DEBUGMSG (ZONE_INIT,(TEXT("-SL_PostInit, 0x%X\r\n"), pHead));
    return(TRUE);
}

//
// @doc OEM 
// @func PVOID | SL_Deinit | De-initializes 16550 device head.  
//
VOID
SL_Deinit(
         PVOID   pHead // @parm points to device head
         )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_CLOSE,(TEXT("+SL_DEINIT, 0x%X\r\n"), pHead));

    DeleteCriticalSection(&(pSer16550->TransmitCritSec));
    DeleteCriticalSection(&(pSer16550->RegCritSec));

    // Free the flushdone event
    if ( pSer16550->FlushDone )
        CloseHandle( pSer16550->FlushDone );

    // Free System Controller memory handle
    //
    if (pSerAMBA->pSC_BASE)
        VirtualFree (pSerAMBA->pSC_BASE, 0, MEM_RELEASE);

    DEBUGMSG (ZONE_CLOSE,(TEXT("-SL_DEINIT, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func void | SL_ClearDtr | This routine clears DTR.
//
// @rdesc None.
//
VOID
SL_ClearDTR(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearDTR, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pSer16550->RegCritSec));
    try {
        if(((PSER_INFO)pHead)->dwDevIndex == 1)
        {
            *pSerAMBA->pSC_MCR   &= ~MCR_DTR;
        }
        else
        {
            DEBUGMSG (ZONE_WARN, (TEXT("SL_ClearDTR: invalid device index (0x%X)\r\n"), ((PSER_INFO)pHead)->dwDevIndex));
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_ClearDTR, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func VOID | SL_SetDTR | This routine sets DTR.
// 
// @rdesc None.
//
VOID
SL_SetDTR(
         PVOID   pHead // @parm PVOID returned by HWinit.
         )
{    
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetDTR, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pSer16550->RegCritSec));
    try {
        // Depending on which port we're talking to, assert the DTR signal.
        //
        if (((PSER_INFO)pHead)->dwDevIndex == 1)
        {
            *pSerAMBA->pSC_MCR   |= MCR_DTR;
        }
        else
        {
            DEBUGMSG (ZONE_WARN, (TEXT("SL_SetDTR: invalid device index (0x%X)\r\n"), ((PSER_INFO)pHead)->dwDevIndex));
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_SetDTR, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func VOID | SL_ClearRTS | This routine clears RTS.
// 
// @rdesc None.
// 
VOID
SL_ClearRTS(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearRTS, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pSer16550->RegCritSec));
    try {
        // Depending on which port we're talking to, deassert the RTS signal.
        //
        if (((PSER_INFO)pHead)->dwDevIndex == 1)
        {
            *pSerAMBA->pSC_MCR   &= ~MCR_RTS;
        }
        else
        {
            DEBUGMSG (ZONE_WARN, (TEXT("SL_ClearRTS: invalid device index (0x%X)\r\n"), ((PSER_INFO)pHead)->dwDevIndex));
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_ClearRTS, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func VOID | SL_SetRTS | This routine sets RTS.
// 
// @rdesc None.
//
VOID
SL_SetRTS(
         PVOID   pHead // @parm PVOID returned by HWinit.
         )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetRTS, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pSer16550->RegCritSec));
    try {
        // Depending on which port we're talking to, assert the DTR signal.
        //
        if (((PSER_INFO)pHead)->dwDevIndex == 1)
        {
            *pSerAMBA->pSC_MCR   |= MCR_RTS;
        }
        else
        {
            DEBUGMSG (ZONE_WARN, (TEXT("SL_SetRTS: invalid device index (0x%X)\r\n"), ((PSER_INFO)pHead)->dwDevIndex));
        }
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_SetRTS, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func VOID | SL_ClearBreak | This routine clears break.
// 
// @rdesc None.
// 
VOID
SL_ClearBreak(
             PVOID   pHead // @parm PVOID returned by HWinit.
             )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_ClearBreak, 0x%X\r\n"), pHead));

    EnterCriticalSection(&(pSer16550->RegCritSec));
    try {
        unsigned char byte;

        byte = INB(pSerAMBA, pUART_LCR_H);
        OUTB(pSerAMBA, pUART_LCR_H, byte & ~AMBA_UARTLCR_H_BRK);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_ClearBreak, 0x%X\r\n"), pHead));
}

//
// @doc OEM
// @func VOID | SL_SetBreak | This routine sets break.
// 
// @rdesc None.
//
VOID
SL_SetBreak(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO  pSer16550 = &(((PSER_INFO)pHead)->ser16550);
    PAMBA_UART_INFO pSerAMBA  = &(((PSER_INFO)pHead)->serAMBA);

    DEBUGMSG (ZONE_FUNCTION, (TEXT("+SL_SetBreak, 0x%X\r\n"), pHead));

    EnterCriticalSection(&(pSer16550->RegCritSec));
    try {
        unsigned char byte;

        byte = INB(pSerAMBA, pUART_LCR_H);
        OUTB(pSerAMBA, pUART_LCR_H, byte | AMBA_UARTLCR_H_BRK);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just exit
    }
    LeaveCriticalSection(&(pSer16550->RegCritSec));

    DEBUGMSG (ZONE_FUNCTION, (TEXT("-SL_SetBreak, 0x%X\r\n"), pHead));
}

//
// SetBaudRate
//
// Internal function.  The only real reason for splitting this out
// is so that we can call it from PowerOn and still allow SL_SetBaud
// to do debug messages, acquire critical sections, etc.
//
BOOL
SetBaudRate(
           PVOID   pHead,
           ULONG   BaudRate
           )

⌨️ 快捷键说明

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