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

📄 sir.cpp

📁 freescale i.mx31 BSP CE5.0全部源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//
// Returns:  
//		This function returns the actually baudrate set.
//
//-----------------------------------------------------------------------------
baudRates SirSetSpeed(pFirDevice_t thisDev)
{
    baudRates rate = BAUDRATE_INVALID;
    ULONG bRefFreq = UART_REF_FREQ;
	ULONG speed = thisDev->newSpeed;
    ULONG baudrate = speed;

	if (speed <= MAX_SIR_SPEED) 
    {
        for (int i=0; i<NUM_BAUDRATES; i++)
        {
            if (speed == supportedBaudRateTable[i].bitsPerSec)
            {
                rate = supportedBaudRateTable[i].tableIndex;
                break;
            }
        }

		// Check whether IR special case is needed.
		if (speed < IRSC_BAUDRATE) 
		{
			DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: SIR special case!")));
			CSP_BITFINS(g_pVSIRReg->UCR4, UART_UCR4_IRSC, UART_UCR4_IRSC_SAMPCLK);
			CSP_BITFINS(g_pVSIRReg->UCR2, UART_UCR2_SRST, UART_UCR2_SRST_RESET);
			CSP_BITFINS(g_pVSIRReg->UCR4, UART_UCR4_IRSC, UART_UCR4_IRSC_REFCLK);
        }
		else 
		{
			CSP_BITFINS(g_pVSIRReg->UCR4, UART_UCR4_IRSC, UART_UCR4_IRSC_SAMPCLK);
			CSP_BITFINS(g_pVSIRReg->UCR2, UART_UCR2_SRST, UART_UCR2_SRST_RESET);
			for (UINT i=0; i<4; i++);	
			CSP_BITFINS(g_pVSIRReg->UCR4, UART_UCR4_IRSC, UART_UCR4_IRSC_SAMPCLK);
		}

		CSP_BITFINS(g_pVSIRReg->UFCR, UART_UFCR_RFDIV, RFDIV_VALUE(BSPUartCalRFDIV(&bRefFreq)));
        g_pVSIRReg->UBIR = UART_UBIR_INCREMENT(speed, UART_UBMR_MOD_DEFAULT, bRefFreq)-1;
        g_pVSIRReg->UBMR = UART_UBMR_MOD_DEFAULT -1;
		NdisStallExecution(5000); // delay
    }
    else
        DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: SirSetSpeed, unsupported bitsPerSec: %d, NOT SIR\r\n"), speed));
    
	DEBUGMSG(ZONE_FUNCTION, (TEXT("Sir: -SirSetSpeed\r\n")));
    return rate;

}

//-----------------------------------------------------------------------------
//
// Function: SirClearInterruptStatus
//
// This function is to clear the interrupts status on UART22.
//
// Parameters:
//		None.
//
// Returns:  
//		None.
//
//-----------------------------------------------------------------------------
VOID SirClearInterruptStatus(VOID)
{
	// We don't use error interrupt, therefore all status bits 
	// will be automatically cleared.
	return;
}

//-----------------------------------------------------------------------------
//
// Function: SirEnableInterrupt
//
// This function is to enable the interrupts from UART2 module.
//
// Parameters:
//      thisDev 
//          [in] .
//
// Returns:  
//    None.
//
//-----------------------------------------------------------------------------
VOID SirEnableInterrupt(pFirDevice_t thisDev)
{
	if (thisDev->writePending) 
	{
		CSP_BITFINS(g_pVSIRReg->UCR1, UART_UCR1_TXMPTYEN, UART_UCR1_TXMPTYEN_ENABLE);	// Transmitter FIFO empty interrupt
	} 
	else 
	{
		CSP_BITFINS(g_pVSIRReg->UCR4, UART_UCR4_DREN, UART_UCR4_DREN_ENABLE);			// Receive data Ready Interrupt
	}
}

//-----------------------------------------------------------------------------
//
// Function: SirDisableInterrupt
//
//  This function is to disable the interrupts from UART2 module.
//
// Parameters:
//      thisDev 
//          [in] .
//
// Returns:  
//		None.
//
//-----------------------------------------------------------------------------
VOID SirDisableInterrupt(pFirDevice_t thisDev)
{
	CSP_BITFINS(g_pVSIRReg->UCR1, UART_UCR1_TXMPTYEN, UART_UCR1_TXMPTYEN_DISABLE);
	CSP_BITFINS(g_pVSIRReg->UCR4, UART_UCR4_DREN, UART_UCR4_DREN_DISABLE);
}


