cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DSO I3C SETDASA

jad1
Associate II

Hello!

I'm working on an Nucleo-H503RB board and trying to communicate with a LSM6DSO over I3C.

I am now able to use ENTDAA to assign a dynamic address to the LSM6DSO.
Next, I want to test using SETDASA to assign a dynamic address based on the static address (0x6A) of the LSM6DSO. I followed Getting started with I3C - stm32mcu(4.2 Dynamic addressing using SETDASA CCC section ), but encountered the following issue.

Issue:

The process stops at RSTDAA and does not continue to SETDASA.

jad1_0-1777514154625.png
jad1_1-1777514179063.png
jad1_2-1777514187310.png
I have already verified via I2C that the static address is 0x6A.

Question:

How can I successfully complete the SETDASA procedure?
 

Full Code:

/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include "target.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
#define Direct_SETDASA 0x87
#define Brodacast_DISEC 0x01
#define Brodacast_RST 0x06

#define LSM6DSO_DYNAMIC_ADDR 0x32
/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define I3C_IDX_FRAME_1         0U  /* Index of Frame 1 */
#define I3C_IDX_FRAME_2         1U  /* Index of Frame 2 */
#define STATIC_ADRESS_LSM6DSO   0x6A
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
COM_InitTypeDef BspCOMInit;
I3C_HandleTypeDef hi3c1;

/* USER CODE BEGIN PV */
uint8_t aSETDASA_LSM6DSO_data[1]   = {(LSM6DSO_DYNAMIC_ADDR << 1)};
uint8_t aDISEC_data[1]   = {0x08}; // Disable IBI interrupt

/* Buffer used for transmission */
uint8_t aTxBuffer[0x0F];

/* Buffer used by HAL to compute control data for the Private Communication */
uint32_t aControlBuffer[0xF];

/* Context buffer related to Frame context, contain different buffer value for a communication */
I3C_XferTypeDef aContextBuffers[2];

/* Descriptor for direct write SETDASA CCC */
I3C_CCCTypeDef aSET_DASA_LSM6DSO[] =
{
    /*Target Addr CCC Value CCC data + defbyte pointer  CCC size + defbyte Direction        */
    {0x6A,Direct_SETDASA,{aSETDASA_LSM6DSO_data,1},HAL_I3C_DIRECTION_WRITE},
};

/* Descriptor for direct write DISEC CCC */
I3C_CCCTypeDef aSET_CCC_DISEC[] =
{
    {0x6A,Brodacast_DISEC, {aDISEC_data,1},LL_I3C_DIRECTION_WRITE},
};

/* Descriptor for direct write RST CCC */
I3C_CCCTypeDef aSET_CCC_RST[] =
{
    {0x6A,Brodacast_RST, {NULL,0},LL_I3C_DIRECTION_WRITE},
};
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_I3C1_Init(void);
static void MX_ICACHE_Init(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I3C1_Init();
  MX_ICACHE_Init();
  /* USER CODE BEGIN 2 */

  /* Send a DISEC to disable IBI interrupt */
    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;

    /* Add context buffer Set CCC frame in Frame context */
    if (HAL_I3C_AddDescToFrame(&hi3c1,
                               aSET_CCC_DISEC,
                               NULL,
                               aContextBuffers,
                               1,
                               I3C_BROADCAST_WITHOUT_DEFBYTE_RESTART) != HAL_OK)
    {
      Error_Handler();
    }

    if (HAL_I3C_Ctrl_TransmitCCC(&hi3c1, aContextBuffers, 1000) != HAL_OK)
    {
      Error_Handler();
    }

    while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY)
    {
    }

    /* Send a RSTDAA to reset previous dynamic address the target */
    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;

    /*Add context buffer Set CCC frame in Frame context */
    if (HAL_I3C_AddDescToFrame(&hi3c1,
                               aSET_CCC_RST,
                               NULL,
                               aContextBuffers,
                               1,
                               I3C_BROADCAST_WITHOUT_DEFBYTE_RESTART) != HAL_OK)
    {
      Error_Handler();
    }

    if (HAL_I3C_Ctrl_TransmitCCC(&hi3c1, aContextBuffers, 1000) != HAL_OK)
    {
      Error_Handler();
    }

    while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY)
    {
    }

    /* Send a SETDASA to set the dynamic on LSM6DSO using his static address */
    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;

    /* Add context buffer Set CCC frame in Frame context */
    if (HAL_I3C_AddDescToFrame(&hi3c1,
                               aSET_DASA_LSM6DSO,
                               NULL,
                               &aContextBuffers[I3C_IDX_FRAME_1],
                               1,
                               I3C_DIRECT_WITHOUT_DEFBYTE_RESTART) != HAL_OK)
    {
      Error_Handler();
    }

    if (HAL_I3C_Ctrl_TransmitCCC_IT(&hi3c1, &aContextBuffers[I3C_IDX_FRAME_1]) != HAL_OK)
    {
      Error_Handler();
    }

    while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY)
    {
    }

    /* After a dynamic address has been assigned, the sensor is recognized as an I3C device */
    /* Check if the LSM6DSO sensor is ready to communicate in I3C */
    if (HAL_I3C_Ctrl_IsDeviceI3C_Ready(&hi3c1, LSM6DSO_DYNAMIC_ADDR, 300, 1000) != HAL_OK)
    {
      Error_Handler();
    }

  /* USER CODE END 2 */
 
4 REPLIES 4
Foued_KH
ST Employee

Hello @jad1 ,

Try to use SETDASA with the raw 7-bit dynamic address in the payload, not the address shifted left by one.
uint8_t aSETDASA_LSM6DSO_data[1] = {LSM6DSO_DYNAMIC_ADDR};
You can also debug the code and tell me whether 
SETDASA is actually sent or not then we can verify the waveform .

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.

Hello Foued,

I changed the dynamic address as below, but the logic analyzer shows the same result.

uint8_t aSETDASA_LSM6DSO_data[1]   = {(LSM6DSO_DYNAMIC_ADDR)};

I tried to print the procedure on the PuTTY log. It seems like it's stuck in adding the SETDASA frame.

jad1_0-1777551760699.png

  if (HAL_I3C_AddDescToFrame(&hi3c1,
                             aSET_DASA_LSM6DSO,
                             NULL,
                             &aContextBuffers[I3C_IDX_FRAME_1],
                             1,
                             I3C_DIRECT_WITHOUT_DEFBYTE_RESTART) != HAL_OK)
  {
    printf("[I3C][ERROR] Add SETDASA frame failed\r\n");
    printf("[I3C] ErrorCode = 0x%08lX\r\n", hi3c1.ErrorCode);
    Error_Handler();
  }

If I have taken any wrong step, please kindly tell me.

Thanks for help!

 

Debug and step into HAL_I3C_AddDescToFrame() to see exactly where the execution gets stuck and identify the root cause.
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.

I resolved the issue by changing the RESTART in the Add RST frame to STOP.
    /*Add context buffer Set CCC frame in Frame context */
    if (HAL_I3C_AddDescToFrame(&hi3c1,
                               aSET_CCC_RST,
                               NULL,
                               aContextBuffers,
                               1,
                               I3C_BROADCAST_WITHOUT_DEFBYTE_STOP) != HAL_OK)
Thank you for your help!