Skip to main content
Visitor II
September 15, 2025
Solved

How to config SMBUS Slave mode and how to get the data once address is acknowledge

  • September 15, 2025
  • 3 replies
  • 508 views

 

void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef* SMBUSHandle)
{
 /** Error_Handler() function is called when error occurs.
 * 1- When Slave doesn't acknowledge its address, Master restarts
 * communication. 2- When Master doesn't acknowledge the last data
 * transferred, Slave doesn't care in this example.
 */
 if (HAL_SMBUS_GetError(SMBUSHandle) != HAL_SMBUS_ERROR_ACKF)
 {
 printf("failed\r\n");
 /* Turn Off LED2 */
 }
}

/**
 * @brief Slave Address Match callbacks.
 * hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
 * the configuration information for the specified SMBUS.
 * @retval None
 */
void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef* hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
 SlaveAddrMatchCode = (AddrMatchCode << 1);
 HAL_SMBUS_EnableListen_IT(&hsmbus1);
 uint8_t tx_buff = 0x00;
 HAL_SMBUS_Slave_Transmit_IT(&hsmbus1, &tx_buff, 1, SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC);
 // HAL_SMBUS_Slave_Transmit_IT(&hsmbus1, &aTxBuffer, 1,
 // SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC);
 UNUSED(TransferDirection);
}
void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef* hsmbus)
{
 HAL_SMBUS_Slave_Receive_IT(&hsmbus1, dummy_data, 2, SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC);
}

//
// return 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--------------------------------------------------------*/

 /* 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_USART3_UART_Init();
 MX_USART2_UART_Init();
 MX_TIM1_Init();
 MX_I2C1_SMBUS_Init();
 MX_I2C3_SMBUS_Init();
 /* USER CODE BEGIN 2 */

 /* Enable the Analog SMBUS Filter */
 HAL_SMBUS_ConfigAnalogFilter(&hsmbus1, SMBUS_ANALOGFILTER_ENABLE);

 /* Enable address Match detect with interrupt */
 HAL_SMBUS_EnableListen_IT(&hsmbus1);
 /* Wait until address matched */

 while (SlaveAddrMatchCode != SMBUS_ADDRESS)
 ;

 /* USER CODE END 2 */

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

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

 

    This topic has been closed for replies.
    Best answer by MOBEJ

    Hello @suguresh_m , 

    I recommend downloading the X-CUBE-SMBUS Expansion Package, which contains the SMBus/PMBus® stack implementation for STM32Cube. This package provides example projects and basic functionality tests for the following boards: NUCLEO-G431RB ,NUCLEO-H743ZI,NUCLEO-L4R5ZI & NUCLEO-WB55RG ...

    You can download the package directly from ST's official website here:
    https://www.st.com/en/embedded-software/x-cube-smbus.html

    Additionally, I suggest reviewing the related Application Note for detailed guidance:
    https://www.st.com/resource/en/application_note/an4502-stm32-smbuspmbus-expansion-package-for-stm32cube-stmicroelectronics.pdf

    This resource should be very helpful in resolving your issue.

    Br

    3 replies

    Visitor II
    September 12, 2025

    Edited by ST moderator to be inline with the community rules especially with the code sharing. In next time please use </> button to paste your code. Please read this post: How to insert source code.

     

    void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef* SMBUSHandle)
    {
     /** Error_Handler() function is called when error occurs.
     * 1- When Slave doesn't acknowledge its address, Master restarts
     * communication. 2- When Master doesn't acknowledge the last data
     * transferred, Slave doesn't care in this example.
     */
     if (HAL_SMBUS_GetError(SMBUSHandle) != HAL_SMBUS_ERROR_ACKF)
     {
     printf("failed\r\n");
     /* Turn Off LED2 */
     }
    }
    
    /**
     * @brief Slave Address Match callbacks.
     * hsmbus : Pointer to a SMBUS_HandleTypeDef structure that contains
     * the configuration information for the specified SMBUS.
     * @retval None
     */
    void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef* hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
    {
     SlaveAddrMatchCode = (AddrMatchCode << 1);
     HAL_SMBUS_EnableListen_IT(&hsmbus1);
     uint8_t tx_buff = 0x00;
     HAL_SMBUS_Slave_Transmit_IT(&hsmbus1, &tx_buff, 1, SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC);
     // HAL_SMBUS_Slave_Transmit_IT(&hsmbus1, &aTxBuffer, 1,
     // SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC);
     UNUSED(TransferDirection);
    }
    void HAL_SMBUS_SlaveRxCpltCallback(SMBUS_HandleTypeDef* hsmbus)
    {
     HAL_SMBUS_Slave_Receive_IT(&hsmbus1, dummy_data, 2, SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC);
    }
    
    //
    // return 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--------------------------------------------------------*/
    
     /* 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_USART3_UART_Init();
     MX_USART2_UART_Init();
     MX_TIM1_Init();
     MX_I2C1_SMBUS_Init();
     MX_I2C3_SMBUS_Init();
     /* USER CODE BEGIN 2 */
    
     /* Enable the Analog SMBUS Filter */
     HAL_SMBUS_ConfigAnalogFilter(&hsmbus1, SMBUS_ANALOGFILTER_ENABLE);
    
     /* Enable address Match detect with interrupt */
     HAL_SMBUS_EnableListen_IT(&hsmbus1);
     /* Wait until address matched */
    
     while (SlaveAddrMatchCode != SMBUS_ADDRESS)
     ;
    
     /* USER CODE END 2 */
    
     /* Infinite loop */
     /* USER CODE BEGIN WHILE */
     while (1)
     {
     /* USER CODE END WHILE */
    
     /* USER CODE BEGIN 3 */
     }
     /* USER CODE END 3 */
    }

     

     

    Visitor II
    September 12, 2025

    Please provide me a solution with SMBUS In SLAVE configuration without PEC or with PEC 

    MOBEJAnswer
    ST Employee
    September 15, 2025

    Hello @suguresh_m , 

    I recommend downloading the X-CUBE-SMBUS Expansion Package, which contains the SMBus/PMBus® stack implementation for STM32Cube. This package provides example projects and basic functionality tests for the following boards: NUCLEO-G431RB ,NUCLEO-H743ZI,NUCLEO-L4R5ZI & NUCLEO-WB55RG ...

    You can download the package directly from ST's official website here:
    https://www.st.com/en/embedded-software/x-cube-smbus.html

    Additionally, I suggest reviewing the related Application Note for detailed guidance:
    https://www.st.com/resource/en/application_note/an4502-stm32-smbuspmbus-expansion-package-for-stm32cube-stmicroelectronics.pdf

    This resource should be very helpful in resolving your issue.

    Br

    Visitor II
    September 15, 2025

    hi MOBEJ,

     

    i tried these examples but no luck.

    Technical Moderator
    September 15, 2025

    Hello @suguresh_m 

    An example of an SMBus receive implementation is provided below.

    #include "stm32xxxx_hal.h" // Replace with your specific device header
    
    // --- Global Variables ---
    SMBUS_HandleTypeDef SmbusHandle;
    uint8_t RxBuffer[NUMDATA]; // Define NUMDATA as needed
    uint16_t Smbus_adresse = 0xXX; // Set your slave address here
    uint16_t SlaveAddrMatchCode = 0;
    
    // --- Function Prototypes ---
    void SystemClock_Config(void);
    void Error_Handler(void);
    
    // --- Main Function ---
    int main(void)
    {
     HAL_Init();
     SystemClock_Config();
    
     // Initialize SMBUS
     HAL_SMBUS_Init(&SmbusHandle);
    
     // Enable Listen mode with interrupt
     if (HAL_SMBUS_EnableListen_IT(&SmbusHandle) != HAL_OK)
     {
     Error_Handler();
     }
    
     // Main loop
     while (1)
     {
     // Your main code here
     }
    }
    
    // --- Address Match Callback ---
    void HAL_SMBUS_AddrCallback(SMBUS_HandleTypeDef *hsmbus, uint8_t TransferDirection, uint16_t AddrMatchCode)
    {
     SlaveAddrMatchCode = (AddrMatchCode << 1);
    
     if (SlaveAddrMatchCode == Smbus_adresse)
     {
     // Start receiving data in interrupt mode
     if (HAL_SMBUS_Slave_Receive_IT(hsmbus, RxBuffer, NUMDATA, SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC) != HAL_OK)
     {
     Error_Handler();
     }
     }
    }
    
    // --- Error Handler ---
    void Error_Handler(void)
    {
     // User can add error handling here
     while (1)
     {
     // Stay here
     }
    }
    
    // --- System Clock Configuration ---
    // Implement this function as per your MCU and application requirements
    void SystemClock_Config(void)
    {
     // System clock configuration code
    }

     

    Visitor II
    September 15, 2025

    im receiving 5pckets to read and write means vise versa once i get some data i need to reply with some data. but its not synchronizing. i tried lot of example but timing issues unable to handle