comm.c

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

C
1,352
字号
		*claimingInterrupt = TRUE;
		*requireDeferredCallback = FALSE;

		while ((IntPndVal & portInfo->bINT) && (loops++ < 0x10)){
//      while ((IntPndVal & portInfo->bINT) ){


		if(IntSubPndVal & (thisDev->portInfo.bErrINT) )  {
//			RETAILMSG (1, (TEXT("SL_GetInterruptType: INTR_LINE\r\n")));
			g_pComm1Reg->UFCON |=(1<<2|1<<1);
			ClearSubINTPnd(portInfo, portInfo->bTxINT | portInfo->bRxINT | portInfo->bErrINT);
			ClearINTPnd(portInfo, portInfo->bINT);
		}else if(IntSubPndVal & (portInfo->bRxINT) ) {
			 DBGOUT((TEXT("COM INTERRUPT: rcv data available!")));
			 DisEnSubINT(portInfo, portInfo->bRxINT);

					thisDev->nowReceiving = TRUE;

					if (!thisDev->mediaBusy){
						thisDev->mediaBusy = TRUE;
						thisDev->haveIndicatedMediaBusy = FALSE;
						*requireDeferredCallback = TRUE;
					}

					if (StepReceiveFSM(thisDev)){
						/*
						 *  The receive engine has accumulated an entire frame.
						 *  Request a deferred callback so we can deliver the frame
						 *  when not in interrupt context.
						 */
						*requireDeferredCallback = TRUE;
						thisDev->nowReceiving = FALSE;
					}
			  EnSubINT(portInfo, portInfo->bRxINT);

		}
		else if (IntSubPndVal & (portInfo->bTxINT)) {

		   DEBUGFIR(1,(_T("COM_ISR tx INTERRUPT\r\n")));

			if (thisDev->portInfo.writePending){

				SetCOMInterrupts(thisDev, FALSE);
				/*
				 *  Try to send a few more bytes
				 */
						
				CLEARREG(UCON , 3);

				if (StepSendFSM(thisDev)){

				/*
				 *  There are no more bytes to send; 
				 *  reset interrupts for receive mode.
				 */
					thisDev->portInfo.writePending = FALSE;
					g_pComm1Reg->UFCON |= (1<<1);			
//                  SetCOMInterrupts(thisDev, TRUE);
					CLEARREG(UCON , (3<<2));

					ClearSubINTPnd(portInfo, portInfo->bTxINT | portInfo->bRxINT | portInfo->bErrINT);
					ClearINTPnd(portInfo, portInfo->bINT);
		
					SETREG(UCON , UCON_RX_INTPOL_MODE);

					/*
					 *  If we just sent the last frame to be sent at the old speed,
					 *  set the hardware to the new speed.
					 */
					if (thisDev->setSpeedAfterCurrentSendPacket){
						thisDev->setSpeedAfterCurrentSendPacket = FALSE;
						thisDev->setSpeedNow = TRUE;
					}

					/*
					 *  Request a DPC so that we can try
					 *  to send other pending write packets.
					 */
					*requireDeferredCallback = TRUE;
				 }
#if 0						
				 else{
					EnSubINT(portInfo, portInfo->bTxINT);
				 }
#endif	
				}
	
			}
		   /*
			 *  After we service each interrupt condition, we read the line status register.
			 *  This clears the current interrupt, and a new interrupt may then appear in
			 *  the interrupt-id register.
			 */
			try {
				IntPndVal = *(portInfo->UART_INTSRCPND);
				IntSubPndVal = *(portInfo->UART_INTSUBSRCPND);
			}
			except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
				EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
				RETAILMSG(1, (TEXT("ACCESS VIOLATION ERROR \r\n")));
				IntPndVal = SER24A0_INT_INVALID; // simulate no interrupt
			}

			ClearSubINTPnd(portInfo, portInfo->bTxINT | portInfo->bRxINT | portInfo->bErrINT);
			ClearINTPnd(portInfo, portInfo->bINT);

	 		DEBUGFIR(1,(_T("COM_ISR Intsrc pnd %x subsrcpnd %x \r\n"),IntPndVal,IntSubPndVal));	
		}
	}

	if(! (*requireDeferredCallback))
		 SetCOMInterrupts(thisDev, TRUE);
	
//	EnSubINT(portInfo, portInfo->bRxINT);
//	EnSubINT(portInfo, portInfo->bTxINT);
//	EnSubINT(portInfo, portInfo->bErrINT);
	
//	EnINT(portInfo, portInfo->bINT);
	
}



/*
 *************************************************************************
 *  OpenCOM
 *************************************************************************
 *
 *  Initialize UART registers
 *
 */
BOOLEAN OpenCOM(IrDevice *thisDev)
{

	DBGOUT((TEXT("-> OpenCOM")));

	DBGOUT((TEXT("-> OpenCOM SetCOMInterrupts :false")));
	/*
	  *  Set dongle- or part-specific info to default
	  */
//  thisDev->portInfo.hwCaps.supportedSpeedsMask    = ALL_SLOW_IRDA_SPEEDS;
	thisDev->portInfo.hwCaps.supportedSpeedsMask    = ALL_IRDA_SPEEDS;
	thisDev->portInfo.hwCaps.turnAroundTime_usec    = DEFAULT_TURNAROUND_usec;
	thisDev->portInfo.hwCaps.extraBOFsRequired      = 0;

	Comm_hw_Init(thisDev);


//    SetCOMInterrupts(thisDev, FALSE);
	
	thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];

	thisDev->currentSpeed = thisDev->linkSpeedInfo->bitsPerSec;
	SetSpeed(thisDev);

	SetCOMInterrupts(thisDev, TRUE);

	
	DBGOUT((TEXT("-> OpenCOM SetCOMInterrupts :true")));

	DBGOUT((TEXT("OpenCOM succeeded")));
	return TRUE;
}


/*
 *************************************************************************
 *  CloseCOM
 *************************************************************************
 *
 */
VOID CloseCOM(IrDevice *thisDev)
{
	/*
	 *  Do special deinit for dongles.
	 *  Some dongles can only rcv cmd sequences at 9600, so set this speed first.
	 */
	thisDev->linkSpeedInfo = &supportedBaudRateTable[BAUDRATE_9600];;
	SetSpeed(thisDev);

	SetCOMInterrupts(thisDev, FALSE);
}



/*
 *************************************************************************
 *  DoRcvDirect
 *************************************************************************
 *
 *  Read up to maxBytes bytes from the UART's receive FIFO.
 *  Return the number of bytes read or (UINT)-1 if an error occurred.
 *
 */
UINT DoRcvDirect(struct IrDevice *thisDev, UCHAR *data, UINT maxBytes)
{

	ULONG        TargetRoom    = maxBytes;
	comPortInfo *portInfo = &thisDev->portInfo;		
	ULONG       rFifoStat, RxFifoCnt, RxDataReady, bytesRead= 0,errStat;
#if 0
    UINT i;
#endif
	UCHAR        cRXChar,*pRxBuffer = data;

	rFifoStat = INREG(UFSTAT);
	RxFifoCnt = rFifoStat & 0x3f;

	if((rFifoStat & (1<<6))||(RxFifoCnt > 0))
		RxDataReady = 1;
	else
		RxDataReady = 0;


	while ( TargetRoom && RxDataReady) {

		errStat =	INREG(UERSTAT);
		if(errStat) {
			g_pComm1Reg->UFCON |= 6;
			RETAILMSG(1, (TEXT("Rx Error  0x%x \r\n"), errStat));
			
		}	

		cRXChar = g_pComm1Reg->URXH;
	//	RETAILMSG(1, (TEXT("  %2x"), cRXChar));

		*pRxBuffer++ = cRXChar;
		bytesRead++;


		rFifoStat = INREG(UFSTAT);
		RxFifoCnt = rFifoStat & 0x3f;


		
		--TargetRoom;
	//	if((rFifoStat & (1<<6))||(RxFifoCnt > 0))
		if(RxFifoCnt > 0)
			RxDataReady = 1;
		else
			RxDataReady = 0;
		

	}

   
	ClearSubINTPnd(portInfo,portInfo->bRxINT);

	if ( *(portInfo->UART_INTSUBSRCPND) & ( portInfo->bRxINT | portInfo->bErrINT ) )
	{
//			RETAILMSG (1, (TEXT("*(portInfo->UART_INTSUBSRCPND) = %x \r\n"), *(portInfo->UART_INTSUBSRCPND)));
//			RETAILMSG (1, (TEXT("Do Not Clear bINT \r\n")));
	;
	}
	else
		ClearINTPnd(portInfo, portInfo->bINT);


//	RETAILMSG(1,(TEXT("-> Number  of bytes received %x\r\n"),bytesRead));

#if 0
	RETAILMSG(1,(TEXT("Rx")));
	for (i=0;i<bytesRead;i++) {
		RETAILMSG(1,(TEXT("%2x "),data[i]));
		if(data[i] == 0xC1) 
			RETAILMSG(1,(TEXT("\r\n")));
	}	
#endif   
		return bytesRead;
}



