📄 sccuart.c
字号:
/*@# Encoder device dirver:sccuart.c */
/*------------------------------------------------------------------------------*/
/* */
/* MODULE: sccuart.c */
/* DATE: 2000/9/10 */
/* PURPOSE: SCC port uart driver module */
/* AUTHOR: JohnnyLing */
/* */
/*------------------------------------------------------------------------------*/
/* */
/* Copyright 2000,HighSun Dvision Inc. */
/* ALL RIGHTS RESERVED */
/*------------------------------------------------------------------------------*/
#include "bsp.h"
#include <psos.h>
#include <prepc.h>
#include <disi.h>
#include <icontrol\mpc8xx.h>
#include <serial\scc8xx.h>
#include "structure.h"
#define NUMBER_OF_CHANNELS 4
extern void my_Delay(unsigned long int dly_ms);
#define MAX_BUFFERS 32
#define ERR_GSALLOCB 5555
/*------------------------------------------------------------------------------*/
/* global varibles define */
/*------------------------------------------------------------------------------*/
unsigned long scclids[NUMBER_OF_CHANNELS];
char SCCQueueName[NUMBER_OF_CHANNELS][4]={"SCC1","SCC2","SCC2","SCC4"};
ULONG SCCQueueID[NUMBER_OF_CHANNELS];
char SCCBDSemaphoreName[NUMBER_OF_CHANNELS][4]={"BDS1","BDS2","BDS3","BDS4"}; /*检查BD表是否已用完的信号量*/
ULONG SCCBDSemaphoreID[NUMBER_OF_CHANNELS];
/*------------------------------------------------------------------------------*/
/* function prototype define */
/*------------------------------------------------------------------------------*/
unsigned long scc_init(struct ioparms *ioparm);
unsigned long scc_open(struct ioparms *ioparm);
unsigned long scc_write(struct ioparms *ioparm);
unsigned long scc_read(struct ioparms *ioparm);
unsigned long scc_close(struct ioparms *ioparm);
static void scc_dataind(Uid uid,mblk_t *mblk_t,unsigned long b_flags);
static void scc_expind(Uid uid,unsigned long exp);
static void scc_datacnf(Uid uid,mblk_t *mblk_t,unsigned long b_flags);
static void scc_ctlcnf(Uid uid,unsigned long cmd);
/*------------------------------------------------------------------------------*/
/*funtion implemetation */
/*------------------------------------------------------------------------------*/
/*------------------------------------------------------------------------------*/
/*清除缓冲区宏定义 */
/*------------------------------------------------------------------------------*/
void bzero(UCHAR *pt,int statlen)
{
int n;
unsigned char *s;
s = pt;
for(n=1;n<=statlen;n++)
*(s++)=0;
}
unsigned long scc_init(struct ioparms *ioparm)
{
UARTBLOCK *iopb; /* 我们传递的i/o参数块 */
int channel; /* 通道号 */
ULONG qid; /* 消息标识 */
ULONG rc; /* return code */
/*----------------------------------------------------------------------*/
/* 建立本通道的中断消息队列和信号量 */
/*----------------------------------------------------------------------*/
iopb=ioparm->in_iopb; /* 获得使用端口号 */
channel=iopb->port-1;
if(channel >= NUMBER_OF_CHANNELS)
return (SIOCBADCHANNELNUM);
if(rc = q_create(SCCQueueName[channel],1024,Q_GLOBAL | Q_FIFO | Q_NOLIMIT | Q_PRIBUF,
&SCCQueueID[channel]))
return(rc);
if(rc = sm_create(SCCBDSemaphoreName[channel],MAX_BUFFERS,SM_GLOBAL | SM_FIFO,
&SCCBDSemaphoreID[channel]))
return(rc);
ioparm->err=0;
ioparm->out_retval=0;
scc8xx_Init();
return(0);
}
/*------------------------------------------------------------------------------*/
/**/
/*------------------------------------------------------------------------------*/
unsigned long scc_open(struct ioparms *ioparm)
{
UARTBLOCK *iopb;
int channel;
ChannelCfg channelcfg;
unsigned long hdwflags;
ULONG volatile rc;
iopb=ioparm->in_iopb;
channel=iopb->port-1;
bzero((UCHAR *)&channelcfg,sizeof(ChannelCfg));
channelcfg.Mode=SIOCASYNC; /* + SIOCLOOPBACK; */
/*----------------------------------------------------------------------*/
/* configure the uart paramaters */
/*----------------------------------------------------------------------*/
if((iopb->CharSize<0x05)||(iopb->CharSize>0x08))
channelcfg.Cfg.Uart.CharSize=SCS8;
else
channelcfg.Cfg.Uart.CharSize=iopb->CharSize;
channelcfg.Cfg.Uart.Flags=0;
if(iopb->StopBits==2)
channelcfg.Cfg.Uart.Flags|=C2STOPB;
/*
Verify=0, no parity;
Verify=1, odd parity;
Verify=2, even parity;
*/
if(iopb->Verify==1)
channelcfg.Cfg.Uart.Flags|=(SPARENB|SPARODD);
else if(iopb->Verify==2)
channelcfg.Cfg.Uart.Flags|=SPARENB;
channelcfg.Cfg.Uart.LineD[0].LChar=0;
channelcfg.Cfg.Uart.LineD[0].LFlags=0;
channelcfg.Cfg.Uart.LineD[1].LChar=0;
channelcfg.Cfg.Uart.LineD[1].LFlags=0;
channelcfg.Cfg.Uart.LineD[2].LChar=0;
channelcfg.Cfg.Uart.LineD[2].LFlags=0;
channelcfg.Cfg.Uart.XOnCharacter=0;
channelcfg.Cfg.Uart.XOffCharacter=0;
channelcfg.Cfg.Uart.MinChar=0x400;
channelcfg.Cfg.Uart.MaxTime=1;
channelcfg.Cfg.Uart.padding1=0;
channelcfg.Cfg.Uart.ParityErrs=0;
channelcfg.Cfg.Uart.FramingErrs=0;
channelcfg.Cfg.Uart.OverrunErrs=0;
channelcfg.Cfg.Uart.AutoBaudEnb=0;
channelcfg.Cfg.Uart.Reserve[0]=0x0;
channelcfg.Cfg.Uart.Reserve[1]=0x0;
channelcfg.Cfg.Uart.Reserve[2]=0x0;
channelcfg.Cfg.Uart.Reserve[3]=0x0;
channelcfg.RBuffSize=0x400+0x20; /* 设置接收缓冲区尺寸为1024 */
channelcfg.NRBuffs=0x20; /* 设置接收缓冲区数目为16 */
channelcfg.OutQLen=0x20; /* 设置等待发送的最大消息数为16 */
if(iopb->BaudRate!=0)
channelcfg.Baud=iopb->BaudRate;
else
channelcfg.Baud=9600;
channelcfg.LineMode=HALFD; /* 设置线模式为双工 */
channelcfg.dataind=scc_dataind; /* 数据描述 */
channelcfg.expind=scc_expind; /* 异常描述 */
channelcfg.datacnf=scc_datacnf; /* 数据确认 */
channelcfg.ctlcnf=scc_ctlcnf; /* 控制确认 */
channelcfg.allocb=gs_allocb; /* 分配消息块 (gsblk.c)*/
channelcfg.freemsg=gs_freemsg; /* 释放信息块 (gsblk.c)*/
channelcfg.esballoc=gs_esballoc; /* 连接消息块 (gsblk.c)*/
channelcfg.uid=(int *)malloc(sizeof(int));
*(int *)channelcfg.uid=channel; /* 设置上层标识为当前通道 */
rc=scc8xx_Open(channel,&channelcfg,(Lid)&scclids[channel] ,&hdwflags);
if(rc==0)
{
/*----------------------------------------------------------------*/
/* 初始化RS485控制芯片,PB18<-0 */
/*----------------------------------------------------------------*/
E_PortBPinAssgmntReg&=0xFFFFDFFF;
E_PortBDataDirReg|=0x00002000;
E_PortBDataReg&=0xFFFFDFFF;
/*----------------------------------------------------------------*/
/* enable TX & RX */
/*----------------------------------------------------------------*/
switch(channel)
{
case 0: break;
case 1:
S_SCC2GenModeReg_l|=(BIT4 |BIT5);
break;
case 2:
S_SCC3GenModeReg_l|=(BIT4 |BIT5);
break;
case 3:
S_SCC4GenModeReg_l|=(BIT4 |BIT5);
break;
}
}
return(rc);
}
unsigned long scc_write(struct ioparms *ioparm)
{
UARTBLOCK *iopb;
int channel;
mblk_t* mblk;
int i;
ULONG rc;
iopb=ioparm->in_iopb;
channel=iopb->port-1;
if((mblk = gs_allocb(iopb->length,0)) == 0)
return(ERR_GSALLOCB);
for(i=0;i<iopb->length;i++,mblk->b_wptr++)
*(mblk->b_wptr)=iopb->pData[i];
if(rc = sm_p(SCCBDSemaphoreID[channel],SM_WAIT,200))
{
gs_freemsg(mblk);
return(0);
}
if(rc=scc8xx_Send((Lid)scclids[channel], mblk))
return(rc);
else
return(0);
}
unsigned long scc_read(struct ioparms *ioparm)
{
UARTBLOCK *iopb;
int channel;
ULONG qid;
ULONG msg_buf[4];
int i;
ULONG rc;
/*----------------------------------------------------------------------*/
/* 获得中断消息队列标识 */
/*----------------------------------------------------------------------*/
iopb=ioparm->in_iopb; /*获得使用端口号 */
channel=iopb->port-1;
/*等待接收中断发来的数据接收消息*/
if(rc = q_receive(SCCQueueID[channel],Q_WAIT,0,msg_buf))
return(rc);
iopb=ioparm->in_iopb;
iopb->length = msg_buf[2];
if(((unsigned long)(iopb->pData) > BSP_RAM_BASE) && ((unsigned long)(iopb->pData) < BSP_RAM_BASE+RamSize()))
{
for(i=0;i<iopb->length;i++)
{
iopb->pData[i]=*((unsigned char *)(((mblk_t *)(msg_buf[0]))->b_rptr)+i);
}
}
gs_freemsg((mblk_t *)(msg_buf[0]));
return(0);
}
unsigned long scc_close(struct ioparms *ioparm)
{
UARTBLOCK *iopb;
int channel;
ULONG qid;
ULONG rc;
/*----------------------------------------------------------------------*/
/* 删除该通道的中断消息队列 */
/*----------------------------------------------------------------------*/
iopb=ioparm->in_iopb;
channel=iopb->port-1;
scc8xx_Close((Lid)scclids[iopb->port-1]);
if(rc = q_delete(SCCQueueID[channel]))
{
return(rc);
}
if(rc = sm_delete(SCCBDSemaphoreID[channel]))
{
return(rc);
}
return(0);
}
static void scc_dataind(Uid uid,mblk_t *mblk_t,unsigned long b_flags)
{
unsigned long qid; /*中断消息队列标识*/
unsigned long msg_buf[4]; /*消息传递的参数*/
int length; /*接收字节数*/
ULONG rc;
length = ((chan_control *)scclids[*(int *)uid])->stats.receive_bytes ;
msg_buf[0]=(ULONG)mblk_t;
msg_buf[1]=b_flags;
msg_buf[2]=length; /*传送接收数据长度给上层DRIVER*/
msg_buf[3]=0L;
if(rc = q_send(SCCQueueID[*(int *)uid],msg_buf))
{
/*
Display("------scc_dataind():q_send(..) 错误 rc=0x%x, channel=%d", rc, *(int *)uid);
*/
}
((chan_control *)scclids[*(int *)uid])->stats.receive_bytes = 0; /*接收字节数清零*/
scc8xx_Ioctl((Lid)scclids[*(int *)uid], SIOCREPLENISH, 0); /*补满缓冲区,否则只能接收MAX_BUFFERS=16次*/
}
static void scc_expind(Uid uid,unsigned long exp)
{
}
static void scc_datacnf(Uid uid,mblk_t *mblk_t,unsigned long b_flags)
{
ULONG rc;
if(rc = sm_v(SCCBDSemaphoreID[*(int *)uid]))
{
/*
Display("------scc_datacnf():sm_v(..) 错误 rc=0x%x, channel=%d", rc, *(int *)uid);
DisplayErrInfo(rc);
*/
}
((chan_control *)scclids[*(int *)uid])->stats.transmit_bytes = 0; /*发送字节数清零*/
gs_freemsg(mblk_t);
}
static void scc_ctlcnf(Uid uid,unsigned long cmd)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -