diff --git a/examples/directRegisterControl/directRegisterControl.ino b/examples/directRegisterControl/directRegisterControl.ino new file mode 100644 index 0000000..d8a8e18 --- /dev/null +++ b/examples/directRegisterControl/directRegisterControl.ino @@ -0,0 +1,108 @@ +/*! + * \name directRegisterControl + * \author Infineon Technologies AG + * \copyright 2025 Infineon Technologies AG + * \brief This example demonstrates how to control two motors via direct register setting + * \details + * If motors are connected to the TLE94112 on certain half bridges, than they can be controlled via direct register + * setting which reduces greatly the overhead and allows fast motor controlling. + * therefore the half bridges HB1 to HB4, HB5 to HB8 and HB9 to HB12 must be used together, either for controlling + * two motors on one tuple (0.9 A), or one motor on one tuple (1.8 A). + * + * SPDX-License-Identifier: MIT + * + */ + + #include + + //! Tle94112 Object + Tle94112Ino controller = Tle94112Ino(); + + //! Tle94112 registers for motor 1 and 2 + uint8_t motor[2][2] = { + {REG_ACT_1, REG_PWM_DC_1}, + {REG_ACT_3, REG_PWM_DC_3} + }; + + //! Tle94112 register for motor direction + volatile uint8_t oldDirection [] = { LL_HH, HH_LL }; + + /** + * @brief Changes the motor direction and speed + * The motor direction is set by the change of the High/Low switching of the motor half bridges in one register. + * This needs some time to change the direction, so its avoided if not needed. + * Setting the speed is done by setting the PWM register. + * + * @param motorNum uint8_t motor number (0 or 1) + * @param dir uint8_t direction (HH_LL or LL_HH for forward/backward of one motor on four half bridges) + * @param speed uint8_t speed (0-255) + * @param errorCheck bool if true, the error register is cleared after setting the speed + */ + void motorSet(uint8_t motorNum, uint8_t dir, uint8_t speed, bool errorCheck = false) + { + if (dir != oldDirection[motorNum]) { + controller.directWriteReg(motor[motorNum][0], dir); + oldDirection[motorNum] = dir; + } + controller.directWriteReg(motor[motorNum][1], speed); + if (errorCheck) { + controller.clearErrors(); + } + } + + + //! connect motor between halfbridge 1 and halfbridge 2 + void setup() + { + + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + Serial.println("TLE94112 Motor Speed Control Example"); + delay(1000); + + // Enable MotorController Tle94112 + // Note: Required to be done before starting to configure the motor + controller.begin(); + + // four half bridges and two PWM channels are used to control two motors + controller.configHB(controller.TLE_HB1, controller.TLE_HIGH, controller.TLE_PWM1); + controller.configHB(controller.TLE_HB2, controller.TLE_HIGH, controller.TLE_PWM1); + controller.configHB(controller.TLE_HB3, controller.TLE_LOW, controller.TLE_NOPWM); + controller.configHB(controller.TLE_HB4, controller.TLE_LOW, controller.TLE_NOPWM); + + controller.configHB(controller.TLE_HB9, controller.TLE_HIGH, controller.TLE_PWM3); + controller.configHB(controller.TLE_HB10, controller.TLE_HIGH, controller.TLE_PWM3); + controller.configHB(controller.TLE_HB11, controller.TLE_LOW, controller.TLE_NOPWM); + controller.configHB(controller.TLE_HB12, controller.TLE_LOW, controller.TLE_NOPWM); + + // all stop + controller.configPWM(controller.TLE_PWM1, controller.TLE_FREQ200HZ, 0); + controller.configPWM(controller.TLE_PWM3, controller.TLE_FREQ200HZ, 0); + controller.clearErrors(); + + delay(1000); + + } + + + void loop() { + controller.clearErrors(); + + Serial.println("forward / backward"); + motorSet(0, HH_LL, 100); + motorSet(1, LL_HH, 100); + delay(1000); + + Serial.println(" speed up / down"); + motorSet(0, HH_LL, 255); + motorSet(1, LL_HH, 50); + delay(1000); + + Serial.print("backward / forward "); + motorSet(0, LL_HH, 255); + motorSet(1, HH_LL, 255); + delay(1000); + + } \ No newline at end of file diff --git a/library.json b/library.json index 1675aba..659a8bb 100644 --- a/library.json +++ b/library.json @@ -12,7 +12,7 @@ "url":"https://www.infineon.com/cms/en/product/power/motor-control-ics/brushed-dc-motor-driver-ics/multi-half-bridge-ics/", "maintainer": true }, - "version":"4.1.1", + "version":"4.2.0", "license":"MIT", "frameworks":"arduino", "platforms":[ diff --git a/library.properties b/library.properties index d591285..9a7758d 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=multi-half-bridge -version=4.1.1 +version=4.2.0 author=Infineon Technologies maintainer=Infineon Technologies sentence=Library of Infineon Multi Half-Bridge IC controllers family diff --git a/src/tle94112-ino.cpp b/src/tle94112-ino.cpp index 7bcb48d..5dded32 100644 --- a/src/tle94112-ino.cpp +++ b/src/tle94112-ino.cpp @@ -25,9 +25,9 @@ Tle94112Ino::Tle94112Ino(void):Tle94112() } /** - * @brief constructor with individual pin assignment + * @brief constructor with individual pin assignment for CS pin * - * @param csPin pin number of the CS pin + * @param csPin pin number of the CS (chip select) pin */ Tle94112Ino::Tle94112Ino(uint8_t csPin):Tle94112() { @@ -35,4 +35,18 @@ Tle94112Ino::Tle94112Ino(uint8_t csPin):Tle94112() Tle94112::cs = new GPIOIno( csPin, OUTPUT, GPIOIno::POSITIVE ); Tle94112::timer = new TimerIno(); Tle94112::sBus = new SPICIno(); +} + +/** + * @brief constructor with individual pin assignment for CS and EN pin. + * + * @param csPin pin number of the CS (chip select) pin + * @param enPin pin number of the EN (enable) pin + */ +Tle94112Ino::Tle94112Ino(uint8_t csPin, uint8_t enPin):Tle94112() +{ + Tle94112::en = new GPIOIno( enPin, OUTPUT, GPIOIno::POSITIVE ); + Tle94112::cs = new GPIOIno( csPin, OUTPUT, GPIOIno::POSITIVE ); + Tle94112::timer = new TimerIno(); + Tle94112::sBus = new SPICIno(); } \ No newline at end of file diff --git a/src/tle94112-ino.hpp b/src/tle94112-ino.hpp index c182f5c..432e111 100644 --- a/src/tle94112-ino.hpp +++ b/src/tle94112-ino.hpp @@ -26,6 +26,7 @@ class Tle94112Ino: virtual public Tle94112 public: Tle94112Ino(void); Tle94112Ino(uint8_t csPin); + Tle94112Ino(uint8_t csPin, uint8_t enPin); }; /** @} */ diff --git a/src/tle94112-types.hpp b/src/tle94112-types.hpp index a4ceb9f..01e6e57 100644 --- a/src/tle94112-types.hpp +++ b/src/tle94112-types.hpp @@ -30,6 +30,40 @@ namespace tle94112 READ_ERROR = -3, /**< Read error */ WRITE_ERROR = -4, /**< Write error */ }; + + #define REG_ACT_1 0x03 + #define REG_ACT_2 0x43 + #define REG_ACT_3 0x23 + + #define REG_MODE_1 0x63 + #define REG_MODE_2 0x13 + #define REG_MODE_3 0x53 + + #define REG_PWM_CH_FREQ 0x33 + + #define REG_PWM_DC_1 0x73 + #define REG_PWM_DC_2 0x0B + #define REG_PWM_DC_3 0x4B + + #define REG_SYS_DIAG 0x1B + #define REG_ERR1 0x5B + #define REG_ERR2 0x3B + #define REG_ERR3 0x7B + #define REG_ERR4 0x07 + #define REG_ERR5 0x47 + #define REG_ERR6 0x27 + + #define REG_FW_OL 0x2B + #define REG_FW_CTRL 0x6B + + #define HL_HL 0b10011001 + #define HL_LH 0b10010110 + #define LH_HL 0b01101001 + #define LH_LH 0b01100110 + + #define HH_LL 0b10100101 + #define LL_HH 0b01011010 + /** @} */ /** @} */ diff --git a/src/tle94112.cpp b/src/tle94112.cpp index de8efea..bc69618 100644 --- a/src/tle94112.cpp +++ b/src/tle94112.cpp @@ -301,6 +301,21 @@ void Tle94112::init(void) /*! \brief time in milliseconds to wait for chipselect signal raised */ #define TLE94112_CS_RISETIME 2 +void Tle94112::directWriteReg(uint8_t reg, uint8_t data) +{ + TLE94112_LOG_MSG(__FUNCTION__); + + uint8_t address = reg | TLE94112_CMD_WRITE; + uint8_t byte0; + uint8_t byte1; + + cs->disable(); + sBus->transfer(address, byte0); + sBus->transfer(data, byte1); + cs->enable(); + timer->delayMilli(TLE94112_CS_RISETIME); +} + void Tle94112::writeReg(uint8_t reg, uint8_t mask, uint8_t shift, uint8_t data) { uint8_t address = mCtrlRegAddresses[reg]; diff --git a/src/tle94112.hpp b/src/tle94112.hpp index 1f1cc2d..54fd5c4 100644 --- a/src/tle94112.hpp +++ b/src/tle94112.hpp @@ -227,6 +227,28 @@ class Tle94112 //! \brief clears all clearable error flags void clearErrors(); + /*! \brief writes data bits directly to a register of the TLE94112 + * + * \param reg address of the register to be written to. + * \param data the data byte that has to be written. + * + * \see mCtrlRegAddresses + * \see mCtrlRegData + */ + void directWriteReg(uint8_t reg, 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); + SPIC *sBus; //