fir24a0.c

来自「S3C24A0的完整BSP包,对开发此芯片的开发者很有用.」· C语言 代码 · 共 1,319 行 · 第 1/3 页

C
1,319
字号
	DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_IER -  0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_IER));
	DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_CNT - 0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_CNT));
	DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_FCR - 0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_FCR));
	DEBUGFIR(DBGIRDA, (TEXT(" rIRDA_PLR - 0x%x\r\n"), (UCHAR)g_pIRDAregs->IRDA_PLR));

}


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

    LOG(TEXT("==> NdisToFirPacket"), 0);
    DEBUGFIR(DBG_OUT, (TEXT("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);

    /*
     *  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("FIR, packet too short in NdisToFirPacket (%d bytes)"), 
             ndisPacketLen));
        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.
         */
        DBGOUT((TEXT("Error: packet too large in "), ndisPacketLen));
        DEBUGFIR(DBG_ERR, 
            (TEXT("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;
        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;


	//	DBGOUT((TEXT("while (ndisBuf) ")));
        NdisQueryBuffer(ndisBuf, (PVOID *)&bufData, &bufLen);

	//	DBGOUT((TEXT("NdisQueryBuffer ")));
        if (ndisPacketBytes + bufLen > ndisPacketLen){
            /*
             *  Packet was corrupt -- it misreported its size.
             */
            *irPacketLen = 0;
            return FALSE;
        }

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

     //   DBGOUT((TEXT("NdisMoveMemory")));
        ndisPacketBytes += bufLen;

        NdisGetNextBuffer(ndisBuf, &ndisBuf);

     //   DBGOUT((TEXT("NdisGetNextBuffer")));
    }

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

    /*
     *  Do a validity 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("Packet corrupt in NdisToIrPacket ")
            TEXT("(buffer lengths don't add up to packet length).")));
        *irPacketLen = 0;
        return FALSE;
    }

#ifdef DBG_ADD_PKT_ID
    if (addPktIdOn){
        static USHORT uniqueId = 0;
        DEBUGFIR(DBG_OUT, ("*** --> 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("<== NdisToFirPacket")));

    return TRUE;
}

/* 	This function initializes the IRDA module and prepares it for 
	reception or transmission
*/
int Irda_Init_Fir(IrDevice *thisDev)
{
    UINT bitsPerSec = thisDev->linkSpeedInfo->bitsPerSec;


//    Irda_Stop_Fir();
    pIrdaGloabls->bFIREnabled = TRUE;
    pIrdaGloabls->bUseDMA = TRUE;


    DEBUGFIR(DBGIRDA, (TEXT("==> Irda_Init_Fir \r\n")));


    if( bitsPerSec == FIR_SPEED_4000000 ) {
        thisDev->firConf.IrMode = S24A0_IRDA_MODEFIR;
    }else {
        thisDev->firConf.IrMode = S24A0_IRDA_MODEMIR;
        if( bitsPerSec == MIR_SPEED_1152000 )    
            thisDev->firConf.MirMode = S24A0_IRDA_MIRFULLSPEED;
        else
            thisDev->firConf.MirMode = S24A0_IRDA_MIRFULLSPEED;
    }
	g_pClkPwrRegs->CLKCON |= IRDA_CLK_ON;

	// Timing Control Register
//	g_pIRDAregs->IRDA_TIME = 0x7D;;

	g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3)| thisDev->firConf.IrMode; // Sip every frame/HP/Mode 

	
	// IrDA Control Register
	g_pIRDAregs->IRDA_CNT = (0<<7)|(0<<6)|(0<<5)|(0<<4)|(1<<3)|(0<<1)|(0);

    if( thisDev->firConf.IrMode == S24A0_IRDA_MODEMIR ) {
        g_pIRDAregs->IRDA_CNT |= thisDev->firConf.MirMode; 
    }    

	// Tx disable/Rx disable/Loop disable/MIR full/SIP/No Frame abort/SDBE High

    //	g_pIRDAregs->IRDA_CNT =  (0<<5)|(0<<4)|(0<<3)|(0);
	
	// Mode & Transceiver Set Register

	// Set Start Field Register or Preamble length

	g_pIRDAregs->IRDA_PLR = (2<<4);

    if( thisDev->firConf.IrMode == S24A0_IRDA_MODEFIR ) {
        g_pIRDAregs->IRDA_PLR |= (1<<6);
    }else {
        g_pIRDAregs->IRDA_PLR |= 4;
    }


	// Interrupt & DMA Control Register
	g_pIRDAregs->IRDA_CNF = 0x0; // Disable Interrupt & DMA

	// Interrupt Enable Register
	g_pIRDAregs->IRDA_IER = 0x0; // Disable All interrupts

	// FIFO Control Register
//	g_pIRDAregs->IRDA_FCR = (0<<6)|(1<<5)|(1<<2)|(1<<1)|(1); 
	g_pIRDAregs->IRDA_FCR = 0; 
	// RX trigger level/FIFO Size/Tx FIFO reset/RX FIFO reset/FIFO enable


	// Receive Frame Length Register
	g_pIRDAregs->IRDA_RXFLL =0;
	g_pIRDAregs->IRDA_RXFLH = 0;

	// Transmit Frame Length Register
	g_pIRDAregs->IRDA_TXFLL = 0;
	g_pIRDAregs->IRDA_TXFLH = 0;

	Irda_GPIO_Conf(FALSE); 

    FirSetupIntRecv(thisDev);
	
	return -1;
}

void Irda_Stop_Fir(void)
{

    DEBUGFIR(DBGIRDA, (TEXT("==> Irda_Stop_Fir \r\n")));
#if 1
	g_pIRDAregs->IRDA_TIME = 0;

	g_pIRDAregs->IRDA_MDR = 0; 
	
	g_pIRDAregs->IRDA_CNT = 0;

	g_pIRDAregs->IRDA_PLR = 0;

	g_pIRDAregs->IRDA_CNF = 0;

	g_pIRDAregs->IRDA_IER = 0;

	g_pIRDAregs->IRDA_FCR = 3 << 1; 

	g_pIRDAregs->IRDA_RXFLL =0;

	g_pIRDAregs->IRDA_RXFLH = 0;

	g_pIRDAregs->IRDA_TXFLL = 0;

	g_pIRDAregs->IRDA_TXFLH = 0;
	
	g_pClkPwrRegs->CLKCON &= ~IRDA_CLK_ON;

#endif
 
    pIrdaGloabls->bFIREnabled = FALSE;
    pIrdaGloabls->bUseDMA = FALSE;


 //   g_pIOPregs->GPCON_U &= ~(3<<24)|(3<<22)|(3<<20);	
//	g_pINTregs->INTMSK &= ~BIT_IRDA_MSTICK;

	g_pINTregs->INTSUBMSK |= BIT_SUB_IRDA;

	
}


void Init_Irda_Rx(int RxLen,int Mode)
{
    DEBUGFIR(DBGIRDA, (TEXT("==> Init_Irda_Rx \r\n")));
	// Mode & Transceiver Set Register

//	g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3) | 0x4; // Sip every frame/HP/Mode 

	
//	g_pIRDAregs->IRDA_TIME = 0x7D; // Check please..... Can't read, only write.

//	g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3) | 0x4; // Sip every frame/HP/Mode 

	// Interrupt & DMA Control Register
	g_pIRDAregs->IRDA_CNT &= ~(3<<6); //Resest Tx and Rx bits

	
	g_pIRDAregs->IRDA_CNF = 0x0; // Disable Interrupt & DMA

	// Interrupt Enable Register
	g_pIRDAregs->IRDA_IER = 0x0; // Disable All interrupts

	// FIFO Control Register
	

	// RX trigger level/FIFO Size/Tx FIFO reset/RX FIFO reset/FIFO enable

//	g_pIRDAregs->IRDA_PLR = ((0<<6) | (1<<4) | 4);
//	g_pIRDAregs->IRDA_PLR = 0;
	
	// Receive Frame Length Register
	g_pIRDAregs->IRDA_RXFLL = RxLen & 0xff;
	g_pIRDAregs->IRDA_RXFLH = (RxLen >> 10) & 0x3f;

	// Transmit Frame Length Register
	g_pIRDAregs->IRDA_TXFLL =  0;
	g_pIRDAregs->IRDA_TXFLH = 0;

	g_pIRDAregs->IRDA_FCR = 	(S24A0_IRDA_RXFIFO64_TRIG16<<6)|
								(S24A0_IRDA_FIFOSIZE64<<5)|(1<<2)|(1<<1)|(1); 

	
//   while(!(g_pIRDAregs->IRDA_FCR & 0x08));


    DEBUGFIR(DBGIRDA, (TEXT("==> after while 1 \r\n")));

	// Mode & Transceiver Set Register

//	g_pIRDAregs->IRDA_IER = 0xFF; // Enisable All interrupts

	g_pIRDAregs->IRDA_IER = 1<<6|1<<4|1<<3|1;
	
	g_pIRDAregs->IRDA_CNT |= (1 <<6); //Enable Rx 

	if(Mode == S24A0_IRDA_RXMODEINT) {
		g_pIRDAregs->IRDA_CNF = ((0<<3) | (0<<2)|1); 	// DMA En | Rx DMA En| Int En	
	}else{
		g_pIRDAregs->IRDA_CNF = ((1<<3) | (1<<2)|0); 	// DMA En | Rx DMA En| Int En	
	}
	
	g_pINTregs->INTMSK &= ~BIT_IRDA_MSTICK;

	g_pINTregs->INTSUBMSK &= ~BIT_SUB_IRDA;


//	DisplayRegs();

	return;
}


void Init_Irda_Tx(int TxLen)
{

    DEBUGFIR(DBGIRDA, (TEXT("==> Init_Irda_Tx \r\n")));

	// Mode & Transceiver Set Register
//	g_pIRDAregs->IRDA_MDR = (1<<4) | (1<<3) | 0x4; // Sip every frame/HP/Mode 

	g_pIRDAregs->IRDA_CNT &= ~(3<<6); //Resest Tx and Rx bits
	
	// Interrupt & DMA Control Register
	g_pIRDAregs->IRDA_CNF = 0x0; // Disable Interrupt & DMA

	// Interrupt Enable Register
	g_pIRDAregs->IRDA_IER = 0x0; // Disable All interrupts


	// Receive Frame Length Register
	g_pIRDAregs->IRDA_RXFLL = 0;
	g_pIRDAregs->IRDA_RXFLH = 0;

	// Transmit Frame Length Register
	g_pIRDAregs->IRDA_TXFLL = TxLen & 0xff ;
	g_pIRDAregs->IRDA_TXFLH = (TxLen >> 8) & 0xff;

	// FIFO Control Register

	g_pIRDAregs->IRDA_FCR = 0;
	g_pIRDAregs->IRDA_FCR = (0<<6)|(1<<5)|(1<<2)|(1<<1)|(1); 
	// RX trigger level/FIFO Size/Tx FIFO reset/RX FIFO reset/FIFO enable

//	g_pIRDAregs->IRDA_PRL = ((0<<6) | (1<<4) | 4);
	
//	while(!(g_pIRDAregs->IRDA_FCR & 0x10));

    DEBUGFIR(DBGIRDA, (TEXT("==> after while 1 \r\n")));


	// Mode & Transceiver Set Register
	g_pIRDAregs->IRDA_CNT &= ~(3<<6); //Disable Rx and Tx
	g_pIRDAregs->IRDA_CNT |= 1 <<7; //Enable Tx 


	g_pIRDAregs->IRDA_CNF = (1<<3) | (0<<2); 		// Enable Tx DMA

	return;
}


BOOLEAN Irda_Int_Tx(IrDevice *thisDev)
{
//    NDIS_STATUS stat;
    PNDIS_PACKET Packet;
    PNDIS_IRDA_PACKET_INFO packetInfo;
    int ret_val;

    DEBUGMSG(DBGIRDA, (TEXT("==> Irda_Int_Tx(0x%x)\r\n"), (UINT) thisDev));

     thisDev->HangChk = 0;

    if (IsListEmpty(&thisDev->SendQueue)) {
        ret_val = FALSE;
    } else {

        // thisDev->portInfo.writePending = TRUE;

        Packet = HEAD_SEND_PACKET(thisDev);

        // Check for min turnaround time set.

        packetInfo = GetPacketInfo(Packet);

        //
        // 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.
        //

        if (packetInfo->MinTurnAroundTime) {
            UINT usecToWait = packetInfo->MinTurnAroundTime;
            UINT msecToWait;
            packetInfo->MinTurnAroundTime = 0;

            // Ndis timer has a 1ms granularity (in theory).  Let's round off.

            msecToWait = (usecToWait<=1000) ? 1 : (usecToWait+500)/1000;


            NdisMSetTimer(&thisDev->TurnaroundTimer, msecToWait);

            DEBUGMSG(DBGIRDA, (TEXT("Irda_Int_Tx:- Do min TAT wait\r\n")));
            return TRUE; // Say we're successful.  We'll come back here.

        }

        NdisToFirPacket(thisDev, 
                        Packet, (UCHAR *) thisDev->portInfo.writeBuf,
                        MAX_IRDA_DATA_SIZE, &thisDev->portInfo.writeBufLen);


        DEBUGMSG(DBGIRDA, (TEXT("Irda_Int_Tx: Sending packet 0x%x, len = %d\r\n"), Packet, thisDev->portInfo.writeBufLen));


		// Initialize the IRDA module with the bytes to be received and transmitted
//		Init_Irda(MAX_IRDA_DATA_SIZE, thisDev->writeBufLen);
		
		g_pIRDAregs->IRDA_CNF |= (1); 		// Enable Tx DMA
		g_pIRDAregs->IRDA_CNT |= (1<<7); 				// Enable Tx
		g_pIRDAregs->IRDA_IER = (1<<5)|(1<<1); // Enable Tx underrun/Tx FIFO trigger 	
		
		DEBUGMSG(DBGIRDA, (TEXT("Irda_Int_Tx: Number of data bytes sent: %x\r\n"), thisDev->portInfo.writeBufLen));
    }

    DEBUGMSG(DBGIRDA, (TEXT("<== Irda_Int_Tx\r\n")));

    return ret_val;

⌨️ 快捷键说明

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