1 Use Smart Switch and TLE94112 for Arduino together
It is great to Use Smart Switch and TLE94112 for Arduino alone, but use them together? At least pins are defined different and can not work together.
And the pinout for each board is predefined, if only one Master Host shall be used. All the pins shall be rearranged in library to make them work together.
And for Smart Switch and TLE94112 shield board, that is possible.
2 How to use Smart Switch library
Here is directory structure,
Source code in /src subdirectory, with
#include <Arduino.h> #include <hss-board-arduino.hpp>
Here is hss-board-arduino.hpp
#ifndef HSS_ARDUINO_H_ #define HSS_ARDUINO_H_ #include "corelib/hss.hpp" #include "framework/arduino/pal/gpio-arduino.hpp" #include "framework/arduino/pal/adc-arduino.hpp" #include "framework/arduino/pal/timer-arduino.hpp" /** * @brief Arduino class of the High-Side-Swich * */ class HssIno : public Hss { public: HssIno(uint8_t den, uint8_t in, uint8_t is, BtsVariants_t *variant); ~HssIno(); }; #endif /** HSS_ARDUINO_H_ **/
hss.hpp and hss-board.hpp defines how to use this library,
/** * @file hss-board.hpp * @brief Defenition of the High-Side-Switch-Board class * @date May 2020 * @copyright Copyright (c) 2019-2020 Infineon Technologies AG * * SPDX-License-Identifier: MIT */ #ifndef HSS_BOARD_HPP_ #define HSS_BOARD_HPP_ #include <Arduino.h> #include "hss.hpp" #include "../utils/filter.hpp" /** * @addtogroup hssCorelib * @{ */ /** * @brief High-Side-Switch-Board Class * This class defines the the PROFET-Shield with all it's functions. */ class HssBoard : Hss { public: HssBoard(); ~HssBoard(); Error_t init(); Error_t deinit(); Error_t switchHxOn(uint8_t x); Error_t switchHxOff(uint8_t x); Error_t switchesHxOn(bool h1 = NULL, bool h2 = NULL, bool h3 = NULL, bool h4 = NULL); Error_t switchesHxOff(bool h1 = NULL, bool h2 = NULL, bool h3 = NULL, bool h4 = NULL); DiagStatus_t readDiagx(uint8_t x); DiagStatus_t diagnosisOff(float currentOn, float currentOff); float readIsx(uint8_t x); float readVss(); bool digitalReadButton(); bool analogReadButton(); protected: ExponentialFilter *filterVbat; GPIO *led1; GPIO *led2; GPIO *led3; GPIO *led4; Hss *hss1; Hss *hss2; Hss *hss3; Hss *hss4; Timer *timer; GPIO *oloff; GPIO *pushButtonDigital; AnalogDigitalConverter *pushButtonAnalog; AnalogDigitalConverter *vBat; const float vBatGain = 1.045; const float vBatOffset = 0.0; }; /** @} */ #endif /** HSS_BOARD_HPP_ **/
In which core function shall be
Error_t switchesHxOn(bool h1 = NULL, bool h2 = NULL, bool h3 = NULL, bool h4 = NULL); Error_t switchesHxOff(bool h1 = NULL, bool h2 = NULL, bool h3 = NULL, bool h4 = NULL);
Which defines how to put the switch into On/Off state. With the pins set on $arduino-1.8.10$\projects\libraries\high-side-switch-master\src\framework\arduino\wrapper\config.cpp
#include "config.hpp" #include <Arduino.h> hardwareconfig_t ARDUINO_UNO { .led1 = 4, //LED 1 .led2 = 5, //LED 2 .led3 = 12, //LED 3 .led4 = 13, //LED 4 .in1 = 9, //IN 1 .in2 = 10, //IN 2 .in3 = 11, //IN 3 .in4 = 3, //IN 4 .oloff = 7, //OLOFF .den1_den3 = 6, //DEN 1_3 .den2_den4 = 8, //DEN 2_4 .pushButtonDigital = 2, //PUSHBUTTONDIGITAL .pushButtonAnalog = A0, //PUSHBUTTONANALOG .vBat = A1, //VBAT .is1_is2 = A2, //IS 1_2 .is3_is4 = A3 //IS 3_4 };
Redefine pin number can avoid conflict with other board.
3 How to use TLE94112 library
Similarily, TLE94112 library share same structure,
Class defination as,
#include <TLE94112-ino.hpp> #if (TLE94112_FRAMEWORK == TLE94112_FRMWK_ARDUINO) Tle94112Ino::Tle94112Ino(void):Tle94112() { Tle94112::en = new GPIOIno(TLE94112_PIN_EN, OUTPUT, GPIOIno::POSITIVE ); Tle94112::cs = new GPIOIno(TLE94112_PIN_CS1, OUTPUT, GPIOIno::POSITIVE ); Tle94112::timer = new TimerIno(); Tle94112::sBus = new SPICIno(); } Tle94112Ino::Tle94112Ino(SPIClass &bus, uint8_t csPin):Tle94112() { Tle94112::en = new GPIOIno(TLE94112_PIN_EN, OUTPUT, GPIOIno::POSITIVE ); Tle94112::cs = new GPIOIno(csPin, OUTPUT, GPIOIno::POSITIVE ); Tle94112::timer = new TimerIno(); Tle94112::sBus = new SPICIno(bus,csPin,MISO,MOSI,SCK); } void Tle94112Ino::begin(void) { mEnabled = false; Tle94112::sBus->init(); Tle94112::en->init(); Tle94112::en->enable(); Tle94112::cs->init(); Tle94112::cs->enable(); Tle94112::timer->init(); mEnabled = true; init(); } void Tle94112Ino::end(void) { mEnabled = false; Tle94112::en->disable(); Tle94112::cs->disable(); Tle94112::timer->stop(); Tle94112::sBus->deinit(); }
Unlike that fo High-switch library with directly pins on/off control, TLE94112 use SPI command to control the on/off state of 12 half bridge. With the following arduino command,
/*! * \file TLE94112.hpp * \name TLE94112.hpp - basic register API * \author Infineon Technologies AG * \copyright 2019-2020 Infineon Technologies AG * \version 2.0.0 * \brief This library includes the basic common functions to controll the TLE94112 registers * \ref tle94112corelib * * SPDX-License-Identifier: MIT * */ #ifndef TLE94112_HPP_ #define TLE94112_HPP_ #include <stdint.h> #include <stdlib.h> #include "tle94112_util.hpp" #include "../pal/timer.hpp" #include "../pal/gpio.hpp" #include "../pal/spic.hpp" /** * @addtogroup tle94112api * @{ */ /*! \brief the number of halfbridges on a TLE94112 (including no halfbridge) * * \see mHalfBridges * \see HalfBridge */ #define TLE94112_NUM_HB 13 /*! \brief the number of pwm modes for a halfbridge (including no pwm) * * \see mPwmChannels * \see PWMChannel */ #define TLE94112_NUM_PWM 4 /*! \brief the number of control registers in a TLE94112 * * \see CtrlRegisters * \see mCtrlRegAddresses * \see mCtrlRegData */ #define TLE94112_NUM_CTRL_REGS 12 /*! \brief the number of status registers in a TLE94112 * * \see StatusRegisters * \see mStatusRegAddresses * \see mStatusRegData */ #define TLE94112_NUM_STATUS_REGS 7 /** * @brief represents a basic TLE94112 * * This class provides a simple API for connecting and controlling motors. * Each motor is assigned to a Tle94112 which acts as output driver. Calls to * Tle94112Motor instances are mapped to calls to Tle94112. Therefore, this * class does not bring new features, it does only provide further abstraction. * * @see Tle94112 */ class Tle94112 { public: //! \brief enum for the halfbridges on a TLE94112 enum HalfBridge { TLE_NOHB = 0, TLE_HB1, TLE_HB2, TLE_HB3, TLE_HB4, TLE_HB5, TLE_HB6, TLE_HB7, TLE_HB8, TLE_HB9, TLE_HB10, TLE_HB11, TLE_HB12 }; //! \brief enum for the PWM channels of a halfbridge on TLE94112 enum PWMChannel { TLE_NOPWM = 0, TLE_PWM1, TLE_PWM2, TLE_PWM3 }; //! \brief enum for the output states of a halfbridge enum HBState { TLE_FLOATING = 0b00, TLE_LOW = 0b01, TLE_HIGH = 0b10 }; //! \brief enum for the frequencies of a PWM channel enum PWMFreq { TLE_FREQOFF = 0b00, TLE_FREQ80HZ, TLE_FREQ100HZ, TLE_FREQ200HZ }; //! \brief enum for the flags in the register SYS_DIAG1 enum DiagFlag { TLE_SPI_ERROR = 0x80, TLE_LOAD_ERROR = 0x40, TLE_UNDER_VOLTAGE = 0x20, TLE_OVER_VOLTAGE = 0x10, TLE_POWER_ON_RESET = 0x08, TLE_TEMP_SHUTDOWN = 0x04, TLE_TEMP_WARNING = 0x02 }; //! \brief Reference value of Status Register static const uint8_t TLE_STATUS_OK = 0U; //! \brief standard constructor with default pin assignment Tle94112(); /*! \brief constructor with individual pin assignment * * \param bus a pointer to the object representing the SPI class * \param csPin pin number of the CS pin */ Tle94112(void* bus, uint8_t csPin); //! \brief standard destructor switches shield off ~Tle94112(); //! \brief enables and initializes the TLE94112 void begin(void); //! \brief deactivates all outputs and disables the TLE94112 void end(void); /*! \brief sets the output state and the PWM channel for a halfbridge (only for passive freewheeling) * * \param hb halfbridge which will be configured * \param state sets the output voltage to high, low or floating * \param pwm selects a PWM channel for PWM output * * \see HalfBridge * \see HBState * \see PWMChannel */ void configHB(HalfBridge hb, HBState state, PWMChannel pwm); /*! \brief sets the output state and the PWM channel for a halfbridge (allows active freewheeling) * * \param hb halfbridge which will be configured * \param state sets the output voltage to high, low or floating * \param pwm selects a PWM channel for PWM output * \param activeFW 1 for active freewheeling * 0 for passive freewheeling (default) * * \see HalfBridge * \see HBState * \see PWMChannel */ void configHB(HalfBridge hb, HBState state, PWMChannel pwm, uint8_t activeFW); /*! \brief sets the frequency and duty cycle for a PWM channel * * \param pwm PWM channel which will be configured * \param freq selects the PWM output frequency * \param dutyCycle a value from 0 to 255 which sets the dutyCycle * * \see PWMChannel * \see PWMFreq */ void configPWM(PWMChannel pwm, PWMFreq freq, uint8_t dutyCycle); /*! \brief returns a diagnosis value for error detection * * \return 0 if everything is ok * non-zero value if errors occurred */ uint8_t getSysDiagnosis(); /*! \brief shows if errors of a specific type have occurred * * \param mask mask to filter for a specific flag * * \return 0 if everything is ok * non-zero value on error condition * * \see DiagFlag */ uint8_t getSysDiagnosis(DiagFlag mask); /*! \brief shows if errors of a specific type have occurred * * \param mask mask to filter for one or more specific flags * this can be a disjunction of DiagFlag values * * \return 0 if everything is ok * non-zero value on error condition * * \see DiagFlag */ uint8_t getSysDiagnosis(uint8_t mask); /*! \brief gets the overcurrent error flag bit for a specific halfbridge * * \param hb halfbridge thats overcurrent flag will be returned * * \return 1 if there HalfBridge was shut down because of an overcurrent * 0 otherwise */ uint8_t getHBOverCurrent(HalfBridge hb); /*! \brief gets the openload error flag bit for a specific halfbridge * * \param hb halfbridge thats openload flag will be returned * * \return 1 if there HalfBridge detected an open load * 0 otherwise */ uint8_t getHBOpenLoad(HalfBridge hb); //! \brief clears all clearable error flags void clearErrors(); SPIC *sBus; //<! \brief SPI cover class as representation of the SPI bus GPIO *en; //<! \brief shield enable GPIO to switch shield on/of GPIO *cs; //<! \brief shield enable GPIO to switch chipselect on/of Timer *timer; //<! \brief timer for delay settings protected: //! \brief enum for the control registers in a TLE94112 enum CtrlRegisters { HB_ACT_1_CTRL = 0, HB_ACT_2_CTRL, HB_ACT_3_CTRL, HB_MODE_1_CTRL, HB_MODE_2_CTRL, HB_MODE_3_CTRL, PWM_CH_FREQ_CTRL, PWM1_DC_CTRL, PWM2_DC_CTRL, PWM3_DC_CTRL, FW_OL_CTRL, FW_CTRL }; //! \brief enum for the control registers in a TLE94112 enum StatusRegisters { SYS_DIAG1 = 0, OP_ERROR_1_STAT, OP_ERROR_2_STAT, OP_ERROR_3_STAT, OP_ERROR_4_STAT, OP_ERROR_5_STAT, OP_ERROR_6_STAT }; //! \brief array of register locations for halfbridges HalfBridge_t mHalfBridges[TLE94112_NUM_HB]; //! \brief array of register locations for PWM channels PWMchannel_t mPwmChannels[TLE94112_NUM_PWM]; //! \brief mapping array for control register addresses uint8_t mCtrlRegAddresses[TLE94112_NUM_CTRL_REGS]; //! \brief mirror array for control register data uint8_t mCtrlRegData[TLE94112_NUM_CTRL_REGS]; //! \brief mapping array for status register addresses uint8_t mStatusRegAddresses[TLE94112_NUM_STATUS_REGS]; //! \brief initializes this object, automatically called by begin() void init(void); /*! \brief sets the output state and the PWM channel for a halfbridge * automatically called by the public version of configHB * * \param hb halfbridge which will be configured * \param state sets the output voltage to high, low or floating * \param pwm selects a PWM channel for PWM output * \param activeFW 1 for active freewheeling * 0 for passive freewheeling (default) */ void configHB(uint8_t hb, uint8_t state, uint8_t pwm, uint8_t activeFW); /*! \brief sets the frequency and duty cycle for a PWM channel * automatically called by the public version of configPWM * * \param pwm PWM channel which will be configured * \param freq selects the PWM output frequency * \param dutyCycle a value from 0 to 255 which sets the dutyCycle */ void configPWM(uint8_t pwm, uint8_t freq, uint8_t dutyCycle); /*! \brief gets the overcurrent error flag bit for a specific halfbridge * automatically called by the public version of getHBOverCurrent * * \param hb halfbridge thats overcurrent flag will be returned * * \return 1 if there HalfBridge was shut down because of an overcurrent * 0 otherwise */ uint8_t getHBOverCurrent(uint8_t hb); /*! \brief gets the openload error flag bit for a specific halfbridge * automatically called by the public version of getHBOpenLoad * * \param hb halfbridge thats openload flag will be returned * * \return 1 if there HalfBridge detected an open load * 0 otherwise */ uint8_t getHBOpenLoad(uint8_t hb); /*! \brief writes data bits to a control register of the TLE94112 * * \param reg control register number(mapping array index / CtrlRegisters constant) of the register * \param mask mask for the bits that have to be written * \param shift data will be shifted left by this amount before masking. This is for the bit alignment of data * \param data the data byte that has to be written. It will be shifted and masked before * * \see CtrlRegisters * \see TLE94112_NUM_CTRL_REGS * \see mCtrlRegAddresses * \see mCtrlRegData */ void writeReg(uint8_t reg, uint8_t mask, uint8_t shift, uint8_t data); /*! \brief reads one byte from a status register of the TLE94112 * * \param reg status register number(mapping array index / StatusRegisters constant) of the register * * \return data byte that has been read * * \see StatusRegisters * \see TLE94112_NUM_STATUS_REGS * \see mStatusRegAddresses */ uint8_t readStatusReg(uint8_t reg); /*! \brief reads some bits from a status register of the TLE94112 * * \param reg status register number(mapping array index / StatusRegisters constant) of the register * \param mask mask for the bits that have to be read * \param shift data will be shifted right by this amount after masking. This is for the bit alignment of data * * \return data bits that have been read (after masking and shifting) * * \see StatusRegisters * \see TLE94112_NUM_STATUS_REGS * \see mStatusRegAddresses */ uint8_t readStatusReg(uint8_t reg, uint8_t mask, uint8_t shift); /*! \brief clears a status register by writing 0x00 to it * * \param reg status register number(mapping array index / StatusRegisters constant) of the register * * \see StatusRegisters * \see TLE94112_NUM_STATUS_REGS * \see mStatusRegAddresses */ void clearStatusReg(uint8_t reg); uint8_t mEnabled; //<! \brief indicates if TLE94112LE is enabled }; /** @} */ #endif /** TLE94112_HPP_ **/
It could be show in arduino speed control, sketch with the key words
controller.configHB(controller.TLE_HB1, controller.TLE_HIGH, controller.TLE_PWM1); controller.configHB(controller.TLE_HB2, controller.TLE_LOW, controller.TLE_NOPWM); controller.configPWM(controller.TLE_PWM1, controller.TLE_FREQ80HZ, dc);
And the motor can be controlled directly, if motor control shall be imported.
#include <TLE94112Motor-ino.hpp>
4 Revise on the library and Arrange Pin layout for new project
In my project, one 12V high swith and one cooling fan motor control shall be used. Here is pins rearrangement,
- The SPI pins for motor control are D8~D14 in TLE94112
- D3 for IN4, D4 for LED1, D13 for LED4, D6 for DEN1+DEN3 , A1 for battery voltage , and A2 for Current in High-swith. It would be easy swap the LED1 and LED4 and use only IN4 and LED4 thereafter,
- Allow I2C for A5 and A6 for later use.
In general, hardwiring and software shall be verified to make new sketch work.
Ready for coding.