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.

BQ76PL536A: SPI Communication

Part Number: BQ76PL536A

I`m developing 2 BQ76PL536A to manage 5 cells each. In order to communicate with the boards I`m using an Arduino Uno. That`s the code I`m using:

#include <SPI.h>
#include <Wire.h>

//
// teste com dois cartoes
//

const byte crcTable[256] = {
  0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A,
  0x2D, 0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
  0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD, 0x90,
  0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD, 0xC7, 0xC0,
  0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA, 0xB7, 0xB0, 0xB9,
  0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A, 0x27, 0x20, 0x29, 0x2E,
  0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A, 0x57, 0x50, 0x59, 0x5E, 0x4B,
  0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A, 0x89, 0x8E, 0x87, 0x80, 0x95, 0x92,
  0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4, 0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB,
  0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4, 0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
  0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44, 0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21,
  0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34, 0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71,
  0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63, 0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08,
  0x0F, 0x1A, 0x1D, 0x14, 0x13, 0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F,
  0x8A, 0x8D, 0x84, 0x83, 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA,
  0xFD, 0xF4, 0xF3
};

#define DEVICE_STATUS   0x00
#define GPAI            0x01
#define VCELL1          0x03
#define VCELL2          0x05
#define VCELL3          0x07
#define VCELL4          0x09
#define VCELL5          0x0B
#define VCELL6          0x0D
#define TEMPERATURE1    0x0F
#define TEMPERATURE2    0x11
#define ALERT_STATUS    0x20
#define FAULT_STATUS    0x21
#define COV_FAULT       0x22
#define CUV_FAULT       0x23
#define PRESULT_A       0x24
#define PRESULT_B       0x25
#define ADC_CONTROL     0x30
#define IO_CONTROL      0x31
#define CB_CTRL         0x32
#define CB_TIME         0x33
#define ADC_CONVERT     0x34
#define SHDW_CTRL       0x3A
#define ADDRESS_CONTROL 0x3B
#define RESET           0x3C
#define TEST_SELECT     0x3D
#define E_EN            0x3F
#define FUNCTION_CONFIG 0x40
#define IO_CONFIG       0x41


#define ALERT_PIN         3
#define FAULT_PIN         4
#define CONV_PIN          5
#define DRDY_PIN          6
#define SLAVE_SELECT_PIN  10
#define MOSI			        11
#define MISO			        12

#define DISCOVERY_ADDR    0x00
#define BROADCAST         0x3F
#define ADDRESS_MAP       0x3F
#define AC_ADDR_RQST      0x80
#define RESET_COMMAND     0xA5

#define dev1              1
#define dev2              2

static int devices_used = 2;

void setup();
void loop();

void setup() {
  // Delay for programming
  delay(2000);
  pinMode (SLAVE_SELECT_PIN, OUTPUT);
  pinMode(FAULT_PIN, INPUT);
  pinMode(ALERT_PIN, INPUT);
  pinMode(DRDY_PIN, INPUT);
  pinMode(CONV_PIN, OUTPUT);
  
  // Write initial pin states
  
  digitalWrite(CONV_PIN, LOW);
  digitalWrite(SLAVE_SELECT_PIN, HIGH);

  // Begin serial communication for serial debug
  Serial.begin(57600);
  delay(100);

  // Set SPI preferences
  SPI.begin();
  SPI.setClockDivider(SPI_CLOCK_DIV32);
  SPI.setBitOrder(MSBFIRST);

  // Connect to BMS shield
  setupDevices();
}


void loop() {

  delay(1000);
}

void setupDevices() 
{
  int num_dev;
  
  num_dev=setAddresses();

  if (num_dev == devices_used)
  {  Serial.print("Found all "); Serial.print(num_dev);
     Serial.println(" devices.");
  }
  else
     Serial.println("Error finding devices...");
}


int setAddresses() {

  byte look_for=0;
  byte n;
  byte temp;
  byte* verify;
  int mystatus;

  Serial.println("Initializing devices.");
  do
  {
    bqWrite(BROADCAST, RESET, RESET_COMMAND);
    look_for++;
    n=0;
    do
    {
      n++;
      bqWrite(DISCOVERY_ADDR, ADDRESS_CONTROL, n);
      *verify=bqRead(n, ADDRESS_CONTROL, 1);
      
      // Verifying if bit 7 of ADDRESS_CONTROL is set properly
      temp= (*verify) & AC_ADDR_RQST;
      
      if ( temp != 0)
      { Serial.print("Bit 7 ADRRESS_CONTROL set OK=");  Serial.println(temp);
        Serial.print("Addrres=");  Serial.println(*verify & ADDRESS_MAP);
      }
      else
      {  Serial.println("ERROR: Bit 7 (ADRRESS_CONTROL) NOT set.");
         Serial.print("Verify="); Serial.println(*verify);
         Serial.print("Address Stored="); Serial.println(*verify & ADDRESS_MAP);
         return n-1;
      }
    } while ( n < look_for);
  } while ( n < devices_used);
  return n;
}


void bqWrite(byte deviceAddress, byte regAddress, byte regData) {
  SPI.setDataMode(SPI_MODE1);

  // Shift the device bit and set bit 0
  byte logicalAddress = deviceAddress << 1;
  logicalAddress |= 1 << 0;  // Set bit 0, test bitSet(x,n)

  byte crcInput[3] = {
    logicalAddress, regAddress, regData
  };

  // Take the SS pin low to select the chip
  digitalWrite(SLAVE_SELECT_PIN, LOW);

  // Send and receive SPI
  SPI.transfer(logicalAddress);
  SPI.transfer(regAddress);
  SPI.transfer(regData);
  SPI.transfer(pec(crcInput));

  // Take the SS pin high to de-select the chip
  digitalWrite(SLAVE_SELECT_PIN, HIGH);

  SPI.setDataMode(SPI_MODE0);
}

byte *bqRead(byte deviceAddress, byte regAddress, byte length)  {
  SPI.setDataMode(SPI_MODE1);

  // Shift the device bit and clear bit 0
  byte logicalAddress = deviceAddress << 1;
  logicalAddress &= ~(1 << 0);  // Clear bit 0, test bitClear(x,n)

  // Create buffer for receivedData and clear it
  static byte receivedData[20];
  memset(receivedData, 0, sizeof(receivedData));

  // take the SS pin low to select the chip:
  digitalWrite(SLAVE_SELECT_PIN, LOW);

  //  Send and receive SPI
  SPI.transfer(logicalAddress);
  SPI.transfer(regAddress);
  SPI.transfer(length);
  for (int i = 0; i < length + 1; i++) {
    receivedData[i] = SPI.transfer(0x00);
  }

  // take the SS pin high to de-select the chip:
  digitalWrite(SLAVE_SELECT_PIN, HIGH);

  SPI.setDataMode(SPI_MODE0);

  // Return data read from registers
  return receivedData;
}

byte pec(byte crcBuffer[]) {
  byte crc = 0;
  int temp = 0;
  for (int i = 0; i < sizeof(crcBuffer) + 1; i++) {
    temp = crc ^ crcBuffer[i];
    crc = crcTable[temp];
  }
  return crc;
}

Unfortunately I have not been able even to set device addresses properly. Below the output I get:

===================

Initializing devices.
ERROR: Bit 7 (ADRRESS_CONTROL) NOT set.
Verify=61
Address Stored=61
Error finding devices...
====================

Any suggestions where to start debugging?

Thanks a lot,

