📄 smcuart.c
字号:
/*@# Encoder device dirver:smcuart.c */
/*------------------------------------------------------------------------------*/
/* */
/* MODULE: smcuart.c */
/* DATE: 2000/9/10 */
/* PURPOSE: SMC 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\smc8xx.h>
#include "structure.h"
#define NUMBER_OF_CHANNELS 2
extern void my_Delay(unsigned long int dly_ms);
#define MAX_BUFFERS 32
#define ERR_GSALLOCB 5555
/*------------------------------------------------------------------------------*/
/* global varibles define */
/*------------------------------------------------------------------------------*/
unsigned long lids[NUMBER_OF_CHANNELS];
char SMCQueueName[NUMBER_OF_CHANNELS][4]={"SMC1","SMC2"};
ULONG SMCQueueID[NUMBER_OF_CHANNELS];
char BDSemaphoreName[NUMBER_OF_CHANNELS][4]={"BDM1","BDM2"}; /*检查BD表是否已用完的信号量*/
ULONG BDSemaphoreID[NUMBER_OF_CHANNELS];
/*------------------------------------------------------------------------------*/
/* function prototype define */
/*------------------------------------------------------------------------------*/
unsigned long smc_init(struct ioparms *ioparm);
unsigned long smc_open(struct ioparms *ioparm);
unsigned long smc_write(struct ioparms *ioparm);
unsigned long smc_read(struct ioparms *ioparm);
unsigned long smc_close(struct ioparms *ioparm);
static void smc_dataind(Uid uid,mblk_t *mblk_t,unsigned long b_flags);
static void smc_expind(Uid uid,unsigned long exp);
static void smc_datacnf(Uid uid,mblk_t *mblk_t,unsigned long b_flags);
static void smc_ctlcnf(Uid uid,unsigned long cmd);
/*------------------------------------------------------------------------------*/
/*funtion implemetation */
/*------------------------------------------------------------------------------*/
extern void bzero(UCHAR *pt,int statlen);
unsigned long smc_init(struct ioparms *ioparm)
{
UARTBLOCK *iopb;
int channel;
ULONG qid;
ULONG rc;
/*----------------------------------------------------------------------*/
/* 建立本通道的中断消息队列和信号量 */
/*----------------------------------------------------------------------*/
iopb=ioparm->in_iopb;
channel=iopb->port-1;
if(channel >= NUMBER_OF_CHANNELS)
return (SIOCBADCHANNELNUM);
if(rc = q_create(SMCQueueName[channel],1024,Q_GLOBAL | Q_FIFO | Q_NOLIMIT | Q_PRIBUF,
&SMCQueueID[channel]))
return(rc);
if(rc = sm_create(BDSemaphoreName[channel],MAX_BUFFERS,SM_GLOBAL | SM_FIFO,
&BDSemaphoreID[channel]))
return(rc);
ioparm->err=0;
ioparm->out_retval=0;
smc8xx_Init();
return(0);
}
/*------------------------------------------------------------------------------*/
/* */
/*------------------------------------------------------------------------------*/
unsigned long smc_open(struct ioparms *ioparm)
{
UARTBLOCK *iopb; /* 我们传递的i/o参数块 */
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; */ /* 设置通道配置模式为UART和环回 */
/*----------------------------------------------------------------------*/
/* 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;
/* channelcfg.Cfg.Uart.Flags=CANON; */
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=0;
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=smc_dataind; /* 数据描述 */
channelcfg.expind=smc_expind; /* 异常描述 */
channelcfg.datacnf=smc_datacnf; /* 数据确认 */
channelcfg.ctlcnf=smc_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=smc8xx_Open(channel,&channelcfg,(Lid)&lids[channel] ,&hdwflags);
if(rc==0)
{
if(channel==0)
{
S_SMC1ModeReg|=0x0003;
S_SMC1EventReg=0xFF;
S_SMC1MaskReg=0x17;
}
else
{
S_SMC2ModeReg|=0x0003;
S_SMC2EventReg=0xFF;
S_SMC2MaskReg=0x17;
}
return(rc);
}
else return(rc);
}
unsigned long smc_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(BDSemaphoreID[channel],SM_WAIT,200))
{
gs_freemsg(mblk);
return(0);
}
if(rc=smc8xx_Send((Lid)lids[channel], mblk))
return(rc);
else
return(0);
}
unsigned long smc_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(SMCQueueID[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 smc_close(struct ioparms *ioparm)
{
UARTBLOCK *iopb;
int channel;
ULONG qid;
ULONG rc;
/*----------------------------------------------------------------------*/
/* 删除该通道的中断消息队列 */
/*----------------------------------------------------------------------*/
iopb=ioparm->in_iopb;
channel=iopb->port-1;
smc8xx_Close((Lid)lids[iopb->port-1]);
if(rc = q_delete(SMCQueueID[channel]))
{
return(rc);
}
if(rc = sm_delete(BDSemaphoreID[channel]))
{
return(rc);
}
return(0);
}
static void smc_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 *)lids[*(int *)uid])->stats.receive_bytes ;
msg_buf[0]=(ULONG)mblk_t;
msg_buf[1]=b_flags;
msg_buf[2]=length;
msg_buf[3]=0L;
if(rc = q_send(SMCQueueID[*(int *)uid],msg_buf))
{
/*
Display("------scc_dataind():q_send(..) 错误 rc=0x%x, channel=%d", rc, *(int *)uid);
*/
}
((chan_control *)lids[*(int *)uid])->stats.receive_bytes = 0; /*接收字节数清零*/
smc8xx_Ioctl((Lid)lids[*(int *)uid], SIOCREPLENISH, 0); /*补满缓冲区,否则只能接收MAX_BUFFERS=16次*/
}
static void smc_expind(Uid uid,unsigned long exp)
{
}
static void smc_datacnf(Uid uid,mblk_t *mblk_t,unsigned long b_flags)
{
ULONG rc;
if(rc = sm_v(BDSemaphoreID[*(int *)uid]))
{
}
((chan_control *)lids[*(int *)uid])->stats.transmit_bytes = 0; /*发送字节数清零*/
gs_freemsg(mblk_t);
}
static void smc_ctlcnf(Uid uid,unsigned long cmd)
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -