C8051F330的SMBus搭配I/O to I2C
目前有一個應用:
想把MCU當作一個轉送器
就是PC下一個command給MCU(這邊使用SMBus)
MCU接收到後,馬上使用I/O to I2C下command給EEPROM要值
MCU接收到EEPROM的值後再丟到SMBus上給PC接收
請問有人做過類似的應用嗎??
目前我的做法如下:
void SMBus_ISR (void) interrupt 7
{
if (ARBLOST == 0)
{
if(SR_Addr_Cnt==0)
{
W_Addr[0]=SMB0DAT;
SR_Addr_Cnt++;
}
switch (SMB0CN & 0xF0) // Decode the SMBus status vector
{
case SMB_SRADD:
STA = 0; // Clear STA bit
if((SMB0DAT&0xFE) == 0xA0 || (SMB0DAT&0xFE) == 0xA2 )
{
ACK = 1; // If the received address matches,
// ACK the received slave address
if((SMB0DAT&0x01) == READ) // If the transfer is a master READ,
{
W_Addr[0]=SMB0DAT;
cnt_plus=W_Addr[1]+ST_Addr_Cnt;
if(W_Addr[0]==A1_SlvAddr)
{
I2CReadByte(0xA0,cnt_plus,&Data_buf[0],1,1);
SMB0DAT = Data_buf[0]; // Prepare outgoing byte
}
else if(W_Addr[0]==A3_SlvAddr)
{
I2CReadByte(0xA2,cnt_plus,&Data_buf[0],1,1);
SMB0DAT = Data_buf[0]; // Prepare outgoing byte
}
}
}
else // If received slave address does not
{ // match,
ACK = 0; // NACK received address
}
break;
// Slave Receiver: Data received
case SMB_SRDB:
W_Addr[SR_Addr_Cnt] = SMB0DAT; // Store incoming data
SR_Addr_Cnt++;
ACK = 1; // ACK received data
break;
// Slave Receiver: Stop received while either a Slave Receiver or
// Slave Transmitter
case SMB_SRSTO:
if(W_Addr[0]==0xA0 || W_Addr[0]==0xA2)
{
STO = 0; // STO must be cleared by software when
// a STOP is detected as a slave
ST_Addr_Cnt=0;
W_to_Flash=1;
Flash_Write();
}
else if(W_Addr[0]==0xA1 || W_Addr[0]==0xA3)
{
STO=0;
W_to_Flash=0;
ST_Addr_Cnt=0;
SR_Addr_Cnt=0;
}
PCA0CPH2 = 0x00; // watchdog clear timer
break;
// Slave Transmitter: Data byte transmitted
case SMB_STDB:
if(ACK==1)
{
ST_Addr_Cnt++;
cnt_plus=W_Addr[1]+ST_Addr_Cnt;
if(W_Addr[0]==0xA1)
{
I2CReadByte(0xA0,cnt_plus,&Data_buf[0],1,1);
SMB0DAT = Data_buf[0]; // Prepare outgoing byte
}
else if(W_Addr[0]==0xA3)
{
I2CReadByte(0xA2,cnt_plus,&Data_buf[0],1,1);
SMB0DAT = Data_buf[0]; // Prepare outgoing byte
}
}
break;
case SMB_STSTO:
STO = 0; // STO must be cleared by software when
// a STOP is detected as a slave
ST_Addr_Cnt=0;
SR_Addr_Cnt=0;
break;
// Default: all other cases undefined
default:
SMB0CF &= ~0x80; // Reset communication
SMB0CF |= 0x80;
STA = 0;
STO = 0;
ACK = 0;
break;
}
}
// ARBLOST = 1, Abort failed transfer
else
{
STA = 0;
STO = 0;
ACK = 0;
}
SI = 0; // Clear SMBus interrupt flag
}
主要的問題是在以下的部分
I2CReadByte(0xA0,cnt_plus,&Data_buf[0],1,1); //I2CReadByte(slave_Addr,word_Addr,DataByte,讀取幾個byte,port);
SMB0DAT = Data_buf[0];
目前的結果來看,從PC端下ByteRead可以讀取到值
但是MultiByte-Read讀到PC上會有錯誤
用Debug模式看到在:
// Slave Transmitter: Data byte transmitted
case SMB_STDB:
有進入這個程式中,執行完I2CReadByte()後,Data_buf[0]有讀取到想要的值,SMB0DAT也有放上想要的值,但是有沒有被PC接收就不清楚,應該是沒有,因為我PC是一次讀取5個byte,但是debug模式下,執行到SMB0DAT = Data_buf[0]之後就會跳到STOP的部分,所以我PC讀取上一直有問題
目前我是用print port to I2C來讓PC和MCU溝通,人機介面是用Labview編寫