cancel
Showing results for 
Search instead for 
Did you mean: 

LSM6DSO I3C SETDASA

jad1
Associate

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 */
 
2 REPLIES 2
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!