//-----------------------------------------------------------------------------
//
// Function: SirInitialize
//
// This function initializes the Sir device.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//
// Returns:  
//		This function returns initialization status.
//
//-----------------------------------------------------------------------------
BOOLEAN SirInitialize(pFirDevice_t thisDev)
{
    PHYSICAL_ADDRESS Addr = {thisDev->SirPhyAddr, 0};
    DEVICE_LOCATION devLoc;

    DEBUGMSG(ZONE_INIT, (TEXT("Sir: +SirInitialize\r\n")));
    // read from registry?
    // Map peripheral physical address to virtual address
    if(g_pVSIRReg == NULL)
    {
        g_pVSIRReg = (PCSP_UART_REG) MmMapIoSpace(Addr, sizeof(CSP_UART_REG), FALSE); 
        
        // Check if virtual mapping failed
        if (g_pVSIRReg == NULL)
        {
            DEBUGMSG(0, (TEXT("Sir:  MmMapIoSpace failed!\r\n")));
            return FALSE;
        }
    }

#if 0
    if (!BSPUartGetIrq((ULONG)thisDev->SirPhyAddr, &thisDev->sysIntrSir))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("Resource: ERROR: Failed to obtain uart info.\r\n")));
        return FALSE;
    }
#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 = (ULONG)thisDev->SirPhyAddr;

    if (!KernelIoControl(IOCTL_HAL_REQUEST_IRQ, &devLoc, sizeof(devLoc),
        &thisDev->sysIntrSir, sizeof(thisDev->sysIntrSir), NULL))
    {
        ERRORMSG(1, (_T("Cannot obtain UART IRQ!\r\n")));
        DEBUGMSG(ZONE_ERROR, (TEXT("Sir - Initialization failed!!\r\n")));
        return FALSE;
    }

    DEBUGMSG(ZONE_INIT, (TEXT("Sir: -SirInitialize\r\n")));
    return TRUE;
}


//-----------------------------------------------------------------------------
//
// Function: SirDeInitialize
//
// This function deinitializes the Sir device.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//
// Returns:  
//		None.
//
//-----------------------------------------------------------------------------
VOID SirDeInitialize(pFirDevice_t thisDev)
{
    DEBUGMSG(ZONE_DEINIT, (TEXT("Sir: +SirDeInitialize\r\n")));

    // Free UART register
    if(g_pVSIRReg)
    {
        MmUnmapIoSpace(g_pVSIRReg, sizeof(CSP_UART_REG));
        g_pVSIRReg = NULL;
    }
    // Release SYSINTR
    KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &thisDev->sysIntrSir, sizeof(DWORD), NULL, 0, NULL);
    thisDev->sysIntrSir = SYSINTR_UNDEFINED;

    DEBUGMSG(ZONE_DEINIT, (TEXT("Sir: -SirDeInitialize\r\n")));
}


//-----------------------------------------------------------------------------
//
// Function: SirClose
//
// This function closes the Sir device.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//
// Returns:  
//		None.
//
//-----------------------------------------------------------------------------
VOID SirClose(pFirDevice_t thisDev)
{
    DEBUGMSG(ZONE_CLOSE, (TEXT("Sir: +SirClose\r\n")));
	
	if (thisDev->portInfo.readBuf) 
	{
		InsertTailList(&thisDev->rcvBufBuf, RCV_BUF_TO_LIST_ENTRY(thisDev->portInfo.readBuf));
		thisDev->portInfo.readBuf  = NULL;
	}

	thisDev->writeBuf = NULL;

    CSP_BITFCLR(g_pVSIRReg->UCR2, UART_UCR2_TXEN);
    CSP_BITFCLR(g_pVSIRReg->UCR2, UART_UCR2_RXEN);
	
	// Reset UART2
	g_pVSIRReg->UCR2 = CSP_BITFVAL(UART_UCR2_SRST, UART_UCR2_SRST_RESET);

    // Disable extern IrDa pin
    BSPIrdaEnable(FALSE);
    BSPUartEnableClock(thisDev->SirPhyAddr, FALSE);

    DEBUGMSG(ZONE_CLOSE, (TEXT("Sir: -SirClose\r\n")));
}

