Skip to main content
Graduate II
June 19, 2024
Question

STM32H503RB I3C private communication

  • June 19, 2024
  • 1 reply
  • 1464 views

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?

    This topic has been closed for replies.

    1 reply

    ST Employee
    June 19, 2024

    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

    SteveDuAuthor
    Graduate II
    June 19, 2024

    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;

     

     

    ST Employee
    June 21, 2024

    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