Skip to content

Feature/direct register access #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 108 additions & 0 deletions examples/directRegisterControl/directRegisterControl.ino
Original file line number Diff line number Diff line change
@@ -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-ino.hpp>

//! 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);

}
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -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":[
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=multi-half-bridge
version=4.1.1
version=4.2.0
author=Infineon Technologies
maintainer=Infineon Technologies <www.infineon.com>
sentence=Library of Infineon Multi Half-Bridge IC controllers family
Expand Down
18 changes: 16 additions & 2 deletions src/tle94112-ino.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,28 @@ 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()
{
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();
}

/**
* @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();
}
1 change: 1 addition & 0 deletions src/tle94112-ino.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Tle94112Ino: virtual public Tle94112
public:
Tle94112Ino(void);
Tle94112Ino(uint8_t csPin);
Tle94112Ino(uint8_t csPin, uint8_t enPin);
};
/** @} */

Expand Down
34 changes: 34 additions & 0 deletions src/tle94112-types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

/** @} */

/** @} */
Expand Down
15 changes: 15 additions & 0 deletions src/tle94112.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
34 changes: 22 additions & 12 deletions src/tle94112.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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; //<! \brief SPI cover class as representation of the SPI bus
GPIOC *cs; //<! \brief shield enable GPIO to switch chipselect on/off
GPIOC *en; //<! \brief shield enable GPIO to switch shield on/off
Expand Down Expand Up @@ -363,18 +385,6 @@ class Tle94112
*/
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
Expand Down
Loading