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

📄 serial.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 3 页
字号:

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Ser_GetRegistryData+:Try to open %s\r\n"), regKeyPath));

    // We've been handed the name of a key in the registry that was generated
    // on the fly by device.exe.  We're going to open that key and pull from it
    // a value that is the name of this serial port's real key.  That key
    // will have the DeviceArrayIndex that we're trying to find.
    hKey = OpenDeviceKey(regKeyPath);
    if (hKey == NULL) {
        DEBUGMSG(ZONE_ERROR, (TEXT("Failed to open device key\r\n")));
        return (FALSE);
    }

    // Okay, we're finally ready to try and load our registry data.
    dwDataSize = PC_REG_DEVINDEX_VAL_LEN;
    regError = RegQueryValueEx(
                              hKey,
                              PC_REG_DEVINDEX_VAL_NAME,
                              NULL,
                              NULL,
                              (LPBYTE)(&pSerHead->dwDevIndex),
                              &dwDataSize);

    if (regError == ERROR_SUCCESS) {
        dwDataSize = PC_REG_IOBASE_VAL_LEN;
        regError = RegQueryValueEx(
                                  hKey,
                                  PC_REG_IOBASE_VAL_NAME,
                                  NULL,
                                  NULL,
                                  (LPBYTE)(&pSerHead->dwIOBase),
                                  &dwDataSize);
    }

    if (regError == ERROR_SUCCESS) {
        dwDataSize = PC_REG_IOLEN_VAL_LEN;
        regError = RegQueryValueEx(
                                  hKey, 
                                  PC_REG_IOLEN_VAL_NAME, 
                                  NULL, 
                                  NULL,
                                  (LPBYTE)(&pSerHead->dwIOLen), 
                                  &dwDataSize);
    }

    RegCloseKey (hKey);

    if (regError != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (TEXT("Failed to get serial registry values, Error 0x%X\r\n"), regError));
        return (FALSE);
    }

    DEBUGMSG(ZONE_FUNCTION, (TEXT("Ser_GetRegistryData-\r\n")));

    return (TRUE); 
}