//-----------------------------------------------------------------------------
//
// Function: SirOpen
//
// This function opens the Sir device.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//
// Returns:  
//		This function returns status of open device.
//
//-----------------------------------------------------------------------------
BOOLEAN SirOpen(pFirDevice_t thisDev)
{
	PLIST_ENTRY pListEntry;
	BOOLEAN result = TRUE;
	UINT i;
	ULONG bRefFreq = UART_REF_FREQ;

	DEBUGMSG(ZONE_OPEN, (TEXT("Sir: +SirOpen")));

	BSPIrdaEnable(TRUE);
	BSPSirSetIOMUX();
	BSPIrdaSetMode(SIR_MODE);

    if (!BSPUartEnableClock(thisDev->SirPhyAddr, TRUE))
    {
        DEBUGMSG(ZONE_ERROR, (TEXT("Fir:  BSPUartEnableClock failed!\r\n")));
        return FALSE;
    }

	if (!thisDev->writeBuf)
		thisDev->writeBuf = (PUCHAR)MyMemAlloc(MAX_IRDA_DATA_SIZE);

	pListEntry = MyRemoveHeadList(&thisDev->rcvBufBuf);
	if (pListEntry) 
	{
		thisDev->portInfo.readBuf = (PUCHAR) LIST_ENTRY_TO_RCV_BUF(pListEntry);
	} 
	else 
	{
		result = FALSE;
		goto done;
	}
	
	thisDev->portInfo.rcvState = STATE_INIT;
	thisDev->writePending = FALSE;
	

	// Configure UART2 registers

	g_pVSIRReg->UCR1 = CSP_BITFVAL(UART_UCR1_UARTEN, UART_UCR1_UARTEN_DISABLE);	// Disable UART
	g_pVSIRReg->UCR2 = CSP_BITFVAL(UART_UCR2_SRST, UART_UCR2_SRST_RESET);			// Reset UART

	// wait for a while
	for (i = 0; i <= 4; i++);

	CSP_BITFINS(g_pVSIRReg->UFCR, UART_UFCR_RFDIV, RFDIV_VALUE(BSPUartCalRFDIV(&bRefFreq)));
    g_pVSIRReg->UBIR = UART_UBIR_INCREMENT(DEFAULT_BAUD_RATE, UART_UBMR_MOD_DEFAULT, bRefFreq)-1;
    g_pVSIRReg->UBMR = UART_UBMR_MOD_DEFAULT -1;
	g_pVSIRReg->ONEMS	= (UART_REF_FREQ / 1000);
	
	g_pVSIRReg->UCR2 |=
		CSP_BITFVAL(UART_UCR2_SRST,	UART_UCR2_SRST_NORESET)	|	// no reset
		CSP_BITFVAL(UART_UCR2_RXEN,	UART_UCR2_RXEN_ENABLE)	|	// enable receiver
		CSP_BITFVAL(UART_UCR2_TXEN,	UART_UCR2_TXEN_ENABLE)	|	// enable transmitter
		CSP_BITFVAL(UART_UCR2_WS,	UART_UCR2_WS_8BIT)		|	// 8 Bits
		CSP_BITFVAL(UART_UCR2_IRTS,	UART_UCR2_IRTS_IGNORERTS);	// ignore RTS pin, for "none flow control"

	g_pVSIRReg->UCR3 =
		CSP_BITFVAL(UART_UCR3_INVT, UART_UCR3_INVT_ACTIVELOW)	|	// transmitter not inverted
		CSP_BITFVAL(UART_UCR3_RXDMUXSEL, UART_UCR3_RXDMUXSEL_MUX);	// new add in mx21

	g_pVSIRReg->UCR4 =
		CSP_BITFVAL(UART_UCR4_INVR, UART_UCR4_INVR_ACTIVELOW)	|	// receiver not inverted
		CSP_BITFVAL(UART_UCR4_CTSTL, 32);

	g_pVSIRReg->UCR1 =
		CSP_BITFVAL(UART_UCR1_UARTEN, UART_UCR1_UARTEN_ENABLE)	|	// Enable UART
		CSP_BITFVAL(UART_UCR1_IREN, UART_UCR1_IREN_ENABLE);			// Enable IR

	// We should call SetSpeed() only at initialization.
	// If this function is called from other functions, 
	// we only need setup UART speed but not all speed info.
	if (!thisDev->linkSpeedInfo)  
		SetSpeed(thisDev);
	else
		SirSetSpeed(thisDev);

done:

	DEBUGMSG(ZONE_OPEN, (TEXT("Sir: -SirOpen %s"), (CHAR *)(result ? "succeeded" : "failed")));

	if (result) 
	{
		return TRUE;
	} 
	else 
	{
		SirClose(thisDev);
		return FALSE;
	}
}


