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

📄 hdlc100init.c

📁 三星4510开发板Sdns100上代的演示程序
💻 C
字号:
/****************************************************************/
/* 																*/ 
/*   MODULE:  BDTest/hdlc100init.c								*/
/*   DATE:    98/12/01       									*/
/*   PURPOSE: hdlc(high level data link control) header			*/
/*                                                    			*/
/*--------------------------------------------------------------*/
/*      Copyright (C) 1998 Samsung Electronics.     			*/
/*                                                 				*/
/****************************************************************/

#include "snds.h"
#include "hdlc100.h"
#include "sysconf.h"
#include "uart.h"
#include "pollio.h"
#include "timer.h"
#include "isr.h"
#include "dma.h"
#include "memory.h"
#include "kslib.h"

/*
 * Function 	: HdlcInitialize
 * Description 	: This function initiailze the HDLC Block 
 */
void HdlcInitialize (void)
{

	U8 	channel;
	U32	UserArea;

	for(channel=HDLCA;channel<=HDLCB;channel++)
	{
		//Reset All HDLC block
		HdlcReset(channel) ;

		// Internal Register Setting for Tx/Rx operation
		HMODE(channel) 	= gMode ;
#if MODE == DMA
		HCON(channel) 	= gControl ;
		HINTEN(channel) = gHIntENA ;
#else
		HCONA  			= Tx1WD|Rx1WD|TxFlag|TxDTR | BRGEN ;
		HINTENA 		= TxFCIE|TxFAIE|TxUIE|RxFAIE|RxFVIE| \
			 			  RxABTIE|RxCRCEIE|RxNOIE|RxOVIE ;
#endif
		HBRGTC(channel) = GetBaudRate(10000000) ;	
		AddressSet(channel) ;

#if MODE == DMA
		MaxFrameLengthSet(channel,MaxFrameLength);
		HRBSR(channel) 	= RxBufLength ;

		// Initialize Buffer Descriptor
		TxBD_init(channel,NORMAL,NORMAL) ;
		RxBD_init(channel) ;
		TxDataWrite(channel,CPU) ;

		// Ready to receive Data
		HDMARxEN(channel) ;	
#endif
		HDLCRxEN(channel) ;	
	
	}

	// Interrupt Vector Setup
	SysSetInterrupt(nHDLCTxA_INT, HDLCTxA_isr );
	SysSetInterrupt(nHDLCRxA_INT, HDLCRxA_isr );
	SysSetInterrupt(nHDLCTxB_INT, HDLCTxB_isr );
	SysSetInterrupt(nHDLCRxB_INT, HDLCRxB_isr );

	Enable_Int(nHDLCTxA_INT);
	Enable_Int(nHDLCRxA_INT);
	Enable_Int(nHDLCTxB_INT);
	Enable_Int(nHDLCRxB_INT);
	Enable_Int(nGLOBAL_INT); 


	// Initialize Global Variables
	gCPUmode = gHdlcRxDone = 0 ;
	for(channel=HDLCA;channel<=HDLCB;channel++)
	{
		gFrameCount[channel]= 0 ;
		//initialize User Area
		UserArea 			= (U32) RxUserArea[channel] | NonCache ;
		gUserArea[channel] 	= (U32 *)UserArea ;
	}
	ClrErrReport() ;
}


/* 
 * Tx Buffer Descriptor generation &  
*/

