简体   繁体   中英

smBus communication testing for fan driver IC in STM32 with C

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 -> %100 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 -> %100 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 -> %100 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 -> %100 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

Datasheet: https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/EMC2301-2-3-5-Data-Sheet-DS20006532A.pdf

Estimation whether code is working or not

Firstly, I would recommend that you use STM's library AN4502 .

  1. The difference between the master and the slave is the same as for the i2c bus. All bus transfers are initialized by the master.
  2. I think there is not emulator of EMC2301. But to test the bus you can use examples from the STM AN4502 .
  3. Your code won't work because the HAL_SMBUS_Master_Transmit_IT and HAL_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 result HAL_BUSY . Use the library AN4502 , it will make it easier to interact with the peripheral.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM