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

📄 hdlc100init.c

📁 本source code 為s3c4510的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
// not first buffer in frame ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////   U32 * fptr;     			// pointer to first buffer   int flen;      			//    fptr = (U32 *) ((U32) HDLCRxUserFirst[cn] | NonCache);   if(fptr == ((U32 *) -1))    {     Print("\nHDLC Rx Internal error");     return(0);    }   if(fptr >= end) { fptr = start; }	//    rotate to queue begin    *fptr |= ((status & 0xFFFF) << 16);    flen = *fptr & 0xFFFF;   *fptr = (*fptr & 0xFFFF0000) | (len & 0xFFFF);    len -= flen;   if((status & HDLCRxBD_L) != 0)    {// last buffer => clear pointer to first ///////////////////////////////////////      HDLCRxUserFirst[cn] = (U32 *) -1;	// clear first pointer     }  }// source address ////////////////////////////////////////////////////////////// data = ((U32 *) buf); wlen = (len + 3) / 4; if(ptr >= end) { ptr = start; }	// rotate to queue start while(wlen-- > 0)  {   *ptr++ = *data++;			//    if(ptr >= end) { ptr = start; }	// rotate to queue start   dcnt += 1;				// bytes is writen  } HDLCRxUserCount[cn]+= dcnt;		// bytes in queue HDLCRxUserWrite[cn] = ptr;		// reset write position  return(1);}#endif 								// USER_AREA#ifdef USER_AREAint HDLCRecv(int cn, U32 * status, U8 * buf, int * size){ U32 intbit; U32 * data; U32 * start; 				// queue start address U32 * end; 				// queue end address  U32 * ptr;				// read pointer  int len;				// data length, bytes  int wlen;				//  int wsize;				//  int dcnt = 0; Disable_Int(nGLOBAL_INT); if(HDLCRxUserCount[cn] < 1)  {   Enable_Int(nGLOBAL_INT);   return(0);  }  start = (U32 *) ((U32) HDLCRxUserArea[cn] | NonCache);	// queue start pointer  ptr   = (U32 *) ((U32) HDLCRxUserRead[cn] | NonCache);	// queue read pointer  end   = start + HDLC_USER_AREA_SIZE; 			// queue end pointer  if(ptr >= end) { ptr = start; } *status = (*ptr >> 16) & 0xFFFF;	// read status  if((*status & HDLCRxBD_L) == 0)  {// last bit not set => wait Rx last buffer /////////////////////////////////////   Enable_Int(nGLOBAL_INT);   return(0);  } len = *ptr & 0xFFFF;			// read length  if(++ptr >= end) { ptr = start; }	// rotate read pointer to queue start// read words from queue /////////////////////////////////////////////////////// dcnt = 1;				// readed header data = (U32 *) buf;			  wlen  = len >> 2;			// frame length, full words wsize = *size >> 2;			// buffer size, full words while(wlen-- > 0)  {   if(wsize-- > 0)    {     *data++ = *ptr;			//     }//    dcnt++;				// readed words from queue   ptr++;				// move pointer    if(ptr >= end) { ptr = start; }	// rotate read pointer to queue start  }  if((len & 0x3) != 0)   {   wlen = len & 0xFFFFFFFC;  		// dst pos    wsize = *ptr;			// read word from queue    if(++ptr >= end) { ptr = start; }	// rotate read pointer to start   dcnt++;				// readed words  //    while(wlen < len)    {     if(wlen >= *size)      {       break;      }     *(buf + wlen++) = (U8) wsize & 0xFF;      wsize >>= 8;    }  } *size = len;				// frame length HDLCRxUserCount[cn]-= dcnt;		// words in queue HDLCRxUserRead[cn]  = ptr;		// reset read pointer  Enable_Int(nGLOBAL_INT);	 return(1);}#elseint HDLCRecv(int cn, U32 * status, U8 * buf, int * size){ sHDLCBD * bd;				// current Rx BD  U32 stat;				// BD status  int cnt;				// BD count  int num;				// BD number int flen;				// total length  int len;				// length  U32 * dst;				// destination address  U32 * src;				// source address  int wlen;				// length, words  int pos;				// destination position if(cn < 0 || cn > 1 || status == 0 || buf == 0 || size == 0)  {					// invalid channel number, data buffer   return(-1);				// or data length ...  } cnt = gHDLCRxCount[cn];		// Rx BD count  if(cnt == 0)  {					// no Rx data   return(0);  }  else if(cnt < 0)  {   Print("\nHDLCRecv internal error. Rx BD count < 0");   return(-1);  }   bd = (sHDLCBD *) gHDLCRxStart[cn]; for(num = 0; num < cnt; ++num)  {   if(bd == 0)    {					// Null terminating List       Print("\nHDLCRecv error, BD == 0");     return(-1);	    }    if((bd->BufferDataPtr & HDLCRxBD_DMA))    {					// owner DMA     return(0);				//    }// read status & check last BD in frame bit   stat = (bd->StatusLength >> 16) & 0xffff;	   if((stat & HDLCRxBD_L) != 0 || (num > 0 && (stat & HDLCRxBD_F)))    {					// last BD in frame, or ommit last BD     break;				//     }     bd = bd->Next;  } if(num >= cnt)  {					// no last BD in frame    return(0);   }//  bd = (sHDLCBD *) gHDLCRxStart[cn];	// start buffer descriptor *status = 0;				// frame status  flen = 0;				// frame length  pos = 0;				// destination buffer position  for(num = 0; num < cnt; ++num)  {   int tmp;   if(bd->BufferDataPtr & HDLCRxBD_DMA)    {					// owner DMA     Print("\nHDLCRecv internal error. Unexpected DMA bit.");     return(0);    }// read BD status, data length   stat = (bd->StatusLength >> 16) &0xffff;	   len  = (bd->StatusLength & 0xFFFF);		   if(num > 0 && (stat & HDLCRxBD_F))    {					// find first BD, ommit last BD     break;    }     *status |= stat;			// frame status//    tmp = flen;   flen = len;   			// total length    len -= tmp;   if(len < 0)    {		     Print("\nHDLCRecv internal error. Length < 0");     return(-1);	    } //   wlen = (len >> 2);   dst = (U32 *)(buf + pos);   src = (U32 *) bd->BufferDataPtr;   while(wlen-- > 0)    {     pos += 4;      if(pos <= *size)      {       *dst++ = *src++;      }    }   if((len & 0x3) != 0)     {     U8 * bsrc;     wlen = len & 0xFFFFFFFC;      bsrc = (U8 *) bd->BufferDataPtr + wlen;     while(wlen++ < len)      {       if(pos < *size)        {        *(buf + pos) =  *bsrc++;        }       pos++;      }    }   bd->Reserved       = 0;		// clear BD reserved field    bd->StatusLength   = 0;		// clear status & length field   bd->BufferDataPtr |= HDLCRxBD_DMA;	// owner DMA   bd = bd->Next;			// move to next descriptor    if((stat & HDLCRxBD_L))    {					// last BD in frame     break;    }    }// save frame length *size = flen; Disable_Int(nGLOBAL_INT);		// disable global int  gHDLCRxCount[cn]-= (num + 1);		// decrement Rx BD count 	 gHDLCRxStart[cn] = (U32) bd;		// move start BD // enable DMA Rx, may be cleared if ovner of current Rx decriptor is CPU  HCON(cn)  |= HCON_DRxEN;   		// enable DMA Rx  Enable_Int(nGLOBAL_INT);		// enable global int return(1);}#endif 						// USER_AREA#ifdef HDLC_RX_ISR_DEBUG#define HDLCRx_isr_debug(ch) put_byte(ch)#else#define HDLCRx_isr_debug(ch)#endif					// HDLC_RX_ISR_DEBUGvoid HDLCRx_isr(int cn){ U32 stat;				// HDLC channel status U32 clear;				// cleared bits stat = HSTAT(cn);			// read HDLC status register  clear = 0;				// start cleared bits	#ifdef HDLC_RX_ISR_DEBUG HDLCRxStatus[cn].RxISR++;#endif 					// HDLC_RX_ISR_DEBUG HDLCRx_isr_debug('R');  if(stat & HSTAT_DRxFD)  {////////////////////////////////////////////////////////////////////////////////// [24] DMA Rx frame done every received frame (DRxFD) /////////////////////////////////////////////////////////////////////////////////////////////////////////   sHDLCBD * bd;   U32 status;   U32 len;   int i;   HDLCRx_isr_debug('D');    clear |= HSTAT_DRxFD;		// clear DMA Rx frame done bit    HDLCRxStatus[cn].DRxFD++;		// DMA Rx frame done statistics	   bd = (sHDLCBD *) gHDLCRxEnd[cn];	// end buffer descriptor    for(i = 0; i < HDLC_MAX_RX_DES; ++i)     {     if((bd->BufferDataPtr & HDLCRxBD_DMA) != 0)      {// descriptor owner DMA (not CPU) => break /////////////////////////////////////       break;      }     if((U32)bd == HDMARXPTR(cn))      {					       break;      }      status = (bd->StatusLength >> 16) &0xffff;	// read status      len    =  bd->StatusLength & 0xffff;	// read length 		     if(       status &         (         HDLCRxBD_CD  |			// CD lost          HDLCRxBD_CRC |			// CRC error          HDLCRxBD_NO  |			// Non octet alignment          HDLCRxBD_OV  |			// Overun          HDLCRxBD_DTM |			// DPLL two miss occurs         HDLCRxBD_ABT |			// received frame abborted         HDLCRxBD_FLV 			// frame length violation         )      )      {// Rx frame error //////////////////////////////////////////////////////////////       if((status & HDLCRxBD_CRC) != 0)        {         HDLCRxStatus[cn].RxCRCE++;	// Rx CRC Error	        }       if((status & HDLCRxBD_NO) != 0)        {         HDLCRxStatus[cn].RxNO++;	// Rx Non Octet        }       if((status & HDLCRxBD_OV) != 0)        {         HDLCRxStatus[cn].RxOV++;	// Rx Overrun        }        if((status & HDLCRxBD_ABT) != 0)        {         HDLCRxStatus[cn].RxABT++;	// Rx Abort        }       if((status & HDLCRxBD_FLV) != 0)        {         HDLCRxStatus[cn].RxFV++;	// Rx Frame Valid        }       if((status & HDLCRxBD_DTM) != 0)        {         HDLCDPLLStatus[cn].DPLLTM++;        }       }  // save Rx buffer (not frame) ////////////////////////////////////////////////// #ifdef USER_AREA     GetRxBDData(cn, bd->BufferDataPtr, status, len); // clear BD fields and move to next BD /////////////////////////////////////////     bd->Reserved       = 0;		// clear BD reserved field      bd->StatusLength   = 0;		// clear status & length field     bd->BufferDataPtr |= HDLCRxBD_DMA;	// owner DMA#else     gHDLCRxCount[cn]++;#endif 								// USER_AREA     bd = bd->Next;			// to next BD     }   gHDLCRxEnd[cn] = (U32) bd;		// set end Rx BD    gHDLCRxDone = (0x1 << cn);		// set Rx done channel bit   }// [9] Rx FIFO available (RxFA) //////////////////////////////////////////////// if(stat & HSTAT_RxFA)  {   HDLCRxStatus[cn].RxFA++;		// Rx FIFO Avail   clear |= HSTAT_RxFA;			// clear Rx FIFO Available bit   HDLCRx_isr_debug('A');  }// [11] Rx flag detected (RxFD) //////////////////////////////////////////////// if(stat & HSTAT_RxFD)  {   U32 hinten;   HDLCRxStatus[cn].RxFD++;		// Rx Flag Detect statistics   clear |= HSTAT_RxFD;			// clear Rx Flag detect bit   hinten = HINTEN(cn);    if(hinten & HINTEN_RxFDIE)    {/* clear flag detect int enable set idle detect int enable */     HINTEN(cn) = ((hinten & 

⌨️ 快捷键说明

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