void TxBD_init(U8 channel,int mode, int arg)
{
	sBufferDescriptor	*psTxBD ;
	sBufferDescriptor	*psStartBD ;
	sBufferDescriptor	*psPrevBD ;
	U32					TxBDataStartAddr ;	
	U32					TxBufLength ;	
	U32					i ;
	U32					MisAlignBytes ;
	U32					NullPoint ;

	// Mode Set
	if(mode == BUFFERLEN) 		TxBufLength = arg ;
	else if(mode == NULLLIST) 	NullPoint   = arg ;

	gCTxBDStart[channel] = (U32)sTxBDStart[channel] | NonCache ;
	HDMATXPTR(channel)   =  gCTxBDStart[channel] ;

	psTxBD 				 = (sBufferDescriptor *)gCTxBDStart[channel] ;
	psStartBD 			 = psTxBD ;
	psTxBD->PrevBD 		 = (sBufferDescriptor *)NULL ;
	
	TxBDataStartAddr 	 = (U32)TxBBaseAddr ;
	TxBDataStartAddr    |= NonCache ; 
	
	for(i=1; i<=MaxTxBDCount; i++){
		if(mode!=1) 		TxBufLength = 0x120; //PatternGen(i) & 0x7ff; //debug
		if(TxBufLength<6) 	TxBufLength = 6 ;
		
		MisAlignBytes 			= (WORD-TxBufLength%WORD)%WORD ;
		psTxBD->BufferDataPtr 	= (U32)TxBDataStartAddr & BOwnerShip_CPU;
		psTxBD->Reserved 		= 0x0; 
		psTxBD->StatusLength 	= TxBufLength  ;   

		//Next Buffer Descriptor Allocation
		if(psTxBD->PrevBD != (sBufferDescriptor *) NULL){
			if(mode==2 && i==NullPoint) {
				psPrevBD->NextBD = 0x0 ;
				break;
		 	}
			else psPrevBD->NextBD = psTxBD ;		
		}

		psPrevBD = psTxBD ; // = psTxBD++
		psTxBD++ ;
		
		if(i!=MaxTxBDCount) psTxBD->PrevBD = psPrevBD ;

		TxBDataStartAddr += TxBufLength + MisAlignBytes ; 
	}
	
	psTxBD-- ;
	//Assign last buffer descriptor
	psTxBD->NextBD = psStartBD ;
	//Assign first buffer descriptor
	psStartBD->PrevBD = psTxBD ; 
}

void TxBufferInitialize(U8 channel)
{	
	sBufferDescriptor	*psTxBD ;
	U32					*BufPtr ;
	U32					*pBDPtr ;
	U32					j, LOOP, TxLength, MisAlignBytes;
	U32					u32TxBD ;

	// check last flag bit of current Buffer Descriptor
	while(1)
	{
		u32TxBD = (!channel) ? HDMATXPTRA : HDMATXPTRB ;
		psTxBD = (sBufferDescriptor *) u32TxBD ;
		pBDPtr = (U32 *)&psTxBD->Reserved ;
		if(*pBDPtr & LastBF) {
			pBDPtr = (U32 *)&psTxBD->BufferDataPtr ;
			while (*pBDPtr & BOwnerShip_DMA) ;
			break;
		} 
	}
	
	// Write Frame Start Address & change Owner for DMA
	BufPtr = (U32 *) ( (U32) TxBBaseAddr + NonCache ) ;
	pBDPtr = (U32 *)gCTxBDStart[channel] ;
	psTxBD = (sBufferDescriptor *) pBDPtr ;
	*pBDPtr |= BOwnerShip_DMA ;	

	TxLength = (U32)psTxBD->StatusLength & 0xFFFFFF ;  
	MisAlignBytes = TxLength & 0x3 ;
	*BufPtr++ = 0xaaaaaaaa ;
	LOOP = (TxLength<4) ? 0 : TxLength/4-1 ;
	for(j=0; j<LOOP; j++) *BufPtr++ = j ; 
  	switch(MisAlignBytes) {
		case 1 : *BufPtr++ = 
					(TxLength<<8) & 0xffffff00 | 0x000000cc ; break; 
		case 2 : *BufPtr++ = 
					(TxLength<<16) & 0xffff0000 | 0x0000cccc ; break;
		case 3 : *BufPtr++ =  
					(TxLength<<24) & 0xff000000 | 0x00cccccc ; break;
		default : break;
	}
}

