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

📄 pdd.c

📁 基于AU1200的CPLD的wince下的驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
		mask = UART_LINECTRL_PE | (3 << 4);
		break;
	default:
		goto cleanUp;
   }   

	EnterCriticalSection(&pPdd->hwCS);
	lineCtrl = INP32(&pPdd->pPortBase->linectrl);
	lineCtrl = (lineCtrl & ~UART_LINECTRL_ST)|mask;
	OUT32(&pPdd->pPortBase->linectrl, lineCtrl);
	LeaveCriticalSection(&pPdd->hwCS);
#endif
	ok = TRUE;

////cleanUp:
	return ok;
}

//------------------------------------------------------------------------------
//
// Function:     SetStopBits
//
// Description:  This function sets word length.
//

static BOOL SetStopBits(UARTPDD *pPdd, UCHAR stopBits)
{
	////UCHAR lineCtrl;
	BOOL ok = FALSE;
	////UCHAR mask;
#if 0
	switch (stopBits) {
	case ONESTOPBIT:
		mask = 0;
		break;
	case ONE5STOPBITS:
	case TWOSTOPBITS:
		mask = UART_LINECTRL_ST;
		break;
	default:
		goto cleanUp;
	}   

	EnterCriticalSection(&pPdd->hwCS);
	lineCtrl = INP32(&pPdd->pPortBase->linectrl);
	lineCtrl = (lineCtrl & ~UART_LINECTRL_ST)|mask;
	OUT32(&pPdd->pPortBase->linectrl, lineCtrl);
	LeaveCriticalSection(&pPdd->hwCS);
#endif
	ok = TRUE;

////cleanUp:
	return ok;
}

//------------------------------------------------------------------------------
//
// Function:     GetSerialObject
//
// Description:  This function returns a pointer to a HWOBJ structure, which
//               contains the correct function pointers and parameters for
//               the relevant PDD layer's hardware interface functions.

PHWOBJ GetSerialObject(DWORD index)
{
	PHWOBJ pHWObj;

	// Allocate space for the HWOBJ.
	pHWObj = malloc(sizeof(HWOBJ));
	if (pHWObj == NULL) goto cleanUp;

	// Fill in the HWObj structure

	pHWObj->BindFlags = THREAD_AT_OPEN; // Have MDD create thread when device is first opened.
	pHWObj->dwIntID = 0;                // SysIntr is filled in at init time
	pHWObj->pFuncTbl = &g_pddVTbl;      // Return pointer to appropriate functions

cleanUp:
	return pHWObj;
}
 

//------------------------------------------------------------------------------
//
// Function:     HWInit
//
// Description:  This function initializes a serial device and it returns
//               information about device
//

