This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430F5342: I2C programming receive interrupt flag (UCRXIFG ) is not working .

Part Number: MSP430F5342
Other Parts Discussed in Thread: TCA9548A

Tool/software: Code Composer Studio

Hi ,

we are using one zcu111 xilinx rfsoc board .This board have a system controller mcu MSP430F5342 .Ther is a i2c mux  (tca9548a) from ti in it, which have 8 channels and I am trying to programme it through MSP430F5342 .I am trying to enable channel 1 in this i2c mux  for that I have taken one master receiver example i2c code given from ti (MSP430F534x_uscib0_i2c_10.c) only by modifying slave address . The tca9548a  address is 0x74 .According to the datasheet it have only one control register which can be read by giving the slave address with read bit as set . I am trying to read the control register but not able to 

I have seen some of the post where they are telling to right shift the slave address by 1 bit as the USCI module will take this by shifting it to 1 bit left automatically . I didn't get this point but still I have tried with 2 addresses  0x74 and 0x3A (by right shifting 0x74) . Issue I am facing is the UCRXIFG is not setting up at all and the isr is not executing  so am I not able to read the UCB0RXBUF. I have attached my code here .Can any one explain what is the problem and where I am going wrong and shifting the slave address is it necessary ?.

Same issue I am facing while configuring the msp430 to master transmitter also . When I an trying to send tx data to UCB0TXBUF , not acknowledgement  (UCNACKIFG) flag is always high .

#include <msp430.h>

unsigned char *PRxData; // Pointer to RX data
unsigned char RXByteCtr;
volatile unsigned char RxBuffer[128]; // Allocate 128 byte of RAM

int main(void)
{
WDTCTL = WDTPW + WDTHOLD;                                 // Stop WDT
P3SEL |= 0x03;                                                                 // Assign I2C pins to USCI_B0
UCB0CTL1 |= UCSWRST;                                                 // Enable SW reset
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC;          // I2C Master, synchronous mode
UCB0CTL1 = UCSSEL_2 + UCSWRST;                         // Use SMCLK, keep SW reset
UCB0BR0 = 12; // fSCL = SMCLK/12 = ~100kHz
UCB0BR1 = 0;


UCB0I2CSA = 0x74; // Slave Address

// UCB0I2CSA = 0x3A;     

UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation
UCB0IE |= UCRXIE; // Enable RX interrupt

while (1)
{
PRxData = (unsigned char *)RxBuffer;                            // Start of RX buffer
RXByteCtr = 1;                                                                 // Load RX byte counter
while (UCB0CTL1 & UCTXSTP);                                    // Ensure stop condition got sent
UCB0CTL1 |= UCTXSTT;                                               // I2C start condition

__bis_SR_register(LPM0_bits + GIE);                          // Enter LPM0, enable interrupts
                                                                                      // Remain in LPM0 until all dat a
                                                                                      // is RX'd
__no_operation();                                                        // Set breakpoint >>here<< and
}                                                                                      // read out the RxBuffer buffer
}

//-------------------------------------------------------------------------------
// The USCI_B0 data ISR is used to move received data from the I2C slave
// to the MSP430 memory. It is structured such that it can be used to receive
// any 2+ number of bytes by pre-loading RXByteCtr with the byte count.
//-------------------------------------------------------------------------------
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
switch(__even_in_range(UCB0IV,12))
{
case 0: break;                  // Vector 0: No interrupts
case 2: break;                 // Vector 2: ALIFG
case 4: break;                 // Vector 4: NACKIFG
case 6: break;                 // Vector 6: STTIFG
case 8: break;                // Vector 8: STPIFG
case 10:                         // Vector 10: RXIFG
RXByteCtr -- ;                // Decrement RX byte counter
if (RXByteCtr)
{
*PRxData++ = UCB0RXBUF;                       // Move RX data to address PRxData
if (RXByteCtr == 1)                                     // Only one byte left?
UCB0CTL1 |= UCTXSTP;                            // Generate I2C stop condition
}
else
{
*PRxData = UCB0RXBUF;                             // Move final RX data to PRxData
__bic_SR_register_on_exit(LPM0_bits);        // Exit active CPU
}
break;
case 12: break; // Vector 12: TXIFG
default: break;
}
}

Regards,

Soumya 

  • Hi Soumya,

    Can you start by running an I2C code example for this device? You can go to resource explorer, select MSP430Ware and then select your device.  I would recommend modifying one of the existing examples to see whether you run into the same problem.

    BR,
    Leo

  • Based on TCA9548A data sheet (SCPS207G) Fig 9, its (7-bit) address is of the form 0x7n, so 0x74 would be the correct thing to put in I2CSA. (Or 0x75 for the other one.)

    The ZCU111 User Guide (UG1271 v1.2) Fig 3-2 shows the MSP430 connected to both I2C0 and I2C1 via "P3" and "P4" respectively. I expect P3 refers to UCB0 (P3.0-1). This is what you're using but those devices are not on I2C0, rather on I2C1.

    So I think you need to use UCB1 via the "P4" pins. UG1271 Fig 3-4 indicates that those are P4.1/2.

    Per F5342 data sheet (SLAS706F) Tables 4-1 and 6-7, P4.1 is PM_UCB1SDA and P4.2 is PM_UCB1SCL.

    To summarize:

    1) You need to use UCB1 here, not UCB0

    2) Change "P3SEL |= 0x03;"  to "P4SEL |= BIT1|BIT2; // P4.1 as UCB1SDA, P4.2 as UCB1SCL" 

    [Edit: minor re-wording]

  • Hi Bruce ,

    Thanks for your correction . I really appreciate this .As you have gone through the  ZCU111 User Guide (UG1271 v1.2) , actually I want to access the clock generator ic SI5341 which is connected to channel number 1 in the i2c mux (tca9548) . To enable channel 1 after writing the control register value (0x02) of i2c mux  do I again need to provide the clock generator ic's address (0x36) mentioned in ZCU111 User Guide (UG1271 v1.2)  Table 3-6 . How should be the code flow ? I am really confused how to access that clock generator (si5341) .Can you please help me with this .

    Regards,

    Soumya .

  • I haven't used a TCA9548A before, but as near as I can tell it creates a (slightly illusory) bus containing itself and some subset of its children. You write a one-byte bitmap to its control register, and the devices on the selected sub-buses appear on the (apparently) single bus. If I'm right, the sequence would be:

    0) On I2C1 (UCB1) [each is a separate I2C transaction]:

    1) Write to address [0x74] data [0x02]   to put sub-bus 1 on the bus (I think you only need to do this once per power-cycle)

    2) Write to address [0x36] data [0x01, 0x00]   to set register 1 (page) =0  

    3) Write to address [0x36] data [0x02]   to request register 2 (base_part_number)

    4) Read 2 bytes from [0x36] , which should be [0x53,0x41] [Ref Si5341 Ref Man (R1.2) Table 14.4]

    For your first attempt, I suggest skipping steps (2)-(3) -- just read 4 bytes and look for [0x53,0x41] in bytes 2-3. I think page=0 at startup.

    [Keep in mind that I don't really know what I'm talking about.]