cancel
Showing results for 
Search instead for 
Did you mean: 

This is an issue related to the initialization of the X-CUBE-SMBUS middleware during code initialization.

jackhung9527
Associate

I have encountered an issue when I tried to use CubeMX to generate code. At the start of a new project, I selected I2C (SMBUS-Alert-mode) and used the X-CUBE-SMBUS middleware. However, some issues occurred during code initialization.

In main.c, it does not execute MX_I2C1_SMBUS_Init();. However, this piece of code must be executed before MX_STACK_SMBUS_Init(); from X-CUBE-SMBUS to ensure proper initialization. Of course, this can be done, for example:

 

void MX_STACK_SMBUS_Init(void)

{



/* USER CODE BEGIN SMBUS_Init 0 */

MX_I2C1_SMBUS_Init();

/* USER CODE END SMBUS_Init 0 */



/* USER CODE BEGIN SMBUS_Init 1 */



/* USER CODE END SMBUS_Init 1 */



context.CMD_table = (st_command_t *) & PMBUS_COMMANDS_TAB[0];

context.CMD_tableSize = PMBUS_COMMANDS_TAB_SIZE;

context.Device = &SMBUS_HANDLE_instance;

context.SRByte = 0x55U;

context.CurrentCommand = NULL;



/* In SMBUS 10-bit addressing is reserved for future use */

assert_param(SMBUS_HANDLE_instance.Init.AddressingMode == SMBUS_ADDRESSINGMODE_7BIT);

context.OwnAddress = SMBUS_HANDLE_instance.Init.OwnAddress1;

/* Address resolved state */

context.StateMachine = SMBUS_SMS_ARP_AR;

/* checking the HAL slave setting */

assert_param(SMBUS_HANDLE_instance.Init.PeripheralMode != SMBUS_PERIPHERAL_MODE_SMBUS_HOST);

context.StateMachine |= SMBUS_SMS_PEC_ACTIVE;

/* checking the HAL is in accord */

assert_param(SMBUS_HANDLE_instance.Init.PacketErrorCheckMode == SMBUS_PEC_ENABLE);

pcontext = &context;



if (STACK_SMBUS_Init( pcontext ) != HAL_OK)

{

Error_Handler();

}

/* USER CODE BEGIN SMBUS_Init 2 */



/* USER CODE END SMBUS_Init 2 */



}

Is there a better solution to ensure the smooth execution of X-CUBE-SMBUS during its

usage?

 

EDITED by ST Moderator, to use </> format option for code sample.

1 REPLY 1
Imen.D
ST Employee

 

 

Hello @jackhung9527 ,

To initialize the SMBus peripheral: make sure first to Initialize GPIOs, Initialize SMBus Peripheral, then initialize SMBus Stack, finally use the stack functions to perform SMBus communication.
Here is an example of how to use the SMBus peripheral and stack:

// 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 recommend that you check the SMBus example available on STM32G0 and review the chapter "32.4.13 SMBus initialization" of the RM0444 which will help you on how to perform SMBus communication.

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen