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

📄 bvd_ser16550.c

📁 cayman提供的PXA270 wince下的bsp源码包
💻 C
📖 第 1 页 / 共 5 页
字号:
          //OUTB(pHWHead, pIER_DLH, (UCHAR)0); 
          //OUTB(pHWHead, pMCR, (UCHAR)0);
          pHWHead->IIR   = INB(pHWHead, pIIR_FCR);
    }
    except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
        // Just get out of here.
    }
    LeaveCriticalSection(&(pHWHead->RegCritSec));

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

//
// @doc OEM 
// @func PVOID | HW_XSC1_Init | Initializes Cotulla's 16550 device head.  
//
VOID
HW_XSC1_Init(
       PVOID   pHead, // @parm points to device head
       PULONG  pRegBase, // Pointer to 16550 register base
       UINT32   RegStride, // Stride amongst the 16550 registers
	   DWORD    dwIoBase,          // IO Base Address
	   volatile XLLP_GPIO_T	  *pGPIOReg,   // @field for configuring GPIO pins
	   volatile XLLP_CLKMGR_T *pClkMgrReg, // @field for configuring clk mgr
       EVENT_FUNC EventCallback, // This callback exists in MDD
       PVOID   pMddHead,         // This is the first parm to callback
       PLOOKUP_TBL   pBaudTable  // BaudRate Table
       )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;
	XLLP_UINT32_T    LockID;

    DEBUGMSG (ZONE_CLOSE,(TEXT("+HW_XSC1_INIT, 0x%X\r\n"), pHWHead));
//	DEBUGMSG (1,(TEXT("??????????????????+HW_XSC1_INIT, 0x%X\r\n"), pHWHead));

    // Set up pointers to 16550 registers
    pHWHead->pTHR_RBR_DLL    = pRegBase + (RegStride * RECEIVE_BUFFER_REGISTER);
    pHWHead->pIER_DLH        = pRegBase + (RegStride * INTERRUPT_ENABLE_REGISTER);
    pHWHead->pIIR_FCR   = pRegBase + (RegStride * INTERRUPT_IDENT_REGISTER);
    pHWHead->pLCR     = pRegBase + (RegStride * LINE_CONTROL_REGISTER);
    pHWHead->pMCR     = pRegBase + (RegStride * MODEM_CONTROL_REGISTER);
    pHWHead->pLSR     = pRegBase + (RegStride * LINE_STATUS_REGISTER);
    pHWHead->pMSR     = pRegBase + (RegStride * MODEM_STATUS_REGISTER);
    pHWHead->pSCR     = pRegBase + (RegStride * SCRATCH_REGISTER);
    //Seting up SLOW_IR_SELECT_REGISTER register also
    //though we don't use it till IR mode is selected.
    pHWHead->pIRDASEL = pRegBase + (RegStride * SLOW_IR_SELECT_REGISTER);
	pHWHead->pFOR     = pRegBase + (RegStride * FIFO_OCCUPANCY_REGISTER);
    pHWHead->pABR     = pRegBase + (RegStride * AUTOBAUD_CONTROL_REGISTER);
	pHWHead->pACR     = pRegBase + (RegStride * AUTOBAUD_COUNT_REGISTER);

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

	//To find out which uart is it 
	pHWHead->IOBase = dwIoBase;
	//To modify GPIO pins
	pHWHead->pGPIOReg = pGPIOReg;
	//To modify peripheral clocks
	pHWHead->pClkMgrReg = pClkMgrReg;


    // Now set up remaining fields
    if ( pBaudTable != NULL )
        pHWHead->pBaudTable = (LOOKUP_TBL *) pBaudTable;
    else
        pHWHead->pBaudTable = (LOOKUP_TBL *) &LS_BaudTable;
    pHWHead->FlushDone      = CreateEvent(0, FALSE, FALSE, NULL);

    pHWHead->OpenCount = 0;

	//UART should not be enabled before GPIO pins are configured.

    #ifndef NON_WS_GPIO
	//Configure GPIOs, peripheral clock and board level registers for UARTs
	if (FFUART_BASE_U_VIRTUAL == pHWHead->IOBase)
	{
	   LockID = XllpLock(GPCR1);
	   //Initialize GPIO pins 
	   //Write 0 on GPIO pins 39, 40 and 41 before configuring them as outputs.
	   pHWHead->pGPIOReg->GPCR1 = ( XLLP_GPIO_BIT_FFDTR | XLLP_GPIO_BIT_FFTXD | 
									XLLP_GPIO_BIT_FFRTS );
	   XllpUnlock(LockID);
	   
      
	   LockID = XllpLock(GPDR1);
	   //Configure direction of GPIO pins 34, 35, 36, 37 and 38 as input 
	   //and GPIO pins 39, 40 and 41 as output
	   pHWHead->pGPIOReg->GPDR1 &= ~( XLLP_GPIO_BIT_FFRXD | XLLP_GPIO_BIT_FFCTS | 
							          XLLP_GPIO_BIT_FFDCD | XLLP_GPIO_BIT_FFDSR | 
							          XLLP_GPIO_BIT_FFRI );
	   pHWHead->pGPIOReg->GPDR1 |= (  XLLP_GPIO_BIT_FFTXD |  XLLP_GPIO_BIT_FFDTR |  
									  XLLP_GPIO_BIT_FFRTS );
	   XllpUnlock(LockID);

	   LockID = XllpLock(GAFR1_L);
	   //Configure GPIO pins 34, 35, 36, 37 and 38 for Alt_fn1. And pins 39, 40 and 41 for Alt_fn2.
	   pHWHead->pGPIOReg->GAFR1_L |= ( XLLP_GPIO_AF_BIT_FFRXD | XLLP_GPIO_AF_BIT_FFCTS | 
									   XLLP_GPIO_AF_BIT_FFDCD | XLLP_GPIO_AF_BIT_FFDSR | 
									   XLLP_GPIO_AF_BIT_FFRI  | XLLP_GPIO_AF_BIT_FFTXD | 
									   XLLP_GPIO_AF_BIT_FFDTR | XLLP_GPIO_AF_BIT_FFRTS );
	   XllpUnlock(LockID);

	   //if (!(StartClock(XLLP_CLKEN_FFUART , NOTINPOWERHANDLER)))
	   //   DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to start FFUART clock!\r\n")));
	  
	   //Enable FFUART clock
	   LockID = XllpLock(CKEN);
	   pHWHead->pClkMgrReg->cken |= XLLP_CLKEN_FFUART ;
	   XllpUnlock(LockID);

	   //RETAILMSG (1,(TEXT("\r\nHW_XSC1_INIT: FFUART, 0x%X\r\n"), pHWHead));
	}
	else if (BTUART_BASE_U_VIRTUAL == pHWHead->IOBase)
	{
	   //Configuring GPIO pins for BTUART
	   //Initialize GPIO pins 
	   //Write 0 on GPIO pins 43 and 45 before configuring them as outputs.
	   LockID = XllpLock(GPCR1);
	   pHWHead->pGPIOReg->GPCR1 = (XLLP_GPIO_BIT_BTTXD | XLLP_GPIO_BIT_BTRTS);
	   XllpUnlock(LockID);

	   //Configure direction of GPIO pins 42 and 44 as input 
	   //and GPIO pins 43 and 45 as output
	   LockID = XllpLock(GPDR1);
	   pHWHead->pGPIOReg->GPDR1 &= ~( XLLP_GPIO_BIT_BTRXD | XLLP_GPIO_BIT_BTCTS); 
	   pHWHead->pGPIOReg->GPDR1 |=  ( XLLP_GPIO_BIT_BTTXD | XLLP_GPIO_BIT_BTRTS);
	   XllpUnlock(LockID);

	   //Configure GPIO pins 42 and 44 for Alt_fn1. And pins 43 and 45 for Alt_fn2.
	   LockID = XllpLock(GAFR1_L);
	   pHWHead->pGPIOReg->GAFR1_L |= ( XLLP_GPIO_AF_BIT_BTRXD | XLLP_GPIO_AF_BIT_BTCTS |
									   XLLP_GPIO_AF_BIT_BTTXD | XLLP_GPIO_AF_BIT_BTRTS );
	   XllpUnlock(LockID);


	   //if (!(StartClock(XLLP_CLKEN_BTUART , NOTINPOWERHANDLER)))
	   //   DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to start BTUART clock!\r\n")));
	  
	   //Enable BTUART clock
	   LockID = XllpLock(CKEN);
	   pHWHead->pClkMgrReg->cken |= XLLP_CLKEN_BTUART ;
	   XllpUnlock(LockID);

	   //RETAILMSG (1,(TEXT("\r\nHW_XSC1_INIT: BTUART, 0x%X\r\n"), pHWHead));
	}
	else if (STUART_BASE_U_VIRTUAL == pHWHead->IOBase)
	{
	   //Initialize GPIO pins 
	   //Write 0 on GPIO pin 47 before configuring it as output.
	   //Verify whether to write zero or not?
	   //pHWHead->pGPIOReg->GPCR_y |=  (GPIO_47);
	   LockID = XllpLock(GPSR1);
	   pHWHead->pGPIOReg->GPSR1 =  (XLLP_GPIO_BIT_STD_TXD);
	   XllpUnlock(LockID);

	   //Configure direction of GPIO pin 46 as input and GPIO pin 47 as output
	   LockID = XllpLock(GPDR1);
	   pHWHead->pGPIOReg->GPDR1 &= (~XLLP_GPIO_BIT_STD_RXD);
	   pHWHead->pGPIOReg->GPDR1 |= ( XLLP_GPIO_BIT_STD_TXD);
	   XllpUnlock(LockID);

	   //Configure GPIO pin 46 for Alt_fn2. And, GPIO pin 47 for Alt_fn1.
	   LockID = XllpLock(GAFR1_L);
	   pHWHead->pGPIOReg->GAFR1_L |= (XLLP_GPIO_AF_BIT_STD_RXD | XLLP_GPIO_AF_BIT_STD_TXD);
	   XllpUnlock(LockID);

	   DEBUGMSG (ZONE_INIT, (TEXT("HW_XSC1_Init - GPIO pins configured for STUART\r\n")));


	  //if (!(StartClock(XLLP_CLKEN_STUART , NOTINPOWERHANDLER)))
	  //   DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to start STUART clock!\r\n")));
	  
	  //Enable STUART clock
	  LockID = XllpLock(CKEN);
	  pHWHead->pClkMgrReg->cken |= XLLP_CLKEN_STUART ;
	  XllpUnlock(LockID);

	  //RETAILMSG (1,(TEXT("\r\nHW_XSC1_INIT: STUART, 0x%X\r\n"), pHWHead));
	} 
    #endif

	//Doing these settings so that Rx FIFO could be served even without COM_Open being called
	//UART and these settings could be potentially turned off in production code to conserve power
	DEBUGMSG (1,(TEXT("??????????????????+HW_XSC1_INIT, 0x%X :Reiniting UART for 38400 8N1 mode !!!\r\n"), pHWHead));
	OUTB(pHWHead, pLCR,     (UCHAR)0);         // clearing DLAB 
    OUTB(pHWHead, pIER_DLH, (UCHAR)0);         // IER_DLH = 0x0 
	//Baud rate 38400
    OUTB(pHWHead, pLCR,        (UCHAR)0x80 );  // Access Divisor 
	OUTB(pHWHead,pTHR_RBR_DLL, (UCHAR)0x18 );  // low byte divisor
	OUTB(pHWHead, pIER_DLH,    (UCHAR)0x0  );  // high byte divisor
    OUTB(pHWHead, pLCR,        (UCHAR)0x0  );  // clearing DLAB 
	//Setting UART properties to 8N1 
	pHWHead->LCR |=  (SERIAL_8_DATA | SERIAL_1_STOP | SERIAL_NONE_PARITY);
    OUTB(pHWHead, pLCR, (pHWHead->LCR) );      //pLCR = 0x3.

	//Ensuring that loop back mode is off
	//For now, disable Autoflow
	pHWHead->MCR &= (~SERIAL_MCR_LOOP & ~SERIAL_MCR_AUTO_FLOW_ENABLE_CTS);
	//Set RTS for non-Autoflow mode and set MCR[OUT]=1 to enable UART IRQ.
	pHWHead->MCR |= (SERIAL_MCR_RTS | SERIAL_MCR_IRQ_ENABLE);
	OUTB(pHWHead, pMCR, (UCHAR) pHWHead->MCR);
/*
	//#ifdef A1_Cotulla
	if((pHWHead->ProcessorStepping == COTULLA_A1_CP15_VAL) || (pHWHead->ProcessorStepping == SABINAL_A1_CP15_VAL) ){
		//Cotulla A1: Set MCR[OUT]=0 to enable UART IRQ
      pHWHead->MCR &= ~SERIAL_MCR_IRQ_ENABLE ;
	}
	//#elif B0_Cotulla
	else if((pHWHead->ProcessorStepping == COTULLA_B0_CP15_VAL) || (pHWHead->ProcessorStepping == SABINAL_B0_CP15_VAL) ){
    	//Cotulla B0: Set MCR[OUT]=1 to enable UART IRQ
      pHWHead->MCR |= SERIAL_MCR_IRQ_ENABLE ;
	}
	//#else 
	else{
		//Default stepping: Set MCR[OUT]=1 to enable UART IRQ.
	    pHWHead->MCR |= SERIAL_MCR_IRQ_ENABLE ;
	}   
	//#endif
*/
	
	//For Bulverde
	//To Do: Change peripheral bus to be 32 bit
    #ifdef UART_32_BIT_PERIPHERAL_BUS
	
	//Set Tx Interrupt level to FIFO half empty
	//Trailing bytes are removed by Processor 
	pHWHead->FCR &=  (  ~SERIAL_FCR_TX_INTR_LEVEL    
	   	              & ~SERIAL_FCR_TRAILING_BYTES); 
	
	//Rx FIFO Interrupt Threshold level is 32 bytes and Enable RxTx FIFOs.
	//Peripheral bus is 32 bit
	pHWHead->FCR |= (SERIAL_FCR_TXRXFIFO_ENABLE | XSC1_SERIAL_32_BYTE_HIGH_WATER |
		             SERIAL_FCR_PERIPHERAL_BUS  ) ;

    #else

	//Set Tx Interrupt level to FIFO half empty
	//Trailing bytes are removed by Processor
	//Peripheral bus is 8 bit
	pHWHead->FCR &=  (  ~SERIAL_FCR_TX_INTR_LEVEL    
	   	               & ~SERIAL_FCR_TRAILING_BYTES   
					   & ~SERIAL_FCR_PERIPHERAL_BUS);
	
	//Rx FIFO Interrupt Threshold level is 32 bytes and Enable RxTx FIFOs.
	pHWHead->FCR |= (SERIAL_FCR_TXRXFIFO_ENABLE | XSC1_SERIAL_32_BYTE_HIGH_WATER) ;
    
    #endif
    OUTB(pHWHead, pIIR_FCR, (UCHAR) pHWHead->FCR);


	//Right now, make sure that ABR bits is set to zero
	pHWHead->ABR &= (  ~SERIAL_ABR_AUTOBAUD_ENABLE
		             & ~SERIAL_ABR_AUTOBAUDLOCK_INTR_ENABLE
					 & ~SERIAL_ABR_UART_PROGRAM
					 & ~SERIAL_ABR_AUTOBAUD_TABLE);
	OUTB(pHWHead, pABR, (UCHAR) pHWHead->ABR);

	DEBUGMSG (1,(TEXT("??????????????????+HW_XSC1_INIT, 0x%X :Not touching UART!!!\r\n"), pHWHead));
    // Don't allow any interrupts till HW_XSC1_PostInit.
    // UART Unit, all interrupts and NRZ encoding are disabled
	//OUTB(pHWHead, pLCR,     (UCHAR)0);   // clearing DLAB 
    //OUTB(pHWHead, pIER_DLH, (UCHAR)0);   // IER_DLH = 0x0 

    InitializeCriticalSection(&(pHWHead->TransmitCritSec));
    InitializeCriticalSection(&(pHWHead->RegCritSec));
    
	// Clear any interrupts which may be pending.  Normally only
    // happens if we were warm reset.
    HW_XSC1_ClearPendingInts( pHWHead );

#ifdef USE_MERLIN
	//Enable interrupts and UART to take care of rx data without COM_Open()
	pHWHead->IER |=  (SERIAL_IER_UUE | IER_NORMAL_INTS) ;
    OUTB(pHWHead, pIER_DLH, (UCHAR) pHWHead->IER);
#endif

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

//
// @doc OEM
// @func void | HW_XSC1_PostInit | This routine takes care of final initialization.
//
// @rdesc None.
//
BOOL
HW_XSC1_PostInit(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;

    DEBUGMSG (ZONE_INIT,(TEXT("+HW_XSC1_PostInit, 0x%X\r\n"), pHWHead));
    
    // 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.
    HW_XSC1_ClearPendingInts( pHWHead );
    
    DEBUGMSG (ZONE_INIT,(TEXT("-HW_XSC1_PostInit, 0x%X\r\n"), pHWHead));
    return(TRUE);
}

//
// @doc OEM 
// @func PVOID | HW_XSC1_Deinit | De-initializes Cotulla's 16550 device head.  
//
VOID
HW_XSC1_Deinit(
         PVOID   pHead // @parm points to device head
         )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;
	XLLP_UINT32_T    LockID;

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

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

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

	//Stop the clock
	if (pHWHead->IOBase == FFUART_BASE_U_VIRTUAL)
	{
	  //Disable FFUART clock
	  LockID = XllpLock(CKEN);
	  pHWHead->pClkMgrReg->cken &= ~XLLP_CLKEN_FFUART ;
	  XllpUnlock(LockID);

      //if (!(StopClock(XLLP_CLKEN_FFUART , NOTINPOWERHANDLER)))
	  //	 DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to stop FFUART clock!\r\n")));;
    }
	else if (pHWHead->IOBase == BTUART_BASE_U_VIRTUAL)
	{
	  //Disable BTUART clock
	  LockID = XllpLock(CKEN);
	  pHWHead->pClkMgrReg->cken &= ~XLLP_CLKEN_BTUART ;
	  XllpUnlock(LockID);

      //if (!(StopClock(XLLP_CLKEN_BTUART , NOTINPOWERHANDLER)))
	  //	 DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to stop BTUART clock!\r\n")));;
    }
	else if (pHWHead->IOBase == STUART_BASE_U_VIRTUAL)
	{
	  //Disable STUART clock
	  LockID = XllpLock(CKEN);
	  pHWHead->pClkMgrReg->cken &= ~XLLP_CLKEN_STUART ;
	  XllpUnlock(LockID);

      //if (!(StopClock(XLLP_CLKEN_STUART , NOTINPOWERHANDLER)))
	  //	 DEBUGMSG(ZONE_ERROR,(TEXT("HW_XSC1_Init: Unable to stop STUART clock!\r\n")));;
    }

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

//
// @doc OEM
// @func void | HW_XSC1_ClearDtr | This routine clears DTR.
//
// @rdesc None.
//
VOID
HW_XSC1_ClearDTR(
           PVOID   pHead // @parm PVOID returned by HWinit.
           )
{
    PSER16550_INFO   pHWHead   = (PSER16550_INFO)pHead;
	
    DEBUGMSG (ZONE_FUNCTION, (TEXT("+HW_XSC1_ClearDTR, 0x%X\r\n"), pHead));
    EnterCriticalSection(&(pHWHead->RegCritSec));
    try {
         ULONG value;

		 if (pHWHead->IOBase == FFUART_BASE_U_VIRTUAL)
		 {
          value = INB((PSER16550_INFO)pHead, pMCR);
          pHWHead->MCR &= ~SERIAL_MCR_DTR;
          OUTB((PSER16550_INFO)pHead, pMCR, value & ~SERIAL_MCR_DTR);
		 }
		 else if (pHWHead->IOBase == BTUART_BASE_U_VIRTUAL)
		 {

		  //DEBUGMSG (1,(TEXT("**************HW_XSC1_ClearDTR %X\r\n"),pHWHead->MSR));

⌨️ 快捷键说明

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