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

📄 hdlc100init.c

📁 本source code 為s3c4510的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
   HDLCDPLLStatus[cn].DPLLTM = 0;	// two clock miss  }}////////////////////////////////////////////////////////////////////////////////// GetBaudRate //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////* [1:0]    Time constant value for CNT2 				      *//*           00 = divide by 1 						      *//*           01 = divide by 16 						      *//*           10 = divide by 32 						      *//* [3:2]    Time constant value for CNT1 				      */	/*           00 = divide by 1 						      *//*           01 = divide by 16 						      *//* [15:4]   Time constant value for CNT0 				      *//* 								              *//* BRGOUT1 = (MCLK2 or RXC) / (CNT0 + 1) / (16 ** CNT1 ) 	              *//* BRGOUT2 = BRGOUT1 / (1 or 16 or 32 according to CNT2 value of the HBRGTC)  */static U32 GetBaudRate(U32 WantedBR){ U32 DIF;				// minimal baudrate difference U32 CNT0;				// selected counter CNT0  U32 CNT1;				// selected counter CNT1 U32 CNT2;				// selected counter CNT2 U32 i;	//	 DIF = 0xFFFFFFFF;			// start minimal baudrate difference for(i = 0; i < 6; ++i)  {   U32 scal0;   U32 scal1;   U32 scal2;   U32 dif;   U32 br;   U32 j;   switch(i)     {     case 0 : scal1 =  1 ; scal2 =  1 ; break;     case 1 : scal1 =  1 ; scal2 = 16 ; break;     case 2 : scal1 =  1 ; scal2 = 32 ; break;     case 3 : scal1 = 16 ; scal2 =  1 ; break;     case 4 : scal1 = 16 ; scal2 = 16 ; break;     case 5 : scal1 = 16 ; scal2 = 32 ; break;     default : ;    }   scal0 = MCLK2 / WantedBR / scal1 / scal2;	   for(j = 0; j < 2; j++, scal0++)		//     {						// scal0 = CNT0 + 1     if(scal0 >= 1 && scal0 <= 4096)		// CNT0 >= 0 && CNT0 <= 4095      {					       br  = MCLK2 / scal0 / scal1 / scal2;	// calculated baudrate        if(br > WantedBR) {dif = br - WantedBR;} // baurate differense        else              {dif = WantedBR - br;} //       if(dif < DIF)        {					// less then minimal dif          DIF =  dif;				// reset minimal difference          CNT0 = scal0 - 1;			// set counter CNT0          CNT1 = scal1 / 16;			// set counter CNT1         CNT2 = scal2 / 16;			// set counter CNT2        }      }    }  } //  return((CNT0 <<4) | (CNT1<<2) | CNT2 );}////////////////////////////////////////////////////////////////////////////////// Tx Buffer Descriptor generation /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// cn          = channel num (0,1)// TxBufLength = transmit buffer length //               0 = default length 0x120// NullPoint   = null pointer entry//               0 = circular BD list//               else prev[NullPoint]->next = 0void TxBD_init(int cn, int NullPoint){ sHDLCBD * bd;				// current buffer descriptor sHDLCBD * start;			// start transmit buffer descriptor  sHDLCBD * prev;			// previous buffer descriptor U32 allocptr;				// alloc position  U32 alloccnt; 				// bytes in buffer  U32 i; int TxBufLength;// align word boundary ///////////////////////////////////////////////////////// TxBufLength = ((HDLC_TX_BUF_LENGTH + 3) >> 2) << 2;// if(NullPoint <= 0 || NullPoint > HDLC_MAX_TX_DES)  {   NullPoint = HDLC_MAX_TX_DES;  } HDMATXPTR(cn)    = 			// HDMATXPTR gHDLCTxStart[cn] = 			// Tx BD start position  gHDLCTxEnd  [cn] = 			// Tx BD end   (U32) sHDLCTxBD[cn] |         NonCache; gHDLCTxCount[cn] = 0;			// Tx BD count with DMA owner bit//  bd = (sHDLCBD *) gHDLCTxStart[cn];	// current buffer descriptor prev  = (sHDLCBD *)NULL;		// previous buffer descriptor start = bd;				// save start buffer descriptor// buffer allocation pointer + non cacheble area allocptr  = (U32) HDLCTxAllocBuf[cn] | NonCache;	// sizeof of alloc buffer, words alloccnt  = HDLC_TX_ALLOC_BUF_SIZE * sizeof(U32);	     for(i = 0; i < HDLC_MAX_TX_DES; ++i)  {   if(TxBufLength > alloccnt)    {     break;				// allocation error    }// set fields off current buffer descriptor ////////////////////////////////////   bd->BufferDataPtr = 			// frame data pointer     (U32) allocptr & 			// allocation pointer       HDLCTxBD_CPU;			// clear DMA bit //    bd->Reserved      = 0x0; 				   bd->StatusLength  = TxBufLength;   	// tx length    bd->Next          = 0; 		// pointer to next BD   bd->Prev          = prev; 		// pointer to previous BD	//    if(prev != (sHDLCBD *) NULL)    {     prev->Next = bd;		    }   if(i == NullPoint)     {     break;    }//    prev = bd; 				// reset previous BD     bd++;				// move to next 		   allocptr += TxBufLength; 		// allocation position    alloccnt -= TxBufLength;		// remain bytes in alloc buffer  }// if(NullPoint == HDLC_MAX_TX_DES)  {// circular BD list /////////////////////////////////////////////////////////////   bd--;			// Last BD 		   bd->Next = start;		// pointer to start descriptor    start->Prev = bd; 		  }}////////////////////////////////////////////////////////////////////////////////// Rx Buffe Descriptors Init ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void RxBD_init(int cn) { sHDLCBD * bd;			// current BD  sHDLCBD * prev;		// previous BD	 sHDLCBD * start;		// start buffer descriptor U32 allocptr;			// allocation position  U32 alloccnt;			// remain bytes in allocation buffer  U32 i; HDMARXPTR(cn) =		// current Rx BD pointer gHDLCRxStart[cn] = 		// start BD pointer   gHDLCRxEnd[cn] =  		// end BD pointer   (U32) sHDLCRxBD[cn] | 	        NonCache;#ifndef USER_AREA gHDLCRxCount[cn] = 0;		// Rx BD count #endif 								// USER_AREA bd    = (sHDLCBD *)gHDLCRxStart[cn]; start =  bd; prev  = (sHDLCBD *)NULL ;  allocptr = (U32) HDLCRxAllocBuf[cn] | NonCache;   // start allocation position  alloccnt = HDLC_RX_ALLOC_BUF_SIZE * sizeof(U32);  // bytes in alloc buffer  for(i = 0; i < HDLC_MAX_RX_DES; ++i)  {   if(HDLC_RX_BUF_LENGTH > alloccnt)    {// out off alloc buffer ////////////////////////////////////////////////////////      break;    }// set fields off current buffer descriptor ////////////////////////////////////       bd->BufferDataPtr = 			// buffer data pointer     allocptr   | 			// current allocation position     HDLCRxBD_DMA;			// owner HDMA//    bd->Reserved      = 0x0;      bd->StatusLength  = 0x0;   		// status & length    bd->Next          = NULL;  		// next BD    bd->Prev          = prev;  		// previous BD   if(prev != (sHDLCBD *) NULL)    {     prev->Next = bd;		    }       prev = bd;				// reset previous BD    bd++;				// move to next buffer descriptor // 		   allocptr += HDLC_RX_BUF_LENGTH;	// next alloc address    alloccnt -= HDLC_RX_BUF_LENGTH;	// remain bytes in alloc buffer   }// bd--;					// Last BD  bd->Next = start;			// Assign last buffer descriptor start->Prev = bd; 			// Assign first buffer descriptor} ////////////////////////////////////////////////////////////////////////////////// This function initiailze the HDLC Block /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void HDLC_Init(void){ U8  cn;				// channel num// clear HDLC Statistics /////////////////////////////////////////////////////// HdlcClrErrReport(); Disable_Int(nGLOBAL_INT);		// global disable int	// Interrupt Vector Setup ////////////////////////////////////////////////////// SysSetInterrupt(nHDLCTxA_INT, HDLCTxA_isr);	// HDLC A Tx ISR SysSetInterrupt(nHDLCRxA_INT, HDLCRxA_isr);	// HDLC A Rx ISR SysSetInterrupt(nHDLCTxB_INT, HDLCTxB_isr);	// HDLC B Tx ISR SysSetInterrupt(nHDLCRxB_INT, HDLCRxB_isr);	// HDLC B Rx ISR// Enable Interrupts /////////////////////////////////////////////////////////// Enable_Int(nHDLCTxA_INT);		// enable HDLC A Tx Interrupt  Enable_Int(nHDLCRxA_INT);		// enable HDLC A Rx Interrupt  Enable_Int(nHDLCTxB_INT);		// enable HDLC B Tx Interrupt Enable_Int(nHDLCRxB_INT);		// enable HDLC B Rx Interrupt  for(cn = 0; cn <= 1; ++cn)  {//Reset All HDLC block /////////////////////////////////////////////////////////   HCON(cn) |=     HCON_TxRS |				// Transmit Reset 	    HCON_RxRS |				// Receive Reset     HCON_DTxRS|				// DMA Tx Reset    HCON_DRxRS; 			// DMA Rx Reset// Internal Register Setting for Tx/Rx operation ///////////////////////////////   HMODE(cn) = gHMODE;			// HDLC mode register    HCON(cn)  = gHCON;			// HDLC control register    if(cn == 0) { HINTENA = gHINTENA; }  // HDLC int enable register   else        { HINTENB = gHINTENB; } // Set Baud Rate Generator Counters ////////////////////////////////////////////   HBRGTC(cn) = GetBaudRate(gHdlcBaudRate);	// Set HDLC Channel Address Registers & Address Mask Register //////////////////   HSAR0(cn) = 0x12345678;		//    HSAR1(cn) = 0xabcdef01;		//    HSAR2(cn) = 0xffffffff;		//    HSAR3(cn) = 0xaaaaaaaa;		//    HMASK(cn) = 0x00000000;		//    HMFLR(cn) = HDLC_MAX_FRAME_LENGTH;	// maximum frame length register    HRBSR(cn) = HDLC_RX_BUF_LENGTH;	// // Initialize Buffer Descriptor ////////////////////////////////////////////////   TxBD_init(cn,0);			// Init Tx Buffer Descriptots	   RxBD_init(cn);			// Init Rx Buffer Descriptots	#ifdef USER_AREA   HDLCRxUserRead [cn] =    HDLCRxUserWrite[cn] = (U32 *) (((U32) HDLCRxUserArea[cn]) | NonCache);   HDLCRxUserFirst[cn] = (U32 *) (-1);   HDLCRxUserCount[cn] = 0;#endif 								// USER_AREA   HCON(cn) |= (HCON_DRxEN|HCON_RxEN);	// HDLCA DMA Rx enable & Rx Enable   }// Initialize Global Variables gHDLCRxDone = 0;			// no Rx interrupts Enable_Int(nGLOBAL_INT); 		// enable global interrupt}////////////////////////////////////////////////////////////////////////////////// Send Data ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// cn   = channel number // data = data buffer // size = data lengthint HDLCSend(int cn, U8 *data, int size){ sHDLCBD * bd;				// current Tx BD  U32 * dst;				// destination buffer pointer  U32 * src;				// source pointer int len;				// length int cnt;				// BD count  if(cn < 0 || cn > 1 || data == 0 || size < 6)  {					// invalid channel number, data buffer   return(0);				// or data length  }  bd = (sHDLCBD *) gHDLCTxEnd[cn];	// End Tx BD pointer  len = size;				// sizeof sended data  while(len > 0)  {   if(bd == 0)    {					// Null terminating List       return(0);				// not sufficient space to send data    }    if(bd->BufferDataPtr & HDLCTxBD_DMA)    {					// owner DMA     return(0);				// not sufficient BDs to send data     }   bd = bd->Next; 			// move to next BD    len -= HDLC_TX_BUF_LENGTH;		// remain data bytes  }// enough space in buffers ///////////////////////////////////////////////////// cnt = 0;				 bd = (sHDLCBD *) gHDLCTxEnd[cn];	// restore bd src = (U32 *) data;			// source address while(size > 0)  {   if(bd == 0)    {					// null terminating list     return(0);				//     }    if((bd->BufferDataPtr & HDLCTxBD_DMA))    {					//      return(0);    }   if(size <= HDLC_TX_BUF_LENGTH)    {// Last Buffer Descriptor //////////////////////////////////////////////////////     bd->Reserved = #ifdef LITTLE      HDLCTxBD_Little  |		// Little-Endian #endif      HDLCTxBD_WA0     |		// No invalid bytes      HDLCTxBD_Last;			// Last buffer      bd->StatusLength = size;		// data length 	    }    else     {// not last BD /////////////////////////////////////////////////////////////////     bd->Reserved = #ifdef LITTLE      HDLCTxBD_Little  |		// Little-Endian #endif      HDLCTxBD_WA0;			// No invalid bytes      bd->StatusLength = HDLC_TX_BUF_LENGTH;    }// copy sended data to destination buffer //////////////////////////////////////   len = ((bd->StatusLength+3)>>2);	// length, words    dst = (U32 *) bd->BufferDataPtr;	// destination pointer   while(len-- > 0)    {					// word copy      *dst++ = *src++;    }    cnt++; 				// used BD count 			   size -= HDLC_TX_BUF_LENGTH;		// remain send data   bd->BufferDataPtr |= HDLCTxBD_DMA;	// owner DMA    bd = bd->Next;			// move to next BD 	  } Disable_Int(nGLOBAL_INT); gHDLCTxCount[cn] += cnt;		// Tx BD count

⌨️ 快捷键说明

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