void TxDataWrite(U8 channel,int Owner)
{
	sBufferDescriptor	*psTxBD ;
	U32					*BufPtr ;
	U32					*pBDPtr ;
	U32					i, j, LOOP, TxLength, MisAlignBytes;

	BufPtr = (U32 *) ( (U32) TxBBaseAddr | NonCache ) ;

	psTxBD = sTxBDStart[channel] ;
	psTxBD = (sBufferDescriptor *) ( (U32) psTxBD | NonCache ) ; 

	for(i=0; i<MaxTxBDCount; i++){
		pBDPtr = (U32 *)&psTxBD->BufferDataPtr ;
		if(Owner==DMA) *pBDPtr |= BOwnerShip_DMA ;	

		psTxBD->Reserved = LastBF; 
		TxLength = (U32)psTxBD->StatusLength & 0xFFFFFF ;  
		MisAlignBytes = (WORD-TxLength%WORD)%WORD ;
		*BufPtr++ = 0xaaaaaaaa ;
		LOOP = (TxLength<4) ? 0 : TxLength/4-1 ;
		for(j=0; j<LOOP; j++) *BufPtr++ = 0xffffff00|(j+i) ; 
		switch(MisAlignBytes) {
			case 1 : *BufPtr++ = 
						(TxLength<<8) & 0xffffff00 | 0x000000cc ; break; 
			case 2 : *BufPtr++ = 
						(TxLength<<16) & 0xffff0000 | 0x0000cccc ; break;
			case 3 : *BufPtr++ =  
						(TxLength<<24) & 0xff000000 | 0x00cccccc ; break;
			default : break;
		}
		psTxBD = psTxBD->NextBD ;
	} 
}

void RxBD_init(U8 channel) 
{
	sBufferDescriptor	*psRxBD ;
	sBufferDescriptor	*psPrevBD, *psStartBD ;
	U32					RxBDataStartAddr ;	
	U32					i ;

	//RxBBaseAddrA = (U32 *)0x200000 ;

	gCRxBDStart[channel] 	= (U32)sRxBDStart[channel] | NonCache ;
	HDMARXPTR(channel)   	= gCRxBDStart[channel] ; 
	psRxBD 					= (sBufferDescriptor *)gCRxBDStart[channel] ;
	psStartBD 				= psRxBD ;
	psRxBD->PrevBD 			= (sBufferDescriptor *)NULL ;
	RxBDataStartAddr 		= (U32)RxBBaseAddr[channel] | NonCache ;
 
	for(i=1; i<=MaxRxBDCount; i++){
		psRxBD->BufferDataPtr 	=(U32)RxBDataStartAddr | BOwnerShip_DMA;
		psRxBD->Reserved 		= 0x0 ;   
		psRxBD->StatusLength 	= 0x0 ;   
		//Next Buffer Descriptor Allocation
		if(psRxBD->PrevBD != (sBufferDescriptor *) NULL)
			psPrevBD->NextBD = psRxBD ;		

		psPrevBD = psRxBD ; // = psRxBD++
		psRxBD++ ;
		
		if(i!=MaxRxBDCount) psRxBD->PrevBD = psPrevBD ;

		RxBDataStartAddr += RxBufLength ;
	}
	//
	psRxBD-- ;
	//Assign last buffer descriptor
	psPrevBD->NextBD 	= psStartBD ;
	//Assign first buffer descriptor
	psStartBD->PrevBD 	= psRxBD ; 
} 
		


void HDLCTxA_isr(void)
{
	U32 i , j ;
	U32 IntHDLCStatus ;
	U32 CheckStatus, TxFail ;
	U32	PacketSize;

	IntHDLCStatus = HSTATA ;
	//HSTATA = IntHDLCStatus ;
	Clear_PendingBit(nHDLCTxA_INT) ;

	TxFail = 0 ;
	
#if MODE == DMA
	if(IntHDLCStatus & DTxFD)
	{
		gHTxStatus[HDLCA].DMATxFD++ ;
		HSTATA = IntHDLCStatus & DTxFD ; 
	}

	CheckStatus = TxSCTS|TxU|DTxABT|DTxNL|DTxNO ;
	if(IntHDLCStatus & CheckStatus){
		if(IntHDLCStatus & (DTxNO|DTxABT|DTxNL)){
			if(IntHDLCStatus & DTxABT){
				gHTxStatus[HDLCA].DMATxABT++ ;
				HSTATA = IntHDLCStatus & DTxABT ; 
			}
			if(IntHDLCStatus & DTxNO){
				gHTxStatus[HDLCA].DMATxNO++ ;
				HSTATA = IntHDLCStatus & DTxNO ; 
			}
			
			if(IntHDLCStatus & DTxNL){
				gHTxStatus[HDLCA].DMATxNL++ ;
				HSTATA = IntHDLCStatus & DTxNL ; 
				put_byte('N') ;
			}
			//TxFail = 1 ;
		}
	}
	if(!CheckTxStatus(HDLCA)|TxFail) 
		Print("\r HDLCA Tx Fail for Null List") ;
#else 
	 if(IntHDLCStatus & TxFA){
		for(i=0; i<gMaxPacketCnt; i++){
		    PacketSize = PatternGen(i)&0xFFFF;	
			if(PacketSize < 2) PacketSize = 2 ;
	
			HTXFIFOCA = 0xFFFF0000 | (i+1) ;
			
			for(j=0; j<PacketSize; j++){
				if(j==(PacketSize-1)){
					HTXFIFOTA = 0xEEEE0000|PacketSize ; 
				} else HTXFIFOCA = PatternGen(j) | i ; 
			}

			if(i==(gMaxPacketCnt-1))
				HINTENA &= ~ TxFAIE ;      
		}
	}

	if(IntHDLCStatus & TxFC){
		gHTxStatus[HDLCA].TxFrameComp++ ;
	}	
	if(IntHDLCStatus & TxU){
		gHTxStatus[HDLCA].TxUnderrun++ ;
	}
#endif
}

void HDLCTxB_isr(void)
{
	U32 i , j ;
	U32 IntHDLCStatus ;
	U32 CheckStatus, TxFail ;
	U32	PacketSize;

	IntHDLCStatus = HSTATB ;
	//HSTATB = IntHDLCStatus ;
	Clear_PendingBit(nHDLCTxB_INT) ;

	TxFail = 0 ;
	
#if MODE == DMA
	if(IntHDLCStatus & DTxFD)
	{
		gHTxStatus[HDLCB].DMATxFD++ ;
		HSTATB = IntHDLCStatus & DTxFD ;
	}

	CheckStatus = TxSCTS|TxU|DTxABT|DTxNL|DTxNO ;
	if(IntHDLCStatus & CheckStatus){
		if(IntHDLCStatus & (DTxNO|DTxABT|DTxNL)){
			
			if(IntHDLCStatus & DTxABT){
				gHTxStatus[HDLCB].DMATxABT++ ;
				HSTATB = IntHDLCStatus & DTxABT ;
			}
			if(IntHDLCStatus & DTxNO){
				gHTxStatus[HDLCB].DMATxNO++ ;
				HSTATB = IntHDLCStatus & DTxNO ;
			}
			if(IntHDLCStatus & DTxNL){
				gHTxStatus[HDLCB].DMATxNL++ ;
				HSTATB = IntHDLCStatus & DTxNL ;
			}
			//TxFail = 1 ;
		}
	}
	if(!CheckTxStatus(HDLCB)|TxFail) Print("\r HDLCB Tx Fail") ;
#else
	 if(IntHDLCStatus & TxFA){
		for(i=0; i<gMaxPacketCnt; i++){
		    PacketSize = PatternGen(i)&0xFFFF;	
			if(PacketSize < 2) PacketSize = 2 ;
	
			HTXFIFOCB = 0xFFFF0000 | (i+1) ;
			
			for(j=0; j<PacketSize; j++){
				if(j==(PacketSize-1)){
					HTXFIFOTB = 0xEEEE0000|PacketSize ; 
				} else HTXFIFOCB = PatternGen(j) | i ; 
			}

			if(i==(gMaxPacketCnt-1))
				HINTENB &= ~ TxFAIE ;      
		}
	}

	if(IntHDLCStatus & TxFC){
		gHTxStatus[HDLCB].TxFrameComp++ ;
	}	
	if(IntHDLCStatus & TxU){
		gHTxStatus[HDLCB].TxUnderrun++ ;
	}
#endif
}


void HDLCRxA_isr(void)
{
	U32 IntHDLCStatus, pRxBDPtr ;
	U32 RxFail ;
	//U32 CheckStatus, 
	U32 RemainByte ;
	IntHDLCStatus = HSTATA ;
	Clear_PendingBit(nHDLCRxA_INT) ;
	RxFail = 0 ;

#if MODE == DMA
	if(IntHDLCStatus & DRxFD){
		gHRxStatus[HDLCA].DMARxFD++ ;
		HSTATA = IntHDLCStatus & DRxFD ;
		
		if(IntHDLCStatus & RxFV){
			gHRxStatus[HDLCA].RxFValid++ ;	
			HSTATA = IntHDLCStatus & DRxFD ;
		}
		if(IntHDLCStatus & RxCRCE) {
			gHRxStatus[HDLCA].RxCRCErr++ ;
			HSTATA = IntHDLCStatus & DRxFD ;
		}
		pRxBDPtr = HDMARXPTRA ;
		gFrameCount[HDLCA]++;
	
		if(!gMultiTransfer) {
			if (!CheckRxStatusHDLC(HDLCA, pRxBDPtr)) RxFail = 1;
		}
	}

	if(IntHDLCStatus & (RxMOV|DRxNL|DRxNO)){//DMARxEN is cleared.
		if(IntHDLCStatus & RxMOV) {
			gHRxStatus[HDLCA].DMARxMOV++ ; 
			HSTATA = IntHDLCStatus & RxMOV ;
			RxFail = 1;
			put_byte('M') ;
		}	
		if(IntHDLCStatus & DRxNL) {
			gHRxStatus[HDLCA].DMARxNL++ ;
			HSTATA = IntHDLCStatus & DRxNL ;
			RxFail = 1;
			put_byte('N') ;
		}	
		if(IntHDLCStatus & DRxNO) {
			gHRxStatus[HDLCA].DMARxNO++ ;
			HSTATA = IntHDLCStatus & RxNO ;
			RxFail = 1;
			put_byte('O') ;
		}
		//HDMARxEN(HDLCA) ;
		//HDMARXPTRA = gCRxBDStartA ; 
	}	

	if(IntHDLCStatus & RxOV) put_byte('.') ;

	// 99.1.3 such
	if (RxFail) Print("\r HDLCA Rx Fail") ;
#else
	if(IntHDLCStatus & (RxFA|RxFV))
	{   
		if(IntHDLCStatus & RxFA)
		  *gUserArea[HDLCA]++ = HRXFIFOA ;
		if(IntHDLCStatus & RxFV)
		{   //put_byte('r') ;

			gHdlcRxDone = 1 ;
			gHRxStatus[HDLCA].RxFValid++ ; 
			RemainByte = IntHDLCStatus & 0xf;

			if(RemainByte ==  RxRB1) 
				*gUserArea[HDLCA]++ = HRXFIFOA & 0xFF000000 ;	
			if(RemainByte ==  RxRB2) 
				*gUserArea[HDLCA]++ = HRXFIFOA & 0xFFFF0000 ;	
			if(RemainByte ==  RxRB3) 
				*gUserArea[HDLCA]++ = HRXFIFOA & 0xFFFFFF00 ;	
			if(RemainByte ==  RxRB4) 
				*gUserArea[HDLCA]++ = HRXFIFOA & 0xFFFFFFFF ;	
			if(!CheckRxCPU()) {
				RxFail = 1 ;
				gRxFail = 1 ;
			}
			PrintMemTestStatus(RemainByte%4) ;
		}
	
	 
	if(IntHDLCStatus & RxCRCE) {
		gHRxStatus[HDLCA].RxCRCErr++ ;
		*gUserArea[HDLCA]++ = 0x0000ffff & HRXFIFOA ;
		RxFail = 1 ;
	}
	if(IntHDLCStatus & RxOV) {
		gHRxStatus[HDLCA].RxOverrun++ ;
		put_byte('O') ;
		RxFail = 1 ;
	}
	if (RxFail) Print("\r HDLCA Rx Fail") ;
  }
#endif
}

