📄 z85230hw.c
字号:
/* z85230Hw.c - implementation of HW-dependant layer *//* Copyright 2000-2002 Dy 4 Systems, Inc. *//*modification history--------------------01c dle, 07jun05 support 183 Serial IPM V201b aak, 14jan03 precise baud constant calculation, HDLC01a srr, 13feb01 changed z85230HwGet/SetRate to use x16 mode see SRR+1*//*DESCRIPTIONUSAGE*/#include <sioLib.h>#include <intLib.h>#include "h/drv/sio/z85230Drv.h"#include "h/drv/sio/z85230Hw.h"#ifdef VME_183#include "cwv183.h"#endif/*************************************************************************** * z85230HwGetOpts - return current selected options - stop bits not * supported * * PRE * interrupts unlocked, extended read set */unsigned char z85230HwGetOpts( Z85230_CHAN * channel ) { int oldLevel; unsigned char wreg3, wreg4, dummy; unsigned char res = 0; volatile unsigned char * cr = channel->hw.cr; /* get bitsize, CREAD, and CLOCAL from WR3 (mapped to RR9) */ oldLevel = intLock(); /* sync */ REG_8530_READ( cr, &dummy ); REG_8530_WRITE( cr, SCC_WR0_SEL_WR9 ); REG_8530_READ( cr, &wreg3 ); REG_8530_WRITE( cr, SCC_WR0_SEL_WR4 ); REG_8530_READ( cr, &wreg4 ); intUnlock( oldLevel ); /* assumption: rx and tx bitsize are the same */ switch ( wreg3 & 0xc0 ) { case SCC_WR3_RX_5_BITS: res |= CS5; break; case SCC_WR3_RX_6_BITS: res |= CS6; break; case SCC_WR3_RX_7_BITS: res |= CS7; break; default: /* 8 bits */ res |= CS8; break; } /* CLOCAL */ if ( (wreg3 & SCC_WR3_AUTO_EN) == 0 ) { res |= CLOCAL; } /* CREAD */ if ( wreg3 & SCC_WR3_RX_EN ) { res |= CREAD; } /* STOPB */ if ( (wreg4 & SCC_WR4_2_STOP) == SCC_WR4_2_STOP ) { res |= STOPB; } /* PARENB, PARODD */ switch ( wreg4 & (SCC_WR4_PAR_EN | SCC_WR4_PAR_EVEN) ) { case SCC_WR4_PAR_EN | SCC_WR4_PAR_EVEN: res |= PARENB; break; case SCC_WR4_PAR_EN: res |= (PARENB | PARODD); break; } return res; }/*************************************************************************** * z85230HwSetOpts - change rx, tx options, does not handle STOPB * * PRE: * interrupts must be unlocked */int z85230HwSetOpts( Z85230_CHAN * channel, unsigned int options, int useSync ) { /* current interrupt level mask */ int oldlevel; /* SCC control reg adr */ volatile unsigned char * cr = channel->hw.cr; /* registers that will be modified */ unsigned char wreg3, wreg5, wreg4, dummy; oldlevel = intLock(); /* sync */ REG_8530_READ( cr, &dummy ); /* get contents of WR5 */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_READ( cr, &wreg5 ); /* get contents of WR3 (mapped to RR9) */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR9 ); REG_8530_READ( cr, &wreg3 ); /* get contents of WR4 */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR4 ); REG_8530_READ( cr, &wreg4 ); intUnlock( oldlevel ); /* mask out all bits touched by this function */ wreg3 &= 0x1e; wreg5 &= 0x9f; wreg4 &= 0xf0; /* character size */ switch ( options & CSIZE ) { case CS5: /* select receive 5 bit data size */ wreg3 |= SCC_WR3_RX_5_BITS; /* select transmit 5 bit data size */ wreg5 |= SCC_WR5_TX_5_BITS; break; case CS6: /* select receive 6 bit data size */ wreg3 |= SCC_WR3_RX_6_BITS; /* select transmit 6 bit data size */ wreg5 |= SCC_WR5_TX_6_BITS; break; case CS7: /* select receive 7 bit data size */ wreg3 |= SCC_WR3_RX_7_BITS; /* select transmit 7 bit data size */ wreg5 |= SCC_WR5_TX_7_BITS; break; default: case CS8: /* select receive 8 bit data size */ wreg3 |= SCC_WR3_RX_8_BITS; /* select transmit 8 bit data size */ wreg5 |= SCC_WR5_TX_8_BITS; break; } /* CLOCAL */ if ( (options & CLOCAL) == 0 ) { /* !clocal enables hardware flow control(DTR/DSR) */ wreg3 |= SCC_WR3_AUTO_EN; } /* CREAD */ if ( options & CREAD ) { wreg3 |= SCC_WR3_RX_EN; } /* PARITY */ switch ( options & (PARENB | PARODD) ) { case PARENB | PARODD: wreg4 |= SCC_WR4_PAR_EN; break; case PARENB: wreg4 |= (SCC_WR4_PAR_EN | SCC_WR4_PAR_EVEN); break; /* parity disabled by default */ } /* STOPB */ if ( !useSync ) { if ( options & STOPB ) { wreg4 |= SCC_WR4_2_STOP; } else { wreg4 |= SCC_WR4_1_STOP; } } else { wreg4 |= SCC_WR4_SYNC_EN; } /* update ESCC */ oldlevel = intLock(); /* write reg 4 - misc params and modes */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR4 ); REG_8530_WRITE( cr, wreg4 ); /* tx params */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR5 ); REG_8530_WRITE( cr, wreg5 ); /* write reg 3 - receive params */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR3 ); REG_8530_WRITE( cr, wreg3 ); intUnlock( oldlevel ); return OK; }#ifndef VME_181/*************************************************************************** * z85230HwSetTimeout - set timeout based on baudrate (DMA Async mode) * * Calculate timeout factor for DMA Async mode: * 2 character, 10 bit per character, 8.4 us unit * 2*10*1000000 * ( ------------ % 8.4 ) + 1 * baud rate * * If input rate = 0 (other mode), timeout will be set to 0. */void z85230HwSetTimeout( Z85230_CHAN * channel, int rate ){ int oldLevel; UINT32 tmp; UINT32 timeout = 0; int cha = channel->channel; /* set timeout for DMA Async mode only */ if (rate) { timeout = (200000000/(rate*84)) + 1; timeout &= 0xFFFF; /* 16 bit */ if (cha == Z85230_CHANNEL_B) timeout <<= 16; } oldLevel = intLock(); tmp = sysInLong(FPGA_SCC_TIMEOUT); if (cha == Z85230_CHANNEL_A) tmp &= 0xFFFF0000; else tmp &= 0x0000FFFF; sysOutLong(FPGA_SCC_TIMEOUT, tmp | timeout); intUnlock( oldLevel ); }#endif /* VME_181 *//*************************************************************************** * z85230HwSetRate - set clock rate * * RETURNS * newly calculated clock rate */int z85230HwSetRate( Z85230_CHAN * channel, int rate ) { int oldLevel; unsigned short baudConstant; volatile unsigned char * cr = channel->hw.cr; int protocol = channel->protocol.protocol; /*SRR+1*/ /*now check which protocol we are using*/ if(protocol==Z85230_PROTOCOL_ASYNC) /*SRR+1*/ { /* * Calculate the baud rate constant for the new baud rate * from the input clock (PCLK) frequency. This assumes that the * divide-by-16 bit is set in the Z8530 WR4 register */ /* baudConstant = ((channel->hw.baudFreq /32) / rate) - 2; *SRR+1*//* Clock Frequency - 3 * 16 * Baud RateTime constant = --------------------------------------------------------------. 2 x 16 x Baud Rate*/#ifdef VME_181 baudConstant = (channel->hw.baudFreq - 3*16*rate) /(2*16*rate);#else baudConstant = ((channel->hw.baudFreq /32) / rate) - 2;#endif } else /*HDLC or LAPB so use x1 clock mode*/ { baudConstant = ((channel->hw.baudFreq /2) / rate) - 2; /*SRR+1*/ } /* disable interrupts during chip access */ oldLevel = intLock(); /* printf("\nnew baud Constant: %d\n",baudConstant); */ /* set the new baud rate */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR12 ); /* LSB of baud constant */ REG_8530_WRITE( cr, (char)baudConstant ); REG_8530_WRITE( cr, SCC_WR0_SEL_WR13 ); /* MSB of baud constant */ REG_8530_WRITE( cr, (char)(baudConstant >> 8) ); /* re-enable interrupts */ intUnlock( oldLevel ); /* new baudrate */ if(protocol==Z85230_PROTOCOL_ASYNC) /*SRR+1*/ {#ifndef VME_181 /* Set timeout value for DMA mode */ if (channel->hw.mode == Z85230_MODE_DMA) z85230HwSetTimeout(channel, rate);#endif return (channel->hw.baudFreq /32) / (baudConstant + 2); /*SRR+1*/ } else /*HDLC or LAPB*/ return (channel->hw.baudFreq /2) / (baudConstant + 2); /*SRR+1*/ }/*************************************************************************** * z85230HwGetRate - This routine returns the baud rate programmed for the * given channel on the Z85230 device. * * RETURNS * current baud rate */int z85230HwGetRate( Z85230_CHAN * channel ) { int oldLevel; unsigned char rr; unsigned short baudConstant; volatile unsigned char * cr = channel->hw.cr; int protocol = channel->protocol.protocol; /*SRR+1*/ /* disable ints */ oldLevel = intLock(); /* get upper, lower bytes of baud constant */ REG_8530_WRITE( cr, SCC_WR0_SEL_WR12 ); /* LSB of baud constant */ REG_8530_READ( cr, &rr ); baudConstant = (unsigned short)(rr) << 8; REG_8530_WRITE( cr, SCC_WR0_SEL_WR13 ); /* MSB of baud constant */ REG_8530_READ( cr, &rr ); baudConstant |= rr; /*re-enable ints */ intUnlock( oldLevel ); /* current clockrate */ if(protocol==Z85230_PROTOCOL_ASYNC) /*SRR+1*/ { return (channel->hw.baudFreq /32) / (baudConstant + 2); /*SRR+1*/ } else /*HDLC or LAPB*/ return (channel->hw.baudFreq /2) / (baudConstant + 2); /*SRR+1*/ }/*************************************************************************** * z85230HwDisableTx - disable the transmit clock and data * * RETURNS * N/A */int txofff=0;int txofff1=0;void z85230HwDisableTx( Z85230_CHAN * channel ){ volatile UINT8 *cr = channel->hw.cr; UINT8 rr = 0 ; /* disable 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 ); /* 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 ); txofff=rr; /* turn off address search mode */ rr &= ~SCC_WR3_ADR_SEARCH ; REG_8530_WRITE( cr, SCC_WR0_SEL_WR3 ); REG_8530_WRITE( cr, rr );txofff1=rr; channel->hw.txDone = 0;}#ifndef VME_181/*************************************************************************** * z85230HwSendByDesc - Send data by TX descriptor * * Return number of bytes sent. */int z85230HwSendByDesc (Z85230_CHAN * channel, UINT8 *buf, int size, UINT8 mask){ int j; UINT32 txDesc; UINT32 stat; UINT8 * dst; Z8530_CHAN * hw = &(channel->hw); UINT32 i = hw->txIndex; /* Get current TX descriptor */ txDesc = (UINT32)(hw->txfpga) + (i * DRI_DESC_OFFSET); /* Check status */ stat = sysInLong(txDesc + DRI_CMDSTAT_OFFSET); if (stat != DRI_BUSY) { for (j = 0, dst = hw->txBuf[i]; j < size; j++) *dst++ = *buf++ & mask; /* Send data */ sysOutLong(txDesc + DRI_BUF_OFFSET, (UINT32)hw->txBuf[i]); sysOutLong(txDesc + DRI_BYTECNT_OFFSET, size << 16); sysOutLong(txDesc + DRI_CMDSTAT_OFFSET, DRI_ENABLE); return size; } return 0; /* all descriptors are busy */}/*************************************************************************** * z85230HwDisablePort - Disable Z85230 port * */int z85230HwDisablePort (Z85230_CHAN * channel){ int cha = channel->channel; UINT32 ctrl = sysInLong (FPGA_SCC_CNTRL); UINT32 intCtrl = sysInLong (FPGA_SCC_INT_CNTRL); if (cha == Z85230_CHANNEL_A) { /* FPGA: Disable the FPGA DMA facility for Ch.A */ sysOutLong (FPGA_SCC_CNTRL, ctrl & ~(SCC_RXA_EN|SCC_TXA_EN)); sysOutLong (FPGA_SCC_INT_CNTRL, intCtrl & ~(DRI_RXA_INT|DRI_TXA_INT|ERRA_INT)); } else if (cha == Z85230_CHANNEL_B) { /* FPGA: Disable the FPGA DMA facility for Ch.B */ sysOutLong (FPGA_SCC_CNTRL, ctrl & ~(SCC_RXB_EN|SCC_TXB_EN)); sysOutLong (FPGA_SCC_INT_CNTRL, intCtrl & ~(DRI_RXB_INT|DRI_TXB_INT|ERRB_INT)); } else return ERROR; return OK;}/*************************************************************************** * z85230HwEnablePort - Enable Z85230 port * */int z85230HwEnablePort (Z85230_CHAN * channel){ UINT32 txDesc; UINT32 rxDesc; UINT32 size; int i; int cha = channel->channel; UINT32 ctrl = sysInLong (FPGA_SCC_CNTRL); UINT32 intCtrl = sysInLong (FPGA_SCC_INT_CNTRL); if (z85230HwDisablePort(channel) != OK) return ERROR; /* Reset index */ channel->hw.txIndex = channel->hw.rxIndex = 0; txDesc = (UINT32)(channel->hw.txfpga); rxDesc = (UINT32)(channel->hw.rxfpga); if (channel->protocol.protocol == Z85230_PROTOCOL_ASYNC) size = Z85230ASYNC_DEFAULT_BUFFERSIZE / Z85230_MAX_DESC; else size = Z85230RHDLC_DEFAULT_BUFFERSIZE; /* Clear TX, enable RX descriptors */ for (i = 0; i < Z85230_MAX_DESC; i++) { sysOutLong(txDesc + DRI_BUF_OFFSET, (UINT32)channel->hw.txBuf[i]); sysOutLong(txDesc + DRI_CMDSTAT_OFFSET, 0); sysOutLong(rxDesc + DRI_BUF_OFFSET, (UINT32)channel->hw.rxBuf[i]); sysOutLong(rxDesc + DRI_BYTECNT_OFFSET, size << 16); sysOutLong(rxDesc + DRI_CMDSTAT_OFFSET, DRI_ENABLE); txDesc += DRI_DESC_OFFSET; rxDesc += DRI_DESC_OFFSET; } if (cha == Z85230_CHANNEL_A) { /* Enable the FPGA DMA facility for Ch.A */ if (channel->protocol.protocol == Z85230_PROTOCOL_ASYNC) ctrl |= SCC_ASYNC_A_MODE; else ctrl &= ~SCC_ASYNC_A_MODE; sysOutLong(FPGA_SCC_INT_CNTRL, intCtrl | DRI_RXA_INT | DRI_TXA_INT | ERRA_INT); sysOutLong(FPGA_SCC_CNTRL, ctrl | SCC_RXA_EN | SCC_TXA_EN); } else { /* Enable the FPGA DMA facility for Ch.B */ if (channel->protocol.protocol == Z85230_PROTOCOL_ASYNC) ctrl |= SCC_ASYNC_B_MODE; else ctrl &= ~SCC_ASYNC_B_MODE; sysOutLong(FPGA_SCC_INT_CNTRL, intCtrl | DRI_RXB_INT | DRI_TXB_INT | ERRB_INT); sysOutLong(FPGA_SCC_CNTRL, ctrl | SCC_RXB_EN | SCC_TXB_EN); } return OK;}#endif /* VME_181 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -