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

📄 nscfir.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
📖 第 1 页 / 共 2 页
字号:
        if((READ_REGISTER_UCHAR(pITSR) & CC_FIR_ITSR_TFUR) == CC_FIR_ITSR_TFUR){


			WRITE_REGISTER_UCHAR(pIRSTCR, CC_FIR_IRSTCR_RSTC_UNDERRUN);/* Reset FIFO Underrun/EOM Latch */

            RegStats.TxUnderruns++;
            status = NDIS_STATUS_FAILURE; 

		WRITE_REGISTER_UCHAR(pIMSTCR, (READ_REGISTER_UCHAR(pIMSTCR) & CC_FIR_IMSTCR_RST_BANK) | CC_FIR_IMSTCR_BANK1);// Switch Bank 1
			RETAILMSG(1, (TEXT("FIR_MegaSendComplete: Transmit Underrun (%d)\r\n"),
				READ_REGISTER_UCHAR(pITBCLR) | 
				((READ_REGISTER_UCHAR(pITBCHR) & 0x1f) << 8)));

            LOG(TEXT("FIR_MegaSendComplete: Transmit Underrun"), 0);
            DEBUGFIR(DBG_TX|DBG_ERR, 
                (TEXT("NSC: FIR_MegaSendComplete: Transmit Underrun")));

#ifdef OUTMSG
			RETAILMSG(0, (TEXT("FIR_MegaSendComplete: Transmit Underrun.\r\n")));
#endif

        }
        else {
            status = NDIS_STATUS_SUCCESS;
			//RETAILMSG(1, (TEXT("FIR_MegaSendComplete: no underrun.\r\n")));
        }

        /* Reset Tx pending. */
        thisDev->portInfo.writePending = FALSE;
		DBGOUT((TEXT("writePending = FALSE")));

        /*
         * Notify NDIS of TX complete.
         */
        NdisMSendComplete(thisDev->ndisAdapterHandle, Packet, status);

    }
    LOG(TEXT("<== FIR_MegaSendComplete"), 1);
    DEBUGFIR(DBG_TX|DBG_OUT, (TEXT("NSC: <== FIR_MegaSendComplete")));
    DBGOUT((TEXT("<==FIR_MegaSendComplete")));

}


