papa123

papa123

0个粉丝

41

问答

0

专栏

11

资料

papa123  发布于  2009-06-25 15:59:35
采纳率 0%
41个问答
3982

Wince 串口驱动详解-转载

 

1、(oalintr.h)注册串口中断 //SP-A1 /* 打开oalintr.h文件,我们添加一个新的串口,并定义中断号。 添加: //SP-A8没什么说的就是注册中断

define SYSINTR_SERIAL1 (SYSINTR_FIRMWARE+19)

这里,我们可以看到SYSINTR_SERIAL1定义到16+19=35=0x23,与注册表中一致。 然后修改下这个地方: MapIrq2SysIntr(DWORD _Irq) { if( _Irq<=19 ) return ( SYSINTR_FIRMWARE + _Irq ); else return (0xffffffff); }
*/

2、(armint.c)在ISR中进行中断判断,中断使能 //SP-A2 /* //SP-A9其中IntPendVal= s2410INT->rINTOFFSET //INTOFFSET是中断偏移寄存器,显示中断请求源,跟SRCPND一样//在IRQ模式中,该寄存器显示INTPND寄存器中的中断请求

搜索:else if(IntPendVal == INTSRC_UART0) 在其后面添加:

//SP-A10此处进行中断请求源的判断。INTSRC_UART1被定义为UART1的中断号,即SRCPND==23 else if(IntPendVal == INTSRC_UART1) { //SP-A11 SUBSRCPND中包含一些中断请求的细节,对于串口就是INT_ERR、INT_RXD、INT_TXD //用于进一步判断中断类型 SubIntPendVal = s2410INT->rSUBSRCPND;

// Note that we only mask the sub source interrupt - the serial driver will clear the // sub source pending register. // //SP-A11.1如果是ERR1则该位置0,解除该位中断屏蔽INTSUBMSK if(SubIntPendVal & INTSUB_ERR1) { s2410INT->rINTSUBMSK |= INTSUB_ERR1; } else if(SubIntPendVal & INTSUB_RXD1) //SP-A11.2 RXD1,解除该位中断屏蔽INTSUBMSK { s2410INT->rINTSUBMSK |= INTSUB_RXD1; } else if(SubIntPendVal & INTSUB_TXD1) //SP-A11.3 TXD1, { s2410INT->rINTSUBMSK |= INTSUB_TXD1; } else { return(SYSINTR_NOP); //SP-A11.4什么都没发生 }

// NOTE: Don't clear INTSRC:UART1 here - serial driver does that. // //SP-A12解放对应位的总中断屏蔽,此时中断请求IRQ已经传达给CPU s2410INT->rINTMSK |= BIT_UART1;

//SP-A13 INTPND显示哪个中断处于非屏蔽且等待服务的状态,即“该中断被确定了(asserted 1)”,“相对于pending(待定)” //现在判断完成,即“该中断被确定了,所以向它发1,将之置0,清除中断请求 if (s2410INT->rINTPND & BIT_UART1) s2410INT->rINTPND = BIT_UART1;

//SP-A14向Wince发出对应的逻辑中断处理请求 return(SYSINTR_SERIAL1);

} */

