2025-12-21 7:48 AM
Hi everyone,
I'm using the NUCLEO-H7S3L8 to try to comunicate with a BOS1921 device using the I3C protocol. To get practice i'm trying to read form the Register Map in 6.10 (see the datasheet). Using some example codes from this link https://www.st.com/resource/en/application_note/an5879-introduction-to-i3c-for-stm32h5-series-mcu-stmicroelectronics.pdf
and this https://wiki.st.com/stm32mcu/wiki/Getting_started_with_I3C .
from the example code that i made i try to give the bos1921 a adres, after that i try to read from the Register 0x02 and expect a value of 0x046A in return. but everytime it looks like it's the value from register 0x1E, that is the CHIP_ID. Even trying to read other registers i get the same result.
Any idea what I'm doing wrong trying to read?
Buffers i made:
I3C_XferTypeDef aContextBuffers[2];
/* Buffer used for transmission */
uint8_t aTxBuffer[2];
uint8_t aRxBuffer[2];
uint8_t readAdress[1] = {0x06};
/* Buffer used by HAL to compute control data for the Private Communication */
uint32_t aControlBuffer[0xF];
I3C_PrivateTypeDef aPrivateDescriptor[3] = \
{
{DEVICE_STA_ADDR, {readAdress, 1}, {NULL, 0}, HAL_I3C_DIRECTION_WRITE},
{DEVICE_STA_ADDR, {NULL, 0}, {aRxBuffer, 2}, HAL_I3C_DIRECTION_READ}
};
The test code that i used for it:
uint64_t TargetPayload;
HAL_StatusTypeDef status = HAL_OK;
/* Assign dynamic address processus */
do
{
status = HAL_I3C_Ctrl_DynAddrAssign(&hi3c1, &TargetPayload, I3C_RSTDAA_THEN_ENTDAA, 5000);
if (status == HAL_BUSY)
{
HAL_I3C_Ctrl_SetDynAddr(&hi3c1, DEVICE_STA_ADDR);
printf("assigned adres to device \n\r");
}
} while (status == HAL_BUSY);
while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY);
if (HAL_I3C_Ctrl_IsDeviceI3C_Ready(&hi3c1, DEVICE_STA_ADDR, 300, 1000) != HAL_OK)
{
/* Error_Handler() function is called when error occurs. */
printf("Device is not ready \n\r");
while(1);
}
printf("Device is ready \n\r");
aContextBuffers[0].CtrlBuf.pBuffer = aControlBuffer;
aContextBuffers[0].CtrlBuf.Size = 1;
aContextBuffers[0].TxBuf.pBuffer = aTxBuffer;
aContextBuffers[0].TxBuf.Size = 1;
aContextBuffers[1].CtrlBuf.pBuffer = aControlBuffer;
aContextBuffers[1].CtrlBuf.Size = 1;
aContextBuffers[1].RxBuf.pBuffer = aRxBuffer;
aContextBuffers[1].RxBuf.Size = 2;
if (HAL_I3C_AddDescToFrame(&hi3c1,
NULL,
&aPrivateDescriptor[0],
&aContextBuffers[0],
aContextBuffers[0].CtrlBuf.Size,
I3C_PRIVATE_WITH_ARB_RESTART) != HAL_OK)
{
printf("error trying to add descriptor \n\r");
while(1);
}
if(HAL_I3C_Ctrl_Transmit(&hi3c1, &aContextBuffers[0], 1000) != HAL_OK)
{
printf("Error sending data \n\r");
while(1);
}
while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY);
if (HAL_I3C_AddDescToFrame(&hi3c1,
NULL,
&aPrivateDescriptor[1],
&aContextBuffers[1],
aContextBuffers[1].CtrlBuf.Size,
I3C_PRIVATE_WITHOUT_ARB_STOP) != HAL_OK)
{
printf("error trying to add descriptor \n\r");
while(1);
}
if(HAL_I3C_Ctrl_Receive(&hi3c1, &aContextBuffers[1], 1000) != HAL_OK)
{
printf("Error Reciving data \n\r");
while(1);
}
printf("data 1 = %x \n\r", aRxBuffer[0]);
printf("data 2 = %x \n\r", aRxBuffer[1]);
Screenshot of the prints that it made:
Screenshots from my logic analyzer:
Assigning adress:
trying to read: