📄 z85230rhdlc.c
字号:
}/*************************************************************************** * z85230RHDLCWrite - write from buffer to channel, enable HW tx if buffer * was previously empty * * RETURNS * the number of bytes written, or <0 on failure */int z85230RHDLCWrite( struct _Z85230_CHAN * channel, unsigned char * buf, int size ) { /* TODO: check channel status */ int bytesWritten = 0; Z85230BUF_FRAMES * txBuf = &(channel->txFrameBuf); if ( txBuf->frames[ txBuf->write ].maxSize < size + 2 ) { /* not enough room to buffer frame */ return -1; } if ( size < 2 ) { /* invalid frame */ return - 1; } /* address */ bytesWritten += z85230BufWriteFrameByte( txBuf, buf[ 0 ] ); /* command */ bytesWritten += z85230BufWriteFrameByte( txBuf, buf[ 1 ] ); /* data */ switch ( channel->hw.options & CSIZE ) { case CS5: bytesWritten += z85230BufWriteFrame( txBuf, &(buf[ 2 ]), size - 2, 5 ); break; case CS6: bytesWritten += z85230BufWriteFrame( txBuf, &(buf[ 2 ]), size - 2, 6 ); break; case CS7: bytesWritten += z85230BufWriteFrame( txBuf, &(buf[ 2 ]), size - 2, 7 ); break; case CS8: bytesWritten += z85230BufWriteFrame( txBuf, &(buf[ 2 ]), size - 2, 8 ); break; default: Z85230_ASSERT( FALSE ); break; } z85230RHDLCTxStartup( channel ); if ( channel->blocking ) { if ( semTake( channel->writeSem, channel->writeTimeout ) == ERROR ) { /* write timeout, abort frame */ rhdlc[ channel->channel ].abort = TRUE; } } else { semTake( channel->writeSem, NO_WAIT ); } return bytesWritten; }/*************************************************************************** * z85230RHDLCIoctl - generic IOCTL command interface * * If the request is to set a sync/async serial driver configuration option, the * configuration to be set is provided via the command (function) argument and * the value to be set is provided via the arg argument. If the request is to access * a sync/async serial driver configuration option, the configuration to be * accessed is provided via the command (function) argument and the current * value is returned via the arg argument. * * RETURNS * Z85230_OK: command successfully run * Z85230_ERR_INVALID_COMMAND: command not implemented * anything else: command failed */int z85230RHDLCIoctl( struct _Z85230_CHAN * channel, int command, int arg ) { Z8530_CHAN * hw = &( channel->hw ); int oldlevel; /* current interrupt level mask */ volatile unsigned char * cr; /* SCC control reg adr */ unsigned char rr; cr = hw->cr; switch( command ) { case FIONREAD: /* Gets # of Bytes ready to be read */ *(int *)arg = z85230BufReadFrameSize( &channel->rxFrameBuf ); return(OK); /*-------------------------------------------------------------*/ case Z85230_FLUSH: { volatile UINT tout = 0x80000000; /* time out value */ /* drop all rx'ed data */ taskDelay(1); oldlevel = intLock(); z85230BufFlushFrames( &channel->rxFrameBuf ); intUnlock( oldlevel ); /* * For half duplex mode wait till * all data queued to be tx'ed is gone * (the echo packet is dropped) */ while ( channel->hw.txing && (tout--) ) { taskDelay( 0 ); } break; } /*-------------------------------------------------------------*/ case Z85230_SET_CHK_CRC: if ( arg ) channel->hw.crcCheck = 1; else channel->hw.crcCheck = 0; return OK; /*-------------------------------------------------------------*/ case Z85230_GET_CHK_CRC: *(int *)arg = channel->hw.crcCheck; return OK; /*-------------------------------------------------------------*/ case Z85230_SET_CHK_ADDR: if ( arg ) { /* check against rxaddr */ oldlevel = intLock(); /* get old value of write reg 3 - mapped to read reg 9 */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR9 ); REG_8530_READ( cr, &rr ); /* use address checking */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR3 ); REG_8530_WRITE( cr, rr | SCC_WR3_ADR_SEARCH ); /* P/T 603 -- keep track of the setting */ channel->hw.addrChk = 1; intUnlock( oldlevel ); } else { /* accept any packets (default) */ oldlevel = intLock(); /* get old value of write reg 3 - mapped to read reg 9 */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR9 ); REG_8530_READ( cr, &rr ); /* use address checking */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR3 ); REG_8530_WRITE( cr, rr & ~SCC_WR3_ADR_SEARCH ); /* P/T 603 -- keep track of the setting */ channel->hw.addrChk = 0; intUnlock( oldlevel ); } return OK; /*-------------------------------------------------------------*/ case Z85230_GET_CHK_ADDR: oldlevel = intLock(); /* get old value of write reg 3 - mapped to read reg 9 */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR9 ); REG_8530_READ( cr, &rr ); intUnlock( oldlevel ); if ( rr & SCC_WR3_ADR_SEARCH ) *(int *)arg = 1; else *(int *)arg = 0; return OK; /*-------------------------------------------------------------*/ case Z85230_SET_HALFDUPLEX: if ( arg ) { oldlevel = intLock(); /* P/T 603 */ /* HwDisable actually turns off address checking*/ /* but does NOT update the addrChk flag in Z8530_CHAN */ if ( !channel->hw.txing ) { z85230HwDisableTx( channel ); } intUnlock( oldlevel ); channel->hw.halfDuplex = 1;#ifdef VME_181 z85230OSClkInit();#endif } else { channel->hw.halfDuplex = 0; oldlevel = intLock(); /* Turn on address search mode */ /* only if the addrChk flag is set*/ /* i.e., app has explicitly called the ioctl*/ /* P/T 603 */ if(channel->hw.addrChk) { /* get the contents of Write Reg 3 - mapped to read Reg 9 */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR9 ); REG_8530_READ( cr, &rr ); /* turn on address search mode */ rr |= SCC_WR3_ADR_SEARCH ; REG_8530_WRITE( cr, SCC_WR0_SEL_WR3 ); REG_8530_WRITE( cr, rr ); } intUnlock( oldlevel );#ifdef VME_181 z85230OSClkClose();#endif } return OK; /*-------------------------------------------------------------*/ case Z85230_GET_HALFDUPLEX: *(int *)arg = channel->hw.halfDuplex; return OK; /*-------------------------------------------------------------*/ case Z85230_SET_TX_CLK_OFF_DELAY : if( (arg < 0) || (arg > 255) || (channel->hw.halfDuplex == FALSE)) { return (EIO); } channel->hw.clockDelay = arg ; return (OK); case Z85230_GET_TX_CLK_OFF_DELAY : *(int*)arg = channel->hw.clockDelay ; return (OK); /*-------------------------------------------------------------*/ case Z85230_SET_RXADDR: if ( arg > 0xff ) { return (Z85230_ERR_INVALID_PARAM); } rhdlc[ channel->channel ].rxAddr = (unsigned char)arg; oldlevel = intLock(); REG_8530_WRITE( cr, SCC_WR0_SEL_WR6 ); REG_8530_WRITE( cr, rhdlc[ channel->channel ].rxAddr ); intUnlock( oldlevel ); return OK; case Z85230_GET_RXADDR: *(unsigned char *)arg = rhdlc[ channel->channel ].rxAddr; return OK; /*-------------------------------------------------------------*/ case FIOBAUDRATE: case Z85230_SET_BAUDRATE: { if (arg < Z85230_MIN_SYNC_BAUDRATE || arg > Z85230_MAX_SYNC_BAUDRATE ) return (EIO); DRV_LOG(DRV_DEBUG_IOCTL,"BaudRate set to %d n",arg,0,0,0,0,0); if (hw->baudRate == arg) /* current baud = requested baud */ return (OK); hw->baudRate = z85230HwSetRate( channel, arg );#ifdef VME_181 /* The FPGA timeout setting should depend on baud rate and frame structure */ arg = ( (8+16) *1000000/ arg ); /* Rx Timeout => 8bit + 16bit CRC */ sysOutWordNoSwap((UINT32)((channel->channel) ? (FPGA_SCC_CHB_TIME) : (FPGA_SCC_CHA_TIME)), arg ); #endif return (OK); } /*-------------------------------------------------------------*/ case Z85230_GET_BAUDRATE: *(int *)arg = hw->baudRate; /* return current baud rate */ return (OK); /*-------------------------------------------------------------*/ case Z85230_MODE_SET:#ifndef VME_181 if (arg != Z85230_MODE_DMA) return (EIO);#endif return (z85230RHDLCModeSet( channel, arg ) == OK ? OK : EIO); /*-------------------------------------------------------------*/ case Z85230_MODE_GET: *(int *)arg = hw->mode; /* return current Z85230 mode */ return (OK); /*-------------------------------------------------------------*/ case Z85230_AVAIL_MODES_GET:#ifdef VME_181 *(int *)arg = Z85230_MODE_INT;#else *(int *)arg = Z85230_MODE_DMA;#endif return (OK); /*-------------------------------------------------------------*/ case Z85230_HW_OPTS_SET: return ((z85230RHDLCOptsSet( channel, arg ) == OK) ? OK : EIO); break; /*-------------------------------------------------------------*/ case Z85230_HW_OPTS_GET: *(int *)arg = channel->hw.options; break; /*-------------------------------------------------------------*/ case Z85230_HUP: /* check if hupcl option is enabled */ if ( hw->options & HUPCL ) return z85230RHDLCHup( channel ); break; /*-------------------------------------------------------------*/ case Z85230_OPEN: /* check if hupcl option is enabled */ if ( hw->options & HUPCL ) return z85230RHDLCConnect( channel ); break; /*-------------------------------------------------------------*/ case Z85230_SET_EXT_RX_CLK: if ( arg ) { /* use an external receive clock */ oldlevel = intLock(); /* 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 ); intUnlock( oldlevel ); } else { /* use an internal receive clock */ oldlevel = intLock(); /* write reg 11 - clock mode */ hw->writeReg11 = SCC_WR11_RX_BR_GEN | 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 ); intUnlock( oldlevel ); } return OK; /*-------------------------------------------------------------*/ case Z85230_GET_EXT_RX_CLK: /* clock is external by default */ if ( (channel->hw.writeReg11 & SCC_WR11_RX_BR_GEN) == SCC_WR11_RX_BR_GEN ) { *(int *)arg = FALSE; } else { *(int *)arg = TRUE; } return OK; /*-------------------------------------------------------------*/ case Z85230_SET_CRC_POLY : oldlevel = intLock(); REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_READ( cr, &rr ); if( arg == Z85230_CRC16_POLY ) rr |= SCC_WR5_CRC16 ; else rr &= ~SCC_WR5_CRC16 ; REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_WRITE( cr, rr ); REG_8530_WRITE( cr, SCC_WR0_RST_TX_CRC ); REG_8530_WRITE( cr, SCC_WR0_RST_RX_CRC ); intUnlock( oldlevel ); return (OK); /*-------------------------------------------------------------*/ case Z85230_GET_CRC_POLY : oldlevel = intLock(); REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_READ( cr, &rr ); intUnlock( oldlevel ); if( rr & SCC_WR5_CRC16 ) *(int*)arg = Z85230_CRC16_POLY ; else *(int*)arg = Z85230_SDLC_POLY ; return (OK); /*-------------------------------------------------------------*/ default: return Z85230_ERR_NOT_IMPLEMENTED; } return OK; }#ifdef DRV_DEBUGunsigned char zRead(int i, char reg){ unsigned char rr; volatile unsigned char * cr; /* SCC control reg adr */if (i) cr = (char *)SBC_Z8530_B_CTRL_REG;else cr = (char *)SBC_Z8530_A_CTRL_REG; /* read register 1 */ REG_8530_WRITE( cr, reg ); REG_8530_READ( cr, &rr ); return rr;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -