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.

MSPM0G3507: I2C controller mode handling NACK

Part Number: MSPM0G3507

Hi,

After updating form the mspm0_sdk_1_20_00_05 to the mspm0_sdk_1_30_00_03 I started to have some problems with my I2C Bus.

The Bus has a i2c eeprom, a display driver and a i2c button controller peripheral. The button controller has a defined behavior where it will always return a NACK upon first communication as it wakes up from sleep mode. It can return to sleep mode if no communications happen within a defined time frame.

What i found is that at the startup, where I am writing/reading the eeprom, communicating with display and perform the initial configuration of the bus controller, the NACK coming from the Button controller is somehow corrupting the eeprom data. i can confirm this by probing the bus, which starts to transfer non-sense data and message sizes. If no button controller communication is performed, the system works ok with eeprom and display simultaneously.

I looked for implementation suggestion related with the NACK interrupt handling but no relevant information was found.

my initialization configuration is as follows:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
uint16_t uiI2CClk;
uint16_t uiI2CFreq;
uint8_t ucI2CPeriod;
int16_t siI2CPeriod;
DL_I2C_ClockConfig strI2CClockConfig;
DL_I2C_reset(ptraI2CBus[enumI2CBus_p]);
DL_I2C_enablePower(ptraI2CBus[enumI2CBus_p]);
delay_cycles(16);
straI2CData[enumI2CBus_p].enumI2CMode = enumI2CMode_p;
straI2CData[enumI2CBus_p].ulMyI2CAddress = ulMyAddress_p;
strI2CClockConfig.clockSel = DL_I2C_CLOCK_BUSCLK;
strI2CClockConfig.divideRatio = DL_I2C_CLOCK_DIVIDE_1;
DL_I2C_setClockConfig(ptraI2CBus[enumI2CBus_p], &strI2CClockConfig);
DL_I2C_setAnalogGlitchFilterPulseWidth(ptraI2CBus[enumI2CBus_p], DL_I2C_ANALOG_GLITCH_FILTER_WIDTH_50NS);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

the write method is defined as:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
uint8_t I2C_sendDataToMemory(EI2CBus enumI2CBus_p, uint8_t ucTargetAddress_p, uint16_t uiMemoryAddress_p, uint8_t ucMemorySize_p, uint8_t* pucTxData_p, uint16_t uiDataSize_p)
{
straI2CData[enumI2CBus_p].ucTargetAddress = ucTargetAddress_p;
straI2CData[enumI2CBus_p].pucTxData = pucTxData_p;
straI2CData[enumI2CBus_p].uiSizeOfDataToSend = uiDataSize_p + (uint16_t)ucMemorySize_p;
straI2CData[enumI2CBus_p].ucMemoryAddressSize = ucMemorySize_p;
if (ucMemorySize_p == 1)
{
straI2CData[enumI2CBus_p].uiaMemoryAddress[0] = (uint8_t)(uiMemoryAddress_p & 0x00FF);
}
else
{
straI2CData[enumI2CBus_p].uiaMemoryAddress[1] = (uint8_t)(uiMemoryAddress_p & 0x00FF);
straI2CData[enumI2CBus_p].uiaMemoryAddress[0] = (uint8_t)(uiMemoryAddress_p >> 8);
}
/*
* Fill the FIFO with the address
* The FIFO is 8-bytes deep, and this function will return number
* of bytes written to FIFO */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The NACK handling is defined as 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
case DL_I2C_IIDX_CONTROLLER_NACK:
if (straI2CData[enumI2CBus_p].ucTransmitionStart)
{
if (straI2CCallbacks[enumI2CBus_p].ErrorCallback != NULL)
{
straI2CCallbacks[enumI2CBus_p].ErrorCallback(straI2CCallbacks[enumI2CBus_p].ucTargetBus);
}
}
DL_I2C_resetControllerTransfer(ptraI2CBus[enumI2CBus_p]);
break;
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The DL_I2C_resetControllerTransfer resets i2c->MASTER.MCTR which has to be reconfigured as the flags set by "DL_I2C_enableControllerReadOnTXEmpty(ptraI2CBus[enumI2CBus_p]);"  will be cleared.

What should be the right way to handle the NACK events?