11129|29

71

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

2440下16C554串口扩展问题 [复制链接]

平台 2440
系统 wince 5.0
芯片 TL16C554a
  
利用微软的16550的代码架构驱动16C554,通过修改pdd层,配置相关的注册表项,目前系统已经可以加载4个串口了,利用调试软件可以打开,关闭。由于扩展的4个串口目前不对外使用,为内部提供给GPRS、GPS使用,因此进行发送测试是通过观察示波器结合打印调试信息完成的,观察到的情况是,发送1个字节 AA  示波器显示是正确的,但如果发送多个字节(长度超过FIFO 深度16)则每次只能发送FIFO 深度值,即最多16个。感觉像是中断线程没有执行。
后对线程部分的调试信息进行分析,似乎线程应该执行,只是不符合再次触发中断的条件,下面是我在发送数据是打印的调试信息

LEO: CPdd16550 XmitInterruptHandler dwDataAvaiable C8   
LEO: CPdd16550 GetLineStatus bData FF
LEO: CPdd16550 SERIAL_LSR_OE failed 2
LEO: CPdd16550 SERIAL_LSR_PE failed 4
LEO: CPdd16550 SERIAL_LSR_FE failed 8  
LEO: CPdd16550 GetWriteableSize dwWriteSize 10
LEO: CPdd16550 XmitInterruptHandler dwWriteSize 10  
CPdd16550::XmitInterruptHandler! Write 16 byte to FIFO   
LEO: CPdd16550 XmitInterruptHandler pBuffLen 10
CPdd16550::ThreadRun IIR=8
CPdd16550::ThreadRun IIR=16   
LEO: CPdd16550 GetLineStatus bData 0  
CPdd16550::NotifyPDDInterrupt interrupts=1
CPdd16550::ThreadRun IIR=18
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=0   
CPdd16550::NotifyPDDInterrupt interrupts=8   
CPdd16550::ThreadRun IIR=18  
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=18  
CPdd16550::NotifyPDDInterrupt interrupts=0   
CPdd16550::ThreadRun IIR=18
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=18   
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=10  
CPdd16550::NotifyPDDInterrupt interrupts=8
CPdd16550::ThreadRun IIR=18
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=18
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=18
CPdd16550::NotifyPDDInterrupt interrupts=0  
CPdd16550::ThreadRun IIR=18
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=18  
CPdd16550::NotifyPDDInterrupt interrupts=0
CPdd16550::ThreadRun IIR=d0
CPdd16550::NotifyPDDInterrupt interrupts=8   
CPdd16550::InterruptDone m_dwSysIntr=15
LEO: CPdd16554SerialA init, m_pIOPregs->GPFCON 55AA
LEO: CPdd16554SerialA init, m_pIOPregs->GPGCON 580FFBA  
LEO: CPdd16554SerialA init, m_pIOPregs->EXTINT0 22222222
LEO: CPdd16554SerialA init, m_pIOPregs->EXTINT1 22222242
LEO: CPdd16554SerialA init, m_pIOPregs->EXTINT2 22222222   
LEO: CPdd16554SerialA init, m_pIOPregs->EINTMASK FFFDF0
  
我一直感觉是我读到的16C554寄存器的值不对,可能是地址不对,或者是别的什么原因。  
在进行寄存器初始化的时候,执行了

CReg16550::CReg16550(PBYTE pRegAddr, DWORD dwStride)   
:   m_pReg (pRegAddr)
,   m_dwStride(dwStride)
{   
    m_pData =  pRegAddr + (dwStride * RECEIVE_BUFFER_REGISTER);     
    m_pIER  =  pRegAddr + (dwStride * INTERRUPT_ENABLE_REGISTER);   
    m_pIIR_FCR=pRegAddr + (dwStride * INTERRUPT_IDENT_REGISTER);   
    m_pLCR  =  pRegAddr + (dwStride * LINE_CONTROL_REGISTER);   
    m_pMCR  =  pRegAddr + (dwStride * MODEM_CONTROL_REGISTER);  
    m_pLSR  =  pRegAddr + (dwStride * LINE_STATUS_REGISTER);  
    m_pMSR  =  pRegAddr + (dwStride * MODEM_STATUS_REGISTER);
    m_pSRC  =  pRegAddr + (dwStride * SCRATCH_REGISTER);  
    m_FCR = 0;  
    m_fIsBackedUp = FALSE;  

这里的dwstride是默认的值1,是不是这个地方的问题?

我的片选是nGCS1,4个串口的对应地址是 0x08080000, 0x08090000, 0x080A0000, 0x080B0000
中断是  EINT3, EINT8,EINT17,EINT18

另外,我想知道怎么样能知道我当前配置的物理地址经过mmu是正确的。
我找不原因了,已经好几天了,快崩溃了

最新回复

我想问你下,能不能把s3c2440下用16c554扩展的串口原理图发上来啊?感激不尽  详情 回复 发表于 2009-12-9 09:23
点赞 关注

回复
举报

69

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
大家都一样,只要波特率高了,扩展串口就反应不过来。

只能一次性发送
16byte

MMU在启动的时候做了映射,楼主对应内存映射表看就可以了。
 
 

回复

68

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
LEO: CPdd16550 GetLineStatus bData FF
这个得到的是LSR的数值,怎么感觉不对啊

还有后面的IIR的值,也是很不符合常理,所以才怀疑我的554芯片的寄存器地址有问题,所以读出来的不对呢

如果这些都是对的,我可能需要在好好看看S3C2440的datasheet了
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

4
 
m_pData =  pRegAddr + (dwStride * RECEIVE_BUFFER_REGISTER);   拿这句代码来分析,其实就是16654中的一个串口的数据寄存器地址,其中pRegAddr是串口的基地址,dwStride * RECEIVE_BUFFER_REGISTER是数据寄存器的偏移地址,dwStride=1是对的针对微软提供的代码来说,关键就是pRegAddr,既然一个能发出去,那么地址应该没什么问题,参考中断发送函数XmitInterruptHandler中代码
            DWORD dwWriteSize = GetWriteableSize();
            for (DWORD dwByteWrite=0; dwByteWrite                 __try {
                    m_pReg16550->Write_DATA(*pTxBuffer);
                }
                __except( EXCEPTION_EXECUTE_HANDLER ) { // Make sure it end normally.
                    dwDataAvaiable = 1 ;
                    dwByteWrite = dwWriteSize-1;
                }
                pTxBuffer ++;
                dwDataAvaiable--;
            }
            DEBUGMSG(ZONE_WRITE,(TEXT("CPdd16550::XmitInterruptHandler! Write %d byte to FIFO\r\n"),dwByteWrite));
            *pBuffLen = dwByteWrite;
            EnableXmitInterrupt(TRUE);   
在最好面执行EnableXmitInterrupt(TRUE),使能了发送中断,所以如果发大于16个字节不出去,应该和你的中断有关系,从你的打印中发现XmitInterruptHandler只执行一次,所以应该从你的中断信号入手,测量16554的中断输出脚,如果有信号,则要看你wince是否检测到EINT3, EINT8,EINT17,EINT18中的中断
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

5
 
周末测试了一下输出的数据,发现波特率不对,好像只有1200的大小,我初始化的时候设置的也不只这个值,在处理过程中也对波特率进行了设置,问题好像是,要么我的寄存器的地址映射的就不对,要么就是我操作寄存器的方式有问题,有人遇到这个问题吗
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

6
 
将你的触发深度设低试下,提高中断优先级。
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(初级)

7
 
引用 3 楼 xunjingzhpu 的回复:
m_pData =  pRegAddr + (dwStride * RECEIVE_BUFFER_REGISTER);  拿这句代码来分析,其实就是16654中的一个串口的数据寄存器地址,其中pRegAddr是串口的基地址,dwStride * RECEIVE_BUFFER_REGISTER是数据寄存器的偏移地址,dwStride=1是对的针对微软提供的代码来说,关键就是pRegAddr,既然一个能发出去,那么地址应该没什么问题,参考中断发送函数XmitInterruptHandler中代码
            DWORD dwWriteSize = GetWriteableS…

中断配置的不对
 
 
 

回复

69

帖子

0

TA的资源

一粒金砂(初级)

8
 
引用 3 楼 xunjingzhpu 的回复:
m_pData =  pRegAddr + (dwStride * RECEIVE_BUFFER_REGISTER);  拿这句代码来分析,其实就是16654中的一个串口的数据寄存器地址,其中pRegAddr是串口的基地址,dwStride * RECEIVE_BUFFER_REGISTER是数据寄存器的偏移地址,dwStride=1是对的针对微软提供的代码来说,关键就是pRegAddr,既然一个能发出去,那么地址应该没什么问题,参考中断发送函数XmitInterruptHandler中代码
            DWORD dwWriteSize = GetWriteableS…



这个分析有道理!
LZ,要么这样,你不用中断来检测和发送数据,直接用pooling方式看看~~
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

9
 
楼主将fifo中断促发条件设为8个字符。如果你觉得地址隐射不对,你可以用这个函数试试:TransBusAddrToVirtual。照理说,你用的微软16550,它bus类会调用那个函数。我在atmel9260上移植的扩展串口驱动,一开始也是用virtualcopy,不过直接报错。我想还是不能将SMC的物理地址当作普通物理地址对待,应该说是总线上的IO地址。
 
 
 

回复

77

帖子

0

TA的资源

一粒金砂(初级)

10
 
这个怎么理解,我今天有重点看了一下2440的中断,我已经把我需要的4个中断进行了设置,是不是554的中断设置,这个我不是很清楚了
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

11
 
554 用的是外部中断啊。哈哈
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

12
 
引用 8 楼 kuron 的回复:
楼主将fifo中断促发条件设为8个字符。如果你觉得地址隐射不对,你可以用这个函数试试:TransBusAddrToVirtual。照理说,你用的微软16550,它bus类会调用那个函数。我在atmel9260上移植的扩展串口驱动,一开始也是用virtualcopy,不过直接报错。我想还是不能将SMC的物理地址当作普通物理地址对待,应该说是总线上的IO地址。

这个就是我一直怀疑的,我向554的寄存器里面写的值根本就不能在读回来,都是不对的,中断那部分也是因为寄存器的条件不符合才没有再次触发发送的中断,试试你的方法看看
 
 
 

回复

89

帖子

0

TA的资源

一粒金砂(初级)

13
 
引用 11 楼 leo_xuxiaohui 的回复:
引用 8 楼 kuron 的回复:
楼主将fifo中断促发条件设为8个字符。如果你觉得地址隐射不对,你可以用这个函数试试:TransBusAddrToVirtual。照理说,你用的微软16550,它bus类会调用那个函数。我在atmel9260上移植的扩展串口驱动,一开始也是用virtualcopy,不过直接报错。我想还是不能将SMC的物理地址当作普通物理地址对待,应该说是总线上的IO地址。


这个就是我一直怀疑的,我向554的寄存器里面写的值根本就不能在读回来,都…

假如你的寄存器地址有问题,那你往发送寄存器里写数据,串口是不可能发送数据出去的,把你的nGCS1地址映射表发上来看看基地址是否有问题
 
 
 

回复

48

帖子

0

TA的资源

禁止发言

14
 
你如果怀疑可能是中断问题,那你就先不用中断,用轮询的方式来发送数据作个测试不就可以定位问题了吗?
建议先缩小范围,再排查。
 
 
 

回复

66

帖子

0

TA的资源

一粒金砂(初级)

15
 
今天忙别的去了,没有给大家通报情况。昨天修改了地址映射的方式,结果是一样的。明天上班好好研究一下中断的问题
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

16
 
uping
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

17
 
楼主弄好了吗?我也是用16C554扩展串口,现在还没有搞定~
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

18
 
还没有进展啊!
问题低级问题:用550的代码修改时,在进行MapHardware时,应该用dwi.memWindows[0].dwBase还是用dwi.ioWindows[0].dwBase啊,我g到的说法都是说iowindows是X86平台的,如果是ARM平台,这个就要用memwindows呢,是不是这么回事
 
 
 

回复

59

帖子

0

TA的资源

一粒金砂(初级)

19
 
引用 17 楼 leo_xuxiaohui 的回复:
还没有进展啊!
问题低级问题:用550的代码修改时,在进行MapHardware时,应该用dwi.memWindows[0].dwBase还是用dwi.ioWindows[0].dwBase啊,我g到的说法都是说iowindows是X86平台的,如果是ARM平台,这个就要用memwindows呢,是不是这么回事

这跟你的注册表里设置有关
通过调用GetWindowInfo函数获取注册表信息
DDKWINDOWINFO dwi;
GetWindowInfo( &dwi);
typedef struct _DDKWINDOWINFO_tag {
        DWORD        cbSize;                                        // size of this structure
        DWORD        dwBusNumber;                        // PCI bus number
        DWORD        dwInterfaceType;                // INTERFACE_TYPE value (probably PCI == 5)
        DWORD        dwNumIoWindows;                        // number of I/O windows
        DEVICEWINDOW ioWindows[MAX_DEVICE_WINDOWS];
        DWORD        dwNumMemWindows;                // number of memory windows
        DEVICEWINDOW memWindows[MAX_DEVICE_WINDOWS];
} DDKWINDOWINFO, *PDDKWINDOWINFO;
如果注册表中是"IoBase"=dword:30000100那么 dwi.ioWindows[0].dwBase就是30000100
如果注册表中是"MemBase"=dword:7C200000那么dwi.memWindows[0].dwBase就是7C200000
其实这些东西东西你只要打印出来就知道,听别人说不如自己试验下
 
 
 

回复

65

帖子

0

TA的资源

一粒金砂(初级)

20
 
问题已经解决了,明天详细解释问题的原因,相信大家会笑话我的
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表