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.
Part Number: MSP432P401R
Need a little help. I'm been trying to use the driverlib example I2C repeat start program to connect to a Si7051x temperature chip with very little luck.
Problem 1: Only able to sample I2C on logic analyzer after pushing reset button. When capturing immediately after pushing the reset, this is what I get from analyzer.
The measure sequence for the Si7051 w/o clockstretching is on page 14 of this document.
http://www.silabs.com/documents/public/data-sheets/Si7050-1-3-4-5-A20.pdf
Problem 2: Stopping at following line when pausing debug. Looks as if nothing is going into the TXBUF
//Poll for transmit interrupt flag.
while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->rIFG.r, UCTXIFG_OFS))
The code I'm using is below: Thanks for the help.
#include "driverlib.h"
/* Standard Defines */
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <Si7051.h>
/* Slave Address for I2C Slave */
#define SLAVE_ADDRESS IC_ADDRESS_TMP7051_ADDRESS
#define NUM_OF_REC_BYTES 2
/* Variables */
//const uint8_t TXData[2] = 0;
static uint8_t RXData[NUM_OF_REC_BYTES];
static volatile uint32_t xferIndex;
static volatile bool stopSent;
/* I2C Master Configuration Parameter */
const eUSCI_I2C_MasterConfig i2cConfig =
{
EUSCI_B_I2C_CLOCKSOURCE_SMCLK, // SMCLK Clock Source
3000000, // SMCLK = 3MHz
EUSCI_B_I2C_SET_DATA_RATE_100KBPS, // Desired I2C Clock of 100khz
0, // No byte counter threshold
EUSCI_B_I2C_NO_AUTO_STOP // No Autostop
};
int main(void)
{
static volatile uint32_t ii;
/* Disabling the Watchdog */
MAP_WDT_A_holdTimer();
/* Select Port 1 for I2C - Set Pin 6, 7 to input Primary Module Function,
* (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
*/
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,
GPIO_PIN6 + GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);
//stopSent = false;
memset(RXData, 0x00, NUM_OF_REC_BYTES);
/* Initializing I2C Master to SMCLK at 100khz with no autostop */
MAP_I2C_initMaster(EUSCI_B0_BASE, &i2cConfig);
/* Specify slave address */
MAP_I2C_setSlaveAddress(EUSCI_B0_BASE, SLAVE_ADDRESS);
/* Set Master in transmit mode */
MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
/* Enable I2C Module to start operations */
MAP_I2C_enableModule(EUSCI_B0_BASE);
/* Enable and clear the interrupt flag */
MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_NAK_INTERRUPT);
MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
//Enable master Transmit interrupt
MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_NAK_INTERRUPT);
MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
MAP_Interrupt_enableSleepOnIsrExit();
MAP_Interrupt_enableInterrupt(INT_EUSCIB0);
while (1)
{
MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
//MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
/* Making sure the last transaction has been completely sent out */
while (MAP_I2C_masterIsStopSent(EUSCI_B0_BASE) == EUSCI_B_I2C_SENDING_STOP);
/* Send start and the first byte of the transmit buffer. We have to send
* two bytes to clean out whatever is in the buffer from a previous
* send */
//MAP_I2C_masterSendSingleByte(EUSCI_B0_BASE, MEAS_TEMP_HOLD_REGISTER);
while (MAP_I2C_isBusBusy(EUSCI_B0_BASE) == EUSCI_B_I2C_BUS_BUSY);
// {
MAP_I2C_masterSendStart(EUSCI_B0_BASE);
MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);
MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);
/* Enabling transfer interrupt after stop has been sent */
MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_RECEIVE_INTERRUPT0);
//MAP_Interrupt_enableSleepOnIsrExit();
//MAP_PCM_gotoLPM0InterruptSafe();
/* While the stop condition hasn't been sent out... */
// while(!stopSent)
//{
//MAP_PCM_gotoLPM0InterruptSafe();
//}
//stopSent = false;
/* Delay between Transmissions */
}
}
/*******************************************************************************
* eUSCIB0 ISR. The repeated start and transmit/receive operations happen
* within this ISR.
*******************************************************************************/
void EUSCIB0_IRQHandler(void)
{
uint_fast16_t status;
status = MAP_I2C_getEnabledInterruptStatus(EUSCI_B0_BASE);
MAP_I2C_clearInterruptFlag(EUSCI_B0_BASE, status);
// if (status & EUSCI_B_I2C_NAK_INTERRUPT)
// {
//MAP_I2C_masterSendSingleByte(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);
// }
/* If we reached the transmit interrupt, it means we are at index 1 of
* the transmit buffer. When doing a repeated start, before we reach the
* last byte we will need to change the mode to receive mode, set the start
* condition send bit, and then load the final byte into the TXBUF.
*/
if (status & EUSCI_B_I2C_TRANSMIT_INTERRUPT0)
{
//MAP_I2C_masterSendSingleByte(EUSCI_B0_BASE, MEAS_TEMP_HOLD_REGISTER);
MAP_I2C_masterSendMultiByteNext(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER);
MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_MODE);
xferIndex = 0;
MAP_I2C_masterReceiveStart(EUSCI_B0_BASE);
MAP_I2C_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
//MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
}
/* Receives bytes into the receive buffer. If we have received all bytes,
* send a STOP condition */
if (status & EUSCI_B_I2C_RECEIVE_INTERRUPT0)
{
if(xferIndex == NUM_OF_REC_BYTES - 2)
{
MAP_I2C_masterReceiveMultiByteStop(EUSCI_B0_BASE);
RXData[0] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
xferIndex++;
}
else if(xferIndex == NUM_OF_REC_BYTES - 1)
{
RXData[1] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
MAP_I2C_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_I2C_RECEIVE_INTERRUPT0);
MAP_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
xferIndex = 0;
//stopSent = true;
//MAP_Interrupt_disableSleepOnIsrExit();
}
else
{
RXData[xferIndex++] = MAP_I2C_masterReceiveMultiByteNext(EUSCI_B0_BASE);
}
}
}
Evan, thanks for the support.
Answering your questions.
1. When I connect to the device and click the debug button and run, the SCL line is pulled low and remains low during each capture. My thoughts on this issue is that since I'm not making it completely to the end of the while(1) loop, its getting hung at the while (!BITBAND_PERI(EUSCI_B_CMSIS(moduleInstance)->rIFG.r, UCTXIFG_OFS)) in the
MAP_I2C_masterSendMultiByteStart(EUSCI_B0_BASE, MEAS_TEMP_NOHOLD_REGISTER) routine.
Also noticed that it doesn't enter into the EUSCIB0_IRQHandler unless I first power cycle(unplug/re-plug). The when I debug, I'm able to step through the code and make it completely through EUSCIB0_IRQHandler
1. It always hangs in the MAP_I2C_masterSendMultiByteStart routine when paused.
2. RXData receives data in RxData[0] only when I step through the routine after a power up.
InovBlue,
There has been an update actually to the example that you were working with with regards to the master/slave repeated start I2C examples. Can you please review and retry? This was to help alleviate a bug that seems to be similar to what you were seeing.
dev.ti.com/.../
Evan,
Thanks for following up and making me aware of this change. I took a look and the ISR is much clearer and follows the technical reference manual's repeat start sequence. Will test later. Thanks.
**Attention** This is a public forum