Skip to main content
Graduate II
July 5, 2024
Question

X-Cube-SMBUS for STM32H7 not working

  • July 5, 2024
  • 1 reply
  • 1263 views

Hi, This is the first time im working with SMBUS peripheral and want to implement this for a project.
I have gone through AN4502 document for SMBUS but im having hard time understanding stack of SMBUS module.
why do we need stack for communication for just one SMBUS peripheral from STM32H7 board. whats the difference between SMBUS_StackHandleTypeDef SMBUS_HandleTypeDef and whats use of this.

i have read the 6.1 Host side point from the same document and initialised things as mentioned in it.

 

MX_GPIO_Init();

MX_SMBus_PMBus_Stack_Init();

MX_I2C1_SMBUS_Init();

STACK_SMBUS_Init(&hsmbus1);

STACK_SMBUS_GetBuffer()

MX_SMBus_PMBus_Stack_Init();

STACK_SMBUS_HostCommand(&hsmbus1, 0x17, 10, 0x17);

but HAL_SMBUS_IsDeviceReady fnction returning HAL_ERROR in response.

can someone guide me in a right direction for this

    This topic has been closed for replies.

    1 reply

    ST Employee
    July 8, 2024

    Hello @_kalpesh 

     

    why do we need stack for communication for just one SMBUS peripheral?
    SMBus is more than just I2C, it has additional features and requirements. The stack handles these additional features, ensuring reliable and correct communication. Using the stack simplifies your code and reduces the risk of errors.

    Difference Between SMBUS_HandleTypeDef and SMBUS_StackHandleTypeDef:

    • SMBUS_HandleTypeDef: This is the handle for the basic SMBus peripheral, similar to how you would use an I2C_HandleTypeDef for I2C communication. It contains configuration and state information for the SMBus peripheral.
    • SMBUS_StackHandleTypeDef: This handle is used for the higher-level stack that manages SMBus-specific features and protocols. It builds on top of the basic SMBus handle to provide additional functionality required by the SMBus protocol.

     To initialize and use the SMBus peripheral on your board: Initialize GPIOs, Initialize SMBus Peripheral, Initialize SMBus Stack finally Use the stack functions to perform SMBus communication.
    Example of how to use the SMBus peripheral and stack:

    #include "main.h"
    #include "stm32h7xx_hal.h"
    #include "smbus.h"
    #include "smbus_stack.h"
    
    // Global variables
    SMBUS_HandleTypeDef hsmbus1;
    SMBUS_StackHandleTypeDef hsmbus_stack;
    
    // Function prototypes
    void SystemClock_Config(void);
    static void MX_GPIO_Init(void);
    static void MX_I2C1_SMBUS_Init(void);
    static void MX_SMBus_PMBus_Stack_Init(void);
    
    int main(void)
    {
     // Initialize the HAL Library
     HAL_Init();
    
     // Configure the system clock
     SystemClock_Config();
    
     // Initialize all configured peripherals
     MX_GPIO_Init();
     MX_I2C1_SMBUS_Init();
     MX_SMBus_PMBus_Stack_Init();
    
     // Initialize the SMBus stack
     STACK_SMBUS_Init(&hsmbus_stack);
    
     // Example: Check if a device is ready
     if (HAL_SMBUS_IsDeviceReady(&hsmbus1, 0x17 << 1, 10, HAL_MAX_DELAY) != HAL_OK)
     {
     // Handle error
     Error_Handler();
     }
    
     // Example: Send a command
     uint8_t command = 0x17;
     uint8_t data = 0x10;
     if (STACK_SMBUS_HostCommand(&hsmbus_stack, command, 1, &data) != STACK_OK)
     {
     // Handle error
     Error_Handler();
     }
    
     // Main loop
     while (1)
     {
     // Your application code
     }
    }
    
    static void MX_GPIO_Init(void)
    {
     // Initialize GPIOs for SMBus
     // This is typically done in the CubeMX-generated code
    }
    
    static void MX_I2C1_SMBUS_Init(void)
    {
     // Initialize the SMBus peripheral
     hsmbus1.Instance = I2C1;
     hsmbus1.Init.Timing = 0x00707CBB;
     hsmbus1.Init.OwnAddress1 = 0;
     hsmbus1.Init.AddressingMode = SMBUS_ADDRESSINGMODE_7BIT;
     hsmbus1.Init.DualAddressMode = SMBUS_DUALADDRESS_DISABLE;
     hsmbus1.Init.OwnAddress2 = 0;
     hsmbus1.Init.OwnAddress2Masks = SMBUS_OA2_NOMASK;
     hsmbus1.Init.GeneralCallMode = SMBUS_GENERALCALL_DISABLE;
     hsmbus1.Init.NoStretchMode = SMBUS_NOSTRETCH_DISABLE;
     hsmbus1.Init.PacketErrorCheckMode = SMBUS_PEC_ENABLE;
     hsmbus1.Init.PeripheralMode = SMBUS_PERIPHERAL_MODE_SMBUS_HOST;
     hsmbus1.Init.SMBusTimeout = 0x00008061;
    
     if (HAL_SMBUS_Init(&hsmbus1) != HAL_OK)
     {
     // Initialization Error
     Error_Handler();
     }
    }
    
    static void MX_SMBus_PMBus_Stack_Init(void)
    {
     // Initialize the SMBus stack
     hsmbus_stack.hi2c = &hsmbus1;
     hsmbus_stack.State = SMBUS_STATE_READY;
     hsmbus_stack.ErrorCode = SMBUS_ERROR_NONE;
     hsmbus_stack.Timeout = HAL_MAX_DELAY;
    }
    
    void SystemClock_Config(void)
    {
     // Configure the system clock
     // This is typically done in the CubeMX-generated code
    }
    
    void Error_Handler(void)
    {
     // Handle errors
     while (1)
     {
     }
    }

     

    I hope my answer has helped you. When your question is answered please close this topic by marking as Best the reply that answered you, it will help others find that answer faster. Thanks for your contribution.

     

    _kalpeshAuthor
    Graduate II
    August 1, 2024

    hey i want to communicate with the device whose address is 0x17 thats why i entered 

    STACK_SMBUS_HostCommand(&hsmbus1, 0x17, 10, 0x17);
    can you please tell me this is correct way to do it