Quantcast
Channel: MSP low-power microcontroller forum - Recent Threads
Viewing all articles
Browse latest Browse all 22138

MSP430G2553: I2C ISRs not running. GIE bit is set, TXIE is set, TXIFG is set

$
0
0

Part Number:MSP430G2553

In my code I have enabled ALL of the USCI_B module's interrupts, set the GIE bit and have an ISR with the correct interrupt vector. (used the vector and ISR name from TI's example code) Currently I use polling to implement I2C. However I'd like to do it the proper way using interrupts to save power since this will a battery operated device.

Using polling, I've verified that the corresponding TX flag is being set and with a logic analyzer I verified that the slave acknowledges each byte. I can't understand why the ISR won't run. Relevant code blocks below:

USCI_B initialization block:

// Initialize USCI_B0 to standard speed I2C master mode. Pins are already assigned to SCL and SDA.
UCB0CTL0 = UCMST | UCMODE_3 | UCSYNC;                    // 7-bit addressing, single master
UCB0CTL1 |= UCSSEL_2 | UCTR | UCSWRST;                     // Transmitter mode, sourced from SMCLK
UCB0BR1 = 0;                                                                                // set the upper baud rate register to 0
UCB0BR0 = I2C_CLOCK_DIV;                                                   // 100KHz bus frequency, sourced from 16MHz SMCLK divided by 40
UCB0STAT = 0;                                                                               // reset state change flags
IFG2 &= ~(UCB0TXIFG | UCB0RXIFG);                                     // reset the transmit and recieve flags
UCB0I2CIE = UCNACKIE | UCSTPIE | UCSTTIE | UCALIE; // Enable interrupts for all bus state changes
IE2 |= UCB0RXIE | UCB0TXIE;                                                   // Enable interrupts for I2C receive and transmit (transmit enabled on default)
UCB0I2CSA = 0;                                                                            // Initialize slave address to 0
UCB0CTL1 &= ~UCSWRST;                                                       // Reset UCSWRST, starting I2C communication
__bis_SR_register(GIE); // enable global interrupts

I2C Bus Initialization loop:

while (~status & MCP23018_INIT) {                                                // while the MCP23018 is NOT initialized
      if (IFG2 & UCB0TXIFG || interrupt_test > 0) {                           // if it is time to load the TXBUFFER
        if (~status & MCP23018_INIT) {                                               // if the MCP23018 is NOT initialized:
          if (i2c_i > OLATB+1) {                                                               // if this is the bit after the last register:
            i2c_i = 0;                                                                                   // reset i2c iterator
            UCB0CTL1 |= UCTXSTP;                                                     // transmit STOP signal
            status |= MCP23018_INIT;
          }
          UCB0TXBUF = MCP23018_INIT_DATA[i2c_i];                  // put the corresponding byte from init data array into the tx buffer
          i2c_i++;                                                                                      // increment the i2c iterator
          }
      } else if (UCB0I2CSA == 0) {                                                     // otherwise: if the slave address is 0
        UCB0I2CSA = MCP23018_OPCODE;                                 // load slave address+0 for write mode
        UCB0CTL1 |= UCTXSTT;                                                        // send I2C start condition
      } else if (UCB0STAT & UCNACKIFG) {                                   // if NACK was recieved
        UCB0STAT &= ~UCNACKIFG;                                              // clear the flag
        i2c_i = 0;                                                                                    // reset address iterator to 0
        UCB0CTL1 |= UCTXSTT;                            // set a start condition
        IFG2 |= UCB0TXIFG;                              // set the TX flag
      }
//__bis_SR_register(LPM0_bits + GIE);                 // turn off the CPU to save power, global interrupt enabled } P1OUT |= BIT0; // light up LED1 when initialized

I2C Data ISR:

#pragma vector=USCIAB0TX_VECTOR                       // since the USCI_B is in I2C mode, this is the I2C data ISR
__interrupt void USCIAB0TX_ISR(void) {                  // when the USCI_B TX register is empty or RX register is full
    __bic_SR_register_on_exit(LPM0_bits);               // clear the bits to wake up the CPU
}                                                       // return to the main loop

I2C State ISR:

#pragma vector=USCIAB0RX_VECTOR                       // since the USCI_B is in I2C mode, this is the I2C state ISR
__interrupt void USCIAB0RX_ISR(void) {                  // when the I2C state changes
    __bic_SR_register_on_exit(LPM0_bits);               // clear the bits to wake up the CPU
}                                                       // return to the main loop


Viewing all articles
Browse latest Browse all 22138

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>