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.

TX ISR and RX ISR for I2C

Other Parts Discussed in Thread: MSP430FR5739

Hi,

I need information how to write separately  TX and Rx ISR vector for I2c using msp430FR5739 MCU.

Any sample code would greatly help.

And i also want information on how to read back transmitter char back using same device address on I2C.

Only transmission part is working fine and Rx buffer never get its data.

Regards.

  • uma pv said:
    I need information how to write separately  TX and Rx ISR vector for I2c using msp430FR5739 MCU.

    When the ISR is called, check the TXIFG and RXIFG bits or use the IV register to get the reason for the interrupt.

    A typical construct is

    do
    {
      switch(_even_in_range(UCB0IV, 0x1e))
      {
        case 0: return;
        case 0x16: // byte received
          break;
        case ...
      }
    } while (1);

    This will handle all pending USCI interrupts and return when done. Saves exiting and re-entering the ISR.
    Note that reading UCBOIV is destructive.

    uma pv said:
    And i also want information on how to read back transmitter char back using same device address on I2C.

    The USCI doesn't support a feedback loop. And cannot (of course) be master and slave at the same time.
    You can setup a second USCI (if present) to act a sslave. Of course your software flow needs then to support both simultaneously.

    However, for debugging, I suggest buying a logic analyzer with protocol analyzer feature. E.g. the Logic8 from Saleae.

  • Hi Jens,

    Thank you for answering to my thread.

    I have written code as below:

    UCB0CTLW0 |= UCSWRST; // put eUSCI_B in reset state
    UCB0CTLW0 |= UCMODE_3 + UCMST + UCSSEL_2;// I2C master mode, SMCLk
    UCB0BRW = 0x8; // baudrate = SMCLK / 8
    UCB0CTLW0 &=~ UCSWRST; //clear reset register
    UCB0IE |= UCTXIE + UCNACKIE; //transmit and NACK interrupt enable
    UCB0IE |= UCRXIE;
    UCB0I2CSA = SlaveAddress;

    while (UCB0CTLW0 & UCTXSTP); // Ensure stop condition got sent

    TXByteCtr = 2;
    PTXData = (unsigned char *)(CTRL_REG1);
    UCB0CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts
    // __no_operation();

    TXByteCtr = 2;
    PTXData = (unsigned char *)(CTRL_REG1 + 2);
    UCB0CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition
    __bis_SR_register(CPUOFF + GIE); // Enter LPM0 w/ interrupts

    #pragma vector = USCI_B0_VECTOR
    __interrupt void USCIB0_ISR(void)
    {
    switch(__even_in_range(UCB0IV,0x1E))
    {
    case 0x00: break; // Vector 0: No interrupts break;
    case 0x02: break;
    case 0x04:
    UCB0CTLW0 |= UCTXSTT; //resend start if NACK
    break; // Vector 4: NACKIFG break;
    case 0x06: break; // Vector 6: STTIFG break;
    case 0x08: break; // Vector 8: STPIFG break;
    case 0x0a: break; // Vector 10: RXIFG3 break;
    case 0x0c: break; // Vector 14: TXIFG3 break;
    case 0x0e: break; // Vector 16: RXIFG2 break;
    case 0x10: break; // Vector 18: TXIFG2 break;
    case 0x12: break; // Vector 20: RXIFG1 break;
    // RXData1 = UCB0RXBUF;
    case 0x14: break; // Vector 22: TXIFG1 break;
    // UCB0TXBUF = 0x20;
    case 0x16:

    RXData = UCB0RXBUF;

    break; // Vector 24: RXIFG0 break; 
    case 0x18:
    if(TXByteCtr) //(TXByteCtr < 1) // Check TX byte counter
    {
    UCB0TXBUF = *PTXData++;//[SlaveFlag]; // Load TX buffer
    TXByteCtr--; // Decrement TX byte counter
    }
    /* else if(TXByteCtr == 2)
    {
    UCB0TXBUF = 0x20;
    TXByteCtr--;
    }*/
    else
    {
    UCB0CTLW0 |= UCTXSTP; // I2C stop condition
    UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag
    __bic_SR_register_on_exit(CPUOFF);// Exit LPM0
    }
    break; // Vector 26: TXIFG0 break;
    default: break;
    }
    }

    where i am not able to next instruction at  second time assignment TXByteCtr = 2;  seems not exiting LPM mode but some times works fine.

    Please help me.

    Thanks in advance.

    Regards.

  • uma pv said:
    UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag

    This is superfluous. Reading UCB0IV has already cleared it. I guess you meant to clear UCB0IE (disable further TX interrupts)?

    uma pv said:
    i am not able to next instruction at  second time assignment TXByteCtr = 2;

    How do you know?

    Note that when you single step over the LPM entry instruction, or set  abreakpoint onto the second TXByteCtr isntruciton, the debugger will stop the CPU on this instruicoin before LPM is entered.
    This i sbecause of the pipelined operation of the CPU core. The breakpoint is triggered when the instruciton is fetched, and not when it is executed. And the TxByteCtr = 2 instruction is fetched the very moment the previous LPM entry instruciton is executed. THis is why many demo code has a dummy NOP instruction right after entering LPM.

    My guess is that the slave doesn't answer and the code endlessly loops in the NACKIFG interrupt.

**Attention** This is a public forum