📄 scc2modem.c
字号:
#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 + -