cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H5 Can't initialize i3c device BMI323

wyatt-m
Associate

I am working off of the example I3C_Controller_ENTDAA_IT for the STM32H5 series to initialize a device (BMI323 IMU). I am hitting an error handler at the HAL_I3C_ErrorCallback before it tries to add the device on the bus.

The SER value at the HAL_I3C_ErrorCallback is 10010.

Is the TargetDesc1 struct wrong or is there something else that could be causing this? Thanks

 

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "desc_target1.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

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

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

I3C_HandleTypeDef hi3c1;
DMA_HandleTypeDef handle_GPDMA1_Channel2;
DMA_HandleTypeDef handle_GPDMA1_Channel1;
DMA_HandleTypeDef handle_GPDMA1_Channel0;

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

/* Number of Targets detected during DAA procedure */
__IO uint32_t uwTargetCount = 0;

// /* Buffer used for reception during Get CCC procedure */
// uint8_t aRxBuffer[0x1F];

// /* Buffer used for transmission during Set CCC procedure */
// uint8_t aTxBuffer[0x0F];

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

/* Array contain targets descriptor */
TargetDesc_TypeDef *aTargetDesc[1] =
    {
        &TargetDesc1 /* DEVICE_ID1 */
};

/* Buffer that contain payload data, mean PID, BCR, DCR */
uint8_t aPayloadBuffer[64 * COUNTOF(aTargetDesc)];

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_GPDMA1_Init(void);
static void MX_I3C1_Init(void);
static void MX_ICACHE_Init(void);
/* USER CODE BEGIN PFP */
static void DisplayCCCValue(I3C_CCCTypeDef *pGetCCCList, char **pCCCCharList, uint8_t *pCCCBuffer, uint8_t nbCCC);
// #if (defined(__GNUC__) && !defined(__ARMCC_VERSION))
// extern void initialise_monitor_handles(void);
// #endif
/* 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 */
  // #if (defined(__GNUC__) && !defined(__ARMCC_VERSION))
  //   initialise_monitor_handles();
  //   printf("Semihosting Test...\n\r");
  // #endif
  /* USER CODE END 1 */

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

  /* 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_GPDMA1_Init();
  MX_I3C1_Init();
  MX_ICACHE_Init();
  /* USER CODE BEGIN 2 */
  /* Configure LED1 */
  BSP_LED_Init(LED1);

  /* Configure USER push-button */
  BSP_PB_Init(BUTTON_USER, BUTTON_MODE_GPIO);

  /* Wait for USER push-button press before starting the Communication */
  // while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_RESET)
  // {
  // }

  /* Wait for USER push-button release before starting the Communication */
  // while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_SET)
  // {
  // }

  /*##- Start the transmission process ###################################*/
  /* Assign dynamic address processus */
  if (HAL_I3C_Ctrl_DynAddrAssign_IT(&hi3c1, I3C_ONLY_ENTDAA) != HAL_OK)
  {
    /* Error_Handler() function is called when error occurs. */
    Error_Handler();
  }

  /*##- Wait for the end of the transfer #################################*/
  /*  Before starting a new communication transfer, you need to check the current
  state of the peripheral; if it’s busy you need to wait for the end of current
  transfer before starting a new one.
  For simplicity reasons, this example is just waiting till the end of the
  transfer, but application may perform other tasks while transfer operation
  is ongoing. */
  while (HAL_I3C_GetState(&hi3c1) != HAL_I3C_STATE_READY)
  {
  }
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}



/**
 * @brief I3C1 Initialization Function
 *  None
 * @retval None
 */
static void MX_I3C1_Init(void)
{

  /* USER CODE BEGIN I3C1_Init 0 */

  /* USER CODE END I3C1_Init 0 */

  I3C_FifoConfTypeDef sFifoConfig = {0};
  I3C_CtrlConfTypeDef sCtrlConfig = {0};

  /* USER CODE BEGIN I3C1_Init 1 */

  /* USER CODE END I3C1_Init 1 */
  hi3c1.Instance = I3C1;
  hi3c1.Mode = HAL_I3C_MODE_CONTROLLER;
  hi3c1.Init.CtrlBusCharacteristic.SDAHoldTime = HAL_I3C_SDA_HOLD_TIME_1_5;
  hi3c1.Init.CtrlBusCharacteristic.WaitTime = HAL_I3C_OWN_ACTIVITY_STATE_0;
  hi3c1.Init.CtrlBusCharacteristic.SCLPPLowDuration = 0x09;
  hi3c1.Init.CtrlBusCharacteristic.SCLI3CHighDuration = 0x09;
  hi3c1.Init.CtrlBusCharacteristic.SCLODLowDuration = 0x59;
  hi3c1.Init.CtrlBusCharacteristic.SCLI2CHighDuration = 0x00;
  hi3c1.Init.CtrlBusCharacteristic.BusFreeDuration = 0x32;
  hi3c1.Init.CtrlBusCharacteristic.BusIdleDuration = 0xf8;
  if (HAL_I3C_Init(&hi3c1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure FIFO
   */
  sFifoConfig.RxFifoThreshold = HAL_I3C_RXFIFO_THRESHOLD_1_4;
  sFifoConfig.TxFifoThreshold = HAL_I3C_TXFIFO_THRESHOLD_1_4;
  sFifoConfig.ControlFifo = HAL_I3C_CONTROLFIFO_DISABLE;
  sFifoConfig.StatusFifo = HAL_I3C_STATUSFIFO_DISABLE;
  if (HAL_I3C_SetConfigFifo(&hi3c1, &sFifoConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure controller
   */
  sCtrlConfig.DynamicAddr = 0;
  sCtrlConfig.StallTime = 0x00;
  sCtrlConfig.HotJoinAllowed = DISABLE;
  sCtrlConfig.ACKStallState = DISABLE;
  sCtrlConfig.CCCStallState = DISABLE;
  sCtrlConfig.TxStallState = DISABLE;
  sCtrlConfig.RxStallState = DISABLE;
  sCtrlConfig.HighKeeperSDA = DISABLE;
  if (HAL_I3C_Ctrl_Config(&hi3c1, &sCtrlConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I3C1_Init 2 */

  /* USER CODE END I3C1_Init 2 */
}

/* USER CODE BEGIN 4 */
/**
 * @brief I3C target request a dynamic address callback.
 *        The main objective of this user function is to check if a target request a dynamic address.
 *        if the case we should assign a dynamic address to the target.
 * @par Called functions
 * - HAL_I3C_TgtReqDynamicAddrCallback()
 * - HAL_I3C_Ctrl_SetDynamicAddress()
 * @retval None
 */
void HAL_I3C_TgtReqDynamicAddrCallback(I3C_HandleTypeDef *hi3c, uint64_t targetPayload)
{
  /* Update Payload on aTargetDesc */
  aTargetDesc[uwTargetCount]->TARGET_BCR_DCR_PID = targetPayload;

  /* Send associated dynamic address */
  HAL_I3C_Ctrl_SetDynAddr(hi3c, aTargetDesc[uwTargetCount++]->DYNAMIC_ADDR);
}

/**
 * @brief  Error callback.
 *   hi3c : [IN] Pointer to an I3C_HandleTypeDef structure that contains the configuration information
 *                     for the specified I3C.
 * @retval None
 */
void HAL_I3C_ErrorCallback(I3C_HandleTypeDef *hi3c)
{
  /* Error_Handler() function is called when error occurs. */
  Error_Handler();
}

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* Error if LED1 is slowly blinking (1 sec. period) */
  while (1)
  {
    BSP_LED_Toggle(LED1);
    HAL_Delay(1000);
  }
  /* USER CODE END Error_Handler_Debug */
}

 

 

 

#ifndef __STM32_I3C_DESC_TARGET1_H
#define __STM32_I3C_DESC_TARGET1_H

/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#define TARGET1_DYN_ADDR 0x32

/********************/
/* Target Descriptor */
/********************/
TargetDesc_TypeDef TargetDesc1 =
    {
        "TARGET_ID1",
        DEVICE_ID1,
        0x07701043000026EF,
        0x68,
        TARGET1_DYN_ADDR,
};

#endif /* __STM32_I3C_DESC_TARGET1_H */

 

 

2 REPLIES 2
Foued_KH
ST Employee

Hello @wyatt-m , 

I don't see the System Clock Configuration ( void SystemClock_Config(void) ) ? 
Try to debug step by step. 

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.

Foued_KH
ST Employee

Hi @wyatt-m , 

Try to reduce the I3C frequency.
Any feedback?

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.