cancel
Showing results for 
Search instead for 
Did you mean: 

How to establish SMBUS communication on STM32F091RCT6 using HAL libraries?

VKamb.1
Associate

I want to configure one STM32F091RCT6 as master and 2nd as slave.

I have used Cubemx to generate code.

In Master I use

HAL_StatusTypeDef HAL_SMBUS_Master_Transmit_IT(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions)

I call the above function with required parameters in while(1).

So should I use

HAL_SMBUS_IsDeviceReady(SMBUS_HandleTypeDef *hsmbus, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)

To check if slave is ready or not and then call the master transmit but IsDeviceready is a blocking function?

Also I am not able to understand what is Xferoptions?

 SMBUS_NEXT_FRAME     ((uint32_t)(SMBUS_RELOAD_MODE | SMBUS_SOFTEND_MODE))

#define SMBUS_FIRST_AND_LAST_FRAME_NO_PEC     SMBUS_AUTOEND_MODE

#define SMBUS_LAST_FRAME_NO_PEC         SMBUS_AUTOEND_MODE

SMBUS_FIRST_FRAME_WITH_PE ((uint32_t(SMBUS_SOFTEND_MODE|SMBUS_SENDPE_MODE))

SMBUS_FIRST_AND_LAST_FRAME_WITH_PEC   ((uint32_t)(SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE))

 SMBUS_LAST_FRAME_WITH_PEC             ((uint32_t)(SMBUS_AUTOEND_MODE | SMBUS_SENDPEC_MODE))

The above underlined have same  SMBUS_AUTOEND_MODE but different names.

In Slave Mode

I was using HAL_SMBUS_Slave_Receive_IT(SMBUS_HandleTypeDef *hsmbus, uint8_t *pData, uint16_t Size,uint32_t XferOptions)

But in the function definition of above function

if ((hsmbus->State & HAL_SMBUS_STATE_LISTEN) == HAL_SMBUS_STATE_LISTEN)

{

body

return HAL_OKAY

}

else

{

return HAL_BUSY

}

By default the hsmbus->State is in HAL_SMBUS_STATE_READY and it always reurns hal_busy. So I called HAL_SMBUS_EnableListen_IT(SMBUS_HandleTypeDef *hsmbus) to set the state to HAL_SMBUS_STATE_LISTEN and then called the HAL_SMBUS_Slave_Receive_IT().

This was able to generate the interrupt on address match. But next iteration the interrupt didn't generate.(because I only called HAL_SMBUS_EnableListen_IT() once outside while(1).

I read the technical reference manual and the code written in "stm32f0xx_hal_smbus.c". I have few questions regarding it.

How to set the controller in slave mode transmit and receive data?(any example code)

How to set controller in master mode and transmitted and read data?(any example code)

How to initiate a restart condition with change in direction (from write to read of N bytes(read block data protocol)?

Can you share an example code for both master and slave?

2 REPLIES 2
LBasc.1
Associate

By any chance, does anyone know the answers to the questions? I am also trying out how to do SMBus master and slave communication in STM32G031K8

TDJ
Lead

@VKamb.1​ The thing is that HAL drivers are generally unsupported and get released untested. I know, it is hard to believe, but it is true. I spent days trying to get things working using HAL, things which could not possibly work well or could not work at all. SMBus HAL driver is written exactly as it was meant to be a repro of ES0431, 2.11.5 Transmission stalled after first byte transfer hardware bug and I am showing that the bug manifests at clock speeds other than those described as well. Probably many developers fall into this and many similar traps like that. What is more, it is not possible to build working SMBus stack without accessing registries directly - see AN4502 and related source code. Comments in code clearly indicate that even ST engineers struggled.

My sincere advice: first read data sheet (DSxxxx), then study reference manual (RMxxxx) like it was some holly text. Make sure you understand, and once you think that you do, study again. I will take days or even weeks, but one day you will be able to write your driver from scratch. I reassure you it would not be that hard since hardware, unlike ST software, is really well thought. That is what people and companies do, and they almost never release their working software for free - that includes ST.