Interfacing MSP430 FRAUNCHPAD with MAX30102

Started by slow_breath 3 years ago2 replieslatest reply 3 years ago186 views

Hi all,

I'm trying to interface the MAXIM MAX30102 with the MSP430FR5739 using I2C protocol. I'm using pull-up resistors (4.7 KOhm) on SDA and SCL lines, using a breakout board. However, the code gets stuck in the "while conditions" when the master is waiting for STOP condition to be sent, for example. I can't actually understand why this happens, because it seems that the msp registers are working properly.

Here are the C file I'm using.






Please I need help, thanks a lot for your support!

[ - ]
Reply by aschatteJuly 8, 2021


I would first suggest that you get a two channel oscilloscope, one on SDA and one on SCL set to trigger on START (SCL high, and negative edge on SDA.  Set up your software to loop sending a Start/Stop sequence and verify that the SDA line transitions correctly.  Then try to send a Start, Address, Stop and see if you get an ACK from the Slave.  Then try a Write to see if the data is Acknowledged at the 9th bit time.  Follow this with a Read to see the Start, Address, Write Data (if any), Restart, Address, Read Data, and Stop.  Hard code these into your program and work with them to get things going.  After that you can abstract your program to handle the data you want.  Start very simply, then add functionality.

I noticed that your I2C_master file had register names that did not appear to be correct or correctly spelled.  For instance,

void _USCI_I2C_init() {

       UCB0CTLW0 = UCSWRST;                      // Enable SW reset

       UCB0CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK

       UCB0BRW = 160;                            // fSCL = SMCLK/160 = ~100kHz

       UCB0I2CSA = SLAVE_ADDR;                   // Slave Address

       UCB0CTLW0 &= ~UCSWRST;                    // Clear SW reset, resume operation

       UCB0IE |= UCNACKIE;


Here is an example from MSP430FR57xx Family User's Guide:

Example 20-1. Master TX With 7-Bit Address 

UCBxCTL1 |= UCSWRST;  // put eUSCI_B in reset state 

UCBxCTLW0 |= UCMODE_3 + UCMST; // I2C master mode 

UCBxBRW = 0x0008; // baud rate = SMCLK / 8 

UCBxCTLW1 = UCASTP_2; // automatic STOP assertion 

UCBxTBCNT = 0x07; // TX 7 bytes of data 

UCBxI2CSA = 0x0012; // address slave is 12hex 

P2SEL |= 0x03; // configure I2C pins (device specific) 

UCBxCTL1 &= ^UCSWRST; // eUSCI_B in operational state 

UCBxIE |= UCTXIE; // enable TX-interrupt 

GIE; // general interrupt enable 


// inside the eUSCI_B TX interrupt service routine 

UCBxTXBUF = 0x77; // fill TX buffer

I would not start with an interrupt version first.  Just put the _USCI_I2C_init into a while (1) loop until you get some communications.  If you don't have access to an oscilloscope, you will need to be able to sense and feedback the I2C lines state after the attempt to ensure that they are both inactive (High) after 1 time (i.e., no more looping).  You can use a volt meter if you have to.

I hope this gets you going,



[ - ]
Reply by jmford94July 8, 2021

A couple of things you can look at without instruments.  I agree with Al that an oscilloscope is one of those things that make the impossible simple...

Check the setup on the USCI to make sure the proper port pins are assigned to that peripheral.

Check that you have a ground wire between the BOB and the launchpad.

Check that the BOB and launchpad have the same signalling level, i.e. 3.3 vs 5v

I noticed in Al's answer the "automatically assert stop" flag.  You might look at the configuration options on that again.