Other Parts Discussed in Thread: EK-TM4C123GXL
Hello, I have an issue with interfacing EK-TM4C123GXL board with MXT641 touch screen the I2C connection sometimes not send or receive so the interrupt line still low and I don't get any data from the screen
#include "HWIi2c_MASTER.h"
#include "EK_TM4C123GXL.h"
#include "driverlib/i2c.h"
#include "RTOS.h"
/**********************************************************************************************************************/
/* CONSTANTS, MACROS */
/**********************************************************************************************************************/
//#define DEBUG_HWIi2c_MASTER
#ifdef DEBUG_HWIi2c_MASTER
#define HWIi2c_MASTER_PRINTF(fmt, ...) debug_printf(fmt, ##__VA_ARGS__)
#else
#define HWIi2c_MASTER_PRINTF(...)
#endif
/**********************************************************************************************************************/
/* PRIVATE FUNCTIONS deceleration */
/**********************************************************************************************************************/
// this is Call back function from I2C interrupt
PRIVATE void HWIi2c_MASTER_vidCallbackFunction(I2C_Handle I2C_Handle , I2C_Transaction *pTransaction , bool bResults);
/**********************************************************************************************************************/
/* PRIVATE VARIABLES */
/**********************************************************************************************************************/
// I2C2-related variables
PRIVATE I2C_Handle HWI_ArrI2C_Handle [EK_TM4C123GXL_I2CCOUNT];
PRIVATE I2C_Params HWI_ArrI2C_Params [] = {
//CY8_KIT_I2C2
{
/*!< I2C_transfer queues transactions and does not block */
.transferMode = I2C_MODE_BLOCKING,
/* In I2C_MODE_BLOCKING: The transferCallbackFxn's bool
* argument will be true if successful; false on an error, such as an
* I2C bus fault (NACK).
*/
.transferCallbackFxn = NULL,
.bitRate = I2C_400kHz
},
};
/* Call back mode : This Flag waiting Call back function to be ready if we enable Call back and will be false if
* there is Bus error
* Blocking mode : Return true if data received / sent correctly and false if there is Problem Like NACK or bus issue
*/
PRIVATE bool I2C_bIsCallBackReached = false;
// key status change notification
PRIVATE tpfvidI2C_DataReceived ptrfvidI2C_DataReceivedDone[EK_TM4C123GXL_I2CCOUNT]= {NULL};
/**********************************************************************************************************************/
/* PUBLIC FUNCTIONS DEFINITIONS */
/**********************************************************************************************************************/
/******************************************************************************/
/* !Function : I2C_bIsDataRecievedCorrectly */
/* !Description : Function To return that I2c Finished and ready for Get data */
/* also checked there is no error on bus */
/* NOTE : USE THIS FUNCTION ONLY IN PERIODIC CALL */
/******************************************************************************/
PUBLIC bool HWIi2c_MASTER_bIsDataRecievedCorrectly(void)
{
return I2C_bIsCallBackReached;
}
/******************************************************************************/
/* !Function : I2C_vidWriteRegister */
/* !Description : Function To write data in specific Register */
/******************************************************************************/
PUBLIC void HWIi2c_MASTER_vidWriteRegister(uint8_t u8I2cId, uint16_t u16RegAdd,
uint8_t *pua8Value,uint8_t u8Length, uint8_t u8SlaveAddress)
{ // buffer for send data to I2C Slave
uint8_t txBuffer[u8Length + 2];
I2C_Transaction i2cTransaction;
uint8_t u8Index;
// check if the transfer mode is CALLBACK then will be wait until finishing read sequence
if(HWI_ArrI2C_Params[u8I2cId].transferMode == I2C_MODE_CALLBACK )
{
// Set the Flag to be false to protect reading value until finishing Read Sequence
I2C_bIsCallBackReached = false;
}
else
{
// In blocking call there is no need to stop reading until get call back as there is no call back
I2C_bIsCallBackReached = true;
}
txBuffer[0] =(uint8_t) u16RegAdd & 0x00FF; //LB Addr
txBuffer[1] =(uint8_t) ((u16RegAdd & 0xFF00) >> 8); //MB Addr
for (u8Index = 2 ;u8Index < u8Length ; u8Index++)
{
txBuffer[u8Index] = pua8Value [u8Index - 2];
}
i2cTransaction.slaveAddress = u8SlaveAddress;
/* Write to a 16-bit status register */
i2cTransaction.writeBuf = txBuffer;
i2cTransaction.writeCount = u8Length + 2;
i2cTransaction.readBuf = NULL;
i2cTransaction.readCount = 0;
/* Call Back mode : I2C_transfers will always return successful
* Blocking mode : if there is problem in bus it will return False*/
if (!I2C_transfer(HWI_ArrI2C_Handle[u8I2cId], &i2cTransaction))
{
I2C_bIsCallBackReached = false;
System_printf("Bad I2C Transfer......!\n");
}
else
{
System_printf("GOOD I2C Transfer......!\n");
}
}
/******************************************************************************/
/* !Function : I2C_vidReadRegister */
/* !Description : Function To Read data in specific Register */
/******************************************************************************/
PUBLIC void HWIi2c_MASTER_vidReadRegister(uint8_t u8I2cId, uint16_t u16RegAdd,
uint8_t *pua8data, uint8_t u8Length, uint8_t u8SlaveAddresss)
{
uint8_t u16TxbufferRegAdd[2] = {0};
I2C_Transaction i2cTransaction;
// check if the transfer mode is CALLBACK then will be wait until finishing read sequence
if(HWI_ArrI2C_Params[u8I2cId].transferMode == I2C_MODE_CALLBACK )
{
// Set the Flag to be false to protect reading value until finishing Read Sequence
I2C_bIsCallBackReached = false;
}
else
{
// In blocking call there is no need to stop reading until get call back as there is no call back
I2C_bIsCallBackReached = true;
}
u16TxbufferRegAdd[0] = (uint8_t) u16RegAdd & 0x00FF; //LB Addr
u16TxbufferRegAdd[1] = (uint8_t) ((u16RegAdd & 0xFF00) >> 8); //MB Addr
i2cTransaction.slaveAddress = u8SlaveAddresss;
/* Write to a 16-bit status register */
i2cTransaction.writeBuf = u16TxbufferRegAdd;
i2cTransaction.readBuf = pua8data;
i2cTransaction.writeCount = 2;
i2cTransaction.readCount = u8Length;
/* Call Back mode : I2C_transfers will always return successful
* Blocking mode : if there is problem in bus it will return False*/
if (!I2C_transfer(HWI_ArrI2C_Handle[u8I2cId], &i2cTransaction))
{
I2C_bIsCallBackReached = false;
System_printf("Bad I2C Read Register.....!\n");
}
else
{
System_printf("Good I2C Read Register.....!\n");
}
}
/******************************************************************************/
/* !Function : I2C_vidInitI2C */
/* !Description : Function To initialization all I2C Configuration */
/******************************************************************************/
PUBLIC void HWIi2c_MASTER_vidInitI2C(void)
{
uint8_t index;
// EK_TM4C129XL_initI2C();
for(index = 0; index < EK_TM4C123GXL_I2CCOUNT; index++)
{
// I2C initialization
HWI_ArrI2C_Handle[index] = I2C_open(index, &HWI_ArrI2C_Params[index]);
if ( HWI_ArrI2C_Handle[index] == NULL)
{
HWIi2c_MASTER_PRINTF("Bad I2C transfer! For I2C ID = %d",index);
}
else
{
HWIi2c_MASTER_PRINTF("Good I2C transfer! For I2C ID = %d",index);
}
}
}
PRIVATE void vidTaskEntryPoint(UArg arg0, UArg arg1)
{
uint8_t au8ReadBuffer[u8RX_BUFFER_SIZE] = {0};
uint8_t u8MessageCount = 0;
uint8_t u8MessageIndex;
uint8_t u8FingerIndex;
uint32_t u32Event;
MXT_tstrFingerInfo astrFingerInfo[MXT_u8MAX_NBR_OF_FINGERS] =
{
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
};
uint8_t u8FirstReportId = 0;
uint8_t u8NbrOfReportId = 0;
uint8_t u8T5ObjectIndex = 0;
uint8_t u8T44ObjectIndex = 0;
//read info block
vidReadInfoBlock(EK_MXT641_I2C);
/* get T5 object address */
u8T5ObjectIndex = u8GetObjectIndex(&MXT_strInformationBlock,u8MESSAGE_PROCESSOR_T5);
if(u8T5ObjectIndex != 0xFF)
{
MXT_u16T5Address = u16GetObjectAddress(&MXT_strInformationBlock, u8T5ObjectIndex);
if(MXT_u16T5Address != 0x0000)
{
//obtain the start report id for object 100 and store it on array to use later
u8NbrOfReportId = u8GetReportIdInfo(&MXT_strInformationBlock, u8MULTI_TOUCH_SCREEN_T100, &u8FirstReportId);
if((u8FirstReportId != 0) && (u8NbrOfReportId != 0))
{
for(u8FingerIndex = 0; u8FingerIndex < MXT_u8MAX_NBR_OF_FINGERS; u8FingerIndex++)
{
// + 2 : the touch status messages corresponds to Report IDs 2 to 18 of T100
MXT_astrObject100ReportIdMap[u8FingerIndex].u16StartReportId = u8FirstReportId + 2 + u8FingerIndex;
CMN_ASSESS(MXT_astrObject100ReportIdMap[u8FingerIndex].u16StartReportId != 0);
}
}
// do calibration
vidCalibrateChip(&MXT_strInformationBlock);
// clear the CHG line by reading available I2C messages
u8T44ObjectIndex = u8GetObjectIndex(&MXT_strInformationBlock, u8MESSAGE_COUNT_T44 );
MXT_u16T44Address = u16GetObjectAddress(&MXT_strInformationBlock, u8T44ObjectIndex);
// read T44 (message count)
HWIi2c_MASTER_vidReadRegister(EK_MXT641_I2C,MXT_u16T44Address,&u8MessageCount,1,u8MXT641_I2C_ADDRESS);
for(u8MessageIndex = 0; u8MessageIndex < u8MessageCount ; u8MessageIndex++)
{
// read T5 (message processor)
HWIi2c_MASTER_vidReadRegister(EK_MXT641_I2C,MXT_u16T5Address,au8ReadBuffer,u8RX_BUFFER_SIZE,u8MXT641_I2C_ADDRESS);
}
}
}
while(1)
{
// wait for the u32TOUCH_FLAG (cleared on reception)
u32Event = Event_pend(MXT_udtEventHandler,Event_Id_NONE, evtTOUCH_FLAG, BIOS_WAIT_FOREVER);
if(u32Event & evtTOUCH_FLAG)
{
// read T44 object
HWIi2c_MASTER_vidReadRegister(EK_MXT641_I2C,MXT_u16T44Address, &u8MessageCount, 1,u8MXT641_I2C_ADDRESS);
for(u8MessageIndex = 0; u8MessageIndex < u8MessageCount ; u8MessageIndex++)
{
// read T5 object
HWIi2c_MASTER_vidReadRegister(EK_MXT641_I2C, MXT_u16T5Address, au8ReadBuffer, u8RX_BUFFER_SIZE,u8MXT641_I2C_ADDRESS);
for(u8FingerIndex = 0; u8FingerIndex < MXT_u8MAX_NBR_OF_FINGERS ; u8FingerIndex++)
{
if(MXT_astrObject100ReportIdMap[u8FingerIndex].u16StartReportId == au8ReadBuffer[0])
{
astrFingerInfo[u8FingerIndex].u8Detect = (au8ReadBuffer[1] & u8DETECT_BIT_MASK) >> (u8SHIFT_ONE_BYTE - 1);
astrFingerInfo[u8FingerIndex].u16XPos = au8ReadBuffer[2] | (au8ReadBuffer[3] << u8SHIFT_ONE_BYTE);
astrFingerInfo[u8FingerIndex].u16YPos = au8ReadBuffer[4] | (au8ReadBuffer[5] << u8SHIFT_ONE_BYTE);
}
}
}
if(MXT_pfvidCapacitiveDataClbck != NULL)
{
// send touch data to upper layer
MXT_pfvidCapacitiveDataClbck(astrFingerInfo, MXT_u8MAX_NBR_OF_FINGERS);
}
}
}
}