在860里增加TL16C554多串口芯片驱动_第1页
在860里增加TL16C554多串口芯片驱动_第2页
在860里增加TL16C554多串口芯片驱动_第3页
在860里增加TL16C554多串口芯片驱动_第4页
在860里增加TL16C554多串口芯片驱动_第5页
免费预览已结束,剩余18页可下载查看

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、在860里增加 TL16C554多串口芯片驱动(一)串口通讯控制器)和2个SMCSerial6个串口。但笔者开发的通讯控制器 smCT展显然不能满足要求,需要需MPC860t 有 4 个 SCC(serial communications controller management controller串口管理控制器),一共可以扩展 项目中,由于考虑到需要扩展8个或更多串口, SCC和求一种新的可扩展的串口芯片。我们采用两个TL16C554芯片来解决这个问题。一个 TL16C554芯片集成了四个 ST16550 ACE (异步通讯元件 ASYNCHRONOUS COMMUNICATIONS E

2、LEMENT )。二.串口驱动简介注意:此处.ttyDrvxxDrv,yyDrv表示一个特定的驱动程序,下同 虚拟驱动,用以.管理 I/O System.调用实际的驱动程序来管理硬件.Model.xxDrv 支持:标准 I/O System 接口Target Agent 接口 两种模式(中断interrupt,轮巡poll).回调 CallBacks允许高层协议来设定驱动怎样收发数据有两个回调(驱动调用)Put回调:传送一个从设备读到的字符到高层协议 get回调:从高层协议取得一个字符以便写到设备 代码实现一般性代码特定执行代码设备特定代码usrC on fig.c sysSerial.c x

3、xDrv.c(调用和实现部分)usrConfig.C'SysSerial.c注意:由于我们采用了多种设备实际的驱动(SMC和16C554),所以在sysSerial.c里需要整合,整合的函数包括sysSerialHwI ni t(),),这里调用了 里定义,它把.(注意,如里与串口有关的部分(前面部分是早期版本的,不予理会ttyDevCreate (),sysSerialChanGet()在 sysSerials.cSIO_CHAN类型的结构关联起来,而这个结构在是至关重要的)sysSerialHwI nit2 (),sysSerialCha nGet(),sysSerialReset

4、() 解读 usrConfig.c 先看 usrConfig.c ttyDrv(),然后用 设备的编号同一个 果系统采用串口调试,则该串口号被保留起来ttyDev()作的工作:调用iosDrvInstall 安装ttyDrv 到设备表(使用 ttyDrv 和tyLib 的入口) ttyDevCreate ()作的工作:申请并初始化设备描述调用 tyDevinit() 初始化 tyLib初始化selectLib 建立输入输出环行缓冲创建信号量调用iosDevAdd()增加设备到设备列表安装tyLib的程序和输入输出回调 使设备开始中断模式#ifdef INCLUDE_TYCODRV_5_2 #i

5、fdef INCLUDE_TTY_DEVif (NUM_TTY > 0) tyCoDrv ();/* in stall con sole driver */for (ix = 0; ix < NUM_TTY; ix+) /* create serial devices */ sprintf (tyName, "%s%d", "/tyCo/", ix);(void) tyCoDevCreate (tyName, ix, 512, 512);if (ix = CONSOLE_TTY)strc py (con soleName, tyName);

6、/* store con sole n ame */con soleFd = open (co nsoleName, O_RDWR, 0);/* set baud rate */(void) ioctl (co nsoleFd, FIOBAUDRA TE, CONSOLE_BAUD_RATE);(void) ioctl (co nsoleFd, FIOSET OP TIONS, OP T_TERMINAL);#endif/* INCLUDE_TTY_DEV */#else/* !INCLUDE TYCODRV 5 2 */#ifdefINCLUDE_TTY_DEVif (NUM_TTY >

7、; 0) ttyDrv();/* i nstall con sole driver */for (ix = 0; ix < NUM_TTY; ix+) /* create serial devices */#if (defi ned(INCLUDE_WDB) && (WDB_COMM_T YPE = WDB_COMM_SERIAL) if (ix = WDB_TTY_CHANNEL)/* don't use WDBs cha nnel */con ti nue;#en difsprintf (tyName, "%s%d", "/tyC