//-----------------------------------------------------------------------------
//
// Function: SerInit
//
//  This routine sets information controlled by 
//  the user such as Line control and baud rate. 
//  It can also initialize events and interrupts, 
//  thereby indirectly managing initializing hardware 
//  buffers. Exported only to driver, called only 
//  once per process.
//
// Parameters:
//      bIR 
//          [in] Is IR mode used.
//      Identifier 
//          [in] Device identifier.
//      pMDDContext 
//          [in] First argument to mdd callbacks.
//      pHWObj 
//          [in] Pointer to our own HW OBJ for this device.
//
// Returns:  
//      The return value is a PVOID to be passed back 
//      into the HW dependent layer when HW functions are 
//      called.
//
//-----------------------------------------------------------------------------
static PVOID SerInit( BOOL bIR, ULONG Identifier, PVOID pMDDContext, PHWOBJ pHWObj )
{
    PSER_INFO pSerHead = NULL;
    BOOL InitError = FALSE;
    ULONG irq;
    DEVICE_LOCATION devLoc;
    uartType_c type;
	DWORD dwSources;
    DWORD dwTransferred;
	UINT16 rxDMASize, txDMASize;

    DEBUGMSG(ZONE_INIT, (TEXT("SerInit+\r\n")));

    // Allocate for our main data structure and one of it's fields.
    pSerHead = (PSER_INFO)LocalAlloc(LMEM_ZEROINIT|LMEM_FIXED, sizeof(SER_INFO));

    if (!pSerHead)
        return(NULL);

   	if (!Ser_GetRegistryData(pSerHead, (LPCTSTR)Identifier)) {
        DEBUGMSG(ZONE_ERROR, (TEXT("SerInit - Unable to read registry data!!\r\n")));
        InitError = TRUE;
    }
	BSPUartConfigureGPIO(pSerHead->dwIOBase, TRUE);
	BSPUartConfigTranceiver(pSerHead->dwIOBase,TRUE);



	if (!InitError){
	  pSerHead->pBaseAddress = Ser_InternalMapRegisterAddresses(pSerHead->dwIOBase, pSerHead->dwIOLen);
	  
       	pSerHead->pHWObj = pHWObj;
        pSerHead->cOpenCount = 0;

        DEBUGMSG(ZONE_FUNCTION, (TEXT("SerInit \r\n")));

        if (!BSPUartGetType(pSerHead->dwIOBase, &type)) {
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Failed to obtain uart info.\r\n")));
            return (NULL);
        }

		

#if 0
        if (!BSPUartGetIrq(pSerHead->dwIOBase, &irq)) {
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Failed to obtain uart info.\r\n")));
            LocalFree(pSerHead);
            DEBUGMSG(ZONE_ERROR, (TEXT("SerInit - Initialization failed!!\r\n")));
            return (NULL);
        }
#endif

        // Use kernel IOCTL to translate the UART base address into an IRQ since
        // the IRQ value differs based on the SoC. Note that DEVICE_LOCATION
        // fields except IfcType and LogicalLoc are ignored for internal SoC 
        // components.
        devLoc.IfcType = Internal;
        devLoc.LogicalLoc = pSerHead->dwIOBase;

        if (!KernelIoControl(IOCTL_HAL_REQUEST_IRQ, &devLoc, sizeof(devLoc),
            &irq, sizeof(irq), NULL))
        {
            ERRORMSG(1, (_T("Cannot obtain UART IRQ!\r\n")));
            LocalFree(pSerHead);
            DEBUGMSG(ZONE_ERROR, (TEXT("SerInit - Initialization failed!!\r\n")));
            return (NULL);
        }

        if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD), 
        &pSerHead->pHWObj->dwIntID, sizeof(DWORD), NULL)) {
            DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: Failed to obtain sysintr value for UART interrupt.\r\n")));
            LocalFree(pSerHead);
            DEBUGMSG(ZONE_ERROR, (TEXT("SerInit - Initialization failed!!\r\n")));
            return (NULL);
        }

		pSerHead->irq = irq;

		// find out if DMA is desired for this UART or not.
		pSerHead->useDMA = BSPSerGetDMAIsEnabled(pSerHead->dwIOBase);
		
		if (pSerHead->useDMA)
		{
			DEBUGMSG(ZONE_FLOW, (TEXT("SerInit: DMA enabled for this UART\r\n")));
			BSPGetDMABuffSize(&rxDMASize,&txDMASize);
			pSerHead->rxDMABufSize = rxDMASize;
			pSerHead->txDMABufSize = txDMASize;

			if(!InitDMA(pSerHead))
				DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: InitDMA failed\r\n")));
		}

		if (!bIR) {
            dwSources = pSerHead->pHWObj->dwIntID;
            if(KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &dwSources, sizeof(DWORD),
                NULL, 0, &dwTransferred) == FALSE)
            {
                DEBUGMSG(ZONE_ERROR, (TEXT("ERROR: IOCTL_HAL_ENABLE_WAKE failed\r\n")));
                LocalFree(pSerHead);
                DEBUGMSG(ZONE_ERROR, (TEXT("SerInit - Initialization failed!!\r\n")));
                return (NULL);
            }
        }
		
		// Set up our Comm Properties data    
        pSerHead->CommProp.wPacketLength = 0xffff;
        pSerHead->CommProp.wPacketVersion = 0xffff;
        pSerHead->CommProp.dwServiceMask = SP_SERIALCOMM;
        pSerHead->CommProp.dwReserved1 = 0;
        pSerHead->CommProp.dwMaxTxQueue = 32;
        pSerHead->CommProp.dwMaxRxQueue = 32;
        pSerHead->CommProp.dwMaxBaud = BAUD_115200;
        pSerHead->CommProp.dwProvSubType = PST_RS232;
 
        pSerHead->CommProp.dwProvCapabilities =
            PCF_DTRDSR | PCF_RLSD | PCF_RTSCTS |
            PCF_SETXCHAR | PCF_INTTIMEOUTS |
            PCF_PARITY_CHECK | PCF_SPECIALCHARS |
            PCF_TOTALTIMEOUTS | PCF_XONXOFF;
  
        pSerHead->CommProp.dwSettableBaud =
            BAUD_075 | BAUD_110 | BAUD_150 | BAUD_300 |
            BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 |
            BAUD_4800 | BAUD_7200 | BAUD_9600 | BAUD_14400 |
            BAUD_19200 | BAUD_38400 | BAUD_56K | BAUD_128K |
            BAUD_115200 | BAUD_57600 | BAUD_USER;
  
        pSerHead->CommProp.dwSettableParams =
            SP_BAUD | SP_DATABITS | SP_HANDSHAKING | SP_PARITY |
            SP_PARITY_CHECK | SP_RLSD | SP_STOPBITS;
   
        pSerHead->CommProp.wSettableData =
 //           DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8;
            DATABITS_7 | DATABITS_8;

        pSerHead->CommProp.wSettableStopParity =
            STOPBITS_10 | STOPBITS_20 |
//            PARITY_NONE | PARITY_ODD | PARITY_EVEN | PARITY_SPACE |
//            PARITY_MARK;
            PARITY_NONE | PARITY_ODD | PARITY_EVEN;

        pSerHead->fIRMode = bIR;
		
		SL_Init(bIR, type, pSerHead->dwIOBase, pSerHead->pBaseAddress,
			pSerHead, EvaluateEventFlag, pMDDContext, (PLOOKUP_TBL)&BaudTable);
   		
		return (pSerHead);
    }
    else {
        if (pSerHead->pBaseAddress)
            MmUnmapIoSpace(pSerHead->pBaseAddress, pSerHead->dwIOLen);

        LocalFree(pSerHead);

        DEBUGMSG(ZONE_INIT, (TEXT("SerInit - Initialization failed!!\r\n")));

        return (NULL);
    }
}


//-----------------------------------------------------------------------------
//
// Function: SerSerialInit
//
//  This function calls SerInit to initialize serial device.
//
// Parameters:
//      Identifier 
//          [in] Device identifier.
//      pMDDContext 
//          [in] First argument to mdd callbacks.
//      pHWObj 
//          [in] Pointer to our own HW OBJ for this device.
//
// Returns:  
//      The return value is a PVOID to be passed back 
//      into the HW dependent layer when HW functions are 
//      called.
//
//-----------------------------------------------------------------------------
static PVOID SerSerialInit( ULONG Identifier, PVOID pMDDContext, PHWOBJ pHWObj )
{
    DEBUGMSG(ZONE_INIT,(TEXT("SerSerialInit+\r\n")));
    return (SerInit(FALSE, Identifier, pMDDContext, pHWObj));
}


//-----------------------------------------------------------------------------
//
// Function: SerIRInit
//
//  This function calls SerInit to initialize serial IR device.
//
// Parameters:
//      Identifier 
//          [in] Device identifier.
//      pMDDContext 
//          [in] First argument to mdd callbacks.
//      pHWObj 
//          [in] Pointer to our own HW OBJ for this device.
//
// Returns:  
//      The return value is a PVOID to be passed back 
//      into the HW dependent layer when HW functions are 
//      called.
//
//-----------------------------------------------------------------------------
static PVOID SerIRInit( ULONG Identifier, PVOID pMDDContext, PHWOBJ pHWObj )
{
    DEBUGMSG(ZONE_INIT,(TEXT("SerIRInit+\r\n")));
    return (SerInit(TRUE, Identifier, pMDDContext, pHWObj));
}


//-----------------------------------------------------------------------------
//
// Function: SerPostInit
//
//  This function is called by the upper layer to
//  perform any necessary operations after initializing
//  all data structures and prepare the serial IST to
//  begin handling interrupts. This call occurs as the
//  last step of the COM_Init routine.
//
// Parameters:
//      pContext 
//          [in] Pointer to a context structure returned 
//                by SerInit function that contains implementation-
//                specific data describing the hardware device.
//
// Returns:  
//      TRUE if success. FALSE if failure.
//
//-----------------------------------------------------------------------------
static BOOL SerPostInit( PVOID pContext )
{
    DEBUGMSG(ZONE_INIT,(TEXT("SerPostInit+\r\n")));

    // 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.
    SL_ClearPendingInts( pContext );
    
    DEBUGMSG(ZONE_INIT,(TEXT("SerPostInit-\r\n")));

    return(TRUE);
}


//-----------------------------------------------------------------------------
//
// Function: SerOpen
//
//  This function is called by the upper layer to
//  open the serial device. This function applies 
//  power to the serial hardware.
//
// Parameters:
//      pContext 
//          [in] Pointer to a context structure returned 
//                by SerInit function that contains implementation-
//                specific data describing the hardware device.
//
// Returns:  
//      TRUE if success. FALSE if failure.
//
//-----------------------------------------------------------------------------
static BOOL SerOpen( PVOID pContext )
{
    PSER_INFO pSerHead = (PSER_INFO)pContext;

    DEBUGMSG(ZONE_OPEN,(TEXT("SerOpen+ \r\n")));

    // Disallow multiple simultaneous opens
    if (pSerHead->cOpenCount)
        return (FALSE);

    pSerHead->cOpenCount++;
 
	SL_Reset(pSerHead);
	SL_Open(pSerHead);
    SL_SetOutputMode(pSerHead, pSerHead->fIRMode, !pSerHead->fIRMode); 
    

    DEBUGMSG(ZONE_OPEN,(TEXT("SerOpen-\r\n")));

    return (TRUE);
}


//-----------------------------------------------------------------------------
//
// Function: SerClose
//
//  This function is called by the upper layer to
//   close the serial device.
//
// Parameters:
//      pContext 
//          [in] Pointer to a context structure returned 
//                by SerInit function that contains implementation-
//                specific data describing the hardware device.
//
// Returns:  
//      Zero indicates success.
//
//-----------------------------------------------------------------------------
static ULONG SerClose( PVOID pContext )
{
    PSER_INFO pSerHead = (PSER_INFO)pContext;
    ULONG uTries;
   
    DEBUGMSG(ZONE_CLOSE,(TEXT("SerClose+ \r\n")));

    if (pSerHead->cOpenCount) {
        DEBUGMSG(ZONE_CLOSE, (TEXT("SerClose - closing device\r\n")));

        pSerHead->cOpenCount--;

        // while we are still transmitting, sleep.
        uTries = 0;
        while(!(pSerHead->uart_info.pUartReg->USR2 & 0x00004000)
              && (uTries++ < 100)){    // TxFifo not empty..
            DEBUGMSG(ZONE_WARN, (TEXT("SerClose, TX in progress.\r\n")));            
            Sleep(10);
        }

        // When the device is closed, we power it down.
        SL_Close(pSerHead);
    }
    
    DEBUGMSG(ZONE_CLOSE,(TEXT("SerClose-\r\n")));

    return (0);
}


//-----------------------------------------------------------------------------
//
// Function: SerDeinit
//
//  This function is called by the upper layer to
//  de-initialize the serial device.

⌨️ 快捷键说明

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