//-----------------------------------------------------------------------------
//
// Function: SirSendPacketQ
//
//  This function sends the packet from the send queue.
//
// Parameters:
//		thisDev 
//			[in] pFirDevice_t.
//		firstBufIsPending
//			[out] BOOLEAN.
//
// Returns:  
//		NDIS_STATUS.
//
//-----------------------------------------------------------------------------
NDIS_STATUS SirSendPacketQ(pFirDevice_t thisDev, BOOLEAN firstBufIsPending)
{
	NDIS_STATUS Result = NDIS_STATUS_FAILURE;
	BOOLEAN sendSucceeded;
	PLIST_ENTRY ListEntry;

    DEBUGMSG(ZONE_SEND, (TEXT("Sir: SirSendPacketQ(dev=0x%x, %hs)\r\n"), 
		(UINT)thisDev, (CHAR *)(firstBufIsPending ? "pend" : "not pend")));

    // Get packet from the head of SendQueue
	ListEntry = MyRemoveHeadList(&thisDev->SendQueue);
	if (ListEntry) 
	{
        PNDIS_PACKET packetToSend = CONTAINING_RECORD(ListEntry,
            NDIS_PACKET, MiniportReserved);
		PNDIS_IRDA_PACKET_INFO packetInfo;

		packetInfo = GetPacketInfo(packetToSend);

		//
		// NOTE: Don't use NdisStallExecution for turnaround delay since
		//       you shouldn't stall for more than 60 us. Calling
		//       NdisStallExecution for large times will degrade system
		//       performance.
		//

        DEBUGMSG(ZONE_SEND, (TEXT("Sir: TurnaroundTimer (%d).\r\n"), packetInfo->MinTurnAroundTime));
		if (packetInfo->MinTurnAroundTime) 
		{
			UINT usecToWait = packetInfo->MinTurnAroundTime;
			UINT msecToWait;

            // Reset the time, so that the packet gets sent out after timeout
			packetInfo->MinTurnAroundTime = 0;

            // Add it back to the head of the SendQueue
			InsertHeadList(&thisDev->SendQueue, (PLIST_ENTRY)packetToSend->MiniportReserved);

			// Ndis timer has a 1ms granularity (in theory).  Let's round off.
			msecToWait = (usecToWait < 1000) ? 1 : (usecToWait + 500) / 1000;

            DEBUGMSG(ZONE_SEND, (TEXT("Sir: TurnaroundTimer (%d).\r\n"), msecToWait));
			NdisMSetTimer(&thisDev->TurnaroundTimer, msecToWait);
			return NDIS_STATUS_PENDING; // Say we're successful.  We'll come back here.
		}

        // See if this was the last packet before we need to change speed.
		if (packetToSend == thisDev->lastPacketAtOldSpeed) 
		{
			thisDev->lastPacketAtOldSpeed = NULL;
			thisDev->setSpeedAfterCurrentSendPacket = TRUE;
		}

        //  Send one packet to the COM port.
        DEBUGMSG(ZONE_SEND, (TEXT("Sir: Sending packet (0x%x).\r\n"), (UINT)packetToSend));
		
		sendSucceeded = SirDoSend(thisDev, packetToSend);

        //  If the buffer we just sent was pending 
        //  (i.e. we returned NDIS_STATUS_PENDING for it in SirSend),

⌨️ 快捷键说明

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