void FIR_DeliverFrames(IrDevice *thisDev)
{
	UINT i;
	ULONG FrameSizeQue[7];
	UINT SizeQuePtr;
    UCHAR frameStat;
    NDIS_STATUS stat;
    ULONG rcvFrameSize;
    PUCHAR NewFrame,TopOfBuf;
    ULONG LastReadDMACount, EndOfData;
    BOOLEAN resetDma = FALSE, OverflowOccurred = FALSE;
    const    UINT    fcsSize    =    (   thisDev->currentSpeed    >=    MIN_FIR_SPEED)    ?    
                                     FAST_IR_FCS_SIZE : MEDIUM_IR_FCS_SIZE;

    DBGOUT((TEXT("==>FIR_DeliverFrames")));
    LOG(TEXT("==> FIR_DeliverFrames"), 0);
    DEBUGFIR(DBG_RX|DBG_OUT, (TEXT("NSC: ==> FIR_DeliverFrames(0x%x)"), 
        (UINT) thisDev));

    LastReadDMACount = NdisMReadDmaCounter(thisDev->DmaHandle);

	// Check for data received since the last time we were here.
	// We also check for data in FIFO. If ther is some, we waite as long
	// as the DMA still has room to capture data.

	thisDev->LineStatus = (UCHAR)READ_REGISTER_UCHAR(pIRSR);

    if (LastReadDMACount != thisDev->LastReadDMACount ||
        ((thisDev->LineStatus & 0x08) && LastReadDMACount != 0)){
        thisDev->LastReadDMACount = LastReadDMACount;
        //
        //  Set Timer Enable bit for another Timeout.
        //
        if((thisDev->LastReadRFPCount == thisDev->ReadRFPCount) ||
           (thisDev->ReadRFPCount == 0)){
           	;
         }else if(thisDev->QueIndex < 7){
           	   thisDev->RFPQue[thisDev->QueIndex++] = thisDev->ReadRFPCount;
           	   thisDev->LastReadRFPCount = thisDev->ReadRFPCount;
        }
        return;
    }
    RegStats.RxDPC_Window++;

    //thisDev->IntMask = 0x04;

	//RETAILMSG(1, (TEXT("DLVFR\r\n")));

    NdisMCompleteDmaTransfer(&stat, thisDev->DmaHandle,
                             thisDev->rcvDmaBuffer, 
                             thisDev->rcvDmaOffset,
                             thisDev->rcvDmaSize, FALSE);
    if (stat != NDIS_STATUS_SUCCESS) {
        DbgBreakPoint();
    }

    if((thisDev->LastReadRFPCount != thisDev->ReadRFPCount) &&
       (thisDev->ReadRFPCount != 0) &&
       (thisDev->QueIndex < 7)){
       	thisDev->RFPQue[thisDev->QueIndex++] = thisDev->ReadRFPCount;
    }

    // Get the exact count.
    thisDev->LastReadRFPCount = 0;
    TopOfBuf = thisDev->portInfo.dmaReadBuf+ thisDev->rcvPktOffset;
    LastReadDMACount = NdisMReadDmaCounter(thisDev->DmaHandle);

    LOG(TEXT("frameStat: "), (UINT) frameStat);
    DEBUGFIR(DBG_RX|DBG_OUT, (TEXT("NSC: frameStat = %xh"), 
        (UINT) frameStat));

	if(thisDev->QueIndex){
		for(i=0;i<thisDev->QueIndex;i++){

	
		NewFrame = thisDev->portInfo.dmaReadBuf + thisDev->rcvPktOffset;
		thisDev->rcvPktOffset = thisDev->RFPQue[i];
		frameStat = TopOfBuf[thisDev->rcvPktOffset];
		rcvFrameSize = (ULONG)(frameStat & 0x1f)*256 +
		                      TopOfBuf[thisDev->rcvPktOffset-1];
		EndOfData = TopOfBuf + thisDev->rcvPktOffset - NewFrame - 1;
		thisDev->rcvPktOffset++;

		if(rcvFrameSize == EndOfData){
			if(!(frameStat & 0xe0)){
				ASSERT(thisDev->rcvPktOffset< RCV_DMA_SIZE);
				rcvFrameSize -= fcsSize;
				if(rcvFrameSize <= MAX_NDIS_DATA_SIZE &&
				   rcvFrameSize >= IR_ADDR_SIZE + IR_CONTROL_SIZE){

				   	QueueReceivePacket(thisDev,NewFrame,rcvFrameSize,TRUE);

#ifdef OUTMSG
	RETAILMSG(1,(TEXT("Qued1 %d\r\n"), rcvFrameSize));
#endif



				}
			}
		}else{
			SizeQuePtr = 0;
			while(((long)rcvFrameSize <= (long)EndOfData) && (SizeQuePtr < 7)){
				FrameSizeQue[SizeQuePtr++] = rcvFrameSize;
				if(rcvFrameSize == EndOfData){
					EndOfData -= rcvFrameSize;
					break;
				}
				EndOfData -= (rcvFrameSize + 2);
				frameStat = NewFrame[EndOfData + 1];
				rcvFrameSize = (ULONG)(frameStat & 0x1f)*256 + NewFrame[EndOfData];

			}
			if((EndOfData == 0) && (SizeQuePtr < 7)){
				rcvFrameSize = 0;
				do {
					NewFrame += rcvFrameSize;
					rcvFrameSize = FrameSizeQue[--SizeQuePtr];
					frameStat = NewFrame[rcvFrameSize + 1];
					if(!(frameStat & 0xe0)){
						QueueReceivePacket(thisDev,NewFrame,rcvFrameSize-fcsSize, TRUE);

#ifdef OUTMSG
	RETAILMSG(1,(TEXT("Qued2\r\n")));
#endif


					}
					rcvFrameSize += 2;
				} while(SizeQuePtr);
			}
		}

		}//loop-end
	}




    SetupRecv(thisDev);

    LOG(TEXT("<== FIR_DeliverFrames"), 1);
    DEBUGFIR(DBG_RX|DBG_OUT, (TEXT("NSC: <== FIR_DeliverFrames")));
    DBGOUT((TEXT("<==FIR_DeliverFrames")));
}


