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

📄 z85230hw.c

📁 Curtiss-Wright Controls Embedded Computing公司的cw183板bsp源代码
💻 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 + -