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

返回顶部