Cesar.

  • Cesar,


    www.ti.com/.../slaa478.pdf

    GO to this application note and you will find actual code for Pl536A.

    Take a look.
  • Thanks Roger for the guidance! But just before buying another micro-controller I would like to show you up what is going on with a previous test I made. This time I`m using just one pl536a, whereas the north communication is floating. I used a variable voltage over a set of series resistors in order to simulated the 5 cells voltages. The code this time is:

    #include <SPI.h>
    #include <Wire.h>
    
    const byte crcTable[256] = {
      0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38,0x3F,0x36,0x31,0x24,0x23,0x2A,
      0x2D,0x70,0x77,0x7E,0x79,0x6C,0x6B,0x62,0x65,0x48,0x4F,0x46,0x41,0x54,0x53,0x5A,0x5D,
      0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,0x90,
      0x97,0x9E,0x99,0x8C,0x8B,0x82,0x85,0xA8,0xAF,0xA6,0xA1,0xB4,0xB3,0xBA,0xBD,0xC7,0xC0,
      0xC9,0xCE,0xDB,0xDC,0xD5,0xD2,0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,0xB7,0xB0,0xB9,
      0xBE,0xAB,0xAC,0xA5,0xA2,0x8F,0x88,0x81,0x86,0x93,0x94,0x9D,0x9A,0x27,0x20,0x29,0x2E,
      0x3B,0x3C,0x35,0x32,0x1F,0x18,0x11,0x16,0x03,0x04,0x0D,0x0A,0x57,0x50,0x59,0x5E,0x4B,
      0x4C,0x45,0x42,0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,0x89,0x8E,0x87,0x80,0x95,0x92,
      0x9B,0x9C,0xB1,0xB6,0xBF,0xB8,0xAD,0xAA,0xA3,0xA4,0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,0xEB,
      0xEC,0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,
      0x51,0x56,0x5F,0x58,0x4D,0x4A,0x43,0x44,0x19,0x1E,0x17,0x10,0x05,0x02,0x0B,0x0C,0x21,
      0x26,0x2F,0x28,0x3D,0x3A,0x33,0x34,0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,0x76,0x71,
      0x78,0x7F,0x6A,0x6D,0x64,0x63,0x3E,0x39,0x30,0x37,0x22,0x25,0x2C,0x2B,0x06,0x01,0x08,
      0x0F,0x1A,0x1D,0x14,0x13,0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,0xBC,0xBB,0x96,0x91,0x98,0x9F,
      0x8A,0x8D,0x84,0x83,0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,0xE6,0xE1,0xE8,0xEF,0xFA,
      0xFD,0xF4,0xF3};
    
    #define DEVICE_STATUS   0x00
    #define GPAI            0x01
    #define VCELL1          0x03
    #define VCELL2          0x05
    #define VCELL3          0x07
    #define VCELL4          0x09
    #define VCELL5          0x0B
    #define VCELL6          0x0D
    #define TEMPERATURE1    0x0F
    #define TEMPERATURE2    0x11
    #define ALERT_STATUS    0x20
    #define FAULT_STATUS    0x21
    #define COV_FAULT       0x22
    #define CUV_FAULT       0x23
    #define PRESULT_A       0x24
    #define PRESULT_B       0x25
    #define ADC_CONTROL     0x30
    #define IO_CONTROL      0x31
    #define CB_CTRL         0x32
    #define CB_TIME         0x33
    #define ADC_CONVERT     0x34
    #define SHDW_CTRL       0x3A
    #define ADDRESS_CONTROL 0x3B
    #define RESET           0x3C
    #define TEST_SELECT     0x3D
    #define E_EN            0x3F
    #define FUNCTION_CONFIG 0x40
    #define IO_CONFIG       0x41
    
    
    #define  ALERT_PIN         3
    #define  FAULT_PIN         4
    #define  CONV_PIN          6
    #define  DRDY_PIN          7
    #define  SLAVE_SELECT_PIN  10
    
    #define dev1              1
    
    
    void setup();
    void loop();
    
    void setup() {
      // Delay for programming
      delay(2000);
    
      // Set pin modes and interrupts
      pinMode (SLAVE_SELECT_PIN, OUTPUT);
      pinMode(FAULT_PIN, INPUT);
      pinMode(ALERT_PIN, INPUT);
      pinMode(DRDY_PIN, INPUT);
      pinMode(CONV_PIN, OUTPUT);
    
      // Write initial pin states
      digitalWrite(CONV_PIN, LOW);
      digitalWrite(SLAVE_SELECT_PIN, HIGH);
    
      // Begin serial communication for serial debug
      Serial.begin(57600);
      delay(100);
    
      // Set SPI preferences
      SPI.begin();
      SPI.setClockDivider(SPI_CLOCK_DIV32);
      SPI.setBitOrder(MSBFIRST);
    
      // Connect to BMS shield
      setupDevices();
    
    }
    
    
    void loop() { 
      double volt_cell;
    
      volt_cell=getCellVoltage(1);
      Serial.print("v1="); Serial.println(volt_cell);
    
      volt_cell=getCellVoltage(2);
      Serial.print("v2="); Serial.println(volt_cell);
    
      volt_cell=getCellVoltage(3);
      Serial.print("v3="); Serial.println(volt_cell);
    
      volt_cell=getCellVoltage(4);
      Serial.print("v4="); Serial.println(volt_cell);
    
      volt_cell=getCellVoltage(5);
      Serial.print("v5="); Serial.println(volt_cell);
    
      Serial.println("============================================");
      delay(1000);
    }
    
    void setupDevices() {
    
      setAddresses();
      delay(10);
    
      bqWrite(0x01,ADC_CONTROL,0x04);
      delay(10);
    }
    
    
    void setAddresses() {  
      // Set bottom address to 1
    
      bqWrite(0x3F,RESET,0xA5);
      bqWrite(0x00,ADDRESS_CONTROL,dev1);
      delay(10);
    
      byte *addr = bqRead(dev1, ALERT_STATUS, 0x01);
      if (((*addr) & 0x80) == 0) // ou bitRead( *addr, 7)
        Serial.println("Error writing address!");
      else 
        Serial.println("Sucess writing address!");
      *addr = bqRead(dev1, ADDRESS_CONTROL, 0x01);
      *addr= (*addr) & 0x3F;
      Serial.print("Address stored:"); Serial.println(*addr);
      
      delay(4000);
    }
    
    double getCellVoltage(byte cellNumber) {
    
      byte deviceAddress;
      byte cellAddress;
    
      switch (cellNumber) {
      case 0x01:
        deviceAddress = 0x01;
        cellAddress = VCELL1;
        break;
      case 0x02:
        deviceAddress = 0x01;
        cellAddress = VCELL2;
        break;
      case 0x03:
        deviceAddress = 0x01;
        cellAddress = VCELL3;
        break;
      case 0x04:
        deviceAddress = 0x01;
        cellAddress = VCELL4;
        break;
      case 0x05:
        deviceAddress = 0x01;
        cellAddress = VCELL5;
        break;
      default:
        deviceAddress = 0x01;
        cellAddress = VCELL5;
        break;
      }
    
      bqWrite(deviceAddress,ADC_CONVERT,0x01);
      delay (100);
      byte *cellRaw = bqRead(deviceAddress,cellAddress,0x02);
      delay(10);
    
      int cellVoltage = (cellRaw[0] * 256) + cellRaw[1];
    
      //prevCellVoltages[cellNumber - 1] = convertCellVoltage(cellVoltage);
    
      return convertCellVoltage(cellVoltage);
    }
    
    double convertCellVoltage(int cellVoltageInt) {
      return ((double) cellVoltageInt) * (6250.0 / 16383.0);
    }
    
    
    void bqWrite(byte deviceAddress, byte regAddress, byte regData) {
      SPI.setDataMode(SPI_MODE1);
    
      // Shift the device bit and set bit 0
      byte logicalAddress = deviceAddress << 1;
      logicalAddress |= 1 << 0;  // Set bit 0, test bitSet(x,n)
    
      byte crcInput[3] = {
        logicalAddress, regAddress, regData                          };
    
      // Take the SS pin low to select the chip
      digitalWrite(SLAVE_SELECT_PIN,LOW);
    
      // Send and receive SPI
      SPI.transfer(logicalAddress);
      SPI.transfer(regAddress);
      SPI.transfer(regData);
      SPI.transfer(pec(crcInput));
    
      // Take the SS pin high to de-select the chip
      digitalWrite(SLAVE_SELECT_PIN,HIGH);
    
      SPI.setDataMode(SPI_MODE0);
    }
    
    byte *bqRead(byte deviceAddress, byte regAddress, byte length)  {
      SPI.setDataMode(SPI_MODE1);
    
      // Shift the device bit and clear bit 0
      byte logicalAddress = deviceAddress << 1;
      logicalAddress &= ~(1 << 0);  // Clear bit 0, test bitClear(x,n)
    
      // Create buffer for receivedData and clear it
      static byte receivedData[20];
      memset(receivedData, 0, sizeof(receivedData));
    
      // take the SS pin low to select the chip:
      digitalWrite(SLAVE_SELECT_PIN,LOW);
    
      //  Send and receive SPI
      SPI.transfer(logicalAddress);
      SPI.transfer(regAddress);
      SPI.transfer(length);
      for (int i = 0; i < length + 1; i++) {
        receivedData[i] = SPI.transfer(0x00);
      }
    
      // take the SS pin high to de-select the chip:
      digitalWrite(SLAVE_SELECT_PIN,HIGH); 
    
      SPI.setDataMode(SPI_MODE0);
    
      // Return data read from registers
      return receivedData;
    }
    
    double convCellVoltage(byte hibyte, byte lobyte) {
      // Use given conversion equation to convert 14 bit cell voltage to double
      return (((double) hibyte * 256.0) + (double) lobyte) * (6250.0 / 16383.0);
    }
    
    byte pec(byte crcBuffer[]) {
      byte crc = 0;
      int temp = 0;
      for (int i = 0; i < sizeof(crcBuffer) + 1; i++) {
        temp = crc ^ crcBuffer[i]; 
        crc = crcTable[temp];
      }
      return crc;
    }

    The output is just shown bellow. What is intriguing me is the fact that when I verify ALERT_STATUS register in order to verify whether or not the address was assigned properly, it shows me fine, since bit 7 is 0. But, when I read the board`s address by reading ADDRESS_CONTROL register, bits 0..5, using mask I do not get address 1... Nevertheless, as I change the voltage it is possible to see that the voltages read follow the variation up and down. Any tip?

    ========================================

    Typical Output While Changing Voltage

    =========================================

    Success writing address!
    Address stored:47
    v1=2449.18
    v2=2571.26
    v3=2741.41
    v4=2274.08
    v5=2438.12
    ============================================
    v1=2430.11
    v2=2443.46
    v3=2374.41
    v4=2509.84
    v5=2472.07
    ============================================
    v1=2388.15
    v2=2316.04
    v3=2506.41
    v4=2425.15
    v5=2539.98
    ============================================
    v1=2448.42
    v2=2470.55
    v3=2631.92
    v4=2631.92
    v5=2969.92
    ============================================
    v1=3229.72
    v2=3030.58
    v3=3320.90
    v4=3099.25
    v5=2931.77
    ============================================
    v1=3124.81
    v2=3278.93
    v3=3203.40
    v4=3418.18
    v5=3238.11
    ============================================
    v1=3283.13
    v2=3145.79
    v3=3432.67
    v4=3246.12
    v5=3103.45
    ============================================
    v1=3711.16
    v2=3906.11
    v3=3805.77
    v4=4508.10
    v5=3125.19
    ============================================
    v1=3913.36
    v2=3125.19
    v3=3979.73
    v4=4684.73
    v5=3906.49
    ============================================
    v1=3911.07
    v2=3912.97
    v3=3982.79
    v4=3906.49
    v5=3906.49
    ============================================
    v1=3911.45
    v2=3918.31
    v3=3906.49
    v4=3943.11
    v5=3930.90
    ============================================
    v1=4097.23
    v2=4101.43
    v3=3906.49
    v4=4132.33
    v5=4125.85
    ============================================
    v1=4093.80
    v2=3125.19
    v3=4166.67
    v4=4126.23
    v5=4296.37
    ============================================
    v1=4686.26
    v2=4687.40
    v3=4684.73
    v4=4492.46
    v5=4492.46
    ============================================
    v1=3923.27
    v2=3922.89
    v3=3125.19
    v4=3125.19
    v5=3954.94
    ============================================
    v1=3918.70
    v2=3921.75
    v3=3994.23
    v4=4521.45
    v5=4221.60
    ============================================
    v1=3414.36
    v2=3257.19
    v3=3187.37
    v4=3403.68
    v5=3237.73
    ============================================
    v1=3099.25
    v2=2942.07
    v3=3167.15
    v4=2973.74
    v5=3196.53
    ============================================
    v1=2615.90
    v2=2643.36
    v3=2411.04
    v4=1562.60
    v5=2494.20
    ============================================
    v1=2579.27
    v2=2592.24
    v3=2489.24
    v4=2583.09
    v5=2605.98
    ============================================
    v1=2623.53
    v2=2348.09
    v3=2343.51
    v4=2441.56
    v5=2413.32
    ============================================

  • Roger, my mistake... Taking a better look at my code, lines 135 and 137 might be interchanged. Well, this means that, now, neither the address has been assigned according to the reading of the ALERT_STATUS register. Would it be any sort of pre-programming GROUP 3 registers at EEPROM that it is causing this?

  • You have to clear the Alert_status bits. It doesn't clear itself. Meaning that Atert_status [AR] will be 1 until you write 1 and 0 to that register.

    Then it will clear. It will only clear if device is properly addressed. IF not then AR bit will not clear.

    Does it make sense. It means you have to write 1 and 0.

    It applies to all ALert and FAULT registers.

    I think  you will have POR (Fault) and AR (ALERT) bits.

  • Group 3 has nothing to do with addressing and ALert AR bit.
  • I think you should monitor the status registers.
    Check description status register from the datasheet.


    Review actual code from MSP430.
    You don't have to buy it.
    I sent you a link earlier and you can review as reference.