/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : stm32wlxx_nucleo_bus.c * @brief : source file for the BSP BUS IO driver ****************************************************************************** * @attention * * Copyright (c) 2023 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "stm32wlxx_nucleo_bus.h" __weak HAL_StatusTypeDef MX_I2C2_Init(I2C_HandleTypeDef* hi2c); /** @addtogroup BSP * @{ */ /** @addtogroup STM32WLXX_NUCLEO * @{ */ /** @defgroup STM32WLXX_NUCLEO_BUS STM32WLXX_NUCLEO BUS * @{ */ /** @defgroup STM32WLXX_NUCLEO_BUS_Exported_Variables BUS Exported Variables * @{ */ I2C_HandleTypeDef hi2c2; /** * @} */ /** @defgroup STM32WLXX_NUCLEO_BUS_Private_Variables BUS Private Variables * @{ */ #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1U) static uint32_t IsI2C2MspCbValid = 0; #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ static uint32_t I2C2InitCounter = 0; /** * @} */ /** @defgroup STM32WLXX_NUCLEO_BUS_Private_FunctionPrototypes BUS Private Function * @{ */ static void I2C2_MspInit(I2C_HandleTypeDef* hI2c); static void I2C2_MspDeInit(I2C_HandleTypeDef* hI2c); #if (USE_CUBEMX_BSP_V2 == 1) static uint32_t I2C_GetTiming(uint32_t clock_src_hz, uint32_t i2cfreq_hz); static void Compute_PRESC_SCLDEL_SDADEL(uint32_t clock_src_freq, uint32_t I2C_Speed); static uint32_t Compute_SCLL_SCLH (uint32_t clock_src_freq, uint32_t I2C_speed); #endif /** * @} */ /** @defgroup STM32WLXX_NUCLEO_LOW_LEVEL_Private_Functions STM32WLXX_NUCLEO LOW LEVEL Private Functions * @{ */ /** @defgroup STM32WLXX_NUCLEO_BUS_Exported_Functions STM32WLXX_NUCLEO_BUS Exported Functions * @{ */ /* BUS IO driver over I2C Peripheral */ /******************************************************************************* BUS OPERATIONS OVER I2C *******************************************************************************/ /** * @brief Initialize I2C HAL * @retval BSP status */ int32_t BSP_I2C2_Init(void) { int32_t ret = BSP_ERROR_NONE; hi2c2.Instance = I2C2; if(I2C2InitCounter++ == 0) { if (HAL_I2C_GetState(&hi2c2) == HAL_I2C_STATE_RESET) { #if (USE_HAL_I2C_REGISTER_CALLBACKS == 0U) /* Init the I2C Msp */ I2C2_MspInit(&hi2c2); #else if(IsI2C2MspCbValid == 0U) { if(BSP_I2C2_RegisterDefaultMspCallbacks() != BSP_ERROR_NONE) { return BSP_ERROR_MSP_FAILURE; } } #endif if(ret == BSP_ERROR_NONE) { /* Init the I2C */ if(MX_I2C2_Init(&hi2c2) != HAL_OK) { ret = BSP_ERROR_BUS_FAILURE; } else if(HAL_I2CEx_ConfigAnalogFilter(&hi2c2, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { ret = BSP_ERROR_BUS_FAILURE; } else { ret = BSP_ERROR_NONE; } } } } return ret; } /** * @brief DeInitialize I2C HAL. * @retval BSP status */ int32_t BSP_I2C2_DeInit(void) { int32_t ret = BSP_ERROR_NONE; if (I2C2InitCounter > 0) { if (--I2C2InitCounter == 0) { #if (USE_HAL_I2C_REGISTER_CALLBACKS == 0U) /* DeInit the I2C */ I2C2_MspDeInit(&hi2c2); #endif /* DeInit the I2C */ if (HAL_I2C_DeInit(&hi2c2) != HAL_OK) { ret = BSP_ERROR_BUS_FAILURE; } } } return ret; } /** * @brief Check whether the I2C bus is ready. * @param DevAddr : I2C device address * @param Trials : Check trials number * @retval BSP status */ int32_t BSP_I2C2_IsReady(uint16_t DevAddr, uint32_t Trials) { int32_t ret = BSP_ERROR_NONE; if (HAL_I2C_IsDeviceReady(&hi2c2, DevAddr, Trials, BUS_I2C2_POLL_TIMEOUT) != HAL_OK) { ret = BSP_ERROR_BUSY; } return ret; } /** * @brief Write a value in a register of the device through BUS. * @param DevAddr Device address on Bus. * @param Reg The target register address to write * @param pData Pointer to data buffer to write * @param Length Data Length * @retval BSP status */ int32_t BSP_I2C2_WriteReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { int32_t ret = BSP_ERROR_NONE; if (HAL_I2C_Mem_Write(&hi2c2, DevAddr,Reg, I2C_MEMADD_SIZE_8BIT,pData, Length, BUS_I2C2_POLL_TIMEOUT) != HAL_OK) { if (HAL_I2C_GetError(&hi2c2) == HAL_I2C_ERROR_AF) { ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; } else { ret = BSP_ERROR_PERIPH_FAILURE; } } return ret; } /** * @brief Read a register of the device through BUS * @param DevAddr Device address on Bus. * @param Reg The target register address to read * @param pData Pointer to data buffer to read * @param Length Data Length * @retval BSP status */ int32_t BSP_I2C2_ReadReg(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { int32_t ret = BSP_ERROR_NONE; if (HAL_I2C_Mem_Read(&hi2c2, DevAddr, Reg, I2C_MEMADD_SIZE_8BIT, pData, Length, BUS_I2C2_POLL_TIMEOUT) != HAL_OK) { if (HAL_I2C_GetError(&hi2c2) == HAL_I2C_ERROR_AF) { ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; } else { ret = BSP_ERROR_PERIPH_FAILURE; } } return ret; } /** * @brief Write a value in a register of the device through BUS. * @param DevAddr Device address on Bus. * @param Reg The target register address to write * @param pData Pointer to data buffer to write * @param Length Data Length * @retval BSP statu */ int32_t BSP_I2C2_WriteReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { int32_t ret = BSP_ERROR_NONE; if (HAL_I2C_Mem_Write(&hi2c2, DevAddr, Reg, I2C_MEMADD_SIZE_16BIT, pData, Length, BUS_I2C2_POLL_TIMEOUT) != HAL_OK) { if (HAL_I2C_GetError(&hi2c2) == HAL_I2C_ERROR_AF) { ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; } else { ret = BSP_ERROR_PERIPH_FAILURE; } } return ret; } /** * @brief Read registers through a bus (16 bits) * @param DevAddr: Device address on BUS * @param Reg: The target register address to read * @param Length Data Length * @retval BSP status */ int32_t BSP_I2C2_ReadReg16(uint16_t DevAddr, uint16_t Reg, uint8_t *pData, uint16_t Length) { int32_t ret = BSP_ERROR_NONE; if (HAL_I2C_Mem_Read(&hi2c2, DevAddr, Reg, I2C_MEMADD_SIZE_16BIT, pData, Length, BUS_I2C2_POLL_TIMEOUT) != HAL_OK) { if (HAL_I2C_GetError(&hi2c2) != HAL_I2C_ERROR_AF) { ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; } else { ret = BSP_ERROR_PERIPH_FAILURE; } } return ret; } /** * @brief Send an amount width data through bus (Simplex) * @param DevAddr: Device address on Bus. * @param pData: Data pointer * @param Length: Data length * @retval BSP status */ int32_t BSP_I2C2_Send(uint16_t DevAddr, uint8_t *pData, uint16_t Length) { int32_t ret = BSP_ERROR_NONE; if (HAL_I2C_Master_Transmit(&hi2c2, DevAddr, pData, Length, BUS_I2C2_POLL_TIMEOUT) != HAL_OK) { if (HAL_I2C_GetError(&hi2c2) != HAL_I2C_ERROR_AF) { ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; } else { ret = BSP_ERROR_PERIPH_FAILURE; } } return ret; } /** * @brief Receive an amount of data through a bus (Simplex) * @param DevAddr: Device address on Bus. * @param pData: Data pointer * @param Length: Data length * @retval BSP status */ int32_t BSP_I2C2_Recv(uint16_t DevAddr, uint8_t *pData, uint16_t Length) { int32_t ret = BSP_ERROR_NONE; if (HAL_I2C_Master_Receive(&hi2c2, DevAddr, pData, Length, BUS_I2C2_POLL_TIMEOUT) != HAL_OK) { if (HAL_I2C_GetError(&hi2c2) != HAL_I2C_ERROR_AF) { ret = BSP_ERROR_BUS_ACKNOWLEDGE_FAILURE; } else { ret = BSP_ERROR_PERIPH_FAILURE; } } return ret; } #if (USE_HAL_I2C_REGISTER_CALLBACKS == 1U) /** * @brief Register Default BSP I2C2 Bus Msp Callbacks * @retval BSP status */ int32_t BSP_I2C2_RegisterDefaultMspCallbacks (void) { __HAL_I2C_RESET_HANDLE_STATE(&hi2c2); /* Register MspInit Callback */ if (HAL_I2C_RegisterCallback(&hi2c2, HAL_I2C_MSPINIT_CB_ID, I2C2_MspInit) != HAL_OK) { return BSP_ERROR_PERIPH_FAILURE; } /* Register MspDeInit Callback */ if (HAL_I2C_RegisterCallback(&hi2c2, HAL_I2C_MSPDEINIT_CB_ID, I2C2_MspDeInit) != HAL_OK) { return BSP_ERROR_PERIPH_FAILURE; } IsI2C2MspCbValid = 1; return BSP_ERROR_NONE; } /** * @brief BSP I2C2 Bus Msp Callback registering * @param Callbacks pointer to I2C2 MspInit/MspDeInit callback functions * @retval BSP status */ int32_t BSP_I2C2_RegisterMspCallbacks (BSP_I2C_Cb_t *Callbacks) { /* Prevent unused argument(s) compilation warning */ __HAL_I2C_RESET_HANDLE_STATE(&hi2c2); /* Register MspInit Callback */ if (HAL_I2C_RegisterCallback(&hi2c2, HAL_I2C_MSPINIT_CB_ID, Callbacks->pMspInitCb) != HAL_OK) { return BSP_ERROR_PERIPH_FAILURE; } /* Register MspDeInit Callback */ if (HAL_I2C_RegisterCallback(&hi2c2, HAL_I2C_MSPDEINIT_CB_ID, Callbacks->pMspDeInitCb) != HAL_OK) { return BSP_ERROR_PERIPH_FAILURE; } IsI2C2MspCbValid = 1; return BSP_ERROR_NONE; } #endif /* USE_HAL_I2C_REGISTER_CALLBACKS */ /** * @brief Return system tick in ms * @retval Current HAL time base time stamp */ int32_t BSP_GetTick(void) { return HAL_GetTick(); } /* I2C2 init function */ __weak HAL_StatusTypeDef MX_I2C2_Init(I2C_HandleTypeDef* hi2c) { HAL_StatusTypeDef ret = HAL_OK; hi2c->Instance = I2C2; hi2c->Init.Timing = 0x20303E5D; hi2c->Init.OwnAddress1 = 0; hi2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c->Init.OwnAddress2 = 0; hi2c->Init.OwnAddress2Masks = I2C_OA2_NOMASK; hi2c->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c->Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(hi2c) != HAL_OK) { ret = HAL_ERROR; } if (HAL_I2CEx_ConfigAnalogFilter(hi2c, I2C_ANALOGFILTER_ENABLE) != HAL_OK) { ret = HAL_ERROR; } if (HAL_I2CEx_ConfigDigitalFilter(hi2c, 0) != HAL_OK) { ret = HAL_ERROR; } return ret; } static void I2C2_MspInit(I2C_HandleTypeDef* i2cHandle) { GPIO_InitTypeDef GPIO_InitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /* USER CODE BEGIN I2C2_MspInit 0 */ /* USER CODE END I2C2_MspInit 0 */ /** Initializes the peripherals clocks */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2C2; PeriphClkInitStruct.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1; HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); __HAL_RCC_GPIOA_CLK_ENABLE(); /**I2C2 GPIO Configuration PA12 ------> I2C2_SCL PA15 ------> I2C2_SDA */ GPIO_InitStruct.Pin = BUS_I2C2_SCL_GPIO_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = BUS_I2C2_SCL_GPIO_AF; HAL_GPIO_Init(BUS_I2C2_SCL_GPIO_PORT, &GPIO_InitStruct); GPIO_InitStruct.Pin = BUS_I2C2_SDA_GPIO_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Alternate = BUS_I2C2_SDA_GPIO_AF; HAL_GPIO_Init(BUS_I2C2_SDA_GPIO_PORT, &GPIO_InitStruct); /* Peripheral clock enable */ __HAL_RCC_I2C2_CLK_ENABLE(); /* USER CODE BEGIN I2C2_MspInit 1 */ /* USER CODE END I2C2_MspInit 1 */ } static void I2C2_MspDeInit(I2C_HandleTypeDef* i2cHandle) { /* USER CODE BEGIN I2C2_MspDeInit 0 */ /* USER CODE END I2C2_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_I2C2_CLK_DISABLE(); /**I2C2 GPIO Configuration PA12 ------> I2C2_SCL PA15 ------> I2C2_SDA */ HAL_GPIO_DeInit(BUS_I2C2_SCL_GPIO_PORT, BUS_I2C2_SCL_GPIO_PIN); HAL_GPIO_DeInit(BUS_I2C2_SDA_GPIO_PORT, BUS_I2C2_SDA_GPIO_PIN); /* USER CODE BEGIN I2C2_MspDeInit 1 */ /* USER CODE END I2C2_MspDeInit 1 */ } /** * @} */ /** * @} */ /** * @} */ /** * @} */