VOID Comm_hw_Init(IrDevice *thisDev)
{
	comPortInfo *portInfo = &thisDev->portInfo;
	UINT32 temp;

	 DBGOUT((TEXT("-> Comm_hw_Init")));

//	return;

	portInfo->bINT = BIT_UART1;
	portInfo->bTxINT = INTSUB_TXD1;
	portInfo->bRxINT = INTSUB_RXD1;
	portInfo->bErrINT = INTSUB_ERR1;


	portInfo->UART_INTMASK = (volatile unsigned int *)&(g_pINTregs->INTMSK);
	portInfo->UART_INTSUBMASK = (volatile unsigned int *)&(g_pINTregs->INTSUBMSK);
	portInfo->UART_INTPND = (volatile unsigned int *)&(g_pINTregs->INTPND);
	portInfo->UART_INTSRCPND = (volatile unsigned int *)&(g_pINTregs->SRCPND);
	portInfo->UART_INTSUBSRCPND = (volatile unsigned int *)&(g_pINTregs->SUBSRCPND);

   /*
	*  Disable all COM interrupts while setting up.
	*/

	g_pClkPwrRegs->CLKCON |= UART1_CLK_ON;


	g_pINTregs->INTMSK |= (BIT_UART1);
	g_pINTregs->INTSUBMSK |=(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);


	Irda_GPIO_Conf(TRUE) ;

	g_pComm1Reg->ULCON=(0<<6)|(0<<3)|(0<<2)|(3);	// Normal,No parity,One stop bit, 8bit
	g_pComm1Reg->UCON = (1<<9)|(1<<8)|(1<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<2)|(0);
	//rUFCON1=(1<<6)|(11<<4)|(1<<2)|(1<<1)|(1);
	g_pComm1Reg->UFCON=(2<<6)|(2<<4)|(1<<2)|(1<<1)|(1);

//	g_pComm1Reg->UFCON= 0;//(2<<6)|(3<<4)|(1<<2)|(1<<1)|(1);
	g_pComm1Reg->ULCON |= (1<<6); // IrDA mode
	g_pComm1Reg->UMCON=0x0;	// Disable Uart1 AFC 

//	g_pIOPregs->GPCON_U = (g_pIOPregs->GPCON_U&~(3<<20))|(1<<20); // GP29(IrDA_SDBW) is output
//	g_pIOPregs->GPDAT &=~(1<<29); // IrDA_SDBW output is low

	g_pComm1Reg->UBRDIV = (int)(S3C24A0_PCLK/16/9600+0.5)-1;


	temp = INREG(UERSTAT);
	if(temp)
		temp =INREG(URXH);

	DBGOUT((TEXT("-> Comm_hw_Init Initialization done, errstat %x"),temp));

	thisDev->portInfo.haveFIFO = TRUE;



	// Clear Int Pending and Unmask 
	g_pINTregs->SUBSRCPND =(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);

	//   	g_pINTregs->INTSUBMSK &= ~(BIT_SUB_RXD1|BIT_SUB_ERR1);


	g_pINTregs->SRCPND = BIT_UART1;
	  g_pINTregs->INTPND = g_pINTregs->INTPND;
	 g_pINTregs->INTPND;   

 // g_pINTregs->INTMSK &= ~(BIT_UART1);

	   
	g_pComm1Reg->UCON |= 1; // interrupt enable, Rx start

	DBGOUT((TEXT("<- Comm_hw_Init Done")));
	
}


VOID Comm_hw_ReInit(IrDevice *thisDev)
{
	comPortInfo *portInfo = &thisDev->portInfo;

	DBGOUT((TEXT("-> Comm_hw_ReInit")));

	Irda_GPIO_Conf(TRUE) ; // Set up GPIO for SIR mode


    g_pClkPwrRegs->CLKCON |= UART1_CLK_ON;

	g_pComm1Reg->ULCON=(1<<6)|(0<<3)|(0<<2)|(3);	// Normal,No parity,One stop bit, 8bit
	g_pComm1Reg->UCON = (1<<9)|(1<<8)|(1<<7)|(1<<6)|(0<<5)|(0<<4)|(0<<2)|(0);
	//rUFCON1=(1<<6)|(11<<4)|(1<<2)|(1<<1)|(1);
	g_pComm1Reg->UFCON=(2<<6)|(2<<4)|(1<<2)|(1<<1)|(1);

	g_pComm1Reg->UMCON=0x0;	// Disable Uart1 AFC 



	DBGOUT((TEXT("-> Comm_hw_Init Initialization done, errstat ")));

	thisDev->portInfo.haveFIFO = TRUE;



	// Clear Int Pending and Unmask 
	g_pINTregs->SUBSRCPND =(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);



	g_pINTregs->SRCPND = BIT_UART1;
	g_pINTregs->INTPND = g_pINTregs->INTPND;
	g_pINTregs->INTPND;   

	g_pComm1Reg->UCON |= 1; // interrupt enable, Rx start
	
	DBGOUT((TEXT("<- Comm_hw_Init Done")));
	
}



VOID Comm_hw_Stop(IrDevice *thisDev)
{
	comPortInfo *portInfo = &thisDev->portInfo;

	DBGOUT((TEXT("-> Comm_hw_Stop")));

   /*
	*  Disable all COM interrupts.
	*/

	g_pINTregs->INTMSK |= (BIT_UART1);
	g_pINTregs->INTSUBMSK |=(BIT_SUB_RXD1|BIT_SUB_TXD1|BIT_SUB_ERR1);

   /*
	*  Reset all UART1 registers
	*/
	g_pComm1Reg->ULCON= 0;
	g_pComm1Reg->UCON = 0;
	g_pComm1Reg->UFCON= 6;

	g_pComm1Reg->UMCON=0x0;	    

   /*
	*  Stop UART1 clock
	*/

    g_pClkPwrRegs->CLKCON &= ~UART1_CLK_ON;

	DBGOUT((TEXT("<- Comm_hw_Stop Done")));
}
	
#if COMM_DEBUG	
void DumpCommReg(void)
{

	RETAILMSG (1, (TEXT("DumpCommReg \r\n")));

	RETAILMSG (1, (TEXT("ULCON 0x%X, UCON 0x%x FCON 0X%x MCON 0x%x \r\n"),g_pComm1Reg->ULCON,g_pComm1Reg->UCON,g_pComm1Reg->UFCON,g_pComm1Reg->UMCON));

	RETAILMSG (1, (TEXT("UTRSTAT 0x%X, UERSTAT 0x%x UFSTAT 0X%x rUMSTAT 0x%x \r\n"),
			g_pComm1Reg->UTRSTAT,g_pComm1Reg->UERSTAT,g_pComm1Reg->UFSTAT,g_pComm1Reg->UMSTAT));
  

	RETAILMSG (1, (TEXT("rUTXH0x%X, URXH 0x%x UBRDIV 0X%x \r\n"),
			g_pComm1Reg->UTXH,g_pComm1Reg->URXH,g_pComm1Reg->UBRDIV));


	RETAILMSG (1, (TEXT("rGPCON_U 0x%X, rGPPU 0x%x rGPDAT 0X%x \r\n"),
			g_pIOPregs->GPCON_U,g_pIOPregs->GPPU,g_pIOPregs->GPDAT));
  

}
	
#endif

⌨️ 快捷键说明

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