Part Number: MSP432P401R
I wrote some code that is supposed to follow the following scheme to communicate with a sensor using I2C.
I expected the oscilloscope reading to be what's in the following table:
| S | 1 | 1 | 0 | 0 | 0 | 0 | 0 | W | ACK | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ACK | S | 1 | 1 | 0 | 0 | 0 | 0 | 0 | R | ACK | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ACK/NACK |
P |
What I got was what is pictured:
I interpret that as:
| S | 1 | 1 | 0 | 0 | 0 | 0 | 0 | W | ACK | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ACK | P | S | 1 | 1 | 0 | 0 | 0 | 0 | 0 | R | ACK | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ACK | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
Issues/Sources of confusion:
- The clock gets held low and the bus can't be used again until a reset occurs
- Extra clock pulses are generated and a stop isn't sent
- I've tested this bug with a separate I2C device and gotten the same issue
My code is as follows:
#include "driverlib.h"
#define I2C_PINS GPIO_PORT_P3, GPIO_PIN6 + GPIO_PIN7
#define USCI_MODULE EUSCI_B2_BASE
#define SLAVE_ADDRESS 0b1100000
#define PROX_REGISTER 0x08
volatile uint16_t response = 0;
volatile uint8_t lsb = 0;
volatile uint8_t msb = 0;
/* 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)
{
WDT_A_holdTimer();
GPIO_setAsPeripheralModuleFunctionInputPin(I2C_PINS, GPIO_PRIMARY_MODULE_FUNCTION);
/* Initializing I2C Master to SMCLK at 100khz with no autostop */
I2C_initMaster(USCI_MODULE, &i2cConfig);
/* Specify slave address */
I2C_setSlaveAddress(USCI_MODULE, SLAVE_ADDRESS);
/* Set Master in transmit mode */
I2C_setMode(USCI_MODULE, EUSCI_B_I2C_TRANSMIT_MODE);
/* Enable I2C Module to start operations */
I2C_enableModule(USCI_MODULE);
while (I2C_isBusBusy(USCI_MODULE) == EUSCI_B_I2C_BUS_BUSY);
I2C_masterSendSingleByte(USCI_MODULE, PROX_REGISTER);
I2C_masterReceiveStart(USCI_MODULE);
lsb = I2C_masterReceiveMultiByteNext(USCI_MODULE);
msb += I2C_masterReceiveMultiByteNext(USCI_MODULE);
I2C_masterReceiveMultiByteStop(USCI_MODULE);
response = (msb << 8 ) | (lsb & 0xff);
while(1);
}
If anyone could shed some light on what is wrong, I would greatly appreciate it.
Thanks,
Christian