8、o/", ix);(void) ttyDevCreate (tyName, sysSerialCha nGet(ix), 512, 512);if (ix = CONSOLE_TTY)/* i nit the tty con sole */strc py (con soleName, tyName);con soleFd = open (con soleName, O_RDWR, 0);(void) ioctl (co nsoleFd, FIOBAUDRA TE, CONSOLE_BAUD_RATE);(void) ioctl (co nsoleFd, FIOSET OP TIONS

9、, OP T_TERMINAL);#endif/* INCLUDE_TTY_DEV */* !INCLUDE TYCODRV 5 2*/#endifsysSerialChanGet():以下是单独采用 860 smc时的情况SIO_CHAN * sysSerialCha nGet ( int cha nnel/* serial cha nnel */)if (cha nnel >= cha nNum)return (SIO_CHAN *) ERROR);return (SIO_CHAN *) &pp c860Cha n chann el); 单独采用16c554时为:SIO_CH

10、AN * sysSerialCha nGet(int cha nnel)if (channel < 0 |channel >= (int) (NELEMENTS(sysSioCha ns) return (SIO_CHAN *) ERROR;/* serial cha nnel */return sysSioCha nscha nn el;我们必须把两种情况整合.SIO_CHAN * sysSerialCha nGet (int cha nnelif (channel < 0 |channel >= (int) (NELEMENTS(sysSioCha ns) retu

11、rn (SIO_CHAN *) ERROR;if cha nn el<=1return (SIO_CHAN *)pp c860Cha n cha nnel elseretur n sysSioCha nscha nn el-2;sysSerialResetO关于sysSerialResset,由于16c554和860的smc采用不同的原理,所以其重启也有不同, 所以在sysSerialResetO里要考虑两中情况void sysSerialReset (void)/* disable serial in terr upts */ in tDisable (devParasO.i ntLe

12、vel);void sysSerialReset (void)sysSerialHwI ni t (); void sysSerialReset (void)sysSerialHwI ni t ();in tDisable (devParas0.i ntLevel);重中之重:关于 sysSerialHwlnit2 ()sysSerialHwInit2()由 usrConfig.c 里的 usrRoot 调用,用于连接中断 smc的如下:void sysSerialHwI nit2 (void)i; /* an in dex */int/* connect serial in terr upt

13、s */for (i = 0; i < cha nNum; i+) switch (i)case 0:(void) in tCo nn ect (IV_SMC1, (VOIDFUNC PTR) pp c860I nt,(int) &PP c860Cha n i);break;case 1:(void) in tCo nn ect (IV_SMC2_ PIP, (VOIDFUNC PTR) pp c860I nt,(int) &PP c860Cha n i);break;default: return;*CIMR(vxlmmrGet() |= (CIMR_SMC1 >

14、> i);CIMR是一个叫CP Int mask reg的宏,这里分别开启 SMC1和SMC2的中断 #defi ne CIMR_SMC10x00000010 /* SMC 1 */#defi ne CIMR_SMC2_ PIP0x00000008 /* SMC 2 */ #defi ne CIMR(base) (CAST(VUINT32 *)(base) + 0x0948)为什么在不在 sysSerialHwinit()里调用连接呢?因为在sysHwInit()执行的时刻内核内存分配算符还没有初始化!16C554 的:void sysSerialHwI nit2 (void)(void

15、) in tCo nn ect (INUM_TO_IVEC(dev Paras0.vector),st16554MuxI nt, (int) & st16554Mux);intEn able (devParas0.i ntLevel);各位必须注意,16c554中断服务程序是一个多重的,意思是:所有使用同一中断的8个通道有一样的中断服务程序,这样在st16554MuxInt ()处理的时候需要做出相应的判断(具体实现见后面)经过整合后的sysSerialHwInit2应该是: void sysSerialHwI nit2 (void)i; /* an in dex */int/* co

16、nnect serial in terr upts */for (i = 0; i < cha nNum; i+) switch (i)case 0:(void) in tCo nn ect (IV_SMC1, (VOIDFUNC PTR) pp c860l nt,(int) &PP c860Cha n i);break;case 1:(void) in tCo nn ect (IV_SMC2_ PIP, (VOIDFUNC PTR) pp c860I nt,(int) &PP c860Cha n i);break;default: return;*CIMR(vxImmr

17、Get() |= (CIMR_SMC1 >> i); void sysSerialHwI nit2 (void)i; /* an in dex */int/* connect serial in terr upts */for (i = 0; i < 2; i+) switch (i)case 0:(void) in tCo nn ect (IV_SMC1, (VOIDFUNC PTR) pp c860I nt,(int) &PP c860Cha n i);break;case 1:(void) in tCo nn ect (IV_SMC2_ PIP, (VOIDFU

18、NC PTR) pp c860I nt,(int) &PP c860Cha n i);break;default: return;*CIMR(vxlmmrGet() |= (CIMR_SMC1 >> i);(void) in tCo nn ect (INUM_TO_IVEC(dev Paras0.vector), st16554MuxI nt, (int) & st16554Mux);intEn able (devParas0.i ntLevel);重中之重:关于 sysSerialHwInit ()首先看16554的:void sysSerialHw In it

19、(void) int i;for (i = 0; i < N_ST16554_UART_CHANNELS; i+)st16554Cha ni.regDelta = devParasi.regS pace;st16554Cha ni.regs = dev Parasi.baseAdrs;st16554Cha ni.baudRate = CONSOLE_BAUD_RATE;st16554Cha ni.xtal = UART_XTAL_FREQ;st16554Cha ni.level = dev Parasi.i ntLevel;/* In itialise driver functions,

20、 getTxChar, pu tRcvChar and* cha nn elMode and init UART.*/st16554DevI nit (&st16554Cha ni);devParas结构用存放设备的一些参数typ edef structUINT vector;UINT8 *baseAdrs;UINT regS pace;UINT in tLevel; CMA_ST16554_CHAN _P ARAS;LOCAL CMA_ST16554_CHAN _P ARAS dev Paras= INT_VEC_COM, UART_REG_ADDR_INTERV AL,INT_LV

21、L_COM,INT_VEC_COM,UART_REG_ADDR_INTERV AL,(UINT8(UINT8*)SERIAL_A_BASE_ADR,*)SERIAL_B_BASE_ADR,INT_LVL_COM, INT_VEC_COM,UART_REG_ADDR_INTERV INT_LVL_COM, INT_VEC_COM,UART_REG_ADDR_INTERV INT_LVL_COM, INT_VEC_COM,UART_REG_ADDR_INTERV INT_LVL_COM, INT_VEC_COM,UART_REG_ADDR_INTERV INT_LVL_COM, INT_VEC_C

22、OM,UART_REG_ADDR_INTERV INT_LVL_COM, INT_VEC_COM,UART_REG_ADDR_INTERV INT_LVL_COM;从 SERIAL_A_BASE_ADR 至U SERIAL_H_BASE_ADR 表示两个 16c554 的 8 个通道的 基地址。INT_VEC_COM 和INT_LVL_COM 是通道所用中断的矢量和中断号,各位可以看 到8个通道(4 X 2)所用的通道一样.当然可以在设计电路的时候选择不同的通道,但这对有 限的中断是浪费.UART_REG_ADDR_INTERV AL是寄存器的步长,或者叫间隔,等于8.SysSerialHwl

23、nit先对st16554Chan结构做一些初始化 (st16554Chan(i)对应相应的通道), 设置寄存器步长regDelta,基地址regs,波特率baudRate,时钟晶振频率xtal,中断号intLevel然后调用xxDrv里的st16554DevInit,关于xxDevInit在xxDrv.c详解里详细介绍. 使用smc的SysSerialHwInit要复杂许多void sysSerialHw In it (void) int(UINT8*)SERIAL_C_BASE_ADR,AL,AL,AL,AL,AL,AL,i;/* an in dex */* en able serial I

24、/O on the board */(UINT8(UINT8(UINT8(UINT8(UINT8*BCSR1 &= (BCSR1_RS232_EN_L);/* If running an 823 or an 850, use only SMC1 */*)SERIAL_D_BASE_ADR,*)SERIAL_E_BASE_ADR,*)SERIAL_F_BASE_ADR,*)SERIAL_G_BASE_ADR,*)SERIAL_H_BASE_ADR,if (*BCSR3 & BCSR3_DBID_MASK) = BCSR3_823DB_MASK) | (*BCSR3 & B

25、CSR3_DBID_MASK) = BCSR3_850DB_MASK) cha nNum = 1;if (cha nNum = 2)*BCSR1 &= (BCSR1_RS232_2_EN_L);/* in tialize the chips device descri ptors */for (i = 0; i < cha nNum; i+) UINT32 regBase;/* BRGCLK freq (Hz) */=BRGCLK_FREQ;pp c860Cha n i.clockRate/* IMMR reg has base adr */pp c860Cha n i.regB

26、ase=vxImmrGet();regBase = pp c860Cha n i.regBase;/* use BRG1 for channel 1 and BRG2 for cha nnel 2 */pp c860Cha n i.bgrNum=(i + 1);/* SMC wired for rs232 */pp c860Cha n i.uart.smcNum=(i + 1);/* i nit the number of TBDs */pp c860Cha n i.uart.txBdNum0/* in it the number of RBDs */=pp c860SmcParmsi.smc

27、TbdNum;pp c860Cha n i.uart.rxBdNum=pp c860SmcParmsi.smcRbdNum;/* tran smit BD base adrs */pp c860Cha n i.uart.txBdBase=(SMC_BUF *)(MP C860_REGB_OFFSET +pp c860Smc Parmsi.smcTbdOff);/* receive BD base adrs */pp c860Cha n i.uart.rxBdBase = (SMC_BUF *)(MP C860_REGB_OFFSET +pp c860Smc Parmsi.smcRbdOff);

28、/* tx buf base */ pp c860Cha n i.uart.txBufBase = (u_char *)(MP C860_D PRAM_BASE (regBase)+ pp c860Smc Parmsi.smcTxBufOff);/* rx buf base */ pp c860Cha n i.uart.rxBufBase = (u_char *)(MP C860_D PRAM_BASE (regBase)+ pp c860Smc Parmsi.smcRxBufOff);/* tran smit buffer size */ pp c860Cha n i.uart.txBufS

29、ize = pp c860SmcParmsi.smcTxBufS z;/* DP RAM addr of SMC1 p arams */ pp c860Cha n i.uart .pSmc = (SMC *) (UINT32) PP C860_D PR_SMC1(MP C860_D PRAM_BASE (regBase)+ (i * 0x100);/* SMCMR1 for SMC1 */ pp c860Cha n i.uart .p SmcReg = (SMC_REG *)(UINT32) MP C860_SMCMR1 (regBase)+ (i * 0x10);/* Mask in ter

30、ru pts */ pp c860Cha n i.uart .p SmcReg->smcm = 0;pp c860Cha n i. pBaud = (UINT32 *) (UINT32) MP C860_BRGC1 (regBase)+ (i * 4);pp c860Cha n i.cha nn elMode = 0;/* select RS232 pins */ *MP C860_ PBP AR(regBase) |= 0xC0 << (i * 4);/* set it to no rmal op eratio ns */*MP C860_SDCR(regBase) = S

31、DCR_RAID_BR5;/* reset the chi p */pp c860DevI nit(&(pp c860Cha n i);经过整合,应该是这样:void sysSerialHw In it (void)inti;/* an in dex */* en able serial I/O on the board */*BCSR1 &= (BCSR1_RS232_EN_L);/* If running an 823 or an 850, use only SMC1 */if (*BCSR3 & BCSR3_DBID_MASK) = BCSR3_823DB_MAS

32、K) | (*BCSR3 & BCSR3_DBID_MASK) = BCSR3_850DB_MASK) cha nNum = 1;if (cha nNum = 2)*BCSR1 &= (BCSR1_RS232_2_EN_L);/* in tialize the chips device descri ptors */for (i = 0; i < 2; i+) UINT32 regBase;/* BRGCLK freq (Hz) */pp c860Cha n i.clockRate=BRGCLK_FREQ;/* IMMR reg has base adr */pp c86

33、0Cha n i.regBase=vxImmrGet();regBase = pp c860Cha n i.regBase;/* use BRG1 for channel 1 and BRG2 for cha nnel 2 */pp c860Cha n i.bgrNum=(i + 1);/* SMC wired for rs232 */pp c860Cha n i.uart.smcNum=(i + 1);/* i nit the number of TBDs */pp c860Cha n i.uart.txBdNum0/* in it the number of RBDs */=pp c860

34、SmcParmsi.smcTbdNum;pp c860Cha n i.uart.rxBdNum=pp c860SmcParmsi.smcRbdNum;/* tran smit BD base adrs */pp c860Cha n i.uart.txBdBase=(SMC_BUF *)(MP C860_REGB_OFFSET +pp c860Smc Parmsi.smcTbdOff);/* receive BD base adrs */pp c860Cha n i.uart.rxBdBase = (SMC_BUF *)(MP C860_REGB_OFFSET +pp c860Smc Parms

35、i.smcRbdOff);/* tx buf base */pp c860Cha n i.uart.txBufBase = (u_char *)(MP C860_D PRAM_BASE (regBase)+ pp c860Smc Parmsi.smcTxBufOff);/* rx buf base */pp c860Cha n i.uart.rxBufBase = (u_char *)(MP C860_D PRAM_BASE (regBase)+ pp c860Smc Parmsi.smcRxBufOff);/* tran smit buffer size */pp c860Cha n i.u

36、art.txBufSize = pp c860SmcParmsi.smcTxBufS z;/* DP RAM addr of SMC1 p arams */pp c860Cha n i.uart .pSmc = (SMC *) (UINT32) PP C860_D PR_SMC1(MP C860_D PRAM_BASE (regBase)+ (i * 0x100);/* SMCMR1 for SMC1 */ pp c860Cha n i.uart .p SmcReg = (SMC_REG *)(UINT32) MP C860_SMCMR1 (regBase)+ (i * 0x10);/* Ma

37、sk in terru pts */ pp c860Cha n i.uart .p SmcReg->smcm = 0;pp c860Cha n i. pBaud = (UINT32 *) (UINT32) MP C860_BRGC1 (regBase)+ (i * 4);pp c860Cha n i.cha nn elMode = 0;/* select RS232 pins */ *MP C860_ PBP AR(regBase) |= 0xC0 << (i * 4);/* set it to no rmal op eratio ns */ *MP C860_SDCR(re

38、gBase) = SDCR_RAID_BR5;/* reset the chip */ pp c860DevI nit(&(pp c860Cha n i);for (i = 0; i < N_ST16554_UART_CHANNELS; i+)st16554Cha ni.regDelta = devParasi.regS pace;st16554Cha ni.regs = devParasi.baseAdrs;st16554Chani.baudRate = CONSOLE_BAUD_RA TE;st16554Cha ni.xtal = UART_XTAL_FREQ;st16554

39、Cha ni.level = dev Parasi.i ntLevel;详细解说:xxDrv for 16c554st16c554.cst16c554.hst15c554.h里除定义一些16c554寄存器的地址偏移量,和一些常数以外,最重要的 就是两个结构.st16554_chan 和 st16554_mux st16554_chan对应于16554串口设备的一个通道/* ST16554_CHAN */typ edef struct st16554_chan/* must be first */sio_chansio;/* sta ndard SIO_CHAN eleme nt */* cal

40、lbacks */STATUS(*getTxChar)();/* in stalled Tx callback routi ne */STATUS(*p utRcvChar)();/* i nstalled Rx callback rout ine */void *getTxArg;/* argume nt to Tx callback routi ne */void *p utRcvArg;/* argume nt to Rx callback rout ine */*/UINT8 *regs;/* ST16554 registers */UINT8level;/* In terr upt

41、level for this device */UINT8ier;/* copy of IER */UINT8lcr;/* copy of LCR */UINT32cha nn elMode;/* such as int, POLL modes */UINT32regDelta;/* register address spacing */intbaudRate;/* the curre nt baud rate */UINT32xtal;/* UART clock freque ncy */ ST16554_CHAN;/* structure used as p arameter to mul

42、t ipl exed in terr upt han dier */typ edef struct st16554_mux int/* ST16554_MUX */* next cha nnel to exam ine on int */n extCha n;ST16554_CHAN *p Cha n; ST16554_MUX;st116554_cha n第一项:标准SIO_CHAN吉构,用于xxDrv与ttyDrv 的通讯接下来是:两个回调函数及参数,用于:当回调需要发生时,把回调函数和参数存放在这里/* array of ST16554_CHAN structs */regs:通道寄存器地

43、址 level:中断级别(号) ier:ier寄存器的软件拷贝icr:icr寄存器的软件拷贝channelmode:通道工作方式(中断模式,轮巡模式) regDelta:寄存器步长baudrate:波特率 xtal:时钟频率st16554_mux:这个结构极其简单,用来存放多重中断服务程序的参数 nextchan:下个需要检查的通道pCha n:指向当前通道的描述结构所有的xxDrv都有类似的框架结构xxCallbaackI nstallxxDevI nitxxTxStart upxxI ntTxxxIn tRcvxxIoCtlxxModeSetxxP olll np utxxP ollOut putxxI ntxxIn tMux驱动回调安装程序int xxCallback In stall( pSsioCha n, callbackT yp e,callback,callbbackArg)pSioChan 指向 SIO_CHAN的指针callbackType SIO CALLBACK GET TX CHAR 或 SIO CALLBACK PUT RCV CHARcallback指向回调

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论