Question
STM32H5 Can't initialize i3c device BMI323
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 */