BOOLEAN NSC_Setup(IrDevice *thisDev)
{
    NDIS_DMA_DESCRIPTION DMAChannelDcr;
    NDIS_STATUS stat;

    DBGOUT((TEXT("==>NSC_Setup")));

    thisDev->rcvDmaOffset = 0;

    /*
     *  Because we enable rcv DMA while SIR receives may still be
     *  going on, we need to keep a separate receive buffer for DMA.
     *  This buffer gets swapped with the rcvBuffer data pointer
     *  and must be the same size.
     */
#ifdef UNDER_CE
    // Windows CE. We get a chunk of memory from our contiguous physical
    // buffer. See externs.h for detailed information.
    ASSERT(g_pvDmaVirtualBase);
    thisDev->portInfo.dmaReadBuf = (PUCHAR)g_pvDmaVirtualBase + RCVDMA_OFFSET;
#else // UNDER_CE
    thisDev->portInfo.dmaReadBuf = MyMemAlloc(RCV_DMA_SIZE, TRUE);
    if (!thisDev->portInfo.dmaReadBuf){
        return FALSE;
    }
#endif //!UNDER_CE

    NdisAllocateBufferPool(&stat, &thisDev->dmaBufferPoolHandle, 2);
    if (stat != NDIS_STATUS_SUCCESS){
        LOG(TEXT("Error: NdisAllocateBufferPool failed in NSC_Setup"), 0);
        DEBUGFIR(DBG_ERR, 
            (TEXT("NSC: NdisAllocateBufferPool failed in NSC_Setup")));
        return FALSE;
    }

    NdisAllocateBuffer(&stat, &thisDev->rcvDmaBuffer, 
                       thisDev->dmaBufferPoolHandle, 
                       thisDev->portInfo.dmaReadBuf,
                       RCV_DMA_SIZE);
    if (stat != NDIS_STATUS_SUCCESS) {
        LOG(TEXT("Error: NdisAllocateBuffer failed (rcv) in NSC_Setup"), 0);
        DEBUGFIR(DBG_ERR, (TEXT("NSC: NdisAllocateBuffer failed (rcv) in NSC_Setup")));
        return FALSE;
    }

    NdisAllocateBuffer(&stat, &thisDev->xmitDmaBuffer, 
                       thisDev->dmaBufferPoolHandle, 
                       thisDev->portInfo.writeBuf,
                       MAX_IRDA_DATA_SIZE);
    if (stat != NDIS_STATUS_SUCCESS) {
        LOG(TEXT("NdisAllocateBuffer failed (xmit) in NSC_Setup"), 0);
        DEBUGFIR(DBG_ERR, (TEXT("NSC: NdisAllocateBuffer failed (xmit) in NSC_Setup")));
        return FALSE;
    }


    /*
     *  Initialize rcv DMA channel
     */
    DMAChannelDcr.DemandMode = TRUE;
    DMAChannelDcr.AutoInitialize = FALSE;
    DMAChannelDcr.DmaChannelSpecified = FALSE;
    DMAChannelDcr.DmaWidth = Width8Bits;
    DMAChannelDcr.DmaSpeed = Compatible;
    DMAChannelDcr.DmaPort = 0;
#ifdef UNDER_CE
    // For now, ndismlib.c (NSC miniport's DMA functions) require this to
    // be set in the DMAChannelDcr structure.
    DMAChannelDcr.DmaChannel = thisDev->portInfo.DMAChannel;
#else // UNDER_CE
    DMAChannelDcr.DmaChannel = 0;
#endif //!UNDER_CE

    stat = NdisMRegisterDmaChannel(&thisDev->DmaHandle,
                                   thisDev->ndisAdapterHandle,
                                   thisDev->portInfo.DMAChannel,
                                   FALSE, &DMAChannelDcr, RCV_DMA_SIZE);

    DBGOUT((TEXT("<==NSC_Setup")));

    if (stat != NDIS_STATUS_SUCCESS) {
        DEBUGFIR(DBG_ERR, (TEXT("NSC: NdisMRegisterDmaChannel failed")));
        DbgBreakPoint();
        return FALSE;
    }

    return TRUE;
}


