我用的是s3c2410开发板+wince5.0。eINT13连接到16550的INT脚;
fpga (xc9536)的14脚 ST16c550_CS 经过244转换后,作为st16c550的片选;在cpld的程序中assign ST16c550_CS = nGCS1;
这样的话,相当于nGCS1作为片选,ST16c550的基地址该是0x0800_0000 这样理解不知道对不对?
1、在map.a(PLATFORM/SMDK2410/KERNEL/HAL/ARM/map.a)中找到了
DCD 0x82000000, 0x08000000, 32 ; 32 MB SROM(SRAM/ROM) BANK 1
这样platform.reg中 "IoBase"=dword:82000000 ;(是mmu后的虚地址,应该不是虚地址吧?)
--->根据大家的经验,这里是要写成物理地址"IoBase"=dword:08000000 对吧?
2、在cfw.c中(platform/smdk2410/kernel/hal/cfw.c)中
2.1 函数OEMInterruptEnable中添加
case SYSINTR_16550:
s2410IOP->rEINTPEND = (1<<13);
s2410IOP->rEINTMASK &= ~(1<<13);
s2410INT->rSRCPND = BIT_EINT8_23;
if (s2410INT->rINTPND & BIT_EINT8_23) s2410INT->rINTPND = BIT_EINT8_23;
s2410INT->rINTMSK &= ~BIT_EINT8_23;
RETAILMSG(1,(TEXT("::: SYSINTR_COM4 OEMInterruptEnable/r/n")));
break;
2.2 函数OEMInterruptDisable中添加:
case SYSINTR_16550:
s2410INT->rINTMSK |= BIT_EINT8_23;
s2410INT->rINTSUBMSK |= (1<<13);
break;
2.3 函数OEMInterruptDone中添加:
case SYSINTR_16550:
s2410INT->rINTMSK &= ~BIT_EINT8_23;
s2410IOP->rEINTMASK &= ~(1<<13);
break;
3、在arminit.c中,已经添加了16550的代码,贴出如下
函数OEMInterruptHandler中
else if (IntPendVal == INTSRC_EINT8_23)// EINT8 ~ 23
{
// ...............
if ( submask & (1 << 13))
{
s2410IOP->rEINTMASK |= 0x2000;
s2410IOP->rEINTPEND = 0x2000;
s2410INT->rSRCPND = BIT_EINT8_23;
if (s2410INT->rINTPND & BIT_EINT8_23) s2410INT->rINTPND = BIT_EINT8_23;
RETAILMSG(1, (TEXT("INT:SYSINTR_16550 INT........../r/n")));
return SYSINTR_16550;
}
// ...................
}
4、最后说明一点,SYSINTR_16550是在PLATFORM/SMDK2410/inc/oalintr.h中定义的,
#define SYSINTR_16550 (SYSINTR_FIRMWARE+20)
我直接用了。(开始还自己定义了一个#define SYSINTR_SERIAL4 (SYSINTR_FIRMWARE+24)后来发觉多余了,呵呵^_^)
5、platform.reg中的代码:
;=========try to add st16c550 begin 2007-2-17==============
[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/SERIAL4]
"DeviceArrayIndex" = dword:3
"SysIntr"=dword:24 ;SYSINTR_FIRMWARE+20 = 16 +20 = 36 =0x24
"Irq"=dword:14 ;20 = 0x14
;"MemBase" = dword:08000000
"IoBase" = dword:08000000
;"MemLen" = dword:10
"IoLen" = dword:2C
"Prefix"="COM"
"Dll" = "Com16550.Dll"
"Order"=dword:0
"Index"=dword:4
"Priority"=dword:0
"Port"="COM4:"
"Tsp"="Unimodem.dll"
"DeviceType"=dword:0
"FriendlyName"="Serial Cable on COM4:"
"DeviceConfig"=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
"IsrDll" = "isr16550.dll"
"IsrHandler" = "ISRHandler"
;[HKEY_LOCAL_MACHINE/Drivers/BuiltIn/Serial4/Unimodem]
; "Tsp"="Unimodem.dll"
; "DeviceType"=dword:0
; "FriendlyName"="Serial Cable on COM4:"
; "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
经过以上修改,build系统后,查看ce系统的注册表,active下有这个com4;打开串口成功,但是读写数据都不行。发送的时候,到writefile函数就死了,应该是没有返回;读取的时候应用程序倒是没有死掉,但是readfile返回读取的数据长度是0
有可能是哪里的问题呢?
另外,从输出的调试信息看,好像只是执行了OEMInterruptEnable ,其他的函数没有执行。
将GPG5配置成中断pin后,还是不行,现象一样;
另外贴出打印信息,请帮忙看一下
//=========com1(uart0)
<=SMILE=>+SerInit in ser2410_ser.c
<=SMILE=>+Ser_GetRegistryData IN ser2410_ser.c;Try to open Drivers/Active/03
<=smile=>SerInit - DevIndex 0, IRQ 3, IOBase 50000000, IOLen 2C
<=SMILE=>-Ser_GetRegistryData IN ser2410_ser.c
<=smile=>+Ser_InternalMapRegisterAddresses : HalTranslateBusAddress in ser2410_ser.c
<=smile=>Ser_InternalMapRegisterAddresses : HalTranslateBusAddress - OK
<=smile=>Ser_InternalMapRegisterAddresses : ! IO Space
<=smile=>- Ser_InternalMapRegisterAddresses : ioPortBase=1310720
<=SMILE=>SerInit - ppBootArgs (1FFFFC) at 150FFC
<=SMILE=>SerInit - pBootArgs (E1A07000) at 160000
<=SMILE=>SerInit - IRQ 3 = SYSINTR 19
<=SMILE=>SerInit - Init 16550 data
SL_Init : IRDA = 0
::: SER_VirtualAlloc()
::: SER_VirtualAlloc() - Success
+ S2410_SetIrDAIOP
S2410_SetIrDAIOP
- S2410_SetIrDAIOP
ClearPendingInts
<=SMILE=>SerInit - Disabling UART Power
SL_GetRxBufferSize
<=smile=>COM1(uart0_) OEMInterruptEnable in cfw.c
<smile>INT:SYSINTR_serial(com1,uart0) INT in OEMInterruptHandler of armint.c..........
<=smile=>::: SYSINTR_COM1(uart0) OEMInterruptDone in cfw.c
<smile>INT:SYSINTR_serial(com1,uart0) INT in OEMInterruptHandler of armint.c..........
SL_PostInit
ClearPendingInts
//=========com4(16550扩展)
<=smile=>+DllEntry in com_mdd2dbg
<=smile=>serial port process attach
<=smile=>-DllEntry function in com_mdd2dbg
<=smile=> +COM_Init in mdd.c of com_mdd2debug
<=smile=>Try to open Drivers/Active/06
<=smile=>DevIndex 3
<=smile=>About to call HWInit(Identifier=Drivers/Active/06,pSerialHead=0x39A50)
<=smile=>+CreateSerialObject in com16550.cpp.
<=smile=>+CPdd16550::Init in pdd16550.cpp of oo16550DBG.
<=smile=>COM4(_SYSINTR_16550_) OEMInterruptEnable in cfw.c
<=smile=>-CreateSerialObject in com16550.cpp.
<=smile=>Back from hardware init
<=smile=>RxHead init'ed
<=smile=>RxBuffer init'ed with start at 3a460
<=smile=>+CPdd16550::PostInit in pdd16550.cpp of oo16550DBG.
<=smile=>ThreadStart()==> Start IST in pdd16550.cpp of oo16550DBG.
SL_GetInterruptType : 0xEF73BF5F, 0x692, 0x2002C00, 0x92, 0x0, 0x0
<=smile=>-CPdd16550::PostInit in pdd16550.cpp of oo16550DBG.
No interrupts pending, vector is useless
<=smile=>-COM_Init
SL_GetInterruptType: INTR_NONE(pHWHead->bINT)