wince下TL16C554串口驱动问题,大侠们过来帮帮我呀!

ismyway26   2007-5-18 22:37 楼主
我在ADS下已经调通了,收、发、中断都没有问题,但是在ce下就是死活不行,参考了网上(包括这个版面)上其

他弟兄的文章,但是就是不行。我先讲一下我的做法。
这个TL16C554是独立的四个通道串口芯片,所以我现在一直在调1通道。
1. A通道的片选接到了ngCS5上面,中断接到了EINT0上。这样A通道的物理地址应该是0X28000000。
2.首先配置了BANK5为8为数据宽度,在memcfg.a里面改B5_BWSCON        EQU        (DW16)为
B5_BWSCON        EQU        (DW8),时序没有修改,读写时序应该能匹配。
然后配置中断
3. oalintr.h 里面加上:
#define SYSINTR_16550                           (SYSINTR_FIRMWARE+20)
4. armint.c 里面加上:
        else if (IntPendVal == INTSRC_EINT0)  { // 16550
                s2410INT->rINTMSK |= BIT_EINT0;
                s2410INT->rSRCPND  = BIT_EINT0;       
                if (s2410INT->rINTPND & BIT_EINT0) s2410INT->rINTPND  = BIT_EINT0;
                return SYSINTR_16550;       
        }
5. cfw.c里面在OEMInitInterrupts里面加上EINT0的初始化:
        s2410IOP->rGPFCON  &= ~( 0x3 << 0);
        s2410IOP->rGPFCON  |=  ( 0x2 << 0);                // GPF0 == EINT0.
        s2410IOP->rGPFUP   = (s2410IOP->rGPFUP   |  0x1 );               
        s2410IOP->rEXTINT0 &= ~(0x7 << 0);                 //  rising edge triggered.
        s2410IOP->rEXTINT0 |=  (0x4 << 0);
在OEMInterruptEnable里面加上:
        case SYSINTR_16550:               
                s2410INT->rSRCPND  = BIT_EINT0;
                if (s2410INT->rINTPND & BIT_EINT0) s2410INT->rINTPND = BIT_EINT0;
                s2410INT->rINTMSK &= ~BIT_EINT0;
                break;
在OEMInterruptDisable加上
        case SYSINTR_16550:
                s2410INT->rINTMSK |= BIT_EINT0;
                break;   
在OEMInterruptDone加上:
        case SYSINTR_16550:               
                s2410INT->rSRCPND = BIT_EINT0;
                if (s2410INT->rINTPND & BIT_EINT0) s2410INT->rINTPND = BIT_EINT0;
                s2410INT->rINTMSK &= ~BIT_EINT0;
                break;
6. 把ce自带的16550驱动(com16550,ser16550,mdd_2,isr16550四个文件夹)拷贝到bsp下的driver文件夹,修改

每个文件夹中的source文件,增加RELEASETYPE=PLATFORM,并且把com16550文件夹下的source中删除了生成lib的

部分。
7. 由于我用的是16M的晶振,所以修改了com16550.c中的波特率表与手册上的除法器值匹配,我的硬件上芯片的

A0-A2分别与地址总线的A0-A2连接,所以g_dwRegStride为1,其他的地方基本没改,就是增加了调试输出信息。
8. 注册表修改如下:
[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\UART3]
   "DeviceArrayIndex"=dword:3
  "SysIntr"=dword:24 ;SYSINTR_FIRMWARE+20 = 16 +20 = 36 =0x24
   "Irq"=dword:14
   "IoBase"=dword:28000000
   "IoLen"=dword:08
   "Prefix"="COM"
   "Dll"="COM16550.Dll"
   "Order"=dword:0
   "Index"=dword:5
   "Priority"=dword:0
   "Port"="COM5:"
   "DeviceType"=dword:0
   "FriendlyName"="Serial Cable on COM5:"
   "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
   "IsrDll" = "isr16550.dll"
   "IsrHandler" = "ISRHandler"
9. 修改了platform.bib添加了com16550.dll和isr16550.dll。
10. 系统能加载COM16550驱动,也能在注册表的ACTIVE里面看到COM5,能打开COM5,但是接收不到任何字符,如果

一点发送的话程序就死了。停在了等待发送中断的那部分。
11. 我按照gerryzhou的方法又做了一个驱动(在2410串口驱动上直接添加554的驱动),修改方法和上面基本差不多

,注册表设置方法和gerryzhou也一样,效果比用ce自带的驱动要好些,至少能收到字符了,接收也产生了中断(

看到了armint.c中我加的调试输出),但是一次只能收一个字符,连发的话只能收到最后一个字符。点发送的话还

是死,在等待发送中断。。。
12. 我后来在这个串口初始化的时候往554的多个寄存器里面写了值,再读出来(我在ADS的驱动里面也写同样的值

,然后读出来),发现ce驱动和ADS驱动读出来的值不一样。ce下读出来的是错误的,我分析可能是寄存器的地址

不对,能接受到是因为接收缓冲区在0地址(说明我的基地址是对的,ce也映射对了),但是其他的寄存器地址我

也看了映射后的,顺序都是对的,但是就是读出来的和写的不匹配。我调试了很久也不知道为什么?

    以上就是我整个的调试过程,调试了很久了,心里非常着急,希望gerryzhou等大侠能帮我看看,哪儿还出了

问题,对了最后补充一点,ce的POWERBUTTON用到了EINT0,我去掉了它的驱动。谢谢呀!
    我的qq 29942206,或者给我发email联系 buaadallas@gmail.com再次感谢!

回复评论 (2)

谢谢大家呀!
点赞  2007-5-18 22:38
自己再顶!
点赞  2007-5-19 13:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复