Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
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

List of 6 messages in thread
TopicAuthorDate
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      

Back to Subject List