I3C target transmit does not trigger a callback upon completion
Hi,
I am developing an I3C target application that responds to I3C private messages from the controller. The application starts by registering the Tx callback.
static void I3C_TxCompleteCallback(hal_i3c_handle_t *hi3c);
// The callback is registered during initialization
hal_status_t status = HAL_I3C_TGT_RegisterTxCpltCallback(hI3C, I3C_TxCompleteCallback);
if (status != HAL_OK) {
SWD_printf("HAL_I3C_TGT_RegisterTxCpltCallback failed.\n");
return status;
}
The target responds to the controller:
hal_status_t status;
hal_i3c_handle_t *hI3C = mx_i3c1_gethandle();
status = HAL_I3C_TGT_Transmit_IT(hI3C, I3C_TxBuffer, 8);
if (status != HAL_OK) {
SWD_printf("HAL_I3C_TGT_Transmit_IT: %lx\n", status);
return status;
}
The controller receives 8 bytes of data and the data is correct but the TxComplete callback does not trigger on the target side.
I placed a breakpoint inside the HAL I3C_Tgt_ISR show below.
/**
* @brief Interrupt Sub-Routine which handles target transmit data in Interrupt mode.
* @param hi3c Pointer to a @ref hal_i3c_handle_t
* @param it_masks Flag Interrupt Masks flags to handle
* @retval HAL_OK Operation completed successfully
*/
static hal_status_t I3C_Tgt_Tx_ISR(hal_i3c_handle_t *hi3c, uint32_t it_masks)
{
I3C_TypeDef *p_i3cx;
p_i3cx = I3C_GET_INSTANCE(hi3c);
/* I3C Tx FIFO not full interrupt Check */
if (I3C_CHECK_FLAG(it_masks, LL_I3C_MISR_TXFNFMIS) != 0U)
{
if (hi3c->tx_count_byte > 0U)
{
hi3c->p_tx_func(hi3c);
}
}
/* I3C target frame complete event Check */
if (I3C_CHECK_FLAG(it_masks, LL_I3C_MISR_FCMIS) != 0U)
{
LL_I3C_ClearFlag_FC(p_i3cx);
/* Check if all data bytes are transmitted */
if (LL_I3C_GetXferDataCount(p_i3cx) == hi3c->data_size_byte)
{
LL_I3C_DisableIT(p_i3cx, LL_I3C_TGT_TX_IT);
I3C_StateIdle(hi3c);
#if (USE_HAL_I3C_REGISTER_CALLBACKS) && (USE_HAL_I3C_REGISTER_CALLBACKS == 1)
hi3c->p_tgt_tx_cplt_cb(hi3c);
#else
HAL_I3C_TGT_TxCpltCallback(hi3c);
#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
}
else
{
I3C_ErrorTreatment(hi3c);
}
}
/* I3C target wakeup event management ----------------------------------*/
if (I3C_CHECK_FLAG(it_masks, LL_I3C_MISR_WKPMIS) != 0U)
{
/* Clear WKP flag */
LL_I3C_ClearFlag_WKP(p_i3cx);
#if (USE_HAL_I3C_REGISTER_CALLBACKS) && (USE_HAL_I3C_REGISTER_CALLBACKS == 1)
hi3c->p_notify_cb(hi3c, HAL_I3C_TGT_NOTIFICATION_WKP);
#else
HAL_I3C_NotifyCallback(hi3c, HAL_I3C_TGT_NOTIFICATION_WKP);
#endif /* USE_HAL_I3C_REGISTER_CALLBACKS */
}
return HAL_OK;
}
When the interrupt occurs the hi3c->p_tx_func is called and sends the 8 bytes into the FIFO. Once it completes the it_masks check that follows fails and therefore the Tx callback is not called:
/* I3C target frame complete event Check */
if (I3C_CHECK_FLAG(it_masks, LL_I3C_MISR_FCMIS) != 0U)
{
// This code does not execute
}Could you help me figure out why the Tx callback does not occur on the target side?
Thank you,
Gil
