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

📄 hdlcinit.c

📁 s3c4510的开发板snds100的源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
	if ( ((U32)(CRxBDPtr->BufferDataPtr) & BOwnership_DMA) )  {

		// Step 4. Clear Ownership bit for DMA 
		DataBuffer = (U32)(CRxBDPtr->BufferDataPtr & BOwnership_CPU ) ;

		// Step 5. Setup Rx DMA and Data buffer
		if ( Dev->HDLC_Rx_Mode == MODE_DMA ) {
			HDMARXBCNT(channel)	= 0x0  ;
			HDMARXMA(channel) 	= DataBuffer ;
			HDMARXCNT(channel) 	= sizeof(sHDLCFrame) ;
			HDMA_Rx_Enable(channel) ;
		}
		else {
			ModeInt_RxDataBuffer[channel] = (U32 *)DataBuffer ;
			ModeInt_RxDataSize[channel] = 0 ;
		}

		// Step 6. Receive enable
		HDLC_Rx_Enable(channel) ;

		return 1 ;
	}
	else return 0 ; // buffer full state, so can't use this buffer before get used
}


/*
 *  Function : SendHdlcFrame
 *  Description : Send HDLC frame
 */
int SendHdlcFrame(U32 channel, U8 *Data, int Size)
{
	sBufferDescriptor 	*CTxBDPtr ;
	HDLC_Device_Entry  	*Dev ;
	U32			*DataBufferPtr ;
	U8			*DataBuffer ;

	// Step 1. Get device entry pointer
	Dev = (HDLC_Device_Entry *)&HDLC_Dev[channel] ; 

	// Step 2. Get transmit buffer descriptor pointer
	CTxBDPtr = (sBufferDescriptor *)pCTxBDPtr[channel] ;

	// Step 3. Get data buffer pointer
	DataBufferPtr  = (U32 *)CTxBDPtr->BufferDataPtr ;
	DataBuffer  = (U8 *)CTxBDPtr->BufferDataPtr ;

	// Step 4. Check DMA ownership, if setted to 1 then exit send frame
	if ( ((U32)CTxBDPtr->BufferDataPtr & BOwnership_DMA) ) return 0 ;

	// Step 5. Copy Tx frame data to frame buffer
	CTxBDPtr->LengthField = Size ;
	memcpy ((U8 *)DataBuffer,(U8 *)Data,Size);

#if 0
	// debug message
	Print("\r++< Tx=>BDP:%x, BD:%x, L:%d ", \
		CTxBDPtr, CTxBDPtr->BufferDataPtr,Size) ;
#endif

	// Step 6. Change ownership to DMA
	CTxBDPtr->BufferDataPtr |= BOwnership_DMA;

	// Step 7. Change current buffer descriptor pointer
	pCTxBDPtr[channel] = (U32)CTxBDPtr->NextBufferDescriptor ;

	// Step 8. Set HDLC transmit DMA or Transmit buffer
	if ( Dev->HDLC_Tx_Mode == MODE_DMA ) {
		// Setup HDLC transmit DMA
		HDMA_Tx_init(channel,(U32)DataBufferPtr,Size) ;
		HDMA_Tx_Enable(channel);
	}
	else {
		// Setup transmit buffer and size to transmit
		ModeInt_TxDataBuffer[channel] = (U8 *)DataBuffer ;
		ModeInt_TxDataSize[channel] = Size ;

		// Enable Transmit FIFO avaliable interrupt
		HINTEN(channel) |= TxFAIE ; 
	}

	return 1 ;
}

/*
 *  Function : WriteDataToFifo
 *  Description : Write frame data to HDLC Tx FIFO
 *                This function is used only interrupt mode transmit
 */
int WriteDataToFifo(U32 channel)
{
	int i, j ;
	U32 *Data ;
	U8  *data ;

	for (i=0 ; i<4 ; i++) {
		if ( ModeInt_TxDataSize[channel] > 4 )  {
			// Read data buffer pointer to transmit
			Data = (U32 *)ModeInt_TxDataBuffer[channel] ;

			// Write Tx frame data to FIFO
			HTXFIFOC(channel) = *Data ;

			// increase data pointer
			ModeInt_TxDataBuffer[channel] += 4 ; 

			// decrement word
			ModeInt_TxDataSize[channel] -= 4 ;   
		}
		else {
			// excuted when left transmit byte is 4 or under 4 byte
			// Disable Transmit FIFO avaliable interrupt
			HINTEN(channel) &= ~TxFAIE ; 

			if (ModeInt_TxDataSize[channel] == 4 ) {
				// if lefted transmit data is 1 word, then write
				// word data to HTXFIFOT register
				Data = (U32 *)ModeInt_TxDataBuffer[channel] ;
				HTXFIFOT(channel) = *Data ;
				ModeInt_TxDataSize[channel] -= 4 ;   // decrement word
			} else {
				// Get byte data pointer 
				data = (U8 *)ModeInt_TxDataBuffer[channel] ;
				HDLCTXFIFOT = (U8 *)&HTXFIFOT(channel) ;
				HDLCTXFIFOC = (U8 *)&HTXFIFOC(channel) ;

				// process under 4 byte data
				for ( j=0 ; j<4; j++) {
					ModeInt_TxDataSize[channel] -- ;// decrement byte
					if (ModeInt_TxDataSize[channel] > 0)  {
						*HDLCTXFIFOC = *data++ ;
					} 
					else {
						// end of frame data
						*HDLCTXFIFOT = *data++ ;
						break ;
					}
				}
			}

			return 0 ; // return end of frame transfer
		}

	}
	return 1 ; // return not end of frame transfer
}

/*
 *  Function : ReadDataFromFifo
 *  Description : Read frame data from HDLC Rx FIFO
 *                This function is only used when interrupt mode receive
 */
int ReadDataFromFifo(U32 channel, U32 bcnt)
{
	int i, cnt ;

	cnt = (int)(((bcnt&~3)+4)/4) ;
	ModeInt_RxDataSize[channel] += (bcnt+1) ;

	for (i=0 ; i<cnt ; i++) 
		*ModeInt_RxDataBuffer[channel]++ = HRXFIFO(channel) ; 

	return 1 ;
}

/*
 *  Function : HDLCA_Isr
 *  Description : HDLC Interrupt service routine for channel A
 */
