cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H503RB I3C private communication

SteveDu
Associate II

Hi all,

I tried to communicate(private) with my I3C slave device by using STM32H503RB board (as a controller).

Here's the code from "Introduction to I3C for STM32 MCUs - Application note Chapter 9.8 Private read" 

 

uint8_t aTxBuffer[1] = {0x0F};

uint8_t aRxBuffer[1];

TargetDesc_TypeDef *aTargetDesc[1] = \

{

&TargetDesc1, /* DEVICE_ID1 */

};

/* Descriptor for private data transmit */

I3C_PrivateTypeDef aPrivateDescriptor[2] = \

{

{TARGET1_DYN_ADDR, {aTxBuffer, TXBUFFERSIZE}, {NULL, 0}, HAL_I3C_DIRECTION_WRITE},

{TARGET1_DYN_ADDR, {NULL, 0}, {aRxBuffer, RXBUFFERSIZE}, HAL_I3C_DIRECTION_READ}

};



aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.pBuffer = aControlBuffer;

aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size = 1;

aContextBuffers[I3C_IDX_FRAME_1].TxBuf.pBuffer = aTxBuffer;

aContextBuffers[I3C_IDX_FRAME_1].TxBuf.Size = TXBUFFERSIZE;



/* Prepare Receive context buffer with the different parameters */

aContextBuffers[I3C_IDX_FRAME_2].CtrlBuf.pBuffer = aControlBuffer;

aContextBuffers[I3C_IDX_FRAME_2].CtrlBuf.Size = 1;

aContextBuffers[I3C_IDX_FRAME_2].RxBuf.pBuffer = aRxBuffer;

aContextBuffers[I3C_IDX_FRAME_2].RxBuf.Size = RXBUFFERSIZE;

if (HAL_I3C_AddDescToFrame(&hi3c1,

NULL,

&aPrivateDescriptor[I3C_IDX_FRAME_1],

&aContextBuffers[I3C_IDX_FRAME_1],

aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size,

I3C_PRIVATE_WITH_ARB_RESTART) != HAL_OK)

{

/* Error_Handler() function is called when error occurs. */

Error_Handler();

}

if (HAL_I3C_Ctrl_Transmit_IT(&hi3c1, &aContextBuffers[I3C_IDX_FRAME_1]) != HAL_OK)

{

/* Error_Handler() function is called when error occurs. */

Error_Handler();

}

while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY)

{

}

if (HAL_I3C_AddDescToFrame(&hi3c1,

NULL,

&aPrivateDescriptor[I3C_IDX_FRAME_2],

&aContextBuffers[I3C_IDX_FRAME_2],

aContextBuffers[I3C_IDX_FRAME_2].CtrlBuf.Size,

I3C_PRIVATE_WITH_ARB_STOP) != HAL_OK)

{

/* Error_Handler() function is called when error occurs. */

Error_Handler();

}

if (HAL_I3C_Ctrl_Transmit_IT(&hi3c1, &aContextBuffers[I3C_IDX_FRAME_2]) != HAL_OK)

{

/* Error_Handler() function is called when error occurs. */

Error_Handler();

}

}
SteveDu_0-1718787262787.png

 

After running debug, the error occurs in "static HAL_StatusTypeDef I3C_Xfer_PriorPreparation()"

condition (global_tx_size > hi3c->pXferData->TxBuf.Size) will always be satisfied unless 'aTxBuffer[]' has more than 147 elements.

Did anyone encounter this problem before?

Btw, should I execute ENTDAA before PrivateRead?

3 REPLIES 3
Foued_KH
ST Employee

Hello @SteveDu , 

Try this one : 

aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.pBuffer = aControlBuffer;
aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size = 1;
aContextBuffers[I3C_IDX_FRAME_1].TxBuf.pBuffer = aTxBuffer;
aContextBuffers[I3C_IDX_FRAME_1].TxBuf.Size = 1;

/* Prepare Receive context buffer with the different parameters */
aContextBuffers[I3C_IDX_FRAME_2].CtrlBuf.pBuffer = aControlBuffer;
aContextBuffers[I3C_IDX_FRAME_2].CtrlBuf.Size = 1;
aContextBuffers[I3C_IDX_FRAME_2].RxBuf.pBuffer = aRxBuffer;
aContextBuffers[I3C_IDX_FRAME_2].RxBuf.Size = 1;


Yes, you should execute ENTDAA before Private Read.

Let me know!
Foued

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi Foued,

I tried the code that you suggested, and the system stuck in the same place.

I found out that 'global_tx_size' came from 'pPrivateDesc.TxBuf.Size', which was set at line 2167.

SteveDu_0-1718794686352.png

However,  I think I fix this problem after this modification.

Before:

I3C_PrivateTypeDef aPrivateDescriptor[2] = \
                                          {
                                            {TARGET1_DYN_ADDR, {aTxBuffer, TXBUFFERSIZE}, {NULL, 0}, HAL_I3C_DIRECTION_WRITE},
                                            {TARGET1_DYN_ADDR, {NULL, 0}, {aRxBuffer, RXBUFFERSIZE}, HAL_I3C_DIRECTION_READ}
                                          };

After:

I3C_PrivateTypeDef aPrivateDescriptor[2] = \
                                          {
                                            {TARGET1_DYN_ADDR, {aTxBuffer, 1}, {NULL, 0}, HAL_I3C_DIRECTION_WRITE},
                                            {TARGET1_DYN_ADDR, {NULL, 0}, {aRxBuffer, 1}, HAL_I3C_DIRECTION_READ}
                                          };

I could capture a waveform as below:

SteveDu_1-1718796473955.png

Q1:

That modification make the system can only send 1byte of data.

Could you provide a better solution?

Q2:

It seems that the system successfully transmit a data (0x20), but why?

Shouldn't the expected value of this data be 0x0F?

	  uint8_t aTxBuffer[1] = {0x0F};
	  uint8_t aRxBuffer[1];
	  aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.pBuffer = aControlBuffer;
	  aContextBuffers[I3C_IDX_FRAME_1].CtrlBuf.Size    = 1;
	  aContextBuffers[I3C_IDX_FRAME_1].TxBuf.pBuffer   = aTxBuffer;
	  aContextBuffers[I3C_IDX_FRAME_1].TxBuf.Size      = 1;

	  /* Prepare Receive context buffer with the different parameters */
	  aContextBuffers[I3C_IDX_FRAME_2].CtrlBuf.pBuffer = aControlBuffer;
	  aContextBuffers[I3C_IDX_FRAME_2].CtrlBuf.Size    = 1;
	  aContextBuffers[I3C_IDX_FRAME_2].RxBuf.pBuffer   = aRxBuffer;
	  aContextBuffers[I3C_IDX_FRAME_2].RxBuf.Size      = 1;

 

 

Hello @SteveDu , 

1/ You can modify the size of the Tx buffer and the Rx buffer to receive more data. 

2/ Could you check the datasheet of your device ( I3C target ) for more details about registers ?

Foued

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.