cancel
Showing results for 
Search instead for 
Did you mean: 

X-Cube-SMBUS for STM32H7 not working

_kalpesh
Associate II

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

1 REPLY 1
nouirakh
ST Employee

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.