void HDLCA_isr(void)
{
	sBufferDescriptor 	*CRxBDPtr, *CTxBDPtr ;
	HDLC_Device_Entry  	*Dev ;
	U32			RxLength, TxLength ;
	U32			channel = HDLCA ;
	U32 			IntHdlcStatus ;

	// 1. Get device entry pointer
	Dev = (HDLC_Device_Entry *)&HDLC_Dev[channel] ; 

	// 2. Save current HDLC status
	IntHdlcStatus = HSTAT(channel) ;

	// 3. Process HDMA receive operation
	//    This routine is used when HDLC DMA mode receive operation
	if ( IntHdlcStatus & ( DRxSTOP | DRxABT) ) {

		if ( IntHdlcStatus & DRxSTOP ) {
			gHdlcRxStatus[channel].DMARxStop++ ;
			HSTAT(channel) |= DRxSTOP ;
		}
		else if ( IntHdlcStatus & DRxABT ) {
			gHdlcRxStatus[channel].DMARxABT++ ;
			HSTAT(channel) |= DRxABT ;
		}

		// Step 1. Get current receive buffer descriptor point
		CRxBDPtr = (sBufferDescriptor *)gCRxBDPtr[channel];

		// Step 2. Clear owner to CPU
		CRxBDPtr->BufferDataPtr &= BOwnership_CPU ; 

		// Step 3. Get length and status
		CRxBDPtr->LengthField = RxLength = HDMARXBCNT(channel) ;
		CRxBDPtr->StatusField = IntHdlcStatus ; 

		// Step 4. Get Next buffer descriptor
		gCRxBDPtr[channel] = (U32)CRxBDPtr->NextBufferDescriptor ;

		// Step 5. Initialize HDLC DMA for receive
		HDLC_Rx_init(channel) ;
	}


	// 4. Process HDLC receive operation
	//    This routine is used when HDLC interrupt mode receive operation
	if (Dev->HDLC_Rx_Mode == MODE_INTERRUPT) {
		if (IntHdlcStatus & (RxFA | RxFV | RxFERR) ) {
			if (IntHdlcStatus & RxFA) 
				gHdlcRxStatus[channel].RxFIFOAvalable++ ;
	
			if (IntHdlcStatus & (RxFV | RxFERR) ) {
		
				if (IntHdlcStatus & RxFV) 
					gHdlcRxStatus[channel].RxLastFrameValid++ ;
		
				if ( IntHdlcStatus & RxFERR ) 
					gHdlcRxStatus[channel].RxFrameError++ ;
		
				// Step 1. Read received data from HDLC receive FIFO entry
				ReadDataFromFifo(channel,(HSTAT(channel)&0xF)) ;
		
				// Step 2. Get current receive buffer descriptor point
				CRxBDPtr = (sBufferDescriptor *)gCRxBDPtr[channel];
		
				// Step 3. Clear owner to CPU
				CRxBDPtr->BufferDataPtr &= BOwnership_CPU ; 

				// Step 4. Get length and status
				CRxBDPtr->LengthField = RxLength = 
						ModeInt_RxDataSize[channel] ; 
				CRxBDPtr->StatusField = IntHdlcStatus ; 

				// Step 5. Get Next buffer descriptor
				gCRxBDPtr[channel] = (U32)CRxBDPtr->NextBufferDescriptor ;
		
				// Step 6. Initialize HDLC DMA for receive
				HDLC_Rx_init(channel) ;
			} else
				// Read received data from HDLC receive FIFO entry
				ReadDataFromFifo(channel, 15) ;
		}
	}
	
	// 5. Save HDLC receive status 
	if ( IntHdlcStatus & ( RxOV|RxABT|RxAERR|RxFAP|RxFD|RxDCD|RxSDCD|RxIDLE) ) {

		// HDLC Rx OverRun Error
		if ( IntHdlcStatus & RxOV ) {
			gHdlcRxStatus[channel].RxOverrun++ ;
			HSTAT(channel) |= RxOV ;

			// check all descriptor is used, then enable HDMA Rx
			if ( gCRxBDPtr[channel] == pCRxBDPtr[channel] )
				HDLC_Rx_init(channel) ;
		}
	
		if ( IntHdlcStatus & RxABT ) {
			gHdlcRxStatus[channel].RxAbort++ ;
			HSTAT(channel) |= RxABT ;
			HDLC_Rx_init(channel) ;
		}

		if ( IntHdlcStatus & RxAERR ) 
			gHdlcRxStatus[channel].RxAddressError++ ;

		if (IntHdlcStatus & RxFAP) 
			gHdlcRxStatus[channel].RxFIFOAddrPresent++ ;

		if (IntHdlcStatus & RxFD) {
			gHdlcRxStatus[channel].RxFlagDetected++ ;
			HSTAT(channel) |= RxFD ;
			}
		if (IntHdlcStatus & RxDCD) 
			gHdlcRxStatus[channel].RxLevelOfDCD++ ;

		if (IntHdlcStatus & RxSDCD) {
			gHdlcRxStatus[channel].RxTransitionOfDCD++ ;
			HSTAT(channel) |= RxSDCD ;
			}
		if (IntHdlcStatus & RxIDLE) {
			gHdlcRxStatus[channel].RxIdle++ ;
			HSTAT(channel) |= RxIDLE ;
			}
	}

	// 6. HDLC Transmit DMA mode Complete
	if ( IntHdlcStatus & (DTxSTOP | DTxABT) ) {

		if ( IntHdlcStatus & DTxSTOP ) {
			gHdlcTxStatus[channel].DMATxStop++ ;
			HSTAT(channel) |= DTxSTOP ;
		}

		if ( IntHdlcStatus & DTxABT ) {
			gHdlcTxStatus[channel].DMATxABT++ ;
			HSTAT(channel) |= DTxABT ;
		}

		do {
			// Step 1. Get current transmit buffer descriptor pointer 
			//         and length
			CTxBDPtr = (sBufferDescriptor *)gCTxBDPtr[channel];
			TxLength = CTxBDPtr->LengthField ;
	
			// Step 2. Clear Length and Status field
			CTxBDPtr->LengthField = (U32)0x0;
			CTxBDPtr->StatusField = (U32)0x0;
	
			// Step 3. Get Next buffer descriptor
			gCTxBDPtr[channel] = (U32)CTxBDPtr->NextBufferDescriptor ;
	
			// Step 4. Clear DMA owner to CPU
			CTxBDPtr->BufferDataPtr &= BOwnership_CPU ; 

		} while (pCTxBDPtr[channel] == gCTxBDPtr[channel]) ;
	}

	// 7. HDLC Transmit Interrupt mode
	if (Dev->HDLC_Tx_Mode == MODE_INTERRUPT) {
		if  (IntHdlcStatus & TxFA) {
			gHdlcTxStatus[channel].TxFIFOAvailable++ ;

			if ( ModeInt_TxDataSize[channel] > 0)
				// Step 1. write 4 word frame data to FIFO
				if ( !WriteDataToFifo(channel) ) {

					// Step 2. Get current receive buffer descriptor point
					CTxBDPtr = (sBufferDescriptor *)gCTxBDPtr[channel];
					TxLength = CTxBDPtr->LengthField ;
			
					// Step 3. Clear length and status field
					CTxBDPtr->LengthField = (U32)0x0;
					CTxBDPtr->StatusField = (U32)0x0;
			
					// Step 4. Get Next buffer descriptor
					gCTxBDPtr[channel] = 

⌨️ 快捷键说明

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