3、(cfw.c)在IST中进行对应中断的使能和禁止 /* //SP-A15此处是串行中断初始化,将所有串行中断屏蔽unmask,将所有串行中断残留pending清除。 BOOL OEMInterruptEnable(DWORD idInt, // @parm Interrupt ID to be enabled. See <l Interrupt ID's.Interrupt ID's> for a list of possble values. LPVOID pvData, // @parm ptr to data passed in in the call DWORD cbData) // @parm Size of data pointed to be

找到这一句:case SYSINTR_SERIAL: 在其后面添加:

case SYSINTR_SERIAL1: // Serial port1. s2410INT->rSUBSRCPND = (INTSUB_RXD1 | INTSUB_TXD1 | INTSUB_ERR1); s2410INT->rINTSUBMSK &= ~INTSUB_RXD1;
s2410INT->rINTSUBMSK &= ~INTSUB_TXD1; s2410INT->rINTSUBMSK &= ~INTSUB_ERR1; s2410INT->rSRCPND = BIT_UART1;
// S3C2410X Developer Notice (page 4) warns against writing a 1 to a 0 bit in the INTPND register. if (s2410INT->rINTPND & BIT_UART1) s2410INT->rINTPND = BIT_UART1; s2410INT->rINTMSK &= ~BIT_UART1;
break;

//SP-A16此处是串行中断禁止,即屏蔽所有串行中断位 搜索: void OEMInterruptDisable(DWORD idInt) // @parm Interrupt ID to be disabled. See <t Interrupt ID's> 还是这一句:case SYSINTR_SERIAL: 在其后面添加:

case SYSINTR_SERIAL1: s2410INT->rINTMSK |= BIT_UART1; s2410INT->rINTSUBMSK |= INTSUB_RXD1; s2410INT->rINTSUBMSK |= INTSUB_TXD1; s2410INT->rINTSUBMSK |= INTSUB_ERR1; break;

//SP-A17解除屏蔽? 搜索: void OEMInterruptDone(DWORD idInt) // @parm Interrupt ID. See <t Interrupt ID's> 依旧找到case SYSINTR_SERIAL: 在其后面添加:

case SYSINTR_SERIAL1: s2410INT->rINTMSK &= ~BIT_UART1; s2410INT->rINTSUBMSK &= ~INTSUB_RXD1; break;

*/

4、(ser2410_hw.c)驱动程序进行处理 //SP-A4 /* 打开串口源文件中ser2410_hw.c文件。 搜索: S2410_SetSerialIOP( PVOID pHead // @parm points to device head ) 将其函数改为:

{ //SP-A18 2410串口信息结构体 PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead; PSER_INFO pHWHead1 = (PSER_INFO)pHead;

RETAILMSG(DEBUGMODE, (TEXT("S2410_SetSerialIOP \r\n"))); if(pHWHead1->dwIOBase == 0x50004000) //SP-UART1 LINE CONTROL {

if USEVIRTUAL

EnterCriticalSection(&(pHWHead->RegCritSec)); v_pIOPregs->rGPHCON &= ~(0x3<<8 | 0x3<<10 /| 0x3<<12 | 0x3<<14/); // clear uart 1 - rx, tx v_pIOPregs->rGPHCON |= (0x2<<8 | 0x2<<10 /| 0x1<<12 | 0x0<<14/); v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 ); v_pIOPregs->rGPHUP |= 0x03; pHWHead->rDTRport = (volatile unsigned int )&(v_pIOPregs->rGPHDAT); pHWHead->rDSRport = (volatile unsigned int )&(v_pIOPregs->rGPHDAT); pHWHead->DtrPortNum = 0; pHWHead->DsrPortNum = 1;

else

volatile IOPreg s2410IOP; s2410IOP = (volatile IOPreg )IOP_BASE;

EnterCriticalSection(&(pHWHead->RegCritSec)); //SP-A19 IO口设置 s2410IOP->rGPHCON &= ~(0x3<<8 | 0x3<<10/ | 0x3<<12 | 0x3<<14/); // clear uart 1 - rx, tx s2410IOP->rGPHCON |= (0x2<<8 | 0x2<<10 /| 0x1<<12 | 0x0<<14/); s2410IOP->rGPHCON |= (0x2<<0 | 0x2<<2 ); s2410IOP->rGPHUP |= 0x03; pHWHead->rDTRport = (volatile unsigned int )(IOP_BASE+0x74); //s2410IOP->rGPHDAT pHWHead->rDSRport = (volatile unsigned int )(IOP_BASE+0x74); pHWHead->DtrPortNum = 0; pHWHead->DsrPortNum = 1;

endif

} else if(pHWHead1->dwIOBase == 0x50008000) //SP-UART2 LINE CONTROL {

if USEVIRTUAL