static PVOID HWInit(ULONG context, PVOID pMdd, PHWOBJ pHWObj)
{
	BOOL ok = FALSE;
	UARTPDD *pPdd = NULL;
	PHYSICAL_ADDRESS phBase;
	HKEY hKey = NULL;
	ULONG UnitIndex;
	ULONG Size;
	CPLD * pCpld = (CPLD *)CPLD_KSEG1_ADDR;  
	
	DEBUGMSG(ZONE_OPEN, (L"+cplduart::HWInit %s 0x%08x 0x%08x\r\n", context, pMdd, pHWObj));

	if(pBootArgs->bUartDebugEnable == 0x2c) {  
	    RETAILMSG(1,(L" cplduart::cpld Uart is using debug\r\n"));
		goto cleanUp;
	}
	
	// Allocate SER_INFO structure
	pPdd = malloc(sizeof(UARTPDD));
	if (pPdd == NULL) goto cleanUp;

	// Clear it
	memset(pPdd, 0, sizeof(UARTPDD));

	// Open registry 
	hKey = OpenDeviceKey((LPCTSTR)context);
	if (hKey == NULL) {
		DEBUGMSG(ZONE_ERROR, (L" cplduart::HWInit - Failed open registry key\r\n"));
		goto cleanUp;
	}

	// Read UnitIndex from the Registry
	Size = sizeof(UnitIndex);
	if (RegQueryValueEx(hKey, L"UnitIndex", NULL, NULL, (PUCHAR)&UnitIndex, &Size)) {
		RETAILMSG(1,(L" cplduart::HWInit - Failed open \"UnitIndex\" registry entry\r\n"));
		goto cleanUp;
	}

	// Check UnitIndex is valid and supported
	if (UnitIndex > UART_CONFIG_SIZE || UartConfig[UnitIndex].UartPhysAddr == 0) {
		RETAILMSG(1,(L" cplduart::HWInit - UnitIndex %d is invalid\r\n", UnitIndex));
		goto cleanUp;
	}

	// Map physical memory
	phBase.QuadPart = UartConfig[UnitIndex].UartPhysAddr;
	//pPdd->pPortBase = (AU1X00_UART*)MmMapIoSpace(phBase, sizeof(AU1X00_UART), FALSE);
	pPdd->pPortBase = (CPLD*)MmMapIoSpace(phBase, sizeof(CPLD), FALSE);
	if (pPdd->pPortBase == NULL) {
		DEBUGMSG(ZONE_ERROR, (L" cplduart::HWInit - Failed map physical memory 0x%x\r\n", phBase.LowPart));
		goto cleanUp;
	}

	// Save IRQ
	pPdd->irq = UartConfig[UnitIndex].UartIrq;

	pPdd->sysIntr = InterruptConnect(Internal,0,pPdd->irq, INTR_MODE_POSITIVE_LOGIC /*| INTR_MODE_NEGATIVE_LOGIC*/ /*| INTR_MODE_EDGE*/ | INTR_MODE_LEVEL);

	if (SYSINTR_NOP==pPdd->sysIntr) {
		DEBUGMSG(ZONE_ERROR, (L" cplduart::HWInit - Failed map IRQ %d\r\n", pPdd->irq));
		goto cleanUp;
	}

	// Save it to HW object
	pHWObj->dwIntID = pPdd->sysIntr;

	// Create sync objects
	InitializeCriticalSection(&pPdd->hwCS);
	InitializeCriticalSection(&pPdd->txCS);
	pPdd->txEvent = CreateEvent(0, FALSE, FALSE, NULL);
	if (pPdd->txEvent == NULL) {
		DEBUGMSG(ZONE_ERROR, (L" cplduart::HWInit - Failed create event\r\n"));
		goto cleanUp;
	}


	// Allow device
	//OUT32(&pPdd->pPortBase->enable, 0);
	//OUT32(&pPdd->pPortBase->enable, UART_ENABLE_CE);
	//OUT32(&pPdd->pPortBase->enable, UART_ENABLE_CE|UART_ENABLE_E);
	ResetUart(pPdd);
	//EnableRxFifo(pPdd, FALSE);	 // cpld里写死了一定要使用fifo
	EnableUart(pPdd, TRUE);
	RETAILMSG(1, (L"CPLD UART CTRL 0x%x\r\n", pPdd->pPortBase->uartCtrl));

	//while( !(pCpld->uartStatus & 0x01) );  // if send fifo is empty
    //pCpld->uartTxData = 'e';
	//while( !(pCpld->uartStatus & 0x01) );  // if send fifo is empty
    //pCpld->uartTxData = 'f';
	

	// Disable all interrupts
	//OUT32(&pPdd->pPortBase->inten, 0);
	//RETAILMSG(1, (L"CPLD UART uartIntEnable 01 0x%x\r\n", pPdd->pPortBase->uartIntEnable)); 
    //pPdd->pPortBase->uartIntEnable &= ~(TX_INT_ENB_BIT| RX_INT_ENB_BIT);
    DISABLE_ALL_INT(pPdd->pPortBase);
	//RETAILMSG(1, (L"CPLD UART uartIntEnable 02 0x%x\r\n", pPdd->pPortBase->uartIntEnable)); 
	
	// Save MDD context for callback
	pPdd->pMdd = pMdd;

	// Initialization succeeded
	ok = TRUE;


cleanUp:
	if (hKey != NULL) RegCloseKey(hKey);
	if (!ok && pPdd != NULL) {
		HWDeinit(pPdd);
		pPdd = NULL;
	}   
	DEBUGMSG(ZONE_OPEN, (L"-cplduart::HWInit 0x%08x\r\n", pPdd));
	return pPdd;
}


//------------------------------------------------------------------------------
//
// Function:     HWPostInit
//
// Description:  This function is called by the upper layer after hardware
//               independent initialization is done (at end of COM_Init).
//

static BOOL HWPostInit(PVOID pContext)
{
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Function:     HWDeinit
//
// Description:  This function is called by the upper layer to de-initialize
//               the hardware when a device driver is unloaded.

static BOOL HWDeinit(PVOID pContext)
{
	UARTPDD *pPdd = (UARTPDD*)pContext;
	CPLD * pCpld = (CPLD *)CPLD_KSEG1_ADDR;  

	DEBUGMSG(ZONE_CLOSE, (L"+cplduart::HWDeinit 0x%08x\r\n", pContext));

	// Disable device
	if (pPdd->pPortBase != NULL) {
		////OUT32(&pPdd->pPortBase->enable, 0);
		EnableUart(pPdd, FALSE);
		MmUnmapIoSpace((PVOID)pPdd->pPortBase, 0x1000);
	}      

	// Disconnect the interrupt
	InterruptDisconnect(pPdd->sysIntr);

	// Delete sync objects
	DeleteCriticalSection(&pPdd->hwCS);
	DeleteCriticalSection(&pPdd->txCS);
	if (pPdd->txEvent != NULL) CloseHandle(pPdd->txEvent);

	// Free driver object
	free(pPdd);

	DEBUGMSG(ZONE_CLOSE, (L"-cplduart::HWDeinit\r\n"));
	return TRUE;
}

//------------------------------------------------------------------------------

static BOOL HWOpen(PVOID pContext)
{
	BOOL ok = FALSE;
	UARTPDD *pPdd = (UARTPDD*)pContext;
	////UCHAR fifoCtrl;

	DEBUGMSG(ZONE_OPEN, (L"+cplduart::HWOpen 0x%x\r\n", pContext));

	if (pPdd->open) goto cleanUp;

	pPdd->commErrors = 0;
	pPdd->overrunCount = 0;
	pPdd->flowOffCTS = FALSE;
	pPdd->flowOffDSR = FALSE;
	pPdd->addTxIntr = FALSE;
	pPdd->powerOff = FALSE;
	pPdd->open = TRUE;

	// Initialize FIFO constant   
	////pPdd->txFifoLength = 16;
	//pPdd->txFifoThresh = 8;
	//pPdd->rxFifoLength = 16;
	//pPdd->rxFifoThresh = 1;
	pPdd->txFifoLength = 15;
	pPdd->txFifoThresh = 1;
	pPdd->rxFifoLength = 16;
	pPdd->rxFifoThresh = 1;

	EnterCriticalSection(&pPdd->hwCS);

	ResetUart(pPdd);   // 这样能使 reset Rx fifo, 同时不影响uart contoller的其它功能

	// Set line control register
	////OUT32(&pPdd->pPortBase->linectrl, 0);
	SetBaudRate(pPdd, pPdd->dcb.BaudRate);
	SetWordLength(pPdd, pPdd->dcb.ByteSize);
	SetStopBits(pPdd, pPdd->dcb.StopBits);
	SetParity(pPdd, pPdd->dcb.Parity);

	// Set modem control register
	////OUT32(&pPdd->pPortBase->mdmctrl, 0);

	// Set FIFO values & enable flags
	////fifoCtrl = UART_FIFOCTRL_FE | UART_FIFOCTRL_MS | (0 << 6) | (2 << 4);

	// Set reset TX & RX flags
	////fifoCtrl |= UART_FIFOCTRL_RR | UART_FIFOCTRL_TR;

	// Set fifo control register
	////OUT32(&pPdd->pPortBase->fifoctrl, fifoCtrl);
	//EnableRxFifo(pPdd, TRUE);  // Enable Rx fifo      // cpld里写死了一定要使用fifo

	// Enable interrupts (no TX interrupt)
	////OUT32(&pPdd->pPortBase->inten, UART_INTEN_TX_OFF);
	//RETAILMSG(1, (L"HWOpen CPLD UART uartIntEnable 01 0x%x\r\n", pPdd->pPortBase->uartIntEnable));
	{
	BYTE ch = pPdd->pPortBase->uartIntEnable;  //????????????????? 这里很 如果我不读一次这个register,那就不能正确写这个register
	}
	//pPdd->pPortBase->uartIntEnable = UART_INTEN_TX_OFF;  // Enable Rx interrupts, disable Tx interrupt
	DISABLE_TX_INT(pPdd->pPortBase);
	RETAILMSG(1, (L"HWOpen CPLD UART uartIntEnable 02 0x%x\r\n", pPdd->pPortBase->uartIntEnable));

	////ReadLineStat(pPdd);
	////ReadModemStat(pPdd);

	// SmartOne add
	// is com4: for BT //// power on bluetooth module 
	//if(pPdd->UnitIndex == 4 ){    
	{
	    CPLD * pCpld = (CPLD *)pPdd->pPortBase;

		// enable BT power
		pCpld->ioASet = CP_AIO_BT_PWR_EN_01;

		// Reset BT module
		pCpld->ioASet = CP_AIO_BT_RESET_00;
		StallExecution(1000);  //1ms
		pCpld->ioAClr = CP_AIO_BT_RESET_00;
		RETAILMSG(1, (L"+cplduart::HWOpen power on and reset bluetooth\r\n"));
	}
	// End SmartOne add

	LeaveCriticalSection(&pPdd->hwCS);

	ok = TRUE;

cleanUp:
	DEBUGMSG(ZONE_OPEN, (L"-cplduart::HWOpen %s\r\n", ok ? L"TRUE" : L"FALSE"));
	return ok;
}

//------------------------------------------------------------------------------

static ULONG HWClose(PVOID pContext)
{
	ULONG rc = -1;
	UARTPDD *pPdd = (UARTPDD*)pContext;

	DEBUGMSG(ZONE_CLOSE, (L"+cplduart::HWClose 0x%x\r\n", pContext));

	if (!pPdd->open) goto cleanUp;

	EnterCriticalSection(&pPdd->hwCS);

	// Disable all interrupts and clear modem control register
	////OUT32(&pPdd->pPortBase->inten, 0);
	////OUT32(&pPdd->pPortBase->mdmctrl, 0);
	////pPdd->pPortBase->uartIntEnable &= ~(TX_INT_ENB_BIT | RX_INT_ENB_BIT);  // disable Tx and Rx interrupt
	DISABLE_ALL_INT(pPdd->pPortBase);

	// SmartOne add
	// is com4: for BT //// power off bluetooth module 
	//if(pPdd->UnitIndex == 4 ){    
	{
	    CPLD * pCpld = (CPLD *)pPdd->pPortBase;

		// power off BT 
		pCpld->ioAClr = CP_AIO_BT_PWR_EN_01;

		// Reset BT module
		//pCpld->ioASet = CP_AIO_BT_RESET_00;
		//StallExecution(1000);  //1ms
		//pCpld->ioAClr = CP_AIO_BT_RESET_00;
		RETAILMSG(1, (L"+cplduart::HWClose power off bluetooth\r\n"));
	}
	// End SmartOne add

	LeaveCriticalSection(&pPdd->hwCS);

	pPdd->open = FALSE;
   
cleanUp:
	DEBUGMSG(ZONE_CLOSE, (L"-cplduart::HWClose %d\r\n", rc));
	return rc;
}

//------------------------------------------------------------------------------
//
// Function:     HWGetInterruptType
//
// Description:  This function is called by the upper layer whenever an
//               interrupt occurs.  The return code is then checked by the MDD
//               to determine which of the four interrupt handling routines are
//               to be called.
// 

static INTERRUPT_TYPE HWGetInterruptType(PVOID pContext)
{

⌨️ 快捷键说明

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