This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SMBus and LTC1380 MUX State Machine Design Problem

I am having problems with this state machine on setting up an LTC1380 Mux Device.





It is really hard to track progress of this state machine without disrupting the bus for logging or stepping through the code/ISR.





Has anyone any comments on why this is failing?





Greatly appreciated in-advance.


void initializeSMBus0(void)
{
BUSY = 0;
ENSMB = 1;
STA = 0;
STO = 0;
SI = 1;
AA = 1;
SMBFTE = 0;
SMBTOE = 0;
}


int getAllADCMuxDataFromInternalBank0ADCs(void){

volatile int i;
volatile int j;
volatile int retVal;

retVal = NO_ADC_ERROR;
for (i=0;i<NUMBER_SMBUS_MUX_CHANNELS; i++)
{
theSMBusMuxChannel = i;
for (j=0;j<NUMBER_SMBUS_MUX_BANKS; j++)
{
theSMBusMuxBank = j;

DISABLE_INTERRUPT_INTERNAL_UART0;
ENABLE_INTERRUPT_SMBUS;
setupSMBusMuxBankAndChannel();
DISABLE_INTERRUPT_SMBUS;
ENABLE_INTERRUPT_INTERNAL_UART0;


AMX0SL = j; // Internal ADC 0 MUX CHANNEL SELECTION.
AD0INT = 0; // Set complete conversion interrupt flag to conversion not completed.
AD0BUSY = 1; // Initiates ADC0 conversion if AD0STM1-0 = 00b (set in init above).

while(AD0BUSY !=0){} // Wait for conversion to complete.

printf ("B[%i] CH[%i] ",j,i);
printf (" 0x%2x ",ADC0H);
printf ("0x%2x ",ADC0L);
printf("SMBusCntr=%d",SMBusCntr++);
printf("\r\n");
}
}

return (retVal);
}




int setupSMBusMuxBankAndChannel(void){

volatile int retVal;

SMBusDevicesClass = EXTERNAL_SMB_MUXS;

ENSMB = 0; // Reset Bus.
ENSMB = 1;
SI = 0;
delayTime(DELAY_WAIT_EXTERNAL_SMBUS_RESET_BUS);

// Hangs Here on second iteration...???
//while (BUSY == SMBUS_BUSY_IS_BUSY){} // If SMBus is busy then stay here.

//?? an113 PG 25
// BUSY = 0; // App note say to do this.


// Start the setting of the Mux
STO = 0;
STA = 1;

return(retVal);
}


void SMBus_ISR(void) interrupt 7 using 2
{
switch (SMBusDevicesClass){
{
// Linear SMBus device LTC1380
case EXTERNAL_SMB_MUXS:

switch(SMB0STA & 0xF8)
{

case 0x08: // Start condition transmitted.
switch(theSMBusMuxBank){
case 0: theSMBusMuxCommand = SMBUS_MUX_BANK_0; // 0x90
break;
case 1: theSMBusMuxCommand = SMBUS_MUX_BANK_1; // 0x92
break;
case 2: theSMBusMuxCommand = SMBUS_MUX_BANK_2; // 0x94
break;
default:;
}
SMB0DAT = theSMBusMuxCommand;
STA = 0;
break;

case 0x18: // ACK from slave was received for valid address.
STO = 0;
switch(theSMBusMuxChannel)
{
case DAQ_CHANNEL_OVEN1 : theSMBusMuxCommand = 0x08; // 0x08 | 0x00
break;
case DAQ_CHANNEL_BLOWER : theSMBusMuxCommand = 0x09; // 0x08 | 0x01
break;
default:;
}

SMB0DAT = theSMBusMuxCommand;

break;

case 0x20: // NACK was received from Slave. Retry Address.
STO = 1; // Set Stop Mode
STA = 1; // Set Start Master Mode.
switch(theSMBusMuxBank){
case 0: theSMBusMuxCommand = SMBUS_MUX_BANK_0; // 0x90
break;
case 1: theSMBusMuxCommand = SMBUS_MUX_BANK_1; // 0x92
break;
case 2: theSMBusMuxCommand = SMBUS_MUX_BANK_2; // 0x94
break;
default:;
}
SMB0DAT = theSMBusMuxCommand;
break;

case 0x28: // Data was sent to slave and received ACK back.
STO = 0; // Done with the single channel data send to slave MUX.
break;

case 0x30: // Data was sent to slave and received NACK back.
// Retry data send to slave MUX.
// NOTE: NEED COUNTER HERE FOR NOT GETTING STUCK IN AN INFINATE LOOP.
// And a global flag for indicating that this happened.
switch(theSMBusMuxChannel)
{
case DAQ_CHANNEL_OVEN1 : theSMBusMuxCommand = 0x08; // 0x08 | 0x00
break;
case DAQ_CHANNEL_BLOWER : theSMBusMuxCommand = 0x09; // 0x08 | 0x01
break;
default:;
}
SMB0DAT = theSMBusMuxCommand;
// Maybe need to reboot (book offers opinion.)

break;

case 0x38: // Arbitration lost.
// Save Current data.
// Nothing to do here for Master to Slave MUX devices.
// ??
// Well maybe keep last value logged in sampling averaging.???
break;


case 0x00: // Bus Error (Illegal Stop Start)
STO = 1; // Reset Bus.
break;

case 0xF8: // IDLE - Does not set Interrupt;
// NOTE: Can poll to send START.
break;
default:;
}
break;
}

case EXTERNAL_SMB_RTC:
break;

default:;
}

SI = 0; // Clear SMBus Interrupt.
}

0