I developed a library for fan IC which use smbus protocol. However ı have some problems and questions. 1 -) what is diff between master and slave for smbus? whether the IC should be slave or master is not specified in the datasheet. Therefore, how can ı decide that stm32 developer board should be slave or master. 2-) unfortunately, ı cannot try my code because fan driver IC ı have not received yet sensor. Do u know any method to test my code. Maybe ardunio library. 3-) to receive data, ı firstly tranmit the register address of data ı want to read. is it correct. You can find datasheet of IC and code ı wrote below
C file
#include "smbusDriver.h"
#include "stm32f0xx_hal_smbus.h"
#include "stm32f0xx_hal.h"
#include "smbusDriver.h"
resultConditions_t InitializeDriver(SMBUS_HandleTypeDef *hsmbus, uint8_t address, addressValues_t *Daddress){
Daddress->Fields.configurationRegisterAddress = 0x20;
Daddress->Fields.FanStatusRegisterAddress = 0x24;
Daddress->Fields.FanStallRegisterAddress = 0x25;
Daddress->Fields.FanSpinRegisterAddress = 0x26;
Daddress->Fields.DriveFailStatusAddress = 0x27;
Daddress->Fields.FanInterruptEnableRegisterAddress = 0x29;
Daddress->Fields.PwmPolarityRegisterAddress = 0x2A;
Daddress->Fields.PwmOutputTypeRegisterAddress = 0x2B;
Daddress->Fields.PwmFrequency45Address = 0x2C;
Daddress->Fields.PwmFrequency123Address = 0x2D;
Daddress->Fields.PwmDivider1Address = 0x31;
Daddress->Fields.PwmDivider2Address = 0x41;
Daddress->Fields.PwmDivider3Address = 0x51;
Daddress->Fields.PwmDivider4Address = 0x61;
Daddress->Fields.PwmSettingAddress1 = 0x30;
Daddress->Fields.PwmSettingAddress2 = 0x40;
Daddress->Fields.PwmSettingAddress3 = 0x50;
Daddress->Fields.PwmSettingAddress4 = 0x60;
resultConditions_t result = RESULT_OK;
uint8_t buf[2];
configuration_t confDriver;
confDriver.Fields.MASK = 0 ; // Alert pin activated.
confDriver.Fields.DIS_TO = 0; // smBUS enabled. If 1, I2C is compatible
confDriver.Fields.WD_EN = 0; // Watchdog is not enabled
confDriver.Fields.DRECK = 1; // Enabled internal clock
confDriver.Fields.USECK = 0; // Connecting internal oscillator
FanInterruptEnableRegister_t FanIntEn;
FanIntEn.Fields.F1ITEN = 1;
FanIntEn.Fields.F2ITEN = 1;
FanIntEn.Fields.F3ITEN = 1;
FanIntEn.Fields.F4ITEN = 1;
FanIntEn.Fields.F5ITEN = 0;
PwmPolarityRegister_t PwmPolarity;
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmPolarity.Fields.PLRITY1 = 0; // FF => 255, 00 => 00
PwmOutputTypeRegister_t OutputType;
OutputType.Fields.PMOT1 = 0;
OutputType.Fields.PMOT2 = 0;
OutputType.Fields.PMOT3 = 0;
OutputType.Fields.PMOT4 = 0;
PwmFrequency45_t BaseFrequency_45;
PwmFrequency123_t BaseFrequency_123;
BaseFrequency_45.Fields.PwmFrequency4 = 0; // 26kHz
BaseFrequency_45.Fields.PwmFrequency5 = 0; // 26kHz
BaseFrequency_123.Fields.PwmFrequency1 = 0; // 26kHz
BaseFrequency_123.Fields.PwmFrequency2 = 0; // 26kHz
BaseFrequency_123.Fields.PwmFrequency3 = 0; // 26kHz
PwmDividerRegister_t Divider;
Divider.Fields.pwmDivider_1 = 0x01; // PWM Divider
Divider.Fields.pwmDivider_2 = 0x01; // PWM Divider
Divider.Fields.pwmDivider_3 = 0x01; // PWM Divider
Divider.Fields.pwmDivider_4 = 0x01; // PWM Divider
HAL_SMBUS_Init(hsmbus);
HAL_Delay(10);
uint16_t DeviceAddress = 0x0000;
DeviceAddress = DeviceAddress | address;
result = HAL_SMBUS_IsDeviceReady(hsmbus, DeviceAddress, 5 , 1000);
if (result != RESULT_OK) return result;
HAL_SMBUS_EnableAlert_IT(hsmbus);
if (result != RESULT_OK) return result;
HAL_SMBUS_EnableListen_IT(hsmbus);
if (result != RESULT_OK) return result;
HAL_Delay(20);
buf[0] = Daddress->Fields.configurationRegisterAddress; // The configuration of board is set
buf[1] = confDriver.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result != RESULT_OK) return result;
HAL_Delay(20);
buf[0] = Daddress->Fields.FanInterruptEnableRegisterAddress; // If any alert shows up, Fans can interrupt the operation
buf[1] = FanIntEn.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmPolarityRegisterAddress; // The high to high, low to low
buf[1] = PwmPolarity.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmOutputTypeRegisterAddress; // Pull-push and Open Drain choose
buf[1] = OutputType.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmFrequency45Address; // Base Frequency 4-5
buf[1] = BaseFrequency_45.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result; // Base Frequency 1-2-3
buf[0] = Daddress->Fields.PwmFrequency123Address;
buf[1] = BaseFrequency_123.value;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider1Address; // Divider of frequency => frequency / divide factor (Duty Cycle is not affected)
buf[1] = Divider.Fields.pwmDivider_1;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider2Address; // Divider of frequency
buf[1] = Divider.Fields.pwmDivider_2;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider3Address; // Divider of frequency
buf[1] = Divider.Fields.pwmDivider_3;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
HAL_Delay(20);
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmDivider4Address; // Divider of frequency
buf[1] = Divider.Fields.pwmDivider_4;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result != RESULT_OK) return result;
return result;
}
resultConditions_t setPwmConfig(uint8_t Pwm, addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
resultConditions_t result = HAL_OK;
PwmSettings_t pwmSet;
uint8_t buf[2];
pwmSet.Fields.pwmSettings1 = Pwm;
pwmSet.Fields.pwmSettings2 = Pwm;
pwmSet.Fields.pwmSettings3 = Pwm;
pwmSet.Fields.pwmSettings4 = Pwm;
uint16_t DeviceAddress = 0x0000;
DeviceAddress = DeviceAddress | address;
buf[0] = Daddress->Fields.PwmSettingAddress1; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings1;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> 0 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmSettingAddress2; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings2;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> 0 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmSettingAddress3; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings3;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> 0 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
buf[0] = Daddress->Fields.PwmSettingAddress4; // Pwm set
buf[1] = pwmSet.Fields.pwmSettings4;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus,DeviceAddress << 0,buf,2,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC); // => 0xHH -> 0 Duty Cycle /\ 0x00 -> %0 Duty Cycle
if (result != RESULT_OK) return result;
return result;
}
generalStatus_t getGeneralStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.FanStatusRegisterAddress;
generalStatus_t returnValue = NO_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf 1,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000){
returnValue = DRIVE_FAIL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b01000000) == (uint8_t)0b01000000){
returnValue = FAN_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000)
{
returnValue = FAN_STALL_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
specialFanStallStatus_t getStallStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.FanStallRegisterAddress;
specialFanStallStatus_t returnValue = NO_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_1_STALL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_2_STALL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
{
returnValue = FAN_3_STALL_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
{
returnValue = FAN_4_STALL_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
specialFanSpinStatus_t getSpinStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.FanSpinRegisterAddress;
specialFanSpinStatus_t returnValue = NO_SPIN_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_1_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_2_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
{
returnValue = FAN_3_SPIN_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
{
returnValue = FAN_4_SPIN_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
specialFanDriveStatus_t getDriveStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address){
uint8_t buf[2];
uint8_t DeviceAddress;
DeviceAddress = DeviceAddress | address;
resultConditions_t result;
buf[0] = Daddress->Fields.DriveFailStatusAddress;
specialFanDriveStatus_t returnValue = NO_ERROR;
result = HAL_SMBUS_Master_Transmit_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
result = HAL_SMBUS_Master_Receive_IT(hsmbus, DeviceAddress,buf,1,SMBUS_FIRST_AND_LAST_FRAME_NO_PEC);
if (result == RESULT_ERROR) return UNEXPECTED_ERROR;
if (buf[0] == 0x00){
return returnValue;
}
else {
if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_1_DRIVE_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b10000000) == (uint8_t)0b10000000){
returnValue = FAN_2_DRIVE_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00100000) == (uint8_t)0b00100000)
{
returnValue = FAN_3_DRIVE_ERROR;
return returnValue;
}
else if ((buf[0] & (uint8_t)0b00010000) == (uint8_t)0b000100000)
{
returnValue = FAN_4_DRIVE_ERROR;
return returnValue;
}
else{
returnValue = UNEXPECTED_ERROR;
return returnValue;
}
}
}
H file
#ifndef smbusDriver
#define smbusDriver
#ifdef __cplusplus
extern "C" {
#endif
#include "smbusDriver.h"
#include "stm32f0xx_hal_smbus.h"
#include "stm32f0xx_hal.h"
typedef union {
struct{
uint8_t configurationRegisterAddress;
uint8_t FanStatusRegisterAddress;
uint8_t FanStallRegisterAddress;
uint8_t FanSpinRegisterAddress;
uint8_t DriveFailStatusAddress;
uint8_t FanInterruptEnableRegisterAddress;
uint8_t PwmPolarityRegisterAddress;
uint8_t PwmOutputTypeRegisterAddress;
uint8_t PwmFrequency45Address;
uint8_t PwmFrequency123Address;
uint8_t PwmDivider1Address;
uint8_t PwmDivider2Address;
uint8_t PwmDivider3Address;
uint8_t PwmDivider4Address;
uint8_t PwmSettingAddress1;
uint8_t PwmSettingAddress2;
uint8_t PwmSettingAddress3;
uint8_t PwmSettingAddress4;
}Fields;
}addressValues_t;
typedef enum{
NO_ERROR,
DRIVE_FAIL_ERROR, // indicate that one or more fan could not be driven (ProgrammingError)
FAN_SPIN_ERROR, // indicate that one or more fan spin
FAN_STALL_ERROR, // indicate that one or more fan is stuck
UNEXPECTED_ERROR
} generalStatus_t;
typedef enum {
NO_STALL_ERROR,
FAN_5_STALL_ERROR,
FAN_4_STALL_ERROR,
FAN_3_STALL_ERROR,
FAN_2_STALL_ERROR,
FAN_1_STALL_ERROR,
UNEXPECTED_STALL_ERROR
} specialFanStallStatus_t;
typedef enum {
NO_SPIN_ERROR,
FAN_5_SPIN_ERROR,
FAN_4_SPIN_ERROR,
FAN_3_SPIN_ERROR,
FAN_2_SPIN_ERROR,
FAN_1_SPIN_ERROR,
UNEXPECTED_SPIN_ERROR
} specialFanSpinStatus_t;
typedef enum {
NO_DRIVE_ERROR,
FAN_5_DRIVE_ERROR,
FAN_4_DRIVE_ERROR,
FAN_3_DRIVE_ERROR,
FAN_2_DRIVE_ERROR,
FAN_1_DRIVE_ERROR,
UNEXPECTED_DRIVE_ERROR
} specialFanDriveStatus_t;
typedef enum{
RESULT_OK,
RESULT_ERROR,
RESULT_TIMEOUT,
RESULT_BUSY,
RESULT_INVALID,
} resultConditions_t;
typedef union {
struct {
uint8_t USECK : 1; // 1 => External Clock & 0 => Internal Clock
uint8_t DRECK : 1; // 1 => Clock pin output and push-pull driver 0 => Clock pin input
uint8_t reserved : 3;
uint8_t WD_EN : 1; // 1 => Watch clock is activated 0 => 0 watch clock is deactivated.
uint8_t DIS_TO : 1; // 1 => I2C is compatible 0 => SMBus time-out is enabled
uint8_t MASK : 1; // 1 => Alert is deactivated 0 => Alert is activated
} Fields;
uint8_t value;
} configuration_t;
typedef union {
struct
{
uint8_t FNSTL : 1; // stall error <=> 1
uint8_t FNSPIN : 1; // Spin up error <=> 1
uint8_t DVFAIL : 1; // Maximum speed PWM error <=> 1
uint8_t reserved : 5;
}Fields;
uint8_t value;
}FanStatusRegister_t;
typedef union {
struct {
uint8_t F1STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F2STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F3STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F4STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t F5STL : 1; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
uint8_t reserved : 3; // tachometer count has exceeded maximum valid TACH count, initializing stall <=> 1
} Fields;
uint8_t value;
} FanStallStatusRegister_t;
typedef union {
struct {
uint8_t F1SPIN : 1; // spin start error <=> 1
uint8_t F2SPIN : 1; // spin start error <=> 1
uint8_t F3SPIN : 1; // spin start error <=> 1
uint8_t F4SPIN : 1; // spin start error <=> 1
uint8_t F5SPIN : 1; // spin start error <=> 1
uint8_t reserved : 3; // spin start error <=> 1
} Fields;
uint8_t value;
}FanSpinStatusRegister_t;
typedef union {
struct{
uint8_t DRVF1 : 1; // rpm error <=> 1
uint8_t DRVF2 : 1; // rpm error <=> 1
uint8_t DRVF3 : 1; // rpm error <=> 1
uint8_t DRVF4 : 1; // rpm error <=> 1
uint8_t DRVF5 : 1; // rpm error <=> 1
uint8_t reserved : 3; // rpm error <=> 1
}Fields;
uint8_t value;
} DriveFailStatus_t;
typedef union {
struct {
uint8_t F1ITEN : 1; // Alert Fan 1 enable <=> 1
uint8_t F2ITEN : 1; // Alert Fan 2 enable <=> 1
uint8_t F3ITEN : 1; // Alert Fan 3 enable <=> 1
uint8_t F4ITEN : 1; // Alert Fan 4 enable <=> 1
uint8_t F5ITEN : 1; // Alert Fan 5 enable <=> 1
uint8_t reserved : 3;
}Fields;
uint8_t value;
}FanInterruptEnableRegister_t;
typedef union {
struct {
uint8_t PLRITY1 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY2 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY3 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY4 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t PLRITY5 : 1; // FFh produce 100% duty cycle <=> 1
uint8_t reserved : 3;
}Fields;
uint8_t value;
}PwmPolarityRegister_t;
typedef union {
struct {
uint8_t PMOT1 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT2 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT3 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT4 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t PMOT5 : 1; // OpenDrain <=> 0 and PullPush output <=> 1
uint8_t reserved : 3;
} Fields;
uint8_t value;
} PwmOutputTypeRegister_t;
typedef union {
struct {
uint8_t PwmFrequency4 : 2;
uint8_t PwmFrequency5 : 2;
uint8_t reserved : 4;
}Fields;
uint8_t value;
}PwmFrequency45_t;
typedef union {
struct {
uint8_t PwmFrequency1 : 2;
uint8_t PwmFrequency2 : 2;
uint8_t PwmFrequency3 : 2;
uint8_t reserved : 2;
}Fields;
uint8_t value;
}PwmFrequency123_t;
typedef union {
struct {
uint8_t DriveSetting_1: 8;
uint8_t DriveSetting_2: 8;
uint8_t DriveSetting_3: 8;
uint8_t DriveSetting_4: 8;
}Fields;
uint32_t value;
}CurrentDriveSettings_t;
typedef union {
struct{
uint8_t pwmDivider_1 :8;
uint8_t pwmDivider_2 :8;
uint8_t pwmDivider_3 :8;
uint8_t pwmDivider_4 :8;
}Fields;
uint32_t value;
}PwmDividerRegister_t;
typedef union{
struct {
uint8_t pwmSettings1 :8;
uint8_t pwmSettings2 :8;
uint8_t pwmSettings3 :8;
uint8_t pwmSettings4 :8;
}Fields;
}PwmSettings_t;
resultConditions_t InitializeDriver(SMBUS_HandleTypeDef *hsmbus, uint8_t address, addressValues_t *Daddress);
resultConditions_t setPwmConfig(uint8_t Pwm, addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address);
generalStatus_t getGeneralStatus(addressValues_t *Daddress,SMBUS_HandleTypeDef *hsmbus, uint8_t address);
#endif
Estimation whether code is working or not
CodePudding user response:
Firstly, I would recommend that you use STM's library AN4502.
- The difference between the master and the slave is the same as for the i2c bus. All bus transfers are initialized by the master.
- I think there is not emulator of EMC2301. But to test the bus you can use examples from the STM AN4502.
- Your code won't work because the
HAL_SMBUS_Master_Transmit_IT
andHAL_SMBUS_Master_Receive_IT
functions are called asynchronously and require you to wait for the execution to finish when you call two functions in a row, you will get the resultHAL_BUSY
. Use the library AN4502, it will make it easier to interact with the peripheral.