void HDLCRxB_isr(void)
{
	U32 IntHDLCStatus, pRxBDPtr ;
	U32 RxFail ;
	//U32 CheckStatus, 
	U32 RemainByte ;

	IntHDLCStatus = HSTATB ;
	//HSTATB = IntHDLCStatus ;
	Clear_PendingBit(nHDLCRxB_INT) ;
	RxFail = 0 ;


#if MODE == DMA
	if(IntHDLCStatus & DRxFD){
		gHRxStatus[HDLCB].DMARxFD++ ;
		HSTATB = IntHDLCStatus & DRxFD ;
	}	
	pRxBDPtr = HDMARXPTRB ;
	gFrameCount[HDLCB]++;

	if(!gMultiTransfer) {
		if (!CheckRxStatusHDLC(HDLCB, pRxBDPtr)) RxFail = 1;
	}
		//while(!(get_byte()=='q'))
		//		MemoryDump() ;
		//gHdlcRxDone = 1;

		//99.1.3 such
	if(IntHDLCStatus & (RxMOV|DRxNL|DRxNO)){//DMARxEN is cleared.
		if(IntHDLCStatus & RxMOV) {
			gHRxStatus[HDLCB].DMARxMOV++ ; 
			HSTATB = IntHDLCStatus & RxMOV ;
			RxFail = 1;
		}	
		if(IntHDLCStatus & DRxNL) {
			gHRxStatus[HDLCB].DMARxNL++ ;
			HSTATB = IntHDLCStatus & DRxNL ;
			RxFail = 1;
		}	
		if(IntHDLCStatus & DRxNO) {
			gHRxStatus[HDLCB].DMARxNO++ ;
			HSTATB = IntHDLCStatus & RxNO ;
			RxFail = 1;
		}
		HDMARxEN(HDLCB) ;//cjw. need to check, this line can be 
						//operated in CheckRxStatus()
		HDMARXPTRB = gCRxBDStart[HDLCB] ; 
	}	

	// 99.1.3 such
	if (RxFail) Print("\r HDLCB Rx Fail") ;
#else
	if(IntHDLCStatus & (RxFA|RxFV))
	{   
		if(IntHDLCStatus & RxFA)
		  *gUserArea[HDLCB]++ = HRXFIFOB ;
		if(IntHDLCStatus & RxFV)
		{   
			gHdlcRxDone = 2 ;
			gHRxStatus[HDLCB].RxFValid++ ; 
			RemainByte = IntHDLCStatus & 0xf;

			if(RemainByte ==  RxRB1) 
				*gUserArea[HDLCB]++ = HRXFIFOB & 0xFF000000 ;	
			if(RemainByte ==  RxRB2) 
				*gUserArea[HDLCB]++ = HRXFIFOB & 0xFFFF0000 ;	
			if(RemainByte ==  RxRB3) 
				*gUserArea[HDLCB]++ = HRXFIFOB & 0xFFFFFF00 ;	
			if(RemainByte ==  RxRB4) 
				*gUserArea[HDLCB]++ = HRXFIFOB & 0xFFFFFFFF ;	
			if(!CheckRxCPU()) {
				RxFail = 1 ;
				gRxFail = 1 ;
			}
			PrintMemTestStatus(RemainByte%4) ;
		}
		//if(IntHDLCStatus & RxFA)
		  //*gUserAreaB++ = HRXFIFOB ;
	
	 
	if(IntHDLCStatus & RxCRCE) {
		gHRxStatus[HDLCB].RxCRCErr++ ;
		*gUserArea[HDLCB]++ = 0x0000ffff & HRXFIFOB ;
		RxFail = 1 ;
	}
	if(IntHDLCStatus & RxOV) {
		gHRxStatus[HDLCB].RxOverrun++ ;
		put_byte('O') ;
		RxFail = 1 ;
	}
	if (RxFail) Print("\r HDLCB Rx Fail") ;
  }
#endif
}


⌨️ 快捷键说明

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