cancel
Showing results for 
Search instead for 
Did you mean: 

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

suguresh_m
Associate II

 

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

 

1 ACCEPTED SOLUTION

Accepted Solutions
MOBEJ
ST Employee

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

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.

View solution in original post

6 REPLIES 6
suguresh_m
Associate II

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

 

 

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

MOBEJ
ST Employee

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

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.
Saket_Om
ST Employee

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
}

 

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.
Saket_Om

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 

   

hi MOBEJ,

 

i tried these examples but no luck.