void NSC_Shutdown(IrDevice *thisDev)
{
    DBGOUT((TEXT("==>NSC_Shutdown")));

    if (thisDev->DmaHandle){
        NdisMDeregisterDmaChannel(thisDev->DmaHandle);
        thisDev->DmaHandle = NULL;
    }

    if (thisDev->xmitDmaBuffer){
        NdisFreeBuffer(   thisDev->xmitDmaBuffer);
        thisDev->xmitDmaBuffer = NULL;
    }

    if (thisDev->rcvDmaBuffer){
        NdisFreeBuffer(thisDev->rcvDmaBuffer);
        thisDev->rcvDmaBuffer = NULL;
    }

    if (thisDev->dmaBufferPoolHandle){
        NdisFreeBufferPool(thisDev->dmaBufferPoolHandle);
        thisDev->dmaBufferPoolHandle = NULL;
    }
    if (thisDev->portInfo.dmaReadBuf){
    #ifdef UNDER_CE
        // Windows CE. Don't need to free since it is just a pointer in our
        // reserved physical memory.
    #else // UNDER_CE
        MyMemFree(thisDev->portInfo.dmaReadBuf, RCV_DMA_SIZE, TRUE);
    #endif //!UNDER_CE
        thisDev->portInfo.dmaReadBuf = NULL;
    }
    DBGOUT((TEXT("<==NSC_Shutdown")));
}


