Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User20495
Level 1
Level 1
Hello,

How do I know when the hardware is done sending all data on the I2C?

I've implemented the protocol interrupt, but when I set the SETEND in ENDCTRL on this interrupt, I can see on the oscilloscope, that not all data is sent.


Write(
uint16_t u16Addr,
uint32_t u32MemAddr,
uint8_t* pau8Data,
uint32_t u32DataLen,
uint32_t u32Timeout_ms
)
{
bool blTimeout = false;
uint32_t u32TimeoutPoint = OS::GetTime_ms() + u32Timeout_ms;

IfxI2c_setTransmitPacketSize( m_ifxI2cHandle.i2c, u32DataLen );

while( !m_blTxDone && !blTimeout )
{
OS::Delay_ms( 1 );
if( OS::GetTime_ms() >= u32TimeoutPoint )
{
blTimeout = true;
}
}

m_ifxI2cHandle.i2c->ENDDCTRL.B.SETEND = 1;
m_ifxI2cHandle.busStatus = IfxI2c_BusStatus_idle;
m_ifxI2cHandle.status = IfxI2c_I2c_Status_ok;
}

void Protocol()
{

if( TRUE == IfxI2c_getProtocolInterruptSourceStatus( m_ifxI2cHandle.i2c,
IfxI2c_ProtocolInterruptSource_transmissionEnd ) )
{
IfxI2c_clearProtocolInterruptSource( m_ifxI2cHandle.i2c, IfxI2c_ProtocolInterruptSource_transmissionEnd );

m_blTxDone = { true };
}
}


I'd appreciate any help. Thank you in advance.

Miguel
0 Likes
5 Replies
MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored
How you write the data in the TX FIFO? The function write only the data length to TPSCTRL.
0 Likes
User20495
Level 1
Level 1
Yes, I use the Tx Interrupt for this.

void TxCallback()
{
if( IfxI2c_getLastBurstRequestInterruptSourceStatus( m_ifxI2cDevice.i2c->i2c ) )
{
IfxI2c_clearLastBurstRequestInterruptSource( m_ifxI2cDevice.i2c->i2c );
}
if( IfxI2c_getBurstRequestInterruptSourceStatus( m_ifxI2cDevice.i2c->i2c ) )
{
IfxI2c_clearBurstRequestInterruptSource( m_ifxI2cDevice.i2c->i2c );
}
if( IfxI2c_getLastSingleRequestInterruptSourceStatus( m_ifxI2cDevice.i2c->i2c ) )
{
IfxI2c_clearLastSingleRequestInterruptSource( m_ifxI2cDevice.i2c->i2c );
}
if( IfxI2c_getSingleRequestInterruptSourceStatus( m_ifxI2cDevice.i2c->i2c ) )
{
IfxI2c_clearSingleRequestInterruptSource( m_ifxI2cDevice.i2c->i2c );
}

if( m_u16TxTrnsDataLen < m_u16TxDataLen )
{
uint32_t u32PopCnt = 0;
if( ( m_u16TxDataLen - m_u16TxTrnsDataLen ) >= 4 )
{
u32PopCnt = 4;
m_u16TxTrnsDataLen += u32PopCnt;
}
else
{
u32PopCnt = m_u16TxDataLen - m_u16TxTrnsDataLen;
m_u16TxTrnsDataLen += u32PopCnt;
}

uint32_t u32TxValue;
m_au8TxBuffer->PopFront( reinterpret_cast( &u32TxValue ), u32PopCnt );

IfxI2c_writeFifo( m_ifxI2cHandle.i2c, u32TxValue );
}
}


I use a buffer where the data to send is stored (m_au8TxBuffer). When the callback is invoked the data is read from my buffer and written into the hardware fifo.

For me it seems like that the IfxI2c_ProtocolInterruptSource_transmissionEnd interrupt is activated when the amount of data written in TPSCTRL has been written into the hardware fifo. Is this correct?
0 Likes
MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored
Understood, I think that your timeout is to small and you cancel outstanding data by set of SETEND to 1. Normally it is not needed to set the SETEND bit, only when you will abort any ongoing transmission.
0 Likes
User20495
Level 1
Level 1
In a debug session I can see that the code doesn't run into a timeout. The variable m_blTxDone is set true in the Protocol callback function. That's why I assume that the IfxI2c_ProtocolInterruptSource_transmissionEnd is triggered by the amount of data written into the hw fifo and not the end of the hardware transmission. If so, is there a way to know when the data has been dispatched?

MoD wrote:
Understood, I think that your timeout is to small and you cancel outstanding data by set of SETEND to 1. Normally it is not needed to set the SETEND bit, only when you will abort any ongoing transmission.

Without this, the next action on the I2C wouldn't be possible, because the bus wouldn't be free. In a previous version of the Write function I had a query on the function IfxI2c_busIsFree and after the first write the bus was always busy.
0 Likes
MoD
Employee
Employee
50 likes received 500 replies posted 100 solutions authored
If there is a NACK then with the default settings the I2C state machine goes in the master restart state and a TX_END interrupt. This can be also the issue in your case. Check if there is the NACK also set in the Protocol interrupt.
The first byte which you send out should be the slave address with R/W bit. I expect here that the R/W bit is 0 which means write to I2C device. Correct?
0 Likes