EnterCriticalSection(&(pHWHead->RegCritSec)); v_pIOPregs->rGPHCON &= ~( 0x3<<12 | 0x3<<14); // clear uart 2 - rx, tx v_pIOPregs->rGPHCON |= ( 0x2<<12 | 0x2<<14); v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 ); v_pIOPregs->rGPHUP &= ~0xc0; pHWHead->rDTRport = (volatile unsigned int )&(v_pIOPregs->rGPHDAT); pHWHead->rDSRport = (volatile unsigned int )&(v_pIOPregs->rGPHDAT); pHWHead->DtrPortNum = 0; pHWHead->DsrPortNum = 1;

else

volatile IOPreg s2410IOP; s2410IOP = (volatile IOPreg )IOP_BASE;

EnterCriticalSection(&(pHWHead->RegCritSec)); s2410IOP->rGPHCON &= ~(0x3<<12 | 0x3<<14); // clear uart 2 - rx, tx s2410IOP->rGPHCON |= ( 0x02<<12 | 0x02<<14); s2410IOP->rGPHCON |= (0x2<<0 | 0x2<<2 ); s2410IOP->rGPHUP &= ~0xc0; pHWHead->rDTRport = (volatile unsigned int )(IOP_BASE+0x74); //s2410IOP->rGPHDAT pHWHead->rDSRport = (volatile unsigned int )(IOP_BASE+0x74); pHWHead->DtrPortNum = 0; pHWHead->DsrPortNum = 1;

endif

} else //SP-UART? LINE CONTROL {

if USEVIRTUAL

EnterCriticalSection(&(pHWHead->RegCritSec)); v_pIOPregs->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6/ | 0x3<<12 | 0x3<<14/); // clear uart 0 - rx, tx v_pIOPregs->rGPHCON |= (0x2<<4 | 0x2<<6/ | 0x1<<12 | 0x0<<14/); v_pIOPregs->rGPHCON |= (0x2<<0 | 0x2<<2 ); v_pIOPregs->rGPHUP |= 0x03; pHWHead->rDTRport = (volatile unsigned int )&(v_pIOPregs->rGPHDAT); pHWHead->rDSRport = (volatile unsigned int )&(v_pIOPregs->rGPHDAT); pHWHead->DtrPortNum = 0; pHWHead->DsrPortNum = 1;

else

volatile IOPreg s2410IOP; s2410IOP = (volatile IOPreg )IOP_BASE;

EnterCriticalSection(&(pHWHead->RegCritSec)); s2410IOP->rGPHCON &= ~(0x3<<0 | 0x3<<2 | 0x3<<4 | 0x3<<6 /| 0x3<<12 | 0x3<<14/); // clear uart 0 - rx, tx s2410IOP->rGPHCON |= (0x2<<4 | 0x2<<6 /| 0x1<<12 | 0x0<<14/); s2410IOP->rGPHCON |= (0x2<<0 | 0x2<<2 ); s2410IOP->rGPHUP |= 0x03; pHWHead->rDTRport = (volatile unsigned int )(IOP_BASE+0x74); //s2410IOP->rGPHDAT pHWHead->rDSRport = (volatile unsigned int )(IOP_BASE+0x74); pHWHead->DtrPortNum = 0; pHWHead->DsrPortNum =1;

endif

} LeaveCriticalSection(&(pHWHead->RegCritSec)); }

接着搜索: SL_Init( PVOID pHead, // @parm points to device head PUCHAR pRegBase, // Pointer to 16550 register base UINT8 RegStride, // Stride amongst the 16550 registers EVENT_FUNC EventCallback, // This callback exists in MDD PVOID pMddHead, // This is the first parm to callback PLOOKUP_TBL pBaudTable // BaudRate Table ) 在PS2410_UART_INFO pHWHead = (PS2410_UART_INFO)pHead;这一句后面添加:

PSER_INFO pHWHead1 = (PSER_INFO)pHead;

再搜索: if ( pHWHead->UseIrDA ) { pHWHead->bINT = BIT_UART2; pHWHead->bTxINT = INTSUB_TXD2; pHWHead->bRxINT = INTSUB_RXD2; pHWHead->bErrINT = INTSUB_ERR2;

if USEVIRTUAL

pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART2regs; pRegBase = (PUCHAR)pHWHead->s2410SerReg;

else

pRegBase = (PUCHAR)UART2_BASE; pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;

endif

} else { 把这其中的代码修改为以下代码 }

if(pHWHead1->dwIOBase == 0x50004000) { pHWHead->bINT = BIT_UART1; pHWHead->bTxINT = INTSUB_TXD1; pHWHead->bRxINT = INTSUB_RXD1; pHWHead->bErrINT = INTSUB_ERR1;

if USEVIRTUAL

 pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART1regs;
 pRegBase = (PUCHAR)pHWHead->s2410SerReg;

else

 pRegBase = (PUCHAR)UART1_BASE;
 pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;

endif

} else if(pHWHead1->dwIOBase == 0x50008000) { pHWHead->bINT = BIT_UART2; pHWHead->bTxINT = INTSUB_TXD2; pHWHead->bRxINT = INTSUB_RXD2; pHWHead->bErrINT = INTSUB_ERR2;

if USEVIRTUAL

 pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART2regs;
 pRegBase = (PUCHAR)pHWHead->s2410SerReg;

else

 pRegBase = (PUCHAR)UART2_BASE;
 pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;

endif

} else {

 pHWHead->bINT = BIT_UART0;
 pHWHead->bTxINT = INTSUB_TXD0;
 pHWHead->bRxINT = INTSUB_RXD0;
 pHWHead->bErrINT = INTSUB_ERR0;

if USEVIRTUAL

 pHWHead->s2410SerReg = (S2410_UART_REG *)v_pUART0regs;
 pRegBase = (PUCHAR)pHWHead->s2410SerReg;

else

 pRegBase = (PUCHAR)UART0_BASE;
 pHWHead->s2410SerReg = (S2410_UART_REG *)pRegBase;

endif

}

再搜索: if ( pHWHead->UseIrDA ) { pHWHead->pUFTXH = (volatile unsigned char )&(v_pUART2regs->rUTXH); pHWHead->pUFRXH = (volatile unsigned char )&(v_pUART2regs->rURXH);
} else { 把这其中的代码修改为以下代码 }

if(pHWHead1->dwIOBase == 0x50004000) { pHWHead->pUFTXH = (volatile unsigned char )&(v_pUART1regs->rUTXH); pHWHead->pUFRXH = (volatile unsigned char )&(v_pUART1regs->rURXH); } else if(pHWHead1->dwIOBase == 0x50008000) { pHWHead->pUFTXH = (volatile unsigned char )&(v_pUART2regs->rUTXH); pHWHead->pUFRXH = (volatile unsigned char )&(v_pUART2regs->rURXH);
} else { pHWHead->pUFTXH = (volatile unsigned char )&(v_pUART0regs->rUTXH); pHWHead->pUFRXH = (volatile unsigned char )&(v_pUART0regs->rURXH);
}

*/

5、(ser2410_ser.c)驱动程序进一步处理 //SP-A4 */ 搜索: const HWOBJ IoObj = { THREAD_AT_INIT, SYSINTR_SERIAL, (PHW_VTBL) &IoVTbl }; 在其后面添加:

const HWOBJ Io1Obj = { THREAD_AT_INIT, SYSINTR_SERIAL1, (PHW_VTBL) &IoVTbl };

const HWOBJ Io2Obj = { THREAD_AT_INIT, SYSINTR_IR, (PHW_VTBL) &IoVTbl };

接着搜索: const PCHWOBJ HWObjects[] = { &IoObj, &IrObj }; 将其修改为:

const PCHWOBJ HWObjects[] = { &IoObj, &Io1Obj, &Io2Obj };

再搜索: GetSerialObject( DWORD DeviceArrayIndex ) 将其函数改为:

{ PHWOBJ pSerObj;

DEBUGMSG(DEBUGMODE,(TEXT("GetSerialObject : DeviceArrayIndex = %d\r\n"), DeviceArrayIndex));

// Now return this structure to the MDD. if ( DeviceArrayIndex == 2 ) {
RETAILMSG(1,(TEXT("GetSerialObject Io2Obj\r\n"))); pSerObj = (PHWOBJ)(&Io2Obj); } else if(DeviceArrayIndex == 1) pSerObj = (PHWOBJ)(&Io1Obj); else pSerObj = (PHWOBJ)(&IoObj);

return (pSerObj); } */

