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

📄 scc2modem.c

📁 860最小系统的bsp
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "copyright_wrs.h" 
#include "vxWorks.h"
#include "iv.h"
#include "intLib.h"
#include "config.h"
#include "sysLib.h"
#include "rngLib.h"
#include "drv/sio/ppc860Sio.h"
#include "drv/multi/ppc860Cpm.h"
#include "bsc860.h"
#include "scc2Modem.h"

static STATUS scc2ModemIoctl (PPC860SCC2MODEM_CHAN *pChan,int request,int arg);
static void   scc2ModemResetChannel (PPC860SCC2MODEM_CHAN *pChan);
static int    scc2ModemRead (PPC860SCC2MODEM_CHAN *,char*,int);
static int    scc2ModemWrite (PPC860SCC2MODEM_CHAN *,char *,int);
static void   scc2ModemInterrupt (PPC860SCC2MODEM_CHAN *);
static int    scc2ModemOpen ( PPC860SCC2MODEM_CHAN *, char *, int);

static int    scc2Read (PPC860SCC2MODEM_CHAN *,char*);


int scc2ModemDrvNum=0;

/*
  scc2 uart channnel  reset,it is not a function of the scc2 uart driver.It is same
  as the function "scc2ModemInit()" in "sysSerial.c"
  parameter: PPC860SCC_CHAN *pChan, all parameters of the uart channel belong to this 
             structure
  return: none
*/

void scc2ModemResetChannel
     (
     PPC860SCC2MODEM_CHAN *pChan
     )
{
	int oldlevel = intLock ();	/* lock interrupts */ 
	UINT32 regBase;
	int i=0;
	
	pChan->clockRate      = BRGCLK_FREQ;	    
	pChan->regBase        = vxImmrGet();  	    

	regBase =pChan->regBase;
	pChan->bgrNum         = 3;                  
	pChan->uart.sccNum    = 2;                  
	pChan->uart.txBdNum   = SCC2MODEM_TXBDNUM;                  
	pChan->uart.rxBdNum   = SCC2MODEM_RXBDNUM;               
	pChan->uart.txBdBase  = (SCC_BUF *)(0x2a00);/*bd结构*/
	pChan->uart.rxBdBase  = (SCC_BUF *)(0x2b00); /*bd结构*/
	pChan->uart.txBufSize = SCC2MODEM_TXBUFFER;
	pChan->uart.rxBufSize = SCC2MODEM_RXBUFFER;
	pChan->uart.pScc = (SCC *) ((UINT32) PPC860_DPR_SCC2
				      (MPC860_DPRAM_BASE (regBase))) ;
	pChan->uart.pSccReg = (SCC_REG *)((UINT32) MPC860_GSMR_L2 (regBase));
	pChan->uart.pSccReg->sccm = 0;              
	pChan->pBaud = (UINT32 *) ((UINT32) MPC860_BRGC3 (regBase));
	pChan->channelMode = 0;  /*中断或轮询*/

	*(pChan->pBaud)=0x0001028c;	/*50M/9600/16=326=0x146,产生9600波特率*/
	
	*MPC860_SICR(regBase)&=0xffff00ff;
	*MPC860_SICR(regBase)|=0x00001200;   /*brg3,NMSI*/
	
	*MPC860_SDCR(regBase) =0x00000001;  /*Normal mode*/
	
	pChan->uart.pScc->param.tbase=SCC2_RBASE_OFFSET; /*0xa00*/
	pChan->uart.pScc->param.rbase=SCC2_TBASE_OFFSET; /*0xb00*/
	
	*MPC860_CPCR(regBase)=0x0041; /*write value to rbptr and tbptr*/
	
	pChan->uart.pScc->param.rfcr=0x10; /*normal*/
	pChan->uart.pScc->param.tfcr=0x10; /*normal*/
	
	pChan->uart.pScc->param.mrblr=SCC2MODEM_RXBUFFER; /*maxium buffer 16 bytes*/
	
    *SCC_MAX_IDL((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    
    *SCC_BRKCR((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x00011;
    /*only one break charcter*/
    
    *SCC_PAREC((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    *SCC_FRMEC((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    *SCC_NOSEC((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    *SCC_BRKEC((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    /*clear parec, frmec ,nosec , brkec*/
    
    *SCC_UADDR1((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    *SCC_UADDR2((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    /*clear UADDR1, UADDR2*/
    
    *SCC_TOSEQ((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x0000;
    /*clear TOSEQ*/
    
    *SCC_CHARACTER1((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    *SCC_CHARACTER2((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    *SCC_CHARACTER3((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    *SCC_CHARACTER4((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    *SCC_CHARACTER5((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    *SCC_CHARACTER6((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    *SCC_CHARACTER7((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    *SCC_CHARACTER8((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0x8000;
    /*clear from character1 to character8 */
	*SCC_RCCM((UINT32)PPC860_DPR_SCC2(MPC860_DPRAM_BASE (regBase)))=0xc0ff;
    /*set rccm*/
    
    /*初始化BD*/
    for(i=0;i<SCC2MODEM_TXBDNUM;i++)
    {
        pChan->uart.txBdBase[i].statusMode = BD_TX_INTERRUPT_BIT;
        pChan->uart.txBdBase[i].dataPointer = pChan->uart.txBufBase +
                                               (i * pChan->uart.txBufSize);	
        pChan->uart.txBdBase[i].dataLength=0; 
    }
    pChan->uart.txBdBase[(i - 1)].statusMode |= BD_TX_WRAP_BIT;
    pChan->uart.txBdNext = 0;
     
     
    for(i=0;i<SCC2MODEM_RXBDNUM;i++)
    {
        pChan->uart.rxBdBase[i].statusMode = BD_RX_INTERRUPT_BIT|BD_RX_EMPTY_BIT ;
        pChan->uart.rxBdBase[i].dataPointer =pChan->uart.rxBufBase +
                                              (i * pChan->uart.rxBufSize);	
        pChan->uart.rxBdBase[i].dataLength=0; 
    }
    pChan->uart.rxBdBase[(i - 1)].statusMode |= BD_RX_WRAP_BIT;
    pChan->uart.rxBdNext = 0;
    
    pChan->uart.pSccReg->scce=0xffff;
    /*clear all previous events*/
    
    pChan->uart.pSccReg->sccm=0x0003;
    /* enable TX and Rx interrupts*/
    
    *MPC860_CIMR(regBase)|=0x20000000;
    /*scc2 allowed to generate a sysytem interrupt*/
    
    *MPC860_CICR(regBase)|=0x00000000;
    /*set cmp interrupt level ,default level 4*/
    
    pChan->uart.pSccReg->gsmrh=0x00000020;
    /*a small Rx FIFO width*/
    
    pChan->uart.pSccReg->gsmrl=0x00028004;
    /*uart mode ,normal operate*/
    
    pChan->uart.pSccReg->psmr=0xb000;
    /*automatic flow control
      8 bit characters
      no parity
      1 stop bit
      asynchronous SCC UART operation*/
      
    pChan->uart.pSccReg->gsmrl|=SCC_GSMRL_ENT|SCC_GSMRL_ENR; 
    /*enable transmitter
      enable receiver
    */ 
      
    intUnlock (oldlevel);			
    /* UNLOCK INTERRUPTS */   
}







/*  driver function table */
/*  打开一个多通道HDLC设备 */
/* 
 参数:1、PPC860SCC2MODEM_CHAN *pchan:此设备的数据结构,是联系驱动程序和I/O设备的纽带,所有
            的调用都要通过此结构体来完成用户需要。
          2、char * remainder:保留参数,没有使用,因此必须为0
          3、 int mode:打开模式,没有使用,必须为0
 返回值:设备数据结构的值 
*/
int scc2ModemOpen  
  (
  PPC860SCC2MODEM_CHAN *pChan, 
  char * remainder, 
  int mode
  )
{ 
     /* serial devices should have no file name part */ 

    if (remainder[0] != 0) 
        return (ERROR); 
    else 
        return ((int) pChan); 
} 





/*
   SCC2口发送数据函数,该发送过程采用写满一个缓冲区,发送一个缓冲区的形式,如果当前待写入的缓冲区
   正处于发送状态,程序会等待10000个循环,如果还没有将数据发送完成,返回错误,如果要发送的数据量
   比较大的时候,可能需要等待的更长时间。
   参数:PPC860SCC2MODEM_CHAN *pChan,这个设备的数据结构
        char *buffer,待发送的数据指针
        int bufferLen 待发送的数据长度
   返回值:EAGAIN,数据发送失败
          OK,数据发送成功
*/
int scc2ModemWrite 
    (
    PPC860SCC2MODEM_CHAN *pChan,
    char *buffer,
    int bufferLen
    )
{
	int i=0,j=0,k=0;
	int activeTxBd=pChan->uart.txBdNext;
	
	if (pChan->uart.txBdBase[activeTxBd].statusMode &BD_TX_READY_BIT)
	  return(EAGAIN);
	/*如果有未发送数据,返回错误*/
	
	pChan->uart.pSccReg->scce = SCCE_TX;
	/*reset the transmiter status bit */
		 
	for(i=0,j=0;i<bufferLen;i++,j++)
	{
	    if(!(pChan->uart.txBdBase[activeTxBd].statusMode &BD_TX_READY_BIT))
	    /*is this buffer  ready ?*/	
	        pChan->uart.txBdBase[activeTxBd].dataPointer[j]=buffer[i];
	    else   
	    {
	       	while((pChan->uart.txBdBase[activeTxBd].statusMode &BD_TX_READY_BIT)|(k<10000))
	       	    k++;
	       	if(pChan->uart.txBdBase[activeTxBd].statusMode &BD_TX_READY_BIT)
	       	/*after 1000 loops,is the tx buffer OK ?*/
	       	    return(i);
	       	else
	       	    pChan->uart.txBdBase[activeTxBd].dataPointer[j]=buffer[i];
	    }
	       
	    if(j>=(pChan->uart.txBufSize)) /*this buffer load full*/
	    {
	        pChan->uart.txBdBase[activeTxBd].dataLength=j+1;
	        /*data length is j+1*/
	        pChan->uart.txBdBase[activeTxBd].statusMode|=BD_TX_READY_BIT;
	        /*transmiter this buffer*/
	        activeTxBd=(activeTxBd+1)%(pChan->uart.txBdNum);
	        /*point to next BD*/
	        j=0;
	    }	
	}
	pChan->uart.txBdBase[activeTxBd].dataLength=j+1;
	/*data length is j+1*/
	pChan->uart.txBdBase[activeTxBd].statusMode|=BD_TX_READY_BIT;
	/*transmiter this buffer*/
	activeTxBd=(activeTxBd+1)%(pChan->uart.txBdNum);
	/*point to next BD*/
	
	return(bufferLen);
	/*all data is transmitered*/
}





/*
  读取SCC2口数据,采用轮询方式,检查所有的接收缓冲区,取走所有的数据
  参数:PPC860SCC2MODEM_CHAN *pChan,这个设备的数据结构
       char *buffer,读取数据的指针
       int bufferLen,读取数据的长度
  返回值:1、EAGIAN, 无数据或读取失败
         2、
*/
int scc2Read 
    (
    PPC860SCC2MODEM_CHAN *pChan,
    char *buffer
     )
{
    int activeRxBd=pChan->uart.rxBdNext;
    int i=0,j=0;
    int tempLen=0;

⌨️ 快捷键说明

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