boly81
驱动小牛
驱动小牛
  • 注册日期2004-06-25
  • 最后登录2012-06-08
  • 粉丝0
  • 关注0
  • 积分490分
  • 威望73点
  • 贡献值0点
  • 好评度49点
  • 原创分0分
  • 专家分0分
阅读:8663回复:44

SMBus 的base address的问题

楼主#
更多 发布于:2004-06-28 12:15
我读取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]

最新喜欢:

philomanphilom...
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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它们是怎么确定不重复的呢?事先约定好的吗?
谢谢!
sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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吧
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地板#
发布于: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
sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2005-06-08 10:34
如果采用block方式读的话,我怎么确定读到的数值是来自register1和register2的呢?是把这两个地址都写到smbase+03h上去吗?写的过程中需不需要什么间隔之类的?

smbase+7h是block的数据,smbase+5h读到的是block的data个数
每取一次smbase+7,写状态位,smbase +7 就得到下一个数据
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-06-06 13:33
如果采用block方式读的话,我怎么确定读到的数值是来自register1和register2的呢?是把这两个地址都写到smbase+03h上去吗?写的过程中需不需要什么间隔之类的?
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2005-06-06 12:24
那实际中该怎么写呢?
不知道有经验的人可不可以介绍一下?
用sharpor的方法我现在还有两个问题没有解决.
1.我每次开机第一次读的数值都是错误的,第二次才能得到正确数值.
2.同时读取两个寄存器数值的时候还是得到两个相同的错误数值.
仔细看了datasheet,各种检测标识位的方法也试过了,结果还是不行.
是不是重置寄存器的方法不对,或者除了bit1和bit6之外,还有那些bit需要检测?
希望有经验的朋友可以指点一下!
谢谢!
boly81
驱动小牛
驱动小牛
  • 注册日期2004-06-25
  • 最后登录2012-06-08
  • 粉丝0
  • 关注0
  • 积分490分
  • 威望73点
  • 贡献值0点
  • 好评度49点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2005-05-31 14:10
datasheet 上的例子 只是show just as this ,实际应用不能靠他的
sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
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
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
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吗?为什么进行这步呢?

谢谢指点!
sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
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
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2005-05-30 16:04
我读的是byte。就是按你说的方法读的。每次先向smbase写0ffh重置状态,然后check 它的bit6。然后分别向偏移地址04h,03h,02h发命令,最后从05h读数据。两次唯一不同的是03h发送register index的数值不同。如果分别写成两个汇编函数读取(C内嵌汇编)的话,其中一个可以随外设状态变化,而另一个不可以。如果写在同一个汇编函数里先后读取的话(就像上面那样),则两个值相同。而且不随状态变化。不知该怎么去分析!
sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2005-05-30 13:39
现在重启的问题解决了,不过说实在话,我自己都不知道为什么:(
现在的问题是我在同时访问两个偏移寄存器数值的时候,读出的数值是错的,而且两个一样。程序大概如下:

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的时候能读到相应的数值,为什么想两个同时得到就不行了呢?



 

你用的是读一个字节的命令还是读一个block的命令。。。
如果是读一个字节的命令,应该每次读都重新送命令。
如果读一个读一个block,在一开始,可以在offset5上读到总字节数,在第7个offset上读数据。每读一次,check busy and set status.读完所有的后,set 传输完位。。。
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
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的时候能读到相应的数值,为什么想两个同时得到就不行了呢?



sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2005-05-26 17:06
我在每次程序开始的时候清除了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里面说的应该就是这个样子啊?谁能帮我分析一下,诚恳感谢!

能不能把你访问smbus的程序贴出来,我帮你看哪里错了。
如果要重起系统,应该是你在驱动中访问了不该访问的内存。。。不会是smbus程序的问题
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
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里面说的应该就是这个样子啊?谁能帮我分析一下,诚恳感谢!
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2005-05-26 08:46
谢谢sharpor这些天对我的帮助!
可能是我的时间比较紧,所以没有顾及去仔细看文档!
以后肯定会补上的!
以后可能还要向你请教的!呵呵!
sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2005-05-25 16:37
不过还是恭喜有了进展哈。+u+u
要清掉SMbase+0的第7个bit。。。
sharpor
驱动小牛
驱动小牛
  • 注册日期2005-04-04
  • 最后登录2007-05-10
  • 粉丝0
  • 关注0
  • 积分127分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2005-05-25 16:32
spec什么都有讲啊,你只要花半天时间就看了,有这么麻烦吗》???
xyz332
驱动牛犊
驱动牛犊
  • 注册日期2005-05-10
  • 最后登录2006-03-31
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2005-05-25 16:19
我现在可以读到数据了,并完成了相应驱动,可以在xp下读取监控端口的数据。但是不知道为什么这个数据并不随电源电压变化而像我们想象的那样改变,一直是个定值。需要重新启动系统才能读到新值。所以在读数据的时候是不是需要什么指令把前面的状态清掉啊?
谢谢!
上一页
游客

返回顶部