6、在CEC中增加特性 //SP-A6 /* 添加UART1这个feature。 搜索 ComponentType ( Name ( "Serial" ) GUID ( {6563AD6C-E71C-11D4-B892-0050FC049781} ) MaxResolvedImpsAllowed( 999 ) Implementations ( Implementation ( Name ( "S32410 Serial UART" ) 在其后面添加:

Implementation
( Name ( "S32410 Serial UART1" ) GUID ( {7C4427A5-286C-4C7A-B687-4E3B364D079B} ) Description ( "Samsung S32410 serial UART controller." ) BSPPlatformDir ( "smdk2410" ) Version ( "5.0.0.0" ) Locale ( 0409 ) Vendor ( "Microsoft" ) Date ( "2003-1-13" ) SizeIsCPUDependent( 1 ) BuildMethods ( BuildMethod ( GUID ( {07DA2083-6261-4ED6-B5BB-70CF4D930D68} ) Step ( BSP ) CPU ( "ARMV4" ) CPU ( "ARMV4I" ) Action ( '#BUILD(SOURCES,"$(_WINCEROOT)\PLATFORM\SMDK2410\drivers\serial")') ) ) ) */

7、修改注册表 //SP-A7 /* 打开platform.reg文件,这个是WinCE注册表文件,在这里,我们要修改并添加串口。 搜索:[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410],这就是串口1。 将其下面的键值改为:

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410] "DeviceArrayIndex"=dword:0 "Irq"=dword:13 "IoBase"=dword:50000000 "IoLen"=dword:2C "Prefix"="COM" "Dll"="SER2410.Dll" "Order"=dword:0 "Priority"=dword:0 "Port"="COM1:" "DeviceType"=dword:0 "FriendlyName"="Serial Cable on COM1:" "Tsp"="Unimodem.dll" "DevConfig"=hex: 10,00, 00,00, 05,00,00,00, 10,01,00,00, 00,4B,00,00, 00,00, 08, 00, 00, 00,00,00,00

再在其后面添加串口2:

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410_2] "DeviceArrayIndex"=dword:1 "Irq"=dword:23 "IoBase"=dword:50004000 "IoLen"=dword:2C "Prefix"="COM" "Dll"="SER2410.Dll" "Order"=dword:1 "Priority"=dword:0 "Port"="COM2:" "DeviceType"=dword:0 "FriendlyName"="Serial Cable on COM2:" "Tsp"="Unimodem.dll" "DevConfig"=hex: 10,00, 00,00, 05,00,00,00, 10,01,00,00, 00,4B,00,00, 00,00, 08, 00, 00, 00,00,00,00

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\SER2410_2\Unimodem] "Tsp"="Unimodem.dll" "DeviceType"=dword:0 "FriendlyName"="SER2410_2 UNIMODEM" "DevConfig"=hex: 10,00, 00,00, 05,00,00,00, 10,01,00,00, 00,4B,00,00, 00,00, 08, 00, 00, 00,00,00,00

再搜索:[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\IRDA2410],这个是红外,也要修改下:

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\IRDA2410] "DeviceArrayIndex"=dword:2 "Irq"=dword:19 "IoBase"=dword:50008000 "IoLen"=dword:2C "Prefix"="COM" "Dll"="IRDA2410.Dll" "Order"=dword:0 "Priority"=dword:0 "Port"="COM3:" "DeviceType"=dword:0 ; IRDA modem, 0 -> null modem "FriendlyName"="S2410 IRDA2410" "Index"=dword:2 "IClass"="{A32942B7-920C-486b-B0E6-92A702A99B35}"

好了,注册表就改到这里,以上要特别注意Irq的值,要和oalintr.h里面的中断定义对应,并且注意Order的顺序,DeviceArrayIndex的值以及IoBase,后面串口源代码中要用到该值作判断。

*/

易百纳技术社区文件: SERIAL.rar
下载
我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区