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

📄 hdlc100init.c

📁 本source code 為s3c4510的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
 Enable_Int(nGLOBAL_INT); gHDLCTxEnd[cn] = (U32) bd;		// reset end pointer // set Tx enable, DMA Tx enable bits /////////////////////////////////////////// HCON  (cn) |= HCON_TxEN | HCON_DTxEN;  // Tx enable & DMA Tx enable HINTEN(cn) |= HINTEN_DTxNOIE;		// enable not owner int 	 return(1);}////////////////////////////////////////////////////////////////////////////////// HDLC Channel A Tx ISR ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef HDLC_TX_ISR_DEBUG#define HDLCTx_isr_debug(ch) put_byte(ch)#else#define HDLCTx_isr_debug(ch)#endif					// HDLC_TX_ISR_DEBUGvoid HDLCTx_isr(int cn){ U32 stat;				// HDLC status register  U32 clear;				// HDLC status register clear bits stat  = HSTAT(cn);			// read status register  clear = 0;				// no cleared registers #ifdef HDLC_TX_ISR_DEBUG HDLCTxStatus[cn].TxISR++;#endif 					// HDLC_TX_ISR_DEBUG HDLCTx_isr_debug('T');			// T = Tx ISR  if(stat & HSTAT_DTxFD)  {////////////////////////////////////////////////////////////////////////////////// Tx Frame Done ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   sHDLCBD * bd;			//    U32 * data;				//    int i;   HDLCTx_isr_debug('D');// HDLC DMA Frame Done /////////////////////////////////////////////////////////   HDLCTxStatus[cn].DMATxFD++;		// Tx Frame Done    clear |= HSTAT_DTxFD; 		// Clear DMA Tx Done Bit// Check Tx Ownership in all Tx BD /////////////////////////////////////////////   bd = (sHDLCBD *) gHDLCTxStart[cn];	// start Tx buffer descriptor    for(i = 0; i < HDLC_MAX_TX_DES; ++i)     {      data = & bd->BufferDataPtr;	// pointer to buffer data & owner bit      if((*data & HDLCTxBD_DMA))      { 				// owner DMA not CPU       break;				// break      }      if((U32) bd == HDMATXPTR(cn))      {       break;      }      if(bd->Next == 0)      {       Print("\nHDLCTxA_isr null next pointer");              break;				// circular buffers      }      data = & bd->Reserved;		// pointer to reserved field     if((*data & HDLCTxBD_Last))      {// last buffer in frame => check Tx Complete bit ///////////////////////////////       data = & bd->StatusLength;	       if((*data & HDLCTxBD_TxComp) == 0)        {          HDLCTxStatus[cn].TxLBDNC++;	        }       }       bd->Reserved     = 0;     bd->StatusLength = 0;     bd = bd->Next;			// move to next BD      gHDLCTxCount[cn]--;		// Tx Queue descriptors     gHDLCTxStart[cn] = (U32) bd;	// reset current Tx BD    }  }//////////////////////////////////////////////////////////////////////////////// // Check and clear other Tx bits /////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////  if(stat & HSTAT_TxFC)	  {// [4] Tx frame complete (TxFC) ////////////////////////////////////////////////    HDLCTxStatus[cn].TxFC++;		// Tx Complete   clear |= HSTAT_TxFC;			// clear Tx Frame complete bit    HDLCTx_isr_debug('C');		//   } if(stat & HSTAT_TxFA)	  {// [5] Tx FIFO available  (TxFA) ///////////////////////////////////////////////    HDLCTxStatus[cn].TxFA++;		/* during the DMA operation this bit allvais zero */   HDLCTx_isr_debug('F');  } if(stat & HSTAT_TxSCTS)  {// [7] Tx stored clear-to-send (TxSCTS) ////////////////////////////////////////    HDLCTxStatus[cn].TxSCTS++;   clear |= HSTAT_TxSCTS; 		// clear stored clear-to-send   HDLCTx_isr_debug('S');//   if((stat & HSTAT_TxCTS))//    {//// nCTS low //////////////////////////////////////////////////////////////////////     if((HCON(cn) & HCON_DTxEN) == 0)//      {//       HDLCTx_isr_debug('E');//       HCON(cn) |= HCON_DTxEN;//      }//    }  //   else//    {//// nSTS high /////////////////////////////////////////////////////////////////////       HDLCTx_isr_debug('R');//    }   } if(stat & HSTAT_TxU)  {// [8] Tx underrun (TxU) ///////////////////////////////////////////////////////    HDLCTxStatus[cn].TxU++;	        // Tx underrun statistics	   clear |= HSTAT_TxU; 			// clear Tx Underrun bit 	   HDLCTx_isr_debug('U');  } if(stat & HSTAT_DTxABT)  {// DMA Tx abbort (due Tx underrun, CTS lost) ///////////////////////////////////     HDLCTxStatus[cn].DMATxABT++;		// DMA Tx Abort statistics   clear |= HSTAT_DTxABT; 		// clear DMA Tx Abort bit // DMA Transmit enable bit DTxEN (in HCON) cleared     HDLCTx_isr_debug('A');//   if((HCON(cn) & HCON_DTxEN) == 0)//    {//#ifdef HDLC_TX_ISR_DEBUG//       HDLCTx_isr_debug('a');//#endif	//     HCON(cn) |= HCON_DTxEN;//    }  } if(stat & HSTAT_DTxNL)  {// [28] DMA Tx null list interrupt /////////////////////////////////////////////     HDLCTxStatus[cn].DMATxNL++;		// DMA Tx Null List statistics   clear |= HSTAT_DTxNL; 		// clear DMA Tx Null List bit    HDLCTx_isr_debug('N');  } if(stat & HSTAT_DTxNO)  {// [29] DMA Tx not owner (DTxNO) ///////////////////////////////////////////////     HDLCTxStatus[cn].DMATxNO++;		// DMA Tx not owner statistics    clear |= HSTAT_DTxNO; 		// clear DMA Tx Not Owner bit // DMA Transmit enable bit DTxEN (in HCON) cleared     HDLCTx_isr_debug('O');   HINTEN(cn) &= ~HINTEN_DTxNOIE;  }// clear status bits ///////////////////////////////////////////////////////////    HSTAT(cn) = clear;			}////////////////////////////////////////////////////////////////////////////////// HDLC Channel A Tx ISR ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void HDLCTxA_isr(void){ HDLCTx_isr(0);}////////////////////////////////////////////////////////////////////////////////// HDLC Channel B Tx ISR ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////void HDLCTxB_isr(void){ HDLCTx_isr(1);}////////////////////////////////////////////////////////////////////////////////// clear Rx buffers ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int HDLCRx_reset(int cn){ sHDLCBD * bd;				// descriptor pointer  U32 intbit;				// HDLC channel Rx Int bit  int i;					// decriptor index if(cn < 0 || cn > 1)  {					// invalid channel    return(0);				// number   }  intbit = (cn ? nHDLCRxB_INT : nHDLCRxA_INT); Disable_Int(intbit);			// disable HDLC Rx Int Clear_PendingBit(intbit);		// clear HDLC Rx pending bit HCON(cn) &= ~(HCON_RxEN | HCON_DRxEN);	// disable Rx & DMA Rx  HCON(cn) |=  (HCON_RxRS | HCON_DRxRS);	// reset Rx & DMA Rx// #ifdef USER_AREA HDLCRxUserRead [cn] = 			// start position  HDLCRxUserWrite[cn] = 			// end position   (U32 *) ((U32) HDLCRxUserArea[cn] | NonCache); HDLCRxUserFirst[cn] = (U32 *) (-1);	// first buffer position  HDLCRxUserCount[cn] = 0;		// bytes count#endif 								// USER_AREA// #ifdef USER_AREA bd = (sHDLCBD *) gHDLCRxEnd[cn];	// moved by ISR #else  bd = (sHDLCBD *) gHDLCRxStart[cn];	// moved by Recv #endif 								// USER_AREA for(i = 0; i < HDLC_MAX_RX_DES; ++i)   {   if((bd->BufferDataPtr & HDLCTxBD_DMA) != 0)    {// descriptor owner DMA (not CPU) => break /////////////////////////////////////     break;    }      bd->BufferDataPtr |= HDLCTxBD_DMA;	// set DMA bit    bd->Reserved       = 0;		// clear reserved field   bd->StatusLength   = 0;		// clear status length field   if(bd->Next == 0)    {					// null terminating list     break;    }    bd = bd->Next;			// move to next descriptor  }//  HDMARXPTR(cn)   = (U32) bd; 		// set current BD register gHDLCRxStart[cn]= (U32) bd;		// set start Rx BD  gHDLCRxEnd[cn]  = (U32) bd;		// set end Rx BD #ifndef USER_AREA gHDLCRxCount[cn]= 0;			// Rx BD count #endif 							// not def USER_AREA HSAR0(cn)  = 0x12345678;		// addr 0 reg HSAR1(cn)  = 0xabcdef01;		// addr 1 reg HSAR2(cn)  = 0xffffffff;		// addr 2 reg HSAR3(cn)  = 0xaaaaaaaa;		// addr 3 reg HMASK(cn)  = 0x00000000;		// addr mask reg HMFLR(cn)  = HDLC_MAX_FRAME_LENGTH;	// maximum frame length register  HRBSR(cn)  = HDLC_RX_BUF_LENGTH;	// recv buffer size  HCON(cn)   = gHCON | HCON_DRxEN | HCON_RxEN;	// restore control register 	 HINTEN(cn) = (cn ? gHINTENB : gHINTENA); 	// restore int reg Enable_Int(intbit);			// enable rx int return(1);}////////////////////////////////////////////////////////////////////////////////// return count not transmitted Tx BD //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int HDLCTxBD_count(int cn){ if(cn < 0 || cn > 1)  {					// invalid channel    return(0);				// number   } return(gHDLCTxCount[cn]);}////////////////////////////////////////////////////////////////////////////////// clear Tx buffer descriptosr /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////int HDLCTx_reset(int cn){ sHDLCBD * bd;				// descriptor pointer  U32 intbit; int i;					// descriptor index if(cn < 0 || cn > 1)  {					// invalid channel number    return(0);				//   } intbit = (cn ? nHDLCTxB_INT : nHDLCTxA_INT); Disable_Int(intbit); Clear_PendingBit(intbit); bd = (sHDLCBD *) HDMATXPTR(cn);		// current Tx bd HCON(cn) &= ~(HCON_TxEN | HCON_DTxEN);	// disable Tx & DMA Tx HCON(cn) |=  (HCON_TxRS | HCON_DTxRS);	// reset Tx & DMA Tx // Check Tx Ownership in all Tx BD ///////////////////////////////////////////// for(i = 0; i < HDLC_MAX_TX_DES; ++i)   {    if((bd->BufferDataPtr & HDLCTxBD_DMA) == 0) 		    { 				// owner CPU => break //////////////////////////////////////////////////////////      break;			    }    bd->BufferDataPtr &= ~HDLCTxBD_DMA;	// Owner CPU   bd->Reserved     = 0;		// clear reserved field   bd->StatusLength = 0;		// clear status length field   if(bd->Next == 0)    {     Print("\nHDLC Tx BD null next pointer");            break;				// circular buffers    }    bd = bd->Next;			// move to next BD   } gHDLCTxStart[cn] = (U32) bd; 		// set start Tx BD gHDLCTxEnd[cn]   = (U32) bd; 		// set end   Tx BD gHDLCTxCount[cn] = 0;			// Tx BD count  HDMATXPTR(cn)    = (U32) bd;		// set current Tx BD pointer  HCON(cn)         = gHCON;		// restore HCON HINTEN(cn) = (cn ? gHINTENB:gHINTENA); // restore HINTEN Enable_Int(intbit); return(1);}////////////////////////////////////////////////////////////////////////////////// save Rx buffer //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#ifdef USER_AREAstatic U32 GetRxBDData(int cn, U32 buf, U32 status, int len){ U32 * data;				//  U32 * ptr;				// write pointer 	 U32 * start; 				// queue start pointer   U32 * end; 				// queue end pointer  int dcnt = 0;				// HDLCRxUserCount increment  int wlen;   wlen = (len + 3) / 4; if(wlen + 1 + HDLCRxUserCount[cn] > HDLC_USER_AREA_SIZE )  {   Print("\nGetRxBDData buffer full %d %d", len, HDLCRxUserCount[cn]);   return(0);  } // // start = (U32 *) HDLCRxUserArea [cn]  /*| NonCache*/;	// start pointer // end   = start + HDLC_USER_AREA_SIZE; 			// end pointer // ptr   = (U32 *) HDLCRxUserWrite[cn]  /*| NonCache*/;	// write pointer  start = (U32 *) ((U32)HDLCRxUserArea [cn] | NonCache); ptr   = (U32 *) ((U32)HDLCRxUserWrite[cn] | NonCache); end   = start + HDLC_USER_AREA_SIZE; 			 if(ptr >= end) { ptr = start; }// if(status & HDLCRxBD_F) 		// [22] First In Frame (F)  {   U32 * fptr;////////////////////////////////////////////////////////////////////////////////// first buffer in frame => write to queue preample, status, length ////////////////////////////////////////////////////////////////////////////////////////////   fptr = (U32 *) ((U32) HDLCRxUserFirst[cn] | NonCache);   if(fptr != (U32 *) -1)    {     if(fptr >= end) { fptr = start; }// rotate to queue start     *fptr |= ((U32)HDLCRxBD_L << 16);    }     if(ptr >= end) { ptr = start; }	// rotate to begin queue   if((status & HDLCRxBD_L) == 0) 	    {					// last bit not set => save first pointer //////////////////////////////////////     HDLCRxUserFirst[cn] = ptr;		// set first buffer pointer      }   else    {// first and last frame buffer /////////////////////////////////////////////////      HDLCRxUserFirst[cn] = (U32 *) -1;	// clear first pointer     }        *ptr = ((status & 0xFFFF) << 16) | (len & 0xFFFF);   if(++ptr >= end) { ptr = start; }	// rotate to queue start   dcnt += 1;				// writed words count  } else  {////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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