2024-12-05 11:18 PM - last edited on 2024-12-06 01:31 AM by Imen.D
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.
2024-12-06 01:27 AM
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.