| ??? 07/10/07 14:28 Read: times |
#141686 - updated post Responding to: ???'s previous message |
My second problem, when think I have workng code.
I add a simple functions, the original behavior changes, as if some var's or registers are being written over. Any idea's why?
// Status code for the SMBus
// (SMB0STA register)
switch (SMB0STA)
{
// Master Transmitter/Receiver:
case SMB_START_08:
SMB0DAT = EPROM_DEVICE_ID;
SMB0DAT &= 0xFE;
// Load R/W bit
SMB0DAT |= SMB_RW;
STA = 0;
// Manually clear STA bit
i = 0;
break;
// Master Transmitter/Receiver:
// Repeated START condition
case SMB_RP_START_10:
SMB0DAT = EPROM_DEVICE_ID; .
SMB0DAT |= SMB_RW;
STA = 0;
i = 0;
break;
// Master Transmitter: Slave address
// + WRITE transmitted.
// ACK received.
case SMB_MTADDACK_18:
// Hi addr has been send,
// Flag it, to send low byte
addrLowSendFlag = 1;
SMB0DAT = CHAR_ADDR_HIGH;
if (SMB_RANDOMREAD)
{
//Send a START after
//the next ACK cycle
SEND_START = 1;
SMB_RW = READ;
}
break;
///-RANSMIT ROUTINES ///
///------------------///
// Master Transmitter: Slave
// address + WRITE transmitted. NACK received.
case SMB_MTADDNACK_20:
if(SMB_ACKPOLL)
{
// Restart transfer
STA = 1;
}
else
{ // Indicate failed transfer
FAIL = 1;
}
break;
// Master Transmitter: Data byte
// transmitted. ACK received.
case SMB_MTDB_ACK_28:
// Has the Addr Hi byte been
// sent, if Yes, send the
//low byte, Flag it
if (addrLowSendFlag)
{
SMB0DAT = CHAR_ADDR_LOW;
//Reset the flag to skip
addrLowSendFlag = 0;
}
else
{
if (SEND_START)
{
STA = 1;
SEND_START = 0;
break;
}
// Is this transfer a WRITE?
if (SMB_RW==WRITE)
{
// Is there data to send?
if (i < SMB_DATA_LEN)
{
SMB0DAT = SMB_SINGLEBYTE_OUT;
i++;
}
else
{
// Set STO to terminte transfer
STO = 1;
// Clear software busy flag
SMB_BUSY = 0;
}
}
else {}
// If this transfer is a READ, then
// take no action, as a repeated
// start will be generated for the
// read operation
}
break;
// Master Transmitter: Data
//byte transmitted.NACK received.
case SMB_MTDB_NACK_30:
if(SMB_ACKPOLL)
{
STA = 1;// Restart transfer
}
else
{
FAIL = 1;// Indicate failed transfer
}
break;
// Master Transmitter: Arbitration lost.
case SMB_MTARBLOST_38:
FAIL = 1; // Indicate failed transfer
// and handle at end of ISR
break;
// For a READ: check if this is a one
//-byte transfer. if so, set the
// NACK after the data byte is received to end the transfer. if not,
// set the ACK and receive the other data bytes.
//
// For a WRITE: N/A
case SMB_MRADDACK_40:
STA =0;
if (i == SMB_DATA_LEN)
{
AA = 0; // Only one byte in this transfer,
// send NACK after byte is received
}
else
{
AA = 1; // More than one byte in this transfer,
// send ACK after byte is received
}
break;
// Master Receiver: Slave address
//+ READ transmitted. NACK received.
case SMB_MRADDNACK_48:
if(SMB_ACKPOLL)
{
STA = 1; // Restart transfer
}
else
{
FAIL = 1; // Indicate failed transfer
} // and handle at end of ISR
break;
// For a READ: receive each byte
// from the EEPROM. if this is the last
// byte, send a NACK and set the STOP bit.
// For a WRITE: N/AGA
case SMB_MRDBACK_50:
if ( i < SMB_DATA_LEN ) // Is there any data remaining?
{
// Read_Array
// ==1 reading Epprom Read Array
switch (ucREAD_Epprom)
{
case 0x01: // array
//hiLowFlag == 0: save low byte;
if (lo_hiByteFlag == 0)
{
*ipSMB_DATA_IN = (int) SMB0DAT;
AA = 1;
lo_hiByteFlag = 1;
}
else
{
//Load Hi Byte; shift to the Lt; mask out low bytes;
//Store it in temp
itemp = 0x0000;
itemp = (int) (SMB0DAT);
AA = 1;
itemp = ((itemp <<8) & 0xFF00);
//assign to hi byte of ifoo
foo = *ipSMB_DATA_IN | itemp;
*ipSMB_DATA_IN = ifoo;
//inc to next location
ipSMB_DATA_IN ++;
//task completed; reset flag;
lo_hiByteFlag = 0;
}
break;
case 0x00:
*pSMB_DATA_IN = SMB0DAT; // Store received byte
break;
}// i < SMB_DATA_LEN
i++; // Increment number of bytes received
AA = 1; // Send ACK (may be cleared later
// in the code)
}
if (i == SMB_DATA_LEN) // This is the last byte
{
SMB_BUSY = 0; // Free SMBus interface
AA = 0; // Send NACK last byte
STO = 1; // Send STOP to terminate transfer
break;
}
break;
// Master Receiver: Data byte received. NACK transmitted.
// Read operation has completed. Read data register and send STOP.
case SMB_MRDBNACK_58:
switch (ucREAD_Epprom)
{
case 0x01: // array
//hiLowFlag == 0: save low byte;
if (lo_hiByteFlag == 0)
{
*ipSMB_DATA_IN = (int) SMB0DAT;
AA = 1;
lo_hiByteFlag = 1;
}
else
{
//Load Hi Byte; shift to the Lt; mask out low bytes;
//Store it in temp
itemp = 0x0000;
itemp = (int) (SMB0DAT);
AA = 1;
itemp = ((itemp <<8) & 0xFF00);
//assign to hi byte of ifoo
foo = *ipSMB_DATA_IN | itemp;
*ipSMB_DATA_IN = ifoo;
//inc to next location
ipSMB_DATA_IN ++;
//task completed; reset flag;
lo_hiByteFlag = 0;
}
break;
case 0x00:
*pSMB_DATA_IN = SMB0DAT; // Store received byte
break;
}
i++; // Increment number of bytes received
AA = 1; // Send ACK (may be cleared later
// in the code)
if (i == SMB_DATA_LEN) // This is the last byte
{
SMB_BUSY = 0; // Free SMBus interface
AA = 0; // Send NACK to indicate last byte
// of this transfer
STO = 1; // Send STOP to terminate transfer
break;
}
STO = 1;
SMB_BUSY = 0;
AA = 1; // Set AA for next transfer
break;
// All other status codes invalid. Reset communication.
default:
FAIL = 1;
break;
}
if (FAIL) // If the transfer failed,
{
SMB0CN &= ~0x40; // Reset communication
SMB0CN |= 0x40;
STA = 0;
STO = 0;
AA = 0;
SMB_BUSY = 0; // Free SMBus
FAIL = 0;
}
SI = 0; // Clear interrupt flag
}
thanks |
| Topic | Author | Date |
| silican labs SMBus and I2c problem f040 | 01/01/70 00:00 | |
| Something missing? | 01/01/70 00:00 | |
| updated post | 01/01/70 00:00 | |
Read it as single-byte variable array | 01/01/70 00:00 | |
| totally ambigous | 01/01/70 00:00 | |
| now that you added f040 I suggest | 01/01/70 00:00 |