BOOLEAN NdisToFirPacket(IrDevice *thisDev, PNDIS_PACKET Packet,
                        UCHAR *irPacketBuf, UINT irPacketBufLen, UINT *irPacketLen)
{
    PNDIS_BUFFER ndisBuf;
    UINT ndisPacketBytes = 0;
    UINT ndisPacketLen;

    DBGOUT((TEXT("==>NdisToFirPacket")));
    LOG(TEXT("==> NdisToFirPacket"), 0);
    DEBUGFIR(DBG_OUT, (TEXT("NSC: ==> NdisToFirPacket(0x%x)"), (UINT) thisDev));

    /*
     *  Get the packet's entire length and its first NDIS buffer 
     */
    NdisQueryPacket(Packet, NULL, NULL, &ndisBuf, &ndisPacketLen);

    LOG(TEXT("NdisToFirPacket, number of bytes:"), ndisPacketLen);
    DEBUGFIR(DBG_OUT, 
        (TEXT("NSC: NdisToFirPacket, number of bytes: %d"), ndisPacketLen));

    /*
     *  Make sure that the packet is big enough to be legal.
     *  It consists of an A, C, and variable-length I field.
     */
    if (ndisPacketLen < IR_ADDR_SIZE + IR_CONTROL_SIZE){
        LOG(TEXT("Error: packet too short in "), ndisPacketLen);
        DEBUGFIR(DBG_ERR, 
            (TEXT("NSC: packet too short in NdisToFirPacket (%d bytes)"), 
             ndisPacketLen));

#ifdef OUTMSG
		RETAILMSG(1, (TEXT("NSC: packet too short in NdisToFirPacket (%d bytes)"), 
             ndisPacketLen));
#endif


        return FALSE;
    }

    /*
     *  Make sure that we won't overwrite our contiguous buffer.
     */
    if (ndisPacketLen > irPacketBufLen){
        /*
         *  The packet is too large
         *  Tell the caller to retry with a packet size large
         *  enough to get past this stage next time.
         */
        LOG(TEXT("Error: packet too large in "), ndisPacketLen);
        DEBUGFIR(DBG_ERR, 
            (TEXT("NSC: Packet too large in NdisToIrPacket (%d=%xh bytes), ")
             TEXT("MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d."),
             ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
        *irPacketLen = ndisPacketLen;


#ifdef OUTMSG
		RETAILMSG(1, (TEXT("NSC: Packet too large in NdisToIrPacket (%d=%xh bytes), ")
             TEXT("MAX_IRDA_DATA_SIZE=%d, irPacketBufLen=%d."),
             ndisPacketLen, ndisPacketLen, MAX_IRDA_DATA_SIZE, irPacketBufLen));
#endif

        return FALSE;
    }


    /* 
     *  Read the NDIS packet into a contiguous buffer.
     *  We have to do this in two steps so that we can compute the
     *  FCS BEFORE applying escape-byte transparency.
     */
    while (ndisBuf) {
        UCHAR *bufData;
        UINT bufLen;

        NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);

        if (ndisPacketBytes + bufLen > ndisPacketLen){
            /*
             *  Packet was corrupt -- it misreported its size.
             */
            *irPacketLen = 0;

#ifdef OUTMSG
			RETAILMSG(1, (TEXT(" Packet was corrupt in NdisToIrPacket\r\n")));
#endif


            return FALSE;
        }

        NdisMoveMemory((PVOID)(irPacketBuf+ndisPacketBytes), 
                       (PVOID)bufData, (ULONG)bufLen);
        ndisPacketBytes += bufLen;

        NdisGetNextBuffer(ndisBuf, &ndisBuf);
    }

    LOG(TEXT("Ir Command byte "), (UINT)*(irPacketBuf+1));

    /*
     *  Do a sanity check on the length of the packet.
     */
    if (ndisPacketBytes != ndisPacketLen){
        /*
         *  Packet was corrupt -- it misreported its size.
         */
        LOG(TEXT("Error: Packet corrupt in NdisToIrPacket ")
            TEXT("(buffer lengths don't add up to packet length)"), 0);
        DEBUGFIR(DBG_ERR, (TEXT("NSC: Packet corrupt in NdisToIrPacket ")
            TEXT("(buffer lengths don't add up to packet length).")));
        *irPacketLen = 0;

#ifdef OUTMSG
		RETAILMSG(1, (TEXT(" Error: Packet corrupt in NdisToIrPacket\r\n")));
#endif

        return FALSE;
    }

#ifdef DBG_ADD_PKT_ID
    if (addPktIdOn){
        static USHORT uniqueId = 0;
        DEBUGFIR(DBG_OUT, ("NSC:  *** --> SEND PKT ID: %xh", (UINT)uniqueId));
        LOG("ID: Send (FIR) Pkt id:", uniqueId);
        *(USHORT *)(irPacketBuf+ndisPacketBytes) = uniqueId++;
        ndisPacketBytes += sizeof(USHORT);
    }
#endif

    *irPacketLen = ndisPacketBytes;

    LOG(TEXT("<== NdisToFirPacket"), 0);
    DEBUGFIR(DBG_OUT, (TEXT("NSC: <== NdisToFirPacket")));
    DBGOUT((TEXT("<==NdisToFirPacket")));

    return TRUE;
}

VOID FIR_WriteBankReg(UINT bank, PUINT16 reg, UCHAR val)
{
	WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) & CC_FIR_IMSTCR_RST_BANK);
	WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) | bank);
	WRITE_REGISTER_UCHAR((PUINT8)reg,val);
}

UCHAR FIR_ReadBankReg(UINT bank, PUINT16 reg)
{
	UCHAR	val;
	WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) & CC_FIR_IMSTCR_RST_BANK);
	WRITE_REGISTER_UCHAR(pIMSTCR,READ_REGISTER_UCHAR(pIMSTCR) | bank);
	val = READ_REGISTER_UCHAR((PUINT8)reg);
	return(val);
}

⌨️ 快捷键说明

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