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

📄 z85230rhdlc.c

📁 Curtiss-Wright Controls Embedded Computing公司的cw183板bsp源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
           * Restart DMA with the next avail. buffer           */          rxBuf = &(channel->rxFrameBuf);          frame = &(rxBuf->frames[ rxBuf->write ]);           /* restart DMA */          z85230DmaStart( SCC_DMA_CHAN_RX,                          channel->hw.rxfpga,                          frame->buf,                          frame->maxSize );		  /*		   * Obtain actual frame size received from the FPGA register:		   */		  frame_size =	(cha)?sysInWordNoSwap ((UINT32)FPGA_SCC_CHB_CNTR)							 :sysInWordNoSwap ((UINT32)FPGA_SCC_CHA_CNTR);		  --frame_size;		  frame0->size = (--frame_size);		  /*logMsg(">>>> FR %x NewFR %x SZ %d\n",(int)frame0,(int)frame ,frame_size,0,0,0);*/          /* z85230DmaSetFrameSize(  rxBuf0 , frame_size-2 );  */          intUnlock( old_level );	}      else	{/*      * Disabling Rx (RxEnable interrupt) has unfortunate side effect	  *  of disabling Tx (TxEnable interrupt) as well. Consequently Rx	  *  will always be enabled during half-duplex mode.	  */        rxBuf = &(channel->rxFrameBuf);        frame = &(rxBuf->frames[ rxBuf->write ]);	/* received a frame that we transmitted because we are in	 * half duplex mode, or a frame with a bad CRC, or	 * a frame too short -> discard it	 */		frame->read = frame->size = 0;        old_level = intLock();        /* restart DMA */        /* z85230DmaAbort( SCC_DMA_CHAN_RX ); */  	    sysOutLong( (UINT32)GT64260_DMACC( SCC_DMA_CHAN_RX ), 0x200 );         z85230DmaStart( SCC_DMA_CHAN_RX,                        channel->hw.rxfpga,                        frame->buf,                        frame->maxSize );        intUnlock( old_level );	}      if ( channel->hw.txDone && channel->hw.halfDuplex )	{	/* finished transmitting - turn off transmitter          * Lets assume that if no cycles have been designated,         * then we want the fastest means possible to turn of         * The Tx Clock         */        if( channel->hw.clockDelay > 0 )          {          z85230ClkStart( channel->channel, channel->hw.clockDelay );          }        else          {          z85230HwDisableTx( channel );          channel->hw.txing = 0 ;          }	}		#endif /* VME_181 */    } /* end of z85230RHDLCfpgaInt *//*************************************************************************** * z85230RHDLCTxDmaInt - interrupt callback * * Invoked through the FPGA request upon * end-of-dma transfer to the Zilog chip. *  */void z85230RHDLCTxDmaInt( struct _Z85230_CHAN * channel )  {#ifndef VME_181  UINT32 txDesc;  Z8530_CHAN * hw = &(channel->hw);#endif     Z85230BUF_FRAMES * txBuf = &(channel->txFrameBuf); #ifndef VME_181      txDesc = (UINT32)(hw->txfpga) + (hw->txIndex * DRI_DESC_OFFSET);      if (sysInLong(txDesc + DRI_CMDSTAT_OFFSET) != DRI_COMPLETE)        return;      sysOutLong(txDesc + DRI_CMDSTAT_OFFSET, 0);      channel->hw.txIndex = (channel->hw.txIndex + 1) % Z85230_MAX_DESC;#endif  /* end of frame reached - allow underrun so that ESCC will close it   * properly   */  /* reset tx underrun/eom latch */	semGive( channel->writeSem );      /* start new frame */      txBuf->frames[ txBuf->read ].size = 0;      txBuf->frames[ txBuf->read ].read = 0;      txBuf->read = (txBuf->read + 1) % txBuf->size;      txBuf->frames[ txBuf->read ].read = 0;  /* In half duplex, indicate the transmit is complete */  if( channel->hw.halfDuplex == TRUE )    channel->hw.txDone = TRUE ;  else    channel->hw.txing = 0;#ifdef VME_181	/*	 *	Sync I/O operation	EIEIO_SYNC;	 */	sysOutWordNoSwap ( (UINT32)FPGA_SCC_CHA_CNTX,0);#endif /* VME_181 */  }/*************************************************************************** * z85230RHDLCOpen - open channel in RHDLC mode * * RETURNS * Z85230_OK: success * anything else: fail */int z85230RHDLCOpen( struct _Z85230_CHAN * channel )  {  Z8530_CHAN *             hw = &(channel->hw);  volatile unsigned char * cr = channel->hw.cr;  unsigned char            rr;  int                      res = FALSE;  int                      oldLevel;  int                      i;  /* initialize variables */  rhdlc[ channel->channel ].rxAddr = 0xff;  rhdlc[ channel->channel ].abort = FALSE;  rhdlc[ channel->channel ].rxStatus =    malloc( Z85230RHDLC_DEFAULT_RX_BUFFERFRAMES * sizeof( unsigned char ) );   if ( rhdlc[ channel->channel ].rxStatus == NULL )    {    errno = Z85230_ERR_OUT_OF_MEM ;    return ERROR;    }   for ( i = 0; i < Z85230RHDLC_DEFAULT_RX_BUFFERFRAMES; i++ )    {    rhdlc[ channel->channel ].rxStatus[ i ] = 0;    }  /* allocate buffers */  res = z85230BufCreateFrames( &(channel->txFrameBuf), NULL, 				Z85230RHDLC_DEFAULT_BUFFERSIZE,				Z85230RHDLC_DEFAULT_TX_BUFFERFRAMES );  if ( res != Z85230_OK )    {    free( rhdlc[ channel->channel ].rxStatus );    return Z85230_ERR_OUT_OF_MEM;    }  res = z85230BufCreateFrames( &(channel->rxFrameBuf), NULL, 				Z85230RHDLC_DEFAULT_BUFFERSIZE,				Z85230RHDLC_DEFAULT_RX_BUFFERFRAMES );  if ( res != Z85230_OK )    {    /* out of memory - clean up */    free( rhdlc[ channel->channel ].rxStatus );    z85230BufDeleteFrames( &(channel->txFrameBuf) );    errno = Z85230_ERR_OUT_OF_MEM ;    return ERROR;    }  oldLevel = intLock();  /* reset the chip */  REG_8530_READ( cr, &rr );    /* write reg 9 - master interrupt control and reset */  REG_8530_WRITE(cr, SCC_WR0_SEL_WR9);    if ( channel->channel == Z85230_CHANNEL_A )    {    REG_8530_WRITE( cr, SCC_WR9_CH_A_RST );      /* reset channel A */    }  else    {    /* channel B */    REG_8530_WRITE( cr, SCC_WR9_CH_B_RST );      /* reset channel B */    }  /* Delay for about 1 uSec (typically) before further chip accesses */  Z8530_RESET_DELAY;  /* reset the chip again */  REG_8530_READ( cr, &rr );  /* write reg 4 - misc parms & modes */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR4 );  REG_8530_WRITE( cr, SCC_WR4_SYNC_EN | SCC_WR4_SDLC | SCC_WR4_1_CLOCK );    /* write reg 10 - misc tx/rx control */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR10 );  /* clear sync, loop, poll */  REG_8530_WRITE( cr, SCC_WR10_CRC_PRESET /* | SCC_WR10_MARK_IDLE */ );    /* write reg 6 - secondary address */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR6 );  REG_8530_WRITE( cr, 0 );  /* write reg 7 - sdlc flag */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR7 );  REG_8530_WRITE( cr, SCC_WR7_SDLC_FLAG );    /* write reg 2 - interrupt vector */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR2 );  REG_8530_WRITE( cr, hw->intVec );  /* write reg 11 - clock mode */  hw->writeReg11 = SCC_WR11_RX_RTXC | SCC_WR11_TX_BR_GEN |     SCC_WR11_TRXC_OI | SCC_WR11_OUT_TX_CLK;  REG_8530_WRITE( cr, SCC_WR0_SEL_WR11 );  REG_8530_WRITE( cr, hw->writeReg11 );  /* write reg 14 - misc control bits */  hw->writeReg14 = SCC_WR14_BR_EN | SCC_WR14_BR_SRC | SCC_WR14_SRC_BR;  REG_8530_WRITE( cr, SCC_WR0_SEL_WR14 );  REG_8530_WRITE( cr, hw->writeReg14 );  /* write reg 15 - disable external/status interrupts */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR15 );  REG_8530_WRITE( cr, SCC_WR15_SDLC_FIFO_EN | SCC_WR15_SYNC_IE );  /* write reg 1 - disable interrupts and xfer mode */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR1 );  REG_8530_WRITE( cr, 0 );  /* end initialization as per ZILOG application note */  /*   * write reg 7` - SDLC options   */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR15 );  REG_8530_READ( cr, &rr );  REG_8530_WRITE( cr, SCC_WR0_SEL_WR15 );  REG_8530_WRITE( cr, rr | SCC_WR15_WR7P_EN ); /* D0=1 points to WR7' */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR7 );  REG_8530_WRITE( cr, SCC_WR7P_EXT_READ_ENB  | 		 /* SCC_WR7P_TXD_HIGH      | */		 /* SCC_WR7P_AUTO_RTS      | */		  SCC_WR7P_TX_FIFO_INT_LVL |		  SCC_WR7P_AUTO_EOM_RST  |		  SCC_WR7P_AUTO_TX_FLAG );  /* reset external interrupts and errors */  REG_8530_WRITE( cr, SCC_WR0_RST_INT );  REG_8530_WRITE( cr, SCC_WR0_ERR_RST );  /* RHDLC address */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR6 );  REG_8530_WRITE( cr, rhdlc[ channel->channel ].rxAddr );  /* write reg 3 - receive params */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR3 );  REG_8530_WRITE( cr, SCC_WR3_RX_8_BITS | SCC_WR3_ENTER_HUNT | 		  SCC_WR3_RX_CRC_EN | SCC_WR3_RX_EN );    /* write reg 5 - tx params */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 );  REG_8530_WRITE( cr, SCC_WR5_TX_8_BITS | SCC_WR5_DTR |		  SCC_WR5_TX_CRC_EN | SCC_WR5_TX_EN | SCC_WR5_SDLC_CRC );		  /*SCC_WR5_TX_CRC_EN | SCC_WR5_TX_EN | SCC_WR5_CRC16 ); */  /* write reg 9 - enable master interrupt control */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR9 );  REG_8530_WRITE( cr, SCC_WR9_MIE | hw->intType );      /* reset Tx CRC generator and any pending ext/status interrupts */  REG_8530_WRITE( cr, SCC_WR0_RST_TX_CRC );  REG_8530_WRITE( cr, SCC_WR0_RST_INT );  REG_8530_WRITE( cr, SCC_WR0_RST_INT );  /* reset SCC register counter */  REG_8530_READ( cr, &rr );  intUnlock( oldLevel );  /* baudrate */  channel->hw.baudRate = z85230HwSetRate( channel, 					  Z85230RHDLC_DEFAULT_BAUDRATE );  /* options */  z85230RHDLCOptsSet( channel, CS8 | CREAD | CLOCAL );#ifdef VME_181  /* default mode is interrupt mode */  z85230RHDLCModeSet( channel, Z85230_MODE_INT );#else  /* default mode is DMA mode */  z85230RHDLCModeSet( channel, Z85230_MODE_DMA );#endif  channel->hw.halfDuplex = 0;  channel->hw.txing = 0;  channel->hw.txDone = 0;  channel->hw.crcCheck = 1;  channel->hw.clockDelay = 0 ;  return Z85230_OK;  }/*************************************************************************** * z85230RHDLCClose - close RHDLC channel * * RETURNS * Z85230_OK: success * anything else: fail */int z85230RHDLCClose( struct _Z85230_CHAN * channel )  {  volatile unsigned char * cr = channel->hw.cr;  int oldLevel;  /* release buffers */  z85230BufDeleteFrames( &(channel->rxFrameBuf) );  z85230BufDeleteFrames( &(channel->txFrameBuf) );   free( rhdlc[ channel->channel ].rxStatus );  oldLevel = intLock();  /* disable interrupts */  REG_8530_WRITE( cr, SCC_WR0_SEL_WR1 );  REG_8530_WRITE( cr, 0 );  #ifndef VME_181  z85230HwDisablePort(channel);#endif  intUnlock( oldLevel );  return Z85230_OK;  }/*************************************************************************** * z85230RHDLCRead - read from channel into buffer * * RETURNS * number of bytes read, or <0 on failure */int z85230RHDLCRead( struct _Z85230_CHAN * channel, 		      unsigned char * buf, int size )  {  /* TODO: check channel status */  Z85230BUF_FRAMES * rxBuf = &(channel->rxFrameBuf);  int bytesRead = 0;  int   i ;  STATUS result = OK ;  if ( channel->blocking )    {    /* decrement counting semaphore with timeout */    semTake( channel->readSem, channel->readTimeout );    }  else    {    /* decrement counting semaphore, returning instantly if empty */    semTake( channel->readSem, NO_WAIT );    }  for( i=0; i<1; i++)  {  if ( rxBuf->frames[ rxBuf->read ].size > size )    {    /* frame too large */    result = ERROR ;    break ;    }   if ( z85230BufNumFrames( rxBuf ) == 0 )    {    /* nothing to read */    result = ERROR ;    break ;    }  Z85230_ASSERT( rxBuf->frames[ rxBuf->read ].size >= 2 );  if(  rxBuf->frames[ rxBuf->read ].size < 2 )    DRV_LOG(DRV_DEBUG_RX,"RHDLCRead: Size 0\n",0,0,0,0,0,0);  if ( rhdlc[ channel->channel ].rxStatus[ rxBuf->read ] != 0 )    {    result = ERROR ;    break ;    }  } if( result == ERROR ) {    /* a problem occured - report it */    channel->readError =       rhdlc[ channel->channel ].rxStatus[ rxBuf->read ];    rhdlc[ channel->channel ].rxStatus[ rxBuf->read ] = 0;    return result ;  }  /* address */  bytesRead += z85230BufReadFrameByte( rxBuf, &(buf[ 0 ]) );  /* command */  bytesRead += z85230BufReadFrameByte( rxBuf, &(buf[ 1 ]) );  switch ( channel->hw.options & CSIZE )    {    case CS5:      bytesRead += z85230BufReadFrame( rxBuf, &(buf[ 2 ]), size - 2, 5 );      break;    case CS6:      bytesRead += z85230BufReadFrame( rxBuf, &(buf[ 2 ]), size - 2, 6 );      break;    case CS7:      bytesRead += z85230BufReadFrame( rxBuf, &(buf[ 2 ]), size - 2, 7 );      break;    default:      /* CS8 */      bytesRead += z85230BufReadFrame( rxBuf, &(buf[ 2 ]), size - 2, 8 );      break;    }  return bytesRead;

⌨️ 快捷键说明

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