📄 z85230rhdlc.c
字号:
/* z85230RHDLC.c - Z85230 SCC Sync Serial Driver *//* Copyright 2000-2003 Dy 4 Systems, Inc. *//*modification history--------------------07jun05, dle - support 183 Serial IPM V211sep03, aak - support debug printouts add FIONREAD, support half-duplex mode fix PT#1654, PT#164614jan03, aak - fix PT#1358, auto CRC mode14feb01, srr - Added Z85230_MAX_SYNC_BAUDRATE to ioctl-SET_BAUDRATE see SRR+102may01, co - Fill in header Modify address recognition and half-duplex ioctls to keep track of address check setting and to keep address recognition off if already off when turning half-duplex ON (P/T 603, Task 2572)*//*DESCRIPTIONThis module contains the Raw HDLC implementation of the driver.The driver supports synchronous raw HDLC (High-Level Data Link Control)data transfer modes with full DMA support as well asconfiguration capabilities (e.g., character size) required for each mode. Theraw HDLC synchronous functionality was designed in accordance with theISO/IEC specifications.Note: In a half duplex configuration, the cabling between cards connectsthe Tx clocks and the Rx clocks together and it connects the transmit datalines and the receive data lines together. On a line, only one device may transmit at a time.In a half duplex configuration, the application must turn on the transmitteronly when it needs to transmit, and turn it off again when the transmission of the message is complete. The application must allow sufficient time fromtransferring the last character in the message to the communications controllerfor that character to be shifted out serially.The API consists of the following routines: z85230RHDLCOptsSet z85230RHDLCHup z85230RHDLCConnect z85230RHDLCTxStartup z85230RHDLCModeSet z85230RHDLCGotFrame z85230RHDLCExInt z85230RHDLCRxInt z85230RHDLCTxInt z85230RHDLCRxDmaInt z85230RHDLCRxDmaInt z85230RHDLCOpen z85230RHDLCClose z85230RHDLCRead z85230RHDLCWrite z85230RHDLCIoctl Dependencies on BSP/OS files: intLib.h sysLib.hDependencies on BSP driver files: timer driver */#include <intLib.h>#include <sysLib.h>#include <msgQLib.h>#include "h/drv/sio/z85230Drv.h"#ifdef VME_181#include "h/drv/sio/z85230Dma.h"#include "h/drv/pciBridge/gt64260_dy4.h"#endif#ifdef VME_183#include "cwv183.h"#endif/* the current frame has a bad crc, or previous dropped frames had bad crc */#define RHDLC_BADCRC (0x1)/* the current frame overflowed the buffer */#define RHDLC_BUFFER_OVERFLOW (0x2)/* frames were dropped after the current frame due to frame buffer overflow */#define RHDLC_FRAME_OVERFLOW (0x4)/* frames were aborted before the current frame */#define RHDLC_ABORTED (0x8) /* local structs */typedef struct _Z85230RHDLC { unsigned char rxAddr; unsigned char * rxStatus; int abort;} Z85230RHDLC;/* local variables */LOCAL Z85230RHDLC rhdlc[ Z85230_NUM_CHANNELS ];/* LOCAL MSG_Q_ID dmaMsgQid[Z85230_NUM_CHANNELS]= {NULL, NULL} ; *//* local functions */static STATUS z85230RHDLCTxStartup( Z85230_CHAN * channel );static STATUS z85230RHDLCModeSet( Z85230_CHAN * channel, int newMode );static STATUS z85230RHDLCConnect( Z85230_CHAN * channel );static STATUS z85230RHDLCHup( Z85230_CHAN * channel );static STATUS z85230RHDLCOptsSet( Z85230_CHAN * channel, unsigned int options );#undef DRV_DEBUG/* Driver debug control */#ifdef DRV_DEBUG#define DRV_DEBUG_OFF 0x0000#define DRV_DEBUG_RX 0x0001#define DRV_DEBUG_TX 0x0002#define DRV_DEBUG_IOCTL 0x0004#define DRV_DEBUG_INT 0x0008#define DRV_DEBUG_START 0x0010#define DRV_DEBUG_DMA 0x0020#define DRV_DEBUG_MEM 0x0040#define DRV_DEBUG_RX_ERR 0x0080#define DRV_DEBUG_TX_ERR 0x0100#define DRV_DEBUG_ALL 0xffff#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ { \ if (rhdlcDebug & FLG) \ if (_func_logMsg != NULL) \ _func_logMsg (X0, X1, X2, X3, X4, X5, X6); \}UINT rhdlcDebug = DRV_DEBUG_OFF; #else /* DRV_DEBUG */#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(FLG, X)#endif /* DRV_DEBUG *//*************************************************************************** * z85230RHDLCOptsSet - set the serial options * * Set the channel operating mode to that specified. The following * sioLib options are supported: CLOCAL, CREAD, CSIZE. * * PRE: * extended read must be set * * RETURNS: * Returns OK to indicate success, otherwise ERROR is returned */static STATUS z85230RHDLCOptsSet( Z85230_CHAN * channel, unsigned int options ) { if ( options & (PARENB | PARODD) ) { return ERROR; } channel->hw.options = options; /* we handle different bitsizes explicitly */ return z85230HwSetOpts( channel, (options & ~CSIZE) | CS8, TRUE ); }/*************************************************************************** * z85230RHDLCHup - hang up the modem control lines * * Resets the RTS and DTR signals. * * RETURNS: OK */static STATUS z85230RHDLCHup( Z85230_CHAN * channel ) { volatile char * cr = channel->hw.cr; /* SCC control reg adr */ int oldlevel; /* current interrupt level mask */ unsigned char wr5; oldlevel = intLock(); REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_READ( cr, &wr5 ); REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_WRITE( cr, wr5 & ~(SCC_WR5_DTR | SCC_WR5_RTS) ); intUnlock( oldlevel ); return OK; } /*************************************************************************** * z85230RHDLCConnect - Set the modem control lines * * Set the modem control line (DTR) TRUE if not already set. * It also clears the receiver, transmitter and enables the fifo. * * RETURNS: OK */static STATUS z85230RHDLCConnect( Z85230_CHAN * channel ) { volatile char * cr = channel->hw.cr; /* SCC control reg adr */ int oldlevel; /* current interrupt level mask */ unsigned char wr5; oldlevel = intLock(); /* get contents of Write Reg 5 */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_READ( cr, &wr5 ); if ( (wr5 & SCC_WR5_DTR) == 0 ) { /* set DTR TRUE */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_WRITE( cr, wr5 | SCC_WR5_DTR ); } intUnlock( oldlevel ); return OK; }/*************************************************************************** * z85230RHDLCTxStartup - start interrupt transmitter * * NOMANUAL aak updated */static STATUS z85230RHDLCTxStartup( Z85230_CHAN * channel ) { char outChar; int lvl; volatile unsigned char * cr = channel->hw.cr; unsigned char rr; /* TODO: handle end of frame */ if ( z85230BufReadFrameByte( &(channel->txFrameBuf), &outChar ) > 0 ) { lvl = intLock (); if ( channel->hw.halfDuplex ) { /* tx clock output */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR11 ); REG_8530_WRITE( cr, channel->hw.writeReg11 ); /* ensure clock is stable before sending */ Z8530_RESET_DELAY; /* enable tx */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_READ( cr, &rr ); REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_WRITE( cr, (rr | SCC_WR5_TX_EN) & ~SCC_WR5_RTS ); /* remember that we are transmitting */ channel->hw.txDone = 0; } channel->hw.txing = 1; intUnlock (lvl); if ( channel->hw.mode == Z85230_MODE_DMA ) { Z85230BUF_FRAMES * txBuf = &(channel->txFrameBuf); Z85230BUF_FRAME * frame = &(txBuf->frames[ txBuf->read ]); Z85230_ASSERT( channel->channel == Z85230_CHANNEL_A || channel->channel == Z85230_CHANNEL_B ); /* start new DMA transfer */#ifdef VME_181 Z85230_ASSERT( z85230DmaStart(SCC_DMA_CHAN_TX, frame->buf, channel->hw.txfpga, frame->size ) == Z85230_OK );#else z85230HwSendByDesc(channel, frame->buf, frame->size, 0xFF);#endif } else { /* write first character to start new transmission */ *channel->hw.dr = outChar; } } return OK; }/*************************************************************************** * z85230RHDLCModeSet - change transmit/receive mode * * REVISION * 05feb03 aak: disable Rx intrpt while in DMA mode * * NOMANUAL */LOCAL STATUS z85230RHDLCModeSet( Z85230_CHAN * channel, int newMode ) { int oldLevel; volatile unsigned char * cr = channel->hw.cr; unsigned char rr;#ifdef VME_181 int cha = channel->channel;#endif STATUS result=OK;#ifdef VME_181 /* * Disable system DMA interrupts */ gtDmaIntDisable(SCC_DMA_CHAN_RX); gtDmaIntDisable(SCC_DMA_CHAN_TX); /* * Reset the DMA facility in the FPGA */ rr=sysInByte ((UINT32)FPGA_SCC_INT_CNTRL); switch ( cha ) { case Z85230_CHANNEL_A: /* FPGA: Disable the FPGA DMA facility for Ch.A */ sysOutByte ((UINT32)FPGA_SCC_INT_CNTRL, rr & (~0xF0)); break; case Z85230_CHANNEL_B: /* FPGA: Disable the FPGA DMA facility for Ch.B */ sysOutByte ((UINT32)FPGA_SCC_INT_CNTRL, rr & (~0x0F)); break; default: return ERROR; }#else if (z85230HwDisablePort(channel) != OK) return ERROR;#endif /* VME_181 */ /* reset the DMA channel */ oldLevel = intLock();#ifdef VME_181 /* reset the DMA channels */ z85230DmaAbort( SCC_DMA_CHAN_RX ); z85230DmaAbort( SCC_DMA_CHAN_TX );#endif /* flush the buffers */ z85230BufFlushFrames( &(channel->txFrameBuf)); z85230BufFlushFrames( &(channel->rxFrameBuf)); if ( newMode == Z85230_MODE_INT ) {/* oldLevel = intLock(); */ /* int and xfer mode */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR1 ); REG_8530_WRITE( cr, SCC_WR1_INT_ALL_RX | SCC_WR1_TX_INT_EN | SCC_WR1_EXT_INT_EN ); /* disable tx underrun int */ 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_TX_UND_IE) | SCC_WR15_WR7P_EN ); intUnlock( oldLevel ); } else if ( newMode == Z85230_MODE_DMA ) { /*oldLevel = intLock(); */#ifdef VME_181 Z85230BUF_FRAMES * rxBuf = &(channel->rxFrameBuf); Z85230BUF_FRAME * frame = &(rxBuf->frames[ rxBuf->write ]);#endif REG_8530_WRITE( cr, SCC_WR0_SEL_WR1 ); /* int and xfer mode */ REG_8530_WRITE( cr, SCC_WR1_RDMA_RECTR | SCC_WR1_RDMA_FUNC | SCC_WR1_RX_INT_DIS /* SCC_WR1_RX_INT_SPE */ | SCC_WR1_RDMA_EN ); REG_8530_WRITE( cr, SCC_WR0_SEL_WR14 ); REG_8530_WRITE( cr, SCC_WR14_BR_EN | SCC_WR14_BR_SRC | SCC_WR14_DTR_FUNC | SCC_WR14_SRC_BR );/*** Bug fix PT#1358 ****/ REG_8530_WRITE( cr, SCC_WR0_SEL_WR7 ); REG_8530_WRITE( cr, SCC_WR7P_EXT_READ_ENB | SCC_WR7P_DTR_REQ_TIMING | SCC_WR7P_TX_FIFO_INT_LVL | SCC_WR7P_AUTO_EOM_RST | SCC_WR7P_AUTO_TX_FLAG ); REG_8530_WRITE( cr, SCC_WR0_SEL_WR1 ); /* int and xfer mode */ REG_8530_WRITE( cr, SCC_WR1_RDMA_RECTR | SCC_WR1_RDMA_FUNC | SCC_WR1_RX_INT_SPE | SCC_WR1_RDMA_EN ); intUnlock( oldLevel ); /* * Setup the FPGA DMA facility */#ifdef VME_181 rr=sysInByte ((UINT32)FPGA_SCC_INT_CNTRL); switch ( cha ) { case Z85230_CHANNEL_A: /* Enable the FPGA DMA facility for Ch.A */ sysOutByte ((UINT32)FPGA_SCC_INT_CNTRL, rr | 0xF0 ); break; case Z85230_CHANNEL_B: /* Enable the FPGA DMA facility for Ch.B */ sysOutByte ((UINT32)FPGA_SCC_INT_CNTRL, rr | 0x0F ); break; default: return ERROR; } result = z85230DmaStart( SCC_DMA_CHAN_RX, channel->hw.rxfpga, frame->buf, frame->maxSize );#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -