阅读:8663回复:44
SMBus 的base address的问题
我读取SMBus 的 PCI配置寄存器得到他的io base address是500h,但是对500h好像访问不了,不管我写进什么读出来都是0ffffh,请高手看看我的代码有什么问题
mov eax, 8000fb20h ;base address ;寄存器地址 mov edx, 0cf8h out dx, eax jcxz $+2 jcxz $+2 mov edx, 0cfch in eax, dx ;eax == 5001h shr eax,5 ;5~15位为ICH4 的SMB base io mov dx, ax in ax,dx ;ax == 0ffffh [编辑 - 6/28/04 by boly81] [编辑 - 6/28/04 by boly81] |
|
最新喜欢:![]() |
沙发#
发布于:2005-06-14 13:34
_outp(SmbusBase+2, 0x54); //start to this SMBus
上面这句体现了是读block数据。但是我不明白的是block读出来的数据是来自哪些寄存器的呢?datasheet上好像找不出来相关信息。 还有下面这句, _outp(SmbusBase+2, 0x20); datasheet的解释是Software sets this bit to indicate that the next byte will be the last byte to be received for the block. The ICH will send a NOT ACK (instead of an ACK) after receiving the last byte.这个在你的程序里有什么作用吗?岂不是block下面只会接受一个byte? 还有一个题外的问题就是每个联在smbus上的芯片应该都有一个独立的slave address,这个slave address它们是怎么确定不重复的呢?事先约定好的吗? 谢谢! |
|
板凳#
发布于:2005-06-09 11:51
void ReadSmbus(WORD SmbusBase,DWORD DeviceId)
{ BYTE buffer[0x80]; DWORD nPort=0x80; BYTE temp_al; const char *outputfilename=\"Smbus.bin\"; FILE *output; void Iodelay(); void check_busy(WORD SmbusBase); void check_done(WORD SmbusBase); void done(WORD SmbusBase); int n=0; output=fopen(outputfilename,\"w+b\"); _outp(SmbusBase+2, 0x20); _outp(SmbusBase+3, 0); //begin byte Iodelay(); _outp(SmbusBase+4, DeviceId+1); //set device no Iodelay(); _outp(SmbusBase+2, 0x54); //start to this SMBus operation.address Iodelay(); check_done(SmbusBase); temp_al=_inp(SmbusBase+5); Iodelay(); for(n=0;n<temp_al;n++) { buffer[n]=_inp(SmbusBase+7); Iodelay(); check_done(SmbusBase); } done(SmbusBase); Iodelay(); _outp(SmbusBase+2, 0x20); check_done(SmbusBase); Iodelay(); fclose(output); } void check_busy(WORD SmbusBase) { _asm{ mov cx,0xffff } xx: _asm{ mov dx,SmbusBase in al,dx out 0eah,al out dx,al and al,NOT 40h or al,al loopnz xx } } void done(WORD SmbusBase) { _asm{ mov dx, SmbusBase in al, dx out 0eah, al out dx, al } } void check_done(WORD SmbusBase) { void debug80(WORD al_data); int n=0; _asm{ mov cx,0ffffh } xx: _asm{ mov dx, SmbusBase in al, dx test al, 80h loopz xx in al, dx out dx, al } } 试试我写的这个吧。你送command的时候应该送block read吧 |
|
地板#
发布于:2005-06-08 14:33
sharpor,你的意思是读完第一个block的数据后重写smbase+03h,然后到smbase+07h去读数吗?
按理说我输入register index到smbase+03h后要读多少位应该由我决定,为什么要到smbase+05h去得到数值呢? 还有,我头痛的是为什么第一次读的值都是错的?现在把代码贴出来,能帮我分析一下吗?谢谢! mov dx,0c400h mov al,0ffh out dx,al mov cx,100h check: in al,dx test al,40h jz next nop loop check next: mov cx,5c24h push cx mov dx,0c400h +04h inc ch mov al,ch ;ID cmd(read) out dx,al nop nop pop ax mov dl,03h ;SMBus_Port +03h mov dh,0c4h ;zhou add out dx,al ;Index nop nop mov dl,02h ;SMBus_Port +02h mov al,48h out dx,al ;read data nop nop mov dh,0c4h ;zhou add mov dl,05 ; SMBus_Port +05h in al,dx ;Data0 mov nByteRead, ax ;get data here |
|
地下室#
发布于:2005-06-08 10:34
如果采用block方式读的话,我怎么确定读到的数值是来自register1和register2的呢?是把这两个地址都写到smbase+03h上去吗?写的过程中需不需要什么间隔之类的? smbase+7h是block的数据,smbase+5h读到的是block的data个数 每取一次smbase+7,写状态位,smbase +7 就得到下一个数据 |
|
5楼#
发布于:2005-06-06 13:33
如果采用block方式读的话,我怎么确定读到的数值是来自register1和register2的呢?是把这两个地址都写到smbase+03h上去吗?写的过程中需不需要什么间隔之类的?
|
|
6楼#
发布于:2005-06-06 12:24
那实际中该怎么写呢?
不知道有经验的人可不可以介绍一下? 用sharpor的方法我现在还有两个问题没有解决. 1.我每次开机第一次读的数值都是错误的,第二次才能得到正确数值. 2.同时读取两个寄存器数值的时候还是得到两个相同的错误数值. 仔细看了datasheet,各种检测标识位的方法也试过了,结果还是不行. 是不是重置寄存器的方法不对,或者除了bit1和bit6之外,还有那些bit需要检测? 希望有经验的朋友可以指点一下! 谢谢! |
|
7楼#
发布于:2005-05-31 14:10
datasheet 上的例子 只是show just as this ,实际应用不能靠他的
|
|
8楼#
发布于:2005-05-31 10:15
[quote我看到一些smbus例程也这样写。但是这句我不大明白:
out dx,al and al,NOT 40h ;强制把al的bit6标记为0?这样做有什么意义呢?datasheet上没有体现这一点啊 or al,al ;结果还不是al吗?为什么进行这步呢? 谢谢指点! [/quote] 结果还是al,但是标志位变了,这是为了下面的跳转指令用的。其实目的就是判断al的第6位是不是0,其实用一个test bit就可以实现...hehe |
|
9楼#
发布于:2005-05-31 08:41
[quote ]
Check_Busy proc near mov dx,SM_Base+00h xx: in al,dx IODELAY ;I/O delay. out dx,al and al,NOT 40h ;mask the INUSE bit or al,al jnz xx ret Check_Busy endp [/quote] 我看到一些smbus例程也这样写。但是这句我不大明白: out dx,al and al,NOT 40h ;强制把al的bit6标记为0?这样做有什么意义呢?datasheet上没有体现这一点啊 or al,al ;结果还不是al吗?为什么进行这步呢? 谢谢指点! |
|
10楼#
发布于:2005-05-30 16:44
我读的是byte。就是按你说的方法读的。每次先向smbase写0ffh重置状态,然后check 它的bit6。然后分别向偏移地址04h,03h,02h发命令,最后从05h读数据。两次唯一不同的是03h发送register index的数值不同。如果分别写成两个汇编函数读取(C内嵌汇编)的话,其中一个可以随外设状态变化,而另一个不可以。如果写在同一个汇编函数里先后读取的话(就像上面那样),则两个值相同。而且不随状态变化。不知该怎么去分析! Check_Busy proc near mov dx,SM_Base+00h xx: in al,dx IODELAY ;I/O delay. out dx,al and al,NOT 40h ;mask the INUSE bit or al,al jnz xx ret Check_Busy endp |
|
11楼#
发布于:2005-05-30 16:04
我读的是byte。就是按你说的方法读的。每次先向smbase写0ffh重置状态,然后check 它的bit6。然后分别向偏移地址04h,03h,02h发命令,最后从05h读数据。两次唯一不同的是03h发送register index的数值不同。如果分别写成两个汇编函数读取(C内嵌汇编)的话,其中一个可以随外设状态变化,而另一个不可以。如果写在同一个汇编函数里先后读取的话(就像上面那样),则两个值相同。而且不随状态变化。不知该怎么去分析!
|
|
12楼#
发布于:2005-05-30 13:39
现在重启的问题解决了,不过说实在话,我自己都不知道为什么:( 你用的是读一个字节的命令还是读一个block的命令。。。 如果是读一个字节的命令,应该每次读都重新送命令。 如果读一个读一个block,在一开始,可以在offset5上读到总字节数,在第7个offset上读数据。每读一次,check busy and set status.读完所有的后,set 传输完位。。。 |
|
13楼#
发布于:2005-05-30 10:11
现在重启的问题解决了,不过说实在话,我自己都不知道为什么:(
现在的问题是我在同时访问两个偏移寄存器数值的时候,读出的数值是错的,而且两个一样。程序大概如下: mov al,0ffh mov dx,smbase out dx,al ;清状态 ...........check busy and set register,etc mov dx, smbase+03h mov al,register1 out dx,al ..........;read data1 ;;;; mov al,0ffh mov dx,smbase out dx,al ;再次清状态 ...........check busy and set register,etc mov dx, smbase+03h mov al,register2 out dx,al ..........;read data2 不知道是不是该检测的位没有检测?单独读data1的时候能读到相应的数值,为什么想两个同时得到就不行了呢? |
|
14楼#
发布于:2005-05-26 17:06
我在每次程序开始的时候清除了smbase的bit7位,结果还是不变啊? 能不能把你访问smbus的程序贴出来,我帮你看哪里错了。 如果要重起系统,应该是你在驱动中访问了不该访问的内存。。。不会是smbus程序的问题 |
|
15楼#
发布于:2005-05-26 12:00
我在每次程序开始的时候清除了smbase的bit7位,结果还是不变啊?
mov al,0ffh mov dx,smbase out dx,al 是不是这样写不对? 还有,在我的程序里一对bit6进行检测的时候,一运行就重启系统 test: mov dx,smbase in al,dx test al,40h jz next loop test next:.... 按照datasheet里面说的应该就是这个样子啊?谁能帮我分析一下,诚恳感谢! |
|
16楼#
发布于:2005-05-26 08:46
谢谢sharpor这些天对我的帮助!
可能是我的时间比较紧,所以没有顾及去仔细看文档! 以后肯定会补上的! 以后可能还要向你请教的!呵呵! |
|
17楼#
发布于:2005-05-25 16:37
不过还是恭喜有了进展哈。+u+u
要清掉SMbase+0的第7个bit。。。 |
|
18楼#
发布于:2005-05-25 16:32
spec什么都有讲啊,你只要花半天时间就看了,有这么麻烦吗》???
|
|
19楼#
发布于:2005-05-25 16:19
我现在可以读到数据了,并完成了相应驱动,可以在xp下读取监控端口的数据。但是不知道为什么这个数据并不随电源电压变化而像我们想象的那样改变,一直是个定值。需要重新启动系统才能读到新值。所以在读数据的时候是不是需要什么指令把前面的状态清掉啊?
谢谢! |
|
上一页
下一页