Compare commits
21 Commits
drop-value
...
731566e7d1
| Author | SHA1 | Date | |
|---|---|---|---|
| 731566e7d1 | |||
| ae0ac5317d | |||
| 5d1e66f5fa | |||
|
|
e0b1e90f6c | ||
| 0f167a5e32 | |||
| aef6c641d1 | |||
| c63e9fa428 | |||
| 4f92e37400 | |||
| e16f02a165 | |||
| 57e6c69a15 | |||
| eb21eccb23 | |||
| 2474d3394c | |||
| 4f1af0f4ae | |||
| 3e9c1cc20b | |||
| e118fa4a20 | |||
| 2c9e9be6b3 | |||
| c36e9053c4 | |||
| 193579e798 | |||
| 3a132bb584 | |||
| 68680db6b4 | |||
| 56ab0fbc0f |
19
.gitignore
vendored
@@ -2,4 +2,21 @@ BionxControl.pro.user
|
||||
build/
|
||||
bcvalue.cpp.autosave
|
||||
.qtcreator/BionxControl.pro.user
|
||||
.user
|
||||
.user
|
||||
|
||||
# Objektdateien ignorieren
|
||||
*.o
|
||||
|
||||
.qtc_clangd/
|
||||
|
||||
# Von Qt generierte MOC-Dateien (Meta-Object Compiler) ignorieren
|
||||
moc_*
|
||||
|
||||
# Von Qt generierte Ressourcen-Dateien ignorieren
|
||||
qrc_*
|
||||
|
||||
BionxControl
|
||||
Makefile
|
||||
ui_*
|
||||
|
||||
.qmake.stash
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
QT += core gui
|
||||
QT += core gui svg
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
@@ -10,13 +10,30 @@ QMAKE_CXXFLAGS += -std=c++23
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
INCLUDEPATH += . lib
|
||||
INCLUDEPATH += . libwin
|
||||
|
||||
linux {
|
||||
#LIBS += -lpigpio -lpigpiod_if2 -lrt
|
||||
# FIXME SOURCES +=
|
||||
linux:contains(QT_ARCH, arm.*)
|
||||
{
|
||||
message("Konfiguration für Raspberry Pi (ARM) erkannt.")
|
||||
|
||||
# 1. Header-Dateien (z.B. für bcm2835.h oder eigene Treiber)
|
||||
#INCLUDEPATH += /usr/local/include \
|
||||
# /home/pi/my_custom_drivers/include
|
||||
|
||||
# not used at the moment
|
||||
# 2. Bibliotheken linken
|
||||
# -L sagt dem Linker WO er suchen soll
|
||||
# -l sagt dem Linker WAS er nehmen soll (z.B. libwiringPi.so -> -lwiringPi)
|
||||
#LIBS += -L/usr/lib \
|
||||
# -lmhstcan
|
||||
|
||||
|
||||
# Optional: Spezielle Compiler-Flags für den Pi (Optimierung)
|
||||
#QMAKE_CXXFLAGS += -O3
|
||||
}
|
||||
|
||||
li
|
||||
|
||||
windows
|
||||
{
|
||||
#LIBS += -L$$PWD/can_api -lmhstcan -lAdvapi32
|
||||
@@ -27,17 +44,19 @@ windows
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
aalegacy.cpp \
|
||||
bc.cpp \
|
||||
bcanimateddelegate.cpp \
|
||||
bcdeviceview.cpp \
|
||||
bcdriver.cpp \
|
||||
bcdrivertinycan.cpp \
|
||||
bclegacy.cpp \
|
||||
bcguihelpers.cpp \
|
||||
bctransmitter.cpp \
|
||||
bcvalue.cpp \
|
||||
bcvaluemodel.cpp \
|
||||
bcxmlloader.cpp \
|
||||
lib/can_drv_win.c \
|
||||
libwin/can_drv_win.c \
|
||||
libwin/mhs_can_drv.c \
|
||||
main.cpp \
|
||||
bcmainwindow.cpp
|
||||
|
||||
@@ -47,6 +66,7 @@ HEADERS += \
|
||||
bcdeviceview.h \
|
||||
bcdriver.h \
|
||||
bcdrivertinycan.h \
|
||||
bcguihelpers.h \
|
||||
bcmainwindow.h \
|
||||
bctransmitter.h \
|
||||
bcvalue.h \
|
||||
|
||||
@@ -185,102 +185,7 @@ double gSetSpeedLimit = -1, gSetMinSpeedLimit = -1, gSetThrottleSpeedLimit = -1;
|
||||
#define BATTERY 3
|
||||
#define BIB 4
|
||||
|
||||
/*
|
||||
class ThemeSwitchButton : public QPushButton {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ThemeSwitchButton(QWidget *parent = nullptr)
|
||||
: QPushButton(parent), m_isDarkMode(true)
|
||||
{
|
||||
// 1. Visuelles Setup: Flach, keine Ränder, Hand-Cursor
|
||||
setFlat(true);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setFixedSize(32, 24); // Kleiner Footprint im StatusBar
|
||||
|
||||
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
|
||||
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
|
||||
setStyleSheet(R"(
|
||||
QPushButton {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
font-size: 14pt;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
|
||||
border-radius: 4px;
|
||||
}
|
||||
)");
|
||||
|
||||
// 2. Initialer Status (Startet im Dark Mode -> zeigt Mond)
|
||||
updateIcon();
|
||||
|
||||
// 3. Klick verbinden
|
||||
connect(this, &QPushButton::clicked, this, &ThemeSwitchButton::toggle);
|
||||
}
|
||||
|
||||
signals:
|
||||
void themeChanged(bool isDark);
|
||||
|
||||
private slots:
|
||||
void toggle() {
|
||||
m_isDarkMode = !m_isDarkMode;
|
||||
updateIcon();
|
||||
emit themeChanged(m_isDarkMode);
|
||||
}
|
||||
|
||||
private:
|
||||
void updateIcon() {
|
||||
// Logik:
|
||||
// Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack).
|
||||
// Hier: Zeige das Symbol des AKTUELLEN Modus.
|
||||
setText(m_isDarkMode ? "🌙" : "☀️");
|
||||
setToolTip(m_isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode");
|
||||
}
|
||||
|
||||
bool m_isDarkMode;
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainWindow(QWidget *parent = nullptr)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
setWindowTitle("Fluent Theme Switcher");
|
||||
resize(800, 600);
|
||||
|
||||
// --- STATUSBAR SETUP ---
|
||||
QStatusBar *statBar = statusBar();
|
||||
|
||||
// Optional: Normale Nachricht links
|
||||
statBar->showMessage("Ready");
|
||||
|
||||
// 1. Unseren Switcher erstellen
|
||||
ThemeSwitchButton *themeBtn = new ThemeSwitchButton(this);
|
||||
|
||||
// 2. WICHTIG: Rechts hinzufügen
|
||||
statBar->addPermanentWidget(themeBtn);
|
||||
|
||||
// 3. Signal verbinden: Button klick -> Theme ändern
|
||||
connect(themeBtn, &ThemeSwitchButton::themeChanged, this, [this](bool isDark){
|
||||
if (isDark) {
|
||||
applyFluentDarkTheme(*qApp); // Funktion von vorhin
|
||||
statusBar()->showMessage("Dark Mode Activated", 3000);
|
||||
} else {
|
||||
applyFluentLightTheme(*qApp); // Funktion von vorhin
|
||||
statusBar()->showMessage("Light Mode Activated", 3000);
|
||||
}
|
||||
});
|
||||
|
||||
// Initiale Anwendung (Dark Mode)
|
||||
applyFluentDarkTheme(*qApp);
|
||||
}
|
||||
};
|
||||
*/
|
||||
|
||||
char *getNodeName(unsigned char id)
|
||||
{
|
||||
@@ -727,24 +632,30 @@ int xmain(int argc, char **argv)
|
||||
CanSetMode(0, OP_CAN_START, CAN_CMD_ALL_CLEAR);
|
||||
CanGetDeviceStatus(0, &status);
|
||||
|
||||
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN) {
|
||||
if (status.CanStatus == CAN_STATUS_BUS_OFF) {
|
||||
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN)
|
||||
{
|
||||
if (status.CanStatus == CAN_STATUS_BUS_OFF)
|
||||
{
|
||||
printf("CAN Status BusOff" _NL);
|
||||
CanSetMode(0, OP_CAN_RESET, CAN_CMD_NONE);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("error: could not open device" _NL);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
|
||||
if (consoleInSlaveMode) {
|
||||
|
||||
if (consoleInSlaveMode)
|
||||
{
|
||||
printf("console already in salve mode. good!" _NL _NL);
|
||||
} else {
|
||||
if (gConsoleSetSlaveMode) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gConsoleSetSlaveMode)
|
||||
{
|
||||
int retry = 20;
|
||||
|
||||
printf("putting console in salve mode ... ");
|
||||
@@ -756,16 +667,21 @@ int xmain(int argc, char **argv)
|
||||
|
||||
doSleep(500); // give the console some time to settle
|
||||
printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed");
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("console not in slave mode" _NL _NL);
|
||||
}
|
||||
}
|
||||
|
||||
if (gAssistInitLevel != -1) {
|
||||
if (gAssistInitLevel != -1)
|
||||
{
|
||||
printf("setting initial assistance level to %d" _NL, gAssistInitLevel);
|
||||
setValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL, gAssistInitLevel);
|
||||
}
|
||||
|
||||
if (gSetSpeedLimit > 0) {
|
||||
if (gSetSpeedLimit > 0)
|
||||
{
|
||||
printf("set speed limit to %0.2f km/h" _NL, gSetSpeedLimit);
|
||||
setSpeedLimit(gSetSpeedLimit);
|
||||
doShutdown = 1;
|
||||
2
bc.cpp
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
2
bc.h
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -45,12 +45,16 @@ BCDeviceView::BCDeviceView(QWidget *parent)
|
||||
_itemDelegate = new BCAnimatedDelegate( _valueModel.getValueList(), this);
|
||||
setItemDelegate( _itemDelegate );
|
||||
|
||||
qDebug() << " --- View size I: " << this->size();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BCDeviceView::setDeviceID( BCDevice::ID deviceID )
|
||||
{
|
||||
qDebug() << " --- View size II: " << this->size();
|
||||
|
||||
_devideID = deviceID;
|
||||
}
|
||||
|
||||
@@ -78,8 +82,8 @@ void BCDeviceView::onValueListReady( BCDevice::ID deviceID, BCValueList valueLis
|
||||
}
|
||||
|
||||
void BCDeviceView::onValueUpdated(int index, BCValue::State state, const QString& newVisibleValue )
|
||||
{
|
||||
_valueModel.onValueUpdated( index,state,newVisibleValue);
|
||||
{
|
||||
_valueModel.onValueUpdated( index, state, newVisibleValue);
|
||||
_itemDelegate->onHighlightRow( index );
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
50
bcdriver.cpp
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -36,12 +36,9 @@
|
||||
#include <bcdriver.h>
|
||||
|
||||
|
||||
|
||||
BCDriver::BCDriver(QObject* parent )
|
||||
: QObject{ parent }
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* @brief Gibt den Treiberstatus zurück.
|
||||
*/
|
||||
|
||||
BCDriver::DriverState BCDriver::getDriverState() const
|
||||
{
|
||||
@@ -59,48 +56,20 @@ BCDriver::DriverState BCDriver::getDriverState() const
|
||||
* aber die Console noch nicht eingeschaltet war.
|
||||
*/
|
||||
|
||||
void BCDriverDummy::onStartDriver()
|
||||
BCDriver::DriverStateResult BCDriverDummy::loadAndStartDriver()
|
||||
{
|
||||
_driverState = DriverState::DeviceReady;
|
||||
emit driverStateChanged( DriverState::DeviceReady, "Driver Ready." );
|
||||
return _driverState;
|
||||
}
|
||||
// __Fix
|
||||
/*
|
||||
try
|
||||
{
|
||||
|
||||
// erstmal die Dll Laden: State::sIdle -> State::sLoaded
|
||||
if( _driverState == DriverState::NotPresent)
|
||||
_driverState = loadAndInitDriver();
|
||||
|
||||
emit stateChanged( _driverState );
|
||||
|
||||
}
|
||||
catch( std::exception& except )
|
||||
{
|
||||
//::CanDownDriver();
|
||||
//::UnloadAndInitDriver();
|
||||
|
||||
emit statusHint( except.what() );
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/// -----------------------------------------------------------------------------------
|
||||
/// -----------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief BCDriverDummy::BCDriverDummy
|
||||
* @param parent
|
||||
* @brief Gibt ein Zufallsbyte zurück.
|
||||
*/
|
||||
|
||||
BCDriverDummy::BCDriverDummy( QObject* parent )
|
||||
: BCDriver(parent)
|
||||
{
|
||||
}
|
||||
|
||||
TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
{
|
||||
Q_UNUSED(deviceID)
|
||||
@@ -110,6 +79,11 @@ TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID
|
||||
return myRandomByte;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Simuliert erfolgreiches scheiben. Tut nix.
|
||||
*/
|
||||
|
||||
TransmitResult BCDriverDummy::writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const
|
||||
{
|
||||
Q_UNUSED(deviceID)
|
||||
|
||||
62
bcdriver.h
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -37,36 +37,6 @@
|
||||
#include <expected>
|
||||
#include <bcvalue.h>
|
||||
|
||||
/*
|
||||
int32_t CanInitDriver(char *options);
|
||||
void CanDownDriver(void);
|
||||
int32_t CanSetOptions(char *options);
|
||||
int32_t CanDeviceOpen(uint32_t index, char *parameter);
|
||||
int32_t CanDeviceClose(uint32_t index);
|
||||
|
||||
int32_t CanSetMode(uint32_t index, unsigned char can_op_mode, uint16_t can_command);
|
||||
|
||||
int32_t CanTransmit(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
void CanTransmitClear(uint32_t index);
|
||||
uint32_t CanTransmitGetCount(uint32_t index);
|
||||
int32_t CanTransmitSet(uint32_t index, uint16_t cmd, uint32_t time);
|
||||
int32_t CanReceive(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
void CanReceiveClear(uint32_t index);
|
||||
uint32_t CanReceiveGetCount(uint32_t index);
|
||||
|
||||
int32_t CanSetSpeed(uint32_t index, uint16_t speed);
|
||||
int32_t CanSetSpeedUser(uint32_t index, uint32_t value);
|
||||
char* CanDrvInfo(void);
|
||||
char* CanDrvHwInfo(uint32_t index);
|
||||
int32_t CanSetFilter(uint32_t index, struct TMsgFilter *msg_filter);
|
||||
int32_t CanGetDeviceStatus(uint32_t index, struct TDeviceStatus *status);
|
||||
void CanSetPnPEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index, int32_t status));
|
||||
void CanSetStatusEventCallback(void (DRV_CALLBACK_TYPE *event) (uint32_t index, struct TDeviceStatus *device_status) );
|
||||
void CanSetRxEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index, struct TCanMsg *msg, int32_t count) );
|
||||
|
||||
void CanSetEvents( uint16_t events );
|
||||
uint32_t CanEventStatus(void);
|
||||
*/
|
||||
|
||||
struct CBCItem;
|
||||
class BCDriverStatus;
|
||||
@@ -84,17 +54,17 @@ class BCDriverStatus;
|
||||
*/
|
||||
|
||||
|
||||
class BCDriver : public QObject
|
||||
class BCDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_GADGET
|
||||
|
||||
public:
|
||||
|
||||
// Die möglichen Zustände beim Laden
|
||||
// des CAN-Bus Treibers.
|
||||
|
||||
enum class DriverState
|
||||
{
|
||||
enum class DriverState : uint8_t
|
||||
{
|
||||
NotPresent,
|
||||
Error,
|
||||
Loaded,
|
||||
@@ -107,9 +77,11 @@ public:
|
||||
// Enthält den Treiberzustand oder einen Fehlerstring
|
||||
using DriverStateResult = std::expected<DriverState,QString>;
|
||||
|
||||
explicit BCDriver( QObject* parent = nullptr );
|
||||
explicit BCDriver() = default;
|
||||
virtual ~BCDriver() = default;
|
||||
|
||||
virtual BCDriver::DriverStateResult loadAndStartDriver() = 0;
|
||||
|
||||
// Gibt den aktuelle Zustand des Treibers zurück. Der DriverState
|
||||
// muss auf DeviceReady stehen, um Werte lesen & schreiben zu können.
|
||||
// Dazu muss das Bionx-System eingeschaltet sein.
|
||||
@@ -122,14 +94,6 @@ public:
|
||||
virtual TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const = 0;
|
||||
virtual TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const = 0;
|
||||
|
||||
public slots:
|
||||
|
||||
virtual void onStartDriver() = 0;
|
||||
|
||||
signals:
|
||||
|
||||
void driverStateChanged( DriverState state, const QString& message="" ) const;
|
||||
|
||||
protected:
|
||||
|
||||
DriverState _driverState{DriverState::NotPresent};
|
||||
@@ -137,20 +101,22 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// -----------------------------------------------------------------------------------
|
||||
/// -----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
class BCDriverDummy : public BCDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCDriverDummy( QObject* parent = nullptr );
|
||||
BCDriver::DriverStateResult loadAndStartDriver() override;
|
||||
|
||||
TransmitResult readRawByte( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
public slots:
|
||||
|
||||
virtual void onStartDriver() override;
|
||||
};
|
||||
|
||||
#endif // BCDRIVER_H
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -36,44 +36,98 @@
|
||||
#include <can_drv.h>
|
||||
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
// Unter Windows steht der Treibername in der registry
|
||||
static const char* cMHS_DRIVERNAME = NULL;
|
||||
#elif defined(Q_OS_LINUX)
|
||||
// Unter linux(artigen) muss der Treibername explizit mit übergeben werden
|
||||
static const char* cMHS_DRIVERNAME = "libmhstcan.so";
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
// TinyCan C-Api
|
||||
// -------------
|
||||
|
||||
BCDriverTinyCan::BCDriverTinyCan( QObject* parent )
|
||||
: BCDriver(parent )
|
||||
int32_t CanInitDriver(char *options);
|
||||
void CanDownDriver(void);
|
||||
int32_t CanSetOptions(char *options);
|
||||
int32_t CanDeviceOpen(uint32_t index, char *parameter);
|
||||
int32_t CanDeviceClose(uint32_t index);
|
||||
|
||||
int32_t CanSetMode(uint32_t index, unsigned char can_op_mode, uint16_t can_command);
|
||||
|
||||
int32_t CanTransmit(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
void CanTransmitClear(uint32_t index);
|
||||
uint32_t CanTransmitGetCount(uint32_t index);
|
||||
int32_t CanTransmitSet(uint32_t index, uint16_t cmd, uint32_t time);
|
||||
int32_t CanReceive(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
void CanReceiveClear(uint32_t index);
|
||||
uint32_t CanReceiveGetCount(uint32_t index);
|
||||
|
||||
int32_t CanSetSpeed(uint32_t index, uint16_t speed);
|
||||
int32_t CanSetSpeedUser(uint32_t index, uint32_t value);
|
||||
char* CanDrvInfo(void);
|
||||
char* CanDrvHwInfo(uint32_t index);
|
||||
int32_t CanSetFilter(uint32_t index, struct TMsgFilter *msg_filter);
|
||||
int32_t CanGetDeviceStatus(uint32_t index, struct TDeviceStatus *status);
|
||||
void CanSetPnPEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index, int32_t status));
|
||||
void CanSetStatusEventCallback(void (DRV_CALLBACK_TYPE *event) (uint32_t index, struct TDeviceStatus *device_status) );
|
||||
void CanSetRxEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index, struct TCanMsg *msg, int32_t count) );
|
||||
|
||||
void CanSetEvents( uint16_t events );
|
||||
uint32_t CanEventStatus(void);
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Destruktor. Entlädt den CAN-Bus Treiber wieder.
|
||||
*/
|
||||
|
||||
BCDriverTinyCan::~BCDriverTinyCan()
|
||||
{
|
||||
|
||||
resetDriver();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BCDriverTinyCan::loadAndStartDriver
|
||||
* @return
|
||||
*/
|
||||
|
||||
void BCDriverTinyCan::onStartDriver()
|
||||
BCDriver::DriverStateResult BCDriverTinyCan::loadAndStartDriver()
|
||||
{
|
||||
DriverStateResult result;
|
||||
if( _driverState < DriverState::Opened)
|
||||
loadDriver();
|
||||
result = loadDriver();
|
||||
if( _driverState == DriverState::Opened)
|
||||
_driverState = connectDriver();
|
||||
result = setConsoleSlaveMode();
|
||||
return result;
|
||||
}
|
||||
|
||||
void BCDriverTinyCan::loadDriver()
|
||||
/**
|
||||
* @brief BCDriverTinyCan::loadDriver
|
||||
* @return
|
||||
*/
|
||||
|
||||
BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
|
||||
{
|
||||
|
||||
|
||||
auto callLoadDriver = []() -> DriverStateResult
|
||||
auto callLoadDriver = [&]() -> DriverStateResult
|
||||
{
|
||||
if( ::LoadDriver( NULL ) < 0 )
|
||||
if( ::LoadDriver( cMHS_DRIVERNAME ) < 0 )
|
||||
return std::unexpected(QString("Driver Error: 'LoadDriver'"));
|
||||
return DriverState::Loaded;
|
||||
_driverState = DriverState::Loaded;
|
||||
return _driverState;
|
||||
};
|
||||
|
||||
auto callInitDriver = [](DriverState state) -> DriverStateResult
|
||||
auto callInitDriver = [&](DriverState state) -> DriverStateResult
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
if( ::CanInitDriver( NULL ) < 0 )
|
||||
return std::unexpected(QString("Driver Error: 'InitDriver'"));
|
||||
return DriverState::Initialized;
|
||||
_driverState = DriverState::Initialized;
|
||||
return _driverState;
|
||||
};
|
||||
|
||||
auto callOpenDevice = [](DriverState state) -> DriverStateResult
|
||||
auto callOpenDevice = [&](DriverState state) -> DriverStateResult
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
if( ::CanDeviceOpen( 0, NULL ) < 0 )
|
||||
@@ -90,48 +144,65 @@ void BCDriverTinyCan::loadDriver()
|
||||
|
||||
if( deviceStatus.CanStatus == CAN_STATUS_BUS_OFF )
|
||||
{
|
||||
::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE );
|
||||
return std::unexpected(QString("Driver Error: CAN Status 'BusOff'" ));
|
||||
::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE );
|
||||
return std::unexpected(QString("Driver Error: CAN Status 'BusOff'" ));
|
||||
}
|
||||
return DriverState::Opened;
|
||||
_driverState = DriverState::Opened;
|
||||
return _driverState;
|
||||
};
|
||||
|
||||
|
||||
// #1. erstmal komplett zurücksetzen
|
||||
resetDriver();
|
||||
// #2. Treiber laden, initialisieren und
|
||||
// mit dem tinyCan Interface verbinden.
|
||||
auto newDriverState = callLoadDriver()
|
||||
.and_then( callInitDriver )
|
||||
.and_then( callOpenDevice );
|
||||
|
||||
_driverState = DriverState::Error;
|
||||
QString message("Driver Ready.");
|
||||
// in Fehlerfall ist der Errorstring gesetzt,
|
||||
// der interne _driverstate ist
|
||||
// irgendwo unter DriverState::Opened
|
||||
return newDriverState;
|
||||
|
||||
if(newDriverState)
|
||||
_driverState = *newDriverState;
|
||||
else
|
||||
message = newDriverState.error();
|
||||
|
||||
emit driverStateChanged( _driverState, message );
|
||||
}
|
||||
|
||||
// __fix
|
||||
BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
|
||||
/**
|
||||
* @brief Um mit dem Bionx eBike reden zu können, müssen wir
|
||||
* die Console in den Slave-Mode setzen.
|
||||
* @return Fehlerstring oder DriverState::DeviceReady
|
||||
*/
|
||||
|
||||
BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
|
||||
{
|
||||
|
||||
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
|
||||
uint8_t slaveFlag = static_cast<uint8_t>(BC::ID::Cons_Status_Slave);
|
||||
uint8_t slaveFlag = static_cast<uint8_t> (BC::ID::Cons_Status_Slave);
|
||||
|
||||
qDebug() << "XXX BCDriverTinyCan::Driver Init: putting Console in slave mode ... ";
|
||||
|
||||
// Console already in slave mode. good!
|
||||
if( readRawByte( console, slaveFlag ) )
|
||||
return DriverState::DeviceReady;
|
||||
TransmitResult isSlave = 0;
|
||||
// Already slave?
|
||||
isSlave = readRawByte( console, slaveFlag );
|
||||
if( isSlave.has_value() )
|
||||
{
|
||||
qDebug() << "Console responded: " << isSlave.value();
|
||||
if( isSlave.value() == 1 )
|
||||
{
|
||||
qDebug() << "Console already in slave mode. good!";
|
||||
return DriverState::DeviceReady;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "BCDriverTinyCan::BCDriverTinyCan::XXX Driver Init: putting Console in slave mode ... ";
|
||||
|
||||
unsigned int retry = cTimeOuts;
|
||||
emit driverStateChanged( _driverState, "Driver Init: putting Console in slave mode ... " );
|
||||
TransmitResult isSlave = 0;
|
||||
|
||||
do
|
||||
{
|
||||
writeRawByte( console, slaveFlag, 1 );
|
||||
isSlave = readRawByte( console, slaveFlag );
|
||||
isSlave = readRawByte( console, slaveFlag );
|
||||
bc::delay_millis( 200 );
|
||||
|
||||
} while( retry-- && !(*isSlave) );
|
||||
@@ -145,19 +216,15 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
try
|
||||
{
|
||||
initBCDevice::ID::Console();
|
||||
}
|
||||
|
||||
catch( std::exception& except )
|
||||
{
|
||||
::CanDownDriver();
|
||||
::UnloadDriver();
|
||||
}
|
||||
*/
|
||||
void BCDriverTinyCan::resetDriver()
|
||||
{
|
||||
if( _driverState > DriverState::NotPresent )
|
||||
{
|
||||
::CanDownDriver();
|
||||
::UnloadDriver();
|
||||
_driverState = DriverState::NotPresent;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@@ -170,17 +237,75 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
{
|
||||
|
||||
qDebug() << " --- CAN Read Byte: Device: "<< deviceID << " register: " << registerID << " TRY! ";
|
||||
|
||||
struct TCanMsg msg;
|
||||
int err, retry = 20;
|
||||
int timeout = 80;
|
||||
|
||||
unsigned char receipient = (unsigned char) deviceID;
|
||||
unsigned char reg = (unsigned char) registerID;
|
||||
|
||||
msg.MsgFlags = 0L;
|
||||
msg.Id = receipient;
|
||||
msg.MsgLen = 2;
|
||||
msg.MsgData[0] = 0x00;
|
||||
msg.MsgData[1] = reg;
|
||||
|
||||
CanTransmit(0, &msg, 1);
|
||||
|
||||
while(timeout-- && CanTransmitGetCount(0))
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if (timeout == -1)
|
||||
qDebug() << "error: could not send value to node ";
|
||||
|
||||
retry:
|
||||
|
||||
timeout = 80;
|
||||
while(timeout-- && !CanReceiveGetCount(0))
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if (timeout == -1)
|
||||
{
|
||||
qDebug() << "error: no response from node";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((err = CanReceive(0, &msg, 1)) > 0)
|
||||
{
|
||||
qDebug() << " retry: " << retry << " BIB:" << BC::ID::ID_Bib << " msg.Id: " << msg.Id << " msg.MsgLen: " << msg.MsgLen << " msg.MsgData[1]: " << msg.MsgData[1] << " reg: " << reg;
|
||||
if (--retry && (msg.Id != (uint32_t)BC::ID::ID_Bib|| msg.MsgLen != 4 || msg.MsgData[1] != reg))
|
||||
goto retry;
|
||||
|
||||
if (!retry)
|
||||
{
|
||||
qDebug() << "XXX error: no response from node: " << err;
|
||||
return 0;
|
||||
}
|
||||
qDebug() << " --- CAN Read Byte: Device: "<< deviceID << " register: " << registerID << " BYTE: " << (uint32_t) msg.MsgData[3];
|
||||
return (unsigned int) msg.MsgData[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "Error:" <<err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/*
|
||||
//TransmitResult
|
||||
qDebug() << " --- BCDriverTinyCan::readRawByte DriverState: " << getDriverState();
|
||||
|
||||
if( getDriverState() != DriverState::DeviceReady)
|
||||
if( _driverState <DriverState::Opened )
|
||||
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
|
||||
|
||||
unsigned char receipient = (unsigned char ) deviceID;
|
||||
::TCanMsg msg;
|
||||
|
||||
// msg verpacken
|
||||
msg.MsgFlags = 0L;
|
||||
msg.Id = deviceID;
|
||||
msg.Id = receipient;//deviceID;
|
||||
msg.MsgLen = 2;
|
||||
msg.MsgData[0] = 0x00;
|
||||
msg.MsgData[1] = registerID;
|
||||
@@ -212,15 +337,15 @@ retry:
|
||||
|
||||
// message empfangen
|
||||
int err = ::CanReceive( 0, &msg, 1 );
|
||||
qDebug() << "HÄÄ ?" << err << "reg: "<< registerID <<" timeOuts: " << timeOuts;
|
||||
//qDebug() << "HÄÄ ?" << err << "reg: "<< registerID <<" timeOuts: " << timeOuts;
|
||||
|
||||
if( err < 0 )
|
||||
//throw BCException( "getValue error: could not receive value" );
|
||||
qDebug( "getValue error: could not receive value" );
|
||||
|
||||
qDebug() << "HÄÄ 2" <<msg.Id;
|
||||
qDebug() << "HÄÄ 2" <<msg.MsgLen;
|
||||
qDebug() << "HÄÄ 2" <<msg.MsgData[1];
|
||||
//qDebug() << "HÄÄ 2" <<msg.Id;
|
||||
//qDebug() << "HÄÄ 2" <<msg.MsgLen;
|
||||
//qDebug() << "HÄÄ 2" <<msg.MsgData[1];
|
||||
|
||||
//if( err > 0 )
|
||||
if( --retries && ( msg.Id != BIB || msg.MsgLen != 4 || msg.MsgData[1] != registerID ) )
|
||||
@@ -229,23 +354,25 @@ retry:
|
||||
if( !timeOuts )
|
||||
return std::unexpected(QString("CAN response errror: timeout" ));
|
||||
|
||||
qDebug() << " --- CAN Read Byte: " << (uint32_t) msg.MsgData[3] << " Device:: "<< deviceID << " register: " << registerID;
|
||||
return (uint32_t) msg.MsgData[3];
|
||||
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
// void BCDriverTinyCan::setValue( unsigned char receipient, unsigned char reg, unsigned char value )
|
||||
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8_t value ) const
|
||||
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const
|
||||
{
|
||||
|
||||
if( getDriverState() != DriverState::DeviceReady)
|
||||
return std::unexpected(QString("writeRawValue error: driver not loaded." ) );
|
||||
if( _driverState <DriverState::Opened )
|
||||
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
|
||||
|
||||
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;
|
||||
|
||||
::TCanMsg msg;
|
||||
int timeout_count = cTIMEOUT_COUNT;
|
||||
|
||||
|
||||
msg.MsgFlags = 0L;
|
||||
msg.Id = deviceID;
|
||||
msg.MsgLen = 4;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -37,39 +37,27 @@
|
||||
|
||||
class BCDriverTinyCan : public BCDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCDriverTinyCan( QObject* parent=nullptr );
|
||||
virtual ~BCDriverTinyCan() = default;
|
||||
virtual ~BCDriverTinyCan();
|
||||
|
||||
BCDriver::DriverStateResult loadAndStartDriver() override;
|
||||
void resetDriver();
|
||||
|
||||
TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
public slots:
|
||||
private:
|
||||
|
||||
void onStartDriver() override;
|
||||
|
||||
protected:
|
||||
|
||||
void loadDriver();
|
||||
DriverState connectDriver();
|
||||
|
||||
//const char* CBCDLL_LIN = "libmhstcan.so";
|
||||
//const char* CBCDLL_WIN = "mhstcan.dll";
|
||||
BCDriver::DriverStateResult loadDriver();
|
||||
BCDriver::DriverStateResult setConsoleSlaveMode();
|
||||
|
||||
static constexpr int cRetries = 5;
|
||||
static constexpr int cTimeOuts = 20;
|
||||
static constexpr int cTIMEOUT_MS = 10; // 10ms
|
||||
static constexpr int cTIMEOUT_COUNT = 10;
|
||||
|
||||
//const unsigned int BATTERY = 0x010;
|
||||
//const unsigned int MOTOR = 0x020;
|
||||
const unsigned int BIB = 0x048;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // BCDRIVERTINYCAN_H
|
||||
|
||||
248
bcguihelpers.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
mhs_can_drv.c
|
||||
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||
@see www.mhs-elektronik.de
|
||||
|
||||
Based on Bionx data type descriptions from:
|
||||
|
||||
BigXionFlasher USB V 0.2.4 rev. 97
|
||||
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||
@see www.bigxionflasher.org
|
||||
|
||||
Bionx Bike Info
|
||||
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||
@see www.ts-soft.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
@see https://github.com/bikemike/bionx-bikeinfo
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <bcguihelpers.h>
|
||||
|
||||
|
||||
BCThemeSwitchButton::BCThemeSwitchButton(QWidget *parent )
|
||||
: QPushButton(parent)
|
||||
{
|
||||
// Visuelles Setup: Flach, keine Ränder, Hand-Cursor
|
||||
setFlat(true);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setFixedSize(24, 24); // Kleiner Footprint im StatusBar
|
||||
|
||||
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
|
||||
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
|
||||
/*
|
||||
setStyleSheet(R"(
|
||||
QPushButton {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
font-size: 11pt;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
|
||||
border-radius: 24px;
|
||||
}
|
||||
)");
|
||||
*/
|
||||
// Initialer Status (Startet im Dark Mode -> zeigt Mond)
|
||||
updateIcon();
|
||||
|
||||
connect(this, &QPushButton::clicked, this, &BCThemeSwitchButton::toggle);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Setzt den DarkMode
|
||||
*/
|
||||
|
||||
void BCThemeSwitchButton::setDarkMode( bool isDark )
|
||||
{
|
||||
_isDarkMode = !isDark;
|
||||
toggleMode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Schaltet den akutellen Mode um.
|
||||
*/
|
||||
|
||||
void BCThemeSwitchButton::toggleMode()
|
||||
{
|
||||
_isDarkMode = !_isDarkMode;
|
||||
updateIcon();
|
||||
emit themeChanged(_isDarkMode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Icon & Tooltip anpassen
|
||||
*/
|
||||
|
||||
void BCThemeSwitchButton::updateIcon()
|
||||
{
|
||||
// Logik:
|
||||
// Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack).
|
||||
// Hier: Zeige das Symbol des AKTUELLEN Modus.
|
||||
setText(_isDarkMode ? "🌙" : "☀️");
|
||||
setToolTip(_isDarkMode ? "Zum LightMode wechseln" : "Zum DarkMode wechseln");
|
||||
}
|
||||
|
||||
|
||||
/// -----------------------------------------------------------------------------------
|
||||
/// -----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Hilfswidget: Zeigt den DriverState als Icon an.
|
||||
*/
|
||||
|
||||
BCDriverStateWidget::BCDriverStateWidget(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QHBoxLayout* layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(10, 2, 10, 2);
|
||||
//layout->setSpacing(8);
|
||||
|
||||
_led = new QLabel(this);
|
||||
_led->setFixedSize(12, 12);
|
||||
|
||||
layout->addWidget(_led);
|
||||
|
||||
// Startzustand
|
||||
onDriverStateChanged(BCDriver::DriverState::NotPresent, "Not Present");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Hauptfunktion zum Setzen des Status
|
||||
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
|
||||
void BCDriverStateWidget::onDriverStateChanged(BCDriver::DriverState state, const QString& customMessage)
|
||||
{
|
||||
_state = state;
|
||||
qDebug() << " --- StateWidget: " << state << " - " << customMessage;
|
||||
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
/*
|
||||
void BCDriverStateWidget::updateStyle()
|
||||
{
|
||||
QString ledStyle;
|
||||
QString labelColor;
|
||||
QString toolTipText;
|
||||
|
||||
switch (_state)
|
||||
{
|
||||
case BCDriver::DriverState::DeviceReady:
|
||||
// FLUENT GREEN (Success)
|
||||
ledStyle = "background-color: #107C10; border: 1px solid #0E600E;#FF5F1F; #FF8C00;<- das isses #FF6700";
|
||||
labelColor = "#FFFFFF"; // Weiß (Hervorgehoben)
|
||||
toolTipText = "Verbindung erfolgreich hergestellt.";
|
||||
break;
|
||||
|
||||
case BCDriver::DriverState::Error:
|
||||
// FLUENT RED (Critical)
|
||||
ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;";
|
||||
labelColor = "#FF99A4"; // Ein helleres Rot für Text, damit es auf Dunkel lesbar ist
|
||||
toolTipText = "Kritischer Fehler bei der Verbindung!";
|
||||
break;
|
||||
|
||||
default:
|
||||
// FLUENT GRAY (Neutral)
|
||||
// Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look
|
||||
ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;";
|
||||
labelColor = "#9E9E9E"; // Ausgegrauter Text
|
||||
toolTipText = "System ist offline.";
|
||||
break;
|
||||
}
|
||||
|
||||
// Styles anwenden (immer rund machen)
|
||||
_led->setStyleSheet(ledStyle + "border-radius: 6px;");
|
||||
|
||||
// Textfarbe setzen
|
||||
_label->setStyleSheet(QString("color: %1; font-weight: %2;")
|
||||
.arg(labelColor)
|
||||
.arg(_state == BCDriver::DriverState::DeviceReady ? "bold" : "normal"));
|
||||
|
||||
setToolTip(toolTipText);
|
||||
}
|
||||
*/
|
||||
|
||||
void BCDriverStateWidget::updateStyle()
|
||||
{
|
||||
QString ledStyle;
|
||||
QString toolTipText;
|
||||
/*
|
||||
NotPresent,
|
||||
Error,
|
||||
Loaded,
|
||||
Initialized,
|
||||
Opened, // bis hierher: dll vorhanden, Treiber geladen
|
||||
DeviceReady
|
||||
*/
|
||||
switch (_state)
|
||||
{
|
||||
case BCDriver::DriverState::NotPresent:
|
||||
// FLUENT GRAY (Neutral)
|
||||
// Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look
|
||||
ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;";
|
||||
toolTipText = "Treiber nicht geladen.";
|
||||
break;
|
||||
|
||||
case BCDriver::DriverState::Error:
|
||||
// FLUENT RED (Critical)
|
||||
ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;";
|
||||
toolTipText = "Fehler beim Laden des Treibers.";
|
||||
break;
|
||||
|
||||
// hier: dll vorhanden, Treiber geladen
|
||||
case BCDriver::DriverState::Loaded:
|
||||
case BCDriver::DriverState::Initialized:
|
||||
case BCDriver::DriverState::Opened:
|
||||
// FLUENT RED (Critical)
|
||||
ledStyle = "background-color: #FF8C00; border: 1px solid #A80000;";
|
||||
toolTipText = "Fehler beim Laden des Treibers.";
|
||||
break;
|
||||
|
||||
case BCDriver::DriverState::DeviceReady:
|
||||
// FLUENT GREEN (Success)
|
||||
ledStyle = "background-color: #107C10; border: 1px solid #0E600E;";
|
||||
toolTipText = "Verbindung erfolgreich hergestellt.";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// Styles anwenden (immer rund machen)
|
||||
_led->setStyleSheet(ledStyle + "border-radius: 6px;");
|
||||
|
||||
/*
|
||||
// Textfarbe setzen
|
||||
_setStyleSheet(QString("color: %1; font-weight: %2;")
|
||||
.arg(labelColor)
|
||||
.arg(_state == BCDriver::DriverState::DeviceReady ? "bold" : "normal"));
|
||||
*/
|
||||
setToolTip(toolTipText);
|
||||
}
|
||||
|
||||
void BCDriverStateWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
emit clicked();
|
||||
}
|
||||
QWidget::mouseReleaseEvent(event);
|
||||
}
|
||||
|
||||
|
||||
113
bcguihelpers.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
mhs_can_drv.c
|
||||
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||
@see www.mhs-elektronik.de
|
||||
|
||||
Based on Bionx data type descriptions from:
|
||||
|
||||
BigXionFlasher USB V 0.2.4 rev. 97
|
||||
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||
@see www.bigxionflasher.org
|
||||
|
||||
Bionx Bike Info
|
||||
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||
@see www.ts-soft.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
@see https://github.com/bikemike/bionx-bikeinfo
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef BCGUIHELPERS_H
|
||||
#define BCGUIHELPERS_H
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
|
||||
#include <bcdriver.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Einfaches Buttonwidget, um zwischen Dark- und Lightmode
|
||||
* zu wechseln
|
||||
*/
|
||||
|
||||
class BCThemeSwitchButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCThemeSwitchButton(QWidget *parent = nullptr);
|
||||
void setDarkMode( bool isDark );
|
||||
|
||||
signals:
|
||||
|
||||
void themeChanged(bool isDark);
|
||||
|
||||
private slots:
|
||||
|
||||
void toggleMode();
|
||||
|
||||
private:
|
||||
|
||||
void updateIcon();
|
||||
|
||||
bool _isDarkMode{false};
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// -----------------------------------------------------------------------------------
|
||||
/// -----------------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* @brief Einfaches Widget, um den Zustand des TinyCan Native
|
||||
* Drivers anzuzeigen.
|
||||
*/
|
||||
|
||||
class BCDriverStateWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCDriverStateWidget(QWidget *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
|
||||
// Hauptfunktion zum Setzen des Status
|
||||
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
|
||||
void onDriverStateChanged(BCDriver::DriverState state, const QString& customMessage = QString());
|
||||
|
||||
signals:
|
||||
|
||||
void clicked();
|
||||
|
||||
protected:
|
||||
|
||||
void updateStyle();
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
|
||||
QLabel* _led;
|
||||
BCDriver::DriverState _state;
|
||||
|
||||
};
|
||||
|
||||
#endif // BCGUIHELPERS_H
|
||||
114
bcmainwindow.cpp
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -29,14 +29,14 @@
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include <QFile>
|
||||
#include <QTimer>
|
||||
|
||||
#include "qassert.h"
|
||||
#include <bcmainwindow.h>
|
||||
#include <bcanimateddelegate.h>
|
||||
#include <ui_bcmainwindow.h>
|
||||
|
||||
#include <bcguihelpers.h>
|
||||
|
||||
/**
|
||||
* @brief Das Mainwindow erzeugen
|
||||
@@ -119,6 +119,7 @@ void BCMainWindow::initMainWindow()
|
||||
configureAction(_batteryButton, _batteryAction, BCDevice::ID::Battery );
|
||||
//configureAction(_pimpButton, _pimpAction, BCDevice::ID::Pimp );
|
||||
|
||||
|
||||
/*
|
||||
bool m_isDarkMode = false;
|
||||
QString icon = m_isDarkMode ? "☀️" : "🌙";
|
||||
@@ -141,20 +142,21 @@ void BCMainWindow::initMainWindow()
|
||||
|
||||
fitzeButton->setStyleSheet(style);
|
||||
*/
|
||||
// besser: model::emit dataChanged
|
||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
||||
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleConnectionState );
|
||||
|
||||
initStatusBar();
|
||||
|
||||
// besser: model::emit dataChanged
|
||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
||||
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleDriverConnection );
|
||||
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
|
||||
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
|
||||
|
||||
|
||||
_transmitter.moveToThread(&_worker);
|
||||
|
||||
connect(this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::enqueueValue);
|
||||
connect(this, &BCMainWindow::requestValueUpdate, &_transmitter, &BCTransmitter::onEnqueueValue);
|
||||
connect(&_worker, &QThread::finished, &_transmitter, &QObject::deleteLater);
|
||||
connect( &_transmitter, &BCTransmitter::driverStateChanged, this, &BCMainWindow::onDriverStateChanged );
|
||||
|
||||
// transmitter starten
|
||||
_transmitter.moveToThread(&_worker);
|
||||
_worker.start();
|
||||
|
||||
// die Daten des eBikes laden
|
||||
@@ -164,34 +166,74 @@ void BCMainWindow::initMainWindow()
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// 2. Bild für den Zustand UNCHECKED (Off) hinzufügen
|
||||
// Das ist das Symbol, wenn NICHT verbunden ist (z.B. ein Stecker)
|
||||
connectIcon.addFile(":/icons/plug_disconnected.svg", QSize(), QIcon::Normal, QIcon::Off);
|
||||
|
||||
// 3. Bild für den Zustand CHECKED (On) hinzufügen
|
||||
// Das ist das Symbol, wenn verbunden IST (z.B. Stecker in Dose)
|
||||
connectIcon.addFile(":/icons/plug_connected.svg", QSize(), QIcon::Normal, QIcon::On);
|
||||
*/
|
||||
|
||||
void BCMainWindow::initStatusBar()
|
||||
{
|
||||
// __fix
|
||||
QStatusBar *statBar = statusBar();
|
||||
|
||||
// Optional: Normale Nachricht links
|
||||
statBar->showMessage("Ready");
|
||||
BCDriverStateWidget* conState = new BCDriverStateWidget(this);
|
||||
connect( &_transmitter, &BCTransmitter::driverStateChanged, conState, &BCDriverStateWidget::onDriverStateChanged );
|
||||
connect( conState, &BCDriverStateWidget::clicked, _connectAction, &QAction::trigger );
|
||||
|
||||
// 1. Unseren Switcher erstellen
|
||||
ThemeSwitchButton *themeBtn = new ThemeSwitchButton(this);
|
||||
statBar->addPermanentWidget(conState);
|
||||
conState->installEventFilter(this);
|
||||
|
||||
// 2. WICHTIG: Rechts hinzufügen
|
||||
BCThemeSwitchButton* themeBtn = new BCThemeSwitchButton(this);
|
||||
statBar->addPermanentWidget(themeBtn);
|
||||
|
||||
// 3. Signal verbinden: Button klick -> Theme ändern
|
||||
connect(themeBtn, &ThemeSwitchButton::themeChanged, this, [this](bool isDark){
|
||||
if (isDark)
|
||||
{
|
||||
//applyFluentDarkTheme(*qApp); // Funktion von vorhin
|
||||
statusBar()->showMessage("Dark Mode Activated", 3000);
|
||||
}
|
||||
else
|
||||
{
|
||||
//applyFluentLightTheme(*qApp); // Funktion von vorhin
|
||||
statusBar()->showMessage("Light Mode Activated", 3000);
|
||||
}
|
||||
connect(themeBtn, &BCThemeSwitchButton::themeChanged, this, [this](bool isDark)
|
||||
{
|
||||
QString message = isDark ? "Dark Mode Activated" : "Light Mode Activated";
|
||||
statusBar()->showMessage( message, 3000);
|
||||
setApplicationStyleSheet( isDark ? ":/claude_dark_mode.qss"_L1 : ":/claude_light_mode.qss"_L1 );
|
||||
});
|
||||
|
||||
// Wir starten im light mode
|
||||
//themeBtn->setDarkMode( false );
|
||||
|
||||
statBar->showMessage("Ready");
|
||||
}
|
||||
|
||||
/*
|
||||
bool BCMainWindow::eventFilter(QObject *obj, QEvent *event)
|
||||
{
|
||||
if (obj == myWidget && event->type() == QEvent::MouseButtonRelease) {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
|
||||
if (mouseEvent->button() == Qt::LeftButton) {
|
||||
myAction->trigger();
|
||||
return true; // Event wurde verarbeitet
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setzt das Stylesheet, hier: Dark- oder Lightmode
|
||||
* @param path Der Pfad zuum Stylesheet
|
||||
* @return
|
||||
*/
|
||||
|
||||
bool BCMainWindow::setApplicationStyleSheet( QAnyStringView path )
|
||||
{
|
||||
QFile styleFile( path.toString() );
|
||||
if (styleFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
QString style = styleFile.readAll();
|
||||
qApp->setStyleSheet(style);
|
||||
styleFile.close();
|
||||
return false;
|
||||
}
|
||||
qWarning() << "Konnte Stylesheet nicht laden:" << styleFile.errorString();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -205,6 +247,10 @@ void BCMainWindow::setHeaderLabel( const QString& headerText)
|
||||
_headerLabel->setText( " BionxControl: " + headerText );
|
||||
}
|
||||
|
||||
void BCMainWindow::onShowMessage( const QString& message, int timeOut )
|
||||
{
|
||||
_statusbar->showMessage( message, timeOut );
|
||||
}
|
||||
|
||||
void BCMainWindow::autoConnect()
|
||||
{
|
||||
@@ -216,6 +262,7 @@ void BCMainWindow::autoConnect()
|
||||
void BCMainWindow::onDriverStateChanged( BCDriver::DriverState state, const QString& message )
|
||||
{
|
||||
qDebug() << " --- on DriverStatusChanged: " << state << ":" << message;
|
||||
_statusbar->showMessage( message, 8000 );
|
||||
}
|
||||
|
||||
void BCMainWindow::onShowDevicePanel( BCDevice::ID deviceID )
|
||||
@@ -271,11 +318,14 @@ void BCMainWindow::onSyncDeviceView()
|
||||
|
||||
for( const BCValuePtr& value : currentList )
|
||||
{
|
||||
qDebug() << " --- begin sync of value: " << value->label;
|
||||
qDebug() << " --- begin sync of value: " << QThread::currentThreadId() << " : " << value->label;
|
||||
// wir setzen auf 'lesen'
|
||||
value->state.setFlag( BCValue::State::ReadMe );
|
||||
// statt '_transmitter.enqueueValueCommand( value )' entkoppeln
|
||||
// wir das eleganter über emit requestValueUpdate()
|
||||
|
||||
// statt '_transmitter.onEnqueueValue( value )' müssen wir hier
|
||||
// über emit requestValueUpdate() zur Thread sysnchronisation
|
||||
// entkoppeln,
|
||||
|
||||
emit requestValueUpdate( value);
|
||||
|
||||
}
|
||||
|
||||
175
bcmainwindow.h
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -60,10 +60,12 @@ public slots:
|
||||
void onConnectButtonToggled(bool active );
|
||||
void onDriverStateChanged( BCDriver::DriverState state, const QString& message="" );
|
||||
|
||||
// Slots für Rückmeldungen vom Runner
|
||||
// Slots für Rückmeldungen vom Transmitter
|
||||
void onValueUpdated( BCDevice::ID deviceID, int index, BCValue::State state, const QString& newValue="" );
|
||||
void onSyncDeviceView();
|
||||
|
||||
void onShowMessage( const QString& message, int timeOut=3000);
|
||||
|
||||
signals:
|
||||
|
||||
// Internes Signal, um Daten an den Worker Thread zu senden
|
||||
@@ -71,10 +73,13 @@ signals:
|
||||
|
||||
protected:
|
||||
|
||||
bool setApplicationStyleSheet( QAnyStringView path );
|
||||
void initMainWindow();
|
||||
void initStatusBar();
|
||||
void autoConnect();
|
||||
|
||||
//bool eventFilter(QObject *obj, QEvent *event) override;
|
||||
|
||||
BCXmlLoader _dataManager;
|
||||
|
||||
// Wir brauchen eine Verbindung zwischen den Views
|
||||
@@ -92,170 +97,4 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ThemeSwitchButton : public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit ThemeSwitchButton(QWidget *parent = nullptr)
|
||||
: QPushButton(parent), m_isDarkMode(true)
|
||||
{
|
||||
// 1. Visuelles Setup: Flach, keine Ränder, Hand-Cursor
|
||||
setFlat(true);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setFixedSize(24, 24); // Kleiner Footprint im StatusBar
|
||||
|
||||
// CSS: Transparent, damit es sich nahtlos in den StatusBar einfügt
|
||||
// Schriftgröße etwas erhöhen, damit die Emojis gut erkennbar sind
|
||||
setStyleSheet(R"(
|
||||
QPushButton {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
font-size: 11pt;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
|
||||
border-radius: 24px;
|
||||
}
|
||||
)");
|
||||
|
||||
// 2. Initialer Status (Startet im Dark Mode -> zeigt Mond)
|
||||
updateIcon();
|
||||
|
||||
// 3. Klick verbinden
|
||||
connect(this, &QPushButton::clicked, this, &ThemeSwitchButton::toggle);
|
||||
}
|
||||
|
||||
signals:
|
||||
void themeChanged(bool isDark);
|
||||
|
||||
private slots:
|
||||
void toggle() {
|
||||
m_isDarkMode = !m_isDarkMode;
|
||||
updateIcon();
|
||||
emit themeChanged(m_isDarkMode);
|
||||
}
|
||||
|
||||
private:
|
||||
void updateIcon() {
|
||||
// Logik:
|
||||
// Ist Dark Mode an? Zeige Mond (oder Sonne, je nach Geschmack).
|
||||
// Hier: Zeige das Symbol des AKTUELLEN Modus.
|
||||
setText(m_isDarkMode ? "🌙" : "☀️");
|
||||
setToolTip(m_isDarkMode ? "Switch to Light Mode" : "Switch to Dark Mode");
|
||||
}
|
||||
|
||||
bool m_isDarkMode;
|
||||
};
|
||||
|
||||
|
||||
class BCConnectionWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// Definition der 3 Zustände
|
||||
enum class State
|
||||
{
|
||||
Disconnected, // Grau: Offline / Standby
|
||||
Connected, // Grün: Alles OK
|
||||
Error // Rot: Fehler / Timeout / Abbruch
|
||||
};
|
||||
Q_ENUM(State) // Damit Qt das Enum kennt (optional, gut für Debugging)
|
||||
|
||||
explicit BCConnectionWidget(QWidget *parent = nullptr)
|
||||
: QWidget(parent)
|
||||
{
|
||||
QHBoxLayout *layout = new QHBoxLayout(this);
|
||||
layout->setContentsMargins(10, 2, 10, 2);
|
||||
layout->setSpacing(8);
|
||||
|
||||
// 1. Die LED
|
||||
m_led = new QLabel(this);
|
||||
m_led->setFixedSize(12, 12);
|
||||
|
||||
// 2. Der Text
|
||||
m_label = new QLabel(this);
|
||||
m_label->setStyleSheet("font-weight: 500;"); // Medium weight
|
||||
|
||||
layout->addWidget(m_led);
|
||||
layout->addWidget(m_label);
|
||||
|
||||
// Startzustand
|
||||
setState(State::Disconnected, "Offline");
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
// Hauptfunktion zum Setzen des Status
|
||||
// 'customMessage' ist optional. Wenn leer, wird ein Standardtext genommen.
|
||||
void setState(State state, const QString &customMessage = QString())
|
||||
{
|
||||
m_state = state;
|
||||
|
||||
// Standard-Texte, falls keine Nachricht übergeben wurde
|
||||
QString text = customMessage;
|
||||
if (text.isEmpty()) {
|
||||
switch (state) {
|
||||
case State::Connected: text = "Online"; break;
|
||||
case State::Disconnected: text = "Not Connected"; break;
|
||||
case State::Error: text = "Connection Error"; break;
|
||||
}
|
||||
}
|
||||
m_label->setText(text);
|
||||
|
||||
updateStyle();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void updateStyle()
|
||||
{
|
||||
QString ledStyle;
|
||||
QString labelColor;
|
||||
QString toolTipText;
|
||||
|
||||
switch (m_state) {
|
||||
case State::Connected:
|
||||
// FLUENT GREEN (Success)
|
||||
ledStyle = "background-color: #107C10; border: 1px solid #0E600E;#FF5F1F; #FF8C00;<- das isses #FF6700";
|
||||
labelColor = "#FFFFFF"; // Weiß (Hervorgehoben)
|
||||
toolTipText = "Verbindung erfolgreich hergestellt.";
|
||||
break;
|
||||
|
||||
case State::Error:
|
||||
// FLUENT RED (Critical)
|
||||
ledStyle = "background-color: #C42B1C; border: 1px solid #A80000;";
|
||||
labelColor = "#FF99A4"; // Ein helleres Rot für Text, damit es auf Dunkel lesbar ist
|
||||
toolTipText = "Kritischer Fehler bei der Verbindung!";
|
||||
break;
|
||||
|
||||
case State::Disconnected:
|
||||
default:
|
||||
// FLUENT GRAY (Neutral)
|
||||
// Wir machen es dunkelgrau mit hellem Rand -> "Ausgeschaltet"-Look
|
||||
ledStyle = "background-color: #3B3B3B; border: 1px solid #606060;";
|
||||
labelColor = "#9E9E9E"; // Ausgegrauter Text
|
||||
toolTipText = "System ist offline.";
|
||||
break;
|
||||
}
|
||||
|
||||
// Styles anwenden (immer rund machen)
|
||||
m_led->setStyleSheet(ledStyle + "border-radius: 6px;");
|
||||
|
||||
// Textfarbe setzen
|
||||
m_label->setStyleSheet(QString("color: %1; font-weight: %2;")
|
||||
.arg(labelColor)
|
||||
.arg(m_state == State::Connected ? "bold" : "normal"));
|
||||
|
||||
setToolTip(toolTipText);
|
||||
}
|
||||
|
||||
QLabel *m_led;
|
||||
QLabel *m_label;
|
||||
State m_state;
|
||||
};
|
||||
|
||||
#endif // BCMAINWINDOW_H
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
<property name="windowTitle">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<widget class="QWidget" name="_centralwidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
@@ -169,13 +172,6 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="fitzeButton">
|
||||
<property name="text">
|
||||
<string>Fitze</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -318,7 +314,11 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="_statusbar"/>
|
||||
<widget class="QStatusBar" name="_statusbar">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">background-color: #DADADA</string>
|
||||
</property>
|
||||
</widget>
|
||||
<action name="_pimpAction">
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -35,44 +35,101 @@
|
||||
|
||||
#include <bctransmitter.h>
|
||||
|
||||
/**
|
||||
* @brief Kosntruktion. Aktiviert erstmal den Dummy-Driver.
|
||||
*/
|
||||
|
||||
BCTransmitter::BCTransmitter(QObject *parent)
|
||||
: QObject(parent), _isBusy(false)
|
||||
{
|
||||
//_canDriver = new BCDriverTinyCan{this};
|
||||
_canDriver = new BCDriverDummy{this};
|
||||
// forward driver state
|
||||
connect( _canDriver, &BCDriver::driverStateChanged, this, &BCTransmitter::driverStateChanged );
|
||||
_canDriver = &_dummyDriver;
|
||||
}
|
||||
|
||||
|
||||
void BCTransmitter::onToggleConnectionState( bool connect )
|
||||
{
|
||||
if( connect )
|
||||
{
|
||||
if( _canDriver->getDriverState() != BCDriver::DriverState::DeviceReady )
|
||||
_canDriver->onStartDriver();
|
||||
/**
|
||||
* @brief Steuert die Verbindung mit dem 'echten' CAN-Bus Treiber.
|
||||
* @param connect true: Vesuche den CAN-Bus Treiber zu laden und zu verbinden
|
||||
* false: Disconnect & Cleanup
|
||||
*/
|
||||
|
||||
// __fix!
|
||||
TransmitResult hwVersion = _canDriver->readRawByte( (uint32_t)BCDevice::ID::Console, (uint8_t)BC::ID::Cons_Rev_Hw);
|
||||
if(!hwVersion)
|
||||
void BCTransmitter::onToggleDriverConnection( bool connect )
|
||||
{
|
||||
qDebug() << " --- onToggleDriverConnection: " << connect;
|
||||
// FIX! Ende der current op abwarten!
|
||||
BCDriver::DriverState state = connect ? BCDriver::DriverState::DeviceReady : BCDriver::DriverState::NotPresent;
|
||||
const QString& message = connect ? "Trying to connect" : " FAILED";
|
||||
emit driverStateChanged(state, message);
|
||||
return;
|
||||
|
||||
// Hier sind wir noch in GUI Thread
|
||||
QMutexLocker locker(&_mutex);
|
||||
// weitere operation stoppen
|
||||
_isBusy = true;
|
||||
connect ? connectCanDriver() : disconnectCanDriver();
|
||||
_isBusy = false;
|
||||
}
|
||||
|
||||
|
||||
void BCTransmitter::onStartNativeDriver()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BCTransmitter::connectCanDriver()
|
||||
{
|
||||
// hier gehts nur um den echten Treiber
|
||||
|
||||
// Treiber laden und/oder starten:
|
||||
BCDriver::DriverStateResult result; //(defaults to 'NotPresent')
|
||||
if( _tinyCanDriver.getDriverState() != BCDriver::DriverState::DeviceReady )
|
||||
result = _tinyCanDriver.loadAndStartDriver();
|
||||
|
||||
QString message("FitzeFatze!");
|
||||
// hat geklappt
|
||||
if( _tinyCanDriver.getDriverState() >= BCDriver::DriverState::Opened )
|
||||
{
|
||||
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
|
||||
uint8_t hwRev = static_cast<uint8_t> (BC::ID::Cons_Rev_Hw);
|
||||
|
||||
TransmitResult hwVersion = _tinyCanDriver.readRawByte( console, hwRev);
|
||||
if( hwVersion.has_value() )
|
||||
{
|
||||
qDebug() << "Console not responding";
|
||||
message = " ---- HAIL to the king!";
|
||||
qDebug() << message;
|
||||
// swap driver
|
||||
_canDriver = &_tinyCanDriver;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
qDebug() << "Console not responding";
|
||||
}
|
||||
|
||||
qDebug() << " ---HAIL to the kings: " << hwVersion.value();
|
||||
}
|
||||
else
|
||||
{
|
||||
message = result.error();
|
||||
}
|
||||
emit driverStateChanged( _tinyCanDriver.getDriverState(), message );
|
||||
}
|
||||
|
||||
void BCTransmitter::disconnectCanDriver()
|
||||
{
|
||||
_tinyCanDriver.resetDriver();
|
||||
_canDriver = &_dummyDriver;
|
||||
emit driverStateChanged( _tinyCanDriver.getDriverState(), "Disconnected" );
|
||||
}
|
||||
|
||||
|
||||
void BCTransmitter::enqueueValue( BCValuePtrConst value)
|
||||
void BCTransmitter::onEnqueueValue( BCValuePtrConst value)
|
||||
{
|
||||
|
||||
// wir stellen hier auf die arte Tour sicher, das onEnqueueValue
|
||||
// nicht aus dem Parent-Thread direkt sondern über die EventQueue aufgerufen wurde.
|
||||
|
||||
Q_ASSERT(QThread::currentThread() == this->thread());
|
||||
|
||||
// Hier sind wir noch in GUI Thread
|
||||
QMutexLocker locker(&_mutex);
|
||||
//QMutexLocker locker(&_mutex);
|
||||
_valueQueue.enqueue( value );
|
||||
|
||||
// wir wollen nicht den ganzen Value verschicken, erstrecht
|
||||
@@ -81,23 +138,17 @@ void BCTransmitter::enqueueValue( BCValuePtrConst value)
|
||||
|
||||
// Trigger processing im Event-Loop des Worker Threads
|
||||
// invokeMethod mit QueuedConnection entkoppelt den Aufruf,
|
||||
// damit enqueueValue sofort zurückkehrt (non-blocking für den Aufrufer).
|
||||
// damit onEnqueueValue sofort zurückkehrt (non-blocking für den Aufrufer).
|
||||
|
||||
QMetaObject::invokeMethod(this, "processValue", Qt::QueuedConnection);
|
||||
|
||||
/*
|
||||
QMetaObject::invokeMethod(this, [this]()
|
||||
{
|
||||
processValue();
|
||||
}, Qt::QueuedConnection );
|
||||
*/
|
||||
//QMetaObject::invokeMethod(this, "onProcessValue", Qt::QueuedConnection);
|
||||
onProcessValue();
|
||||
}
|
||||
|
||||
void BCTransmitter::processValue()
|
||||
void BCTransmitter::onProcessValue()
|
||||
{
|
||||
|
||||
if (_isBusy)
|
||||
return;
|
||||
//if (_isBusy)
|
||||
// return;
|
||||
|
||||
_isBusy = true;
|
||||
|
||||
@@ -105,7 +156,7 @@ void BCTransmitter::processValue()
|
||||
{
|
||||
BCValuePtrConst valuePtr{};
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
//QMutexLocker locker(&_mutex);
|
||||
if (_valueQueue.isEmpty())
|
||||
{
|
||||
_isBusy = false;
|
||||
@@ -117,6 +168,8 @@ void BCTransmitter::processValue()
|
||||
// Kosmetik
|
||||
const BCValue& value = *(valuePtr.get());
|
||||
|
||||
qDebug() << "------- DE.-.QUEUE: " << QThread::currentThreadId() << ": " << value.label;
|
||||
|
||||
// Value ist 'under construction'
|
||||
//emit valueUpdated( value.deviceID, value.indexRow, BCValue::State::Locked );
|
||||
|
||||
@@ -153,17 +206,16 @@ void BCTransmitter::processValue()
|
||||
emit valueUpdated( value.deviceID, value.indexRow, newState, newVisibleValue );
|
||||
|
||||
// __fix
|
||||
bc::processEventsFor(50);
|
||||
//bc::processEventsFor(150);
|
||||
bc::delay_millis(150);
|
||||
|
||||
//emit valueStateChanged(cmd.id, true);
|
||||
//emit valueStateChanged(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t registerID )
|
||||
{
|
||||
qDebug() << " --- YES: Read ByteValue: " << registerID;
|
||||
//qDebug() << " --- YES: Read ByteValue: " << registerID;
|
||||
// Wir lesen nur ein Byte und gut.
|
||||
return _canDriver->readRawByte( deviceID, registerID );
|
||||
}
|
||||
@@ -171,7 +223,7 @@ TransmitResult BCTransmitter::readByteValue( uint32_t deviceID, uint8_t register
|
||||
|
||||
TransmitResult BCTransmitter::readWordValue( uint32_t deviceID, uint8_t registerID )
|
||||
{
|
||||
qDebug() << " --- YES: Read WordValue: " << registerID;
|
||||
//qDebug() << " --- YES: Read WordValue: " << registerID;
|
||||
|
||||
uint32_t result{};
|
||||
// hi byte Leseversuch.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -60,14 +60,12 @@ public:
|
||||
|
||||
explicit BCTransmitter(QObject *parent = nullptr);
|
||||
|
||||
//TransmitResult readByte( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
//TransmitResult writeByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
public slots:
|
||||
|
||||
void onToggleConnectionState( bool connect );
|
||||
void enqueueValue(BCValuePtrConst value );
|
||||
void processValue();
|
||||
void onToggleDriverConnection( bool connect );
|
||||
void onEnqueueValue(BCValuePtrConst value );
|
||||
void onProcessValue();
|
||||
void onStartNativeDriver();
|
||||
|
||||
signals:
|
||||
|
||||
@@ -76,11 +74,11 @@ signals:
|
||||
|
||||
private:
|
||||
|
||||
void connectCanDriver();
|
||||
void disconnectCanDriver();
|
||||
|
||||
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
|
||||
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
|
||||
//TransmitResult writeByteValue( uint32_t deviceID, uint8_t registerID );
|
||||
//TransmitResult writeWordValue( uint32_t deviceID, uint8_t registerID );
|
||||
|
||||
|
||||
using BCDataQueue = QQueue<BCValuePtrConst>;
|
||||
|
||||
@@ -88,8 +86,10 @@ private:
|
||||
QMutex _mutex;
|
||||
std::atomic<bool> _isBusy{ false };
|
||||
|
||||
// __fix! set two
|
||||
BCDriver* _canDriver{};
|
||||
// __fix!
|
||||
BCDriver* _canDriver{};
|
||||
BCDriverTinyCan _tinyCanDriver{};
|
||||
BCDriverDummy _dummyDriver{};
|
||||
|
||||
};
|
||||
|
||||
|
||||
47
bcvalue.cpp
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -44,42 +44,6 @@ BCValue::BCValue( BCDevice::ID deviceID_, BC::ID registerID_)
|
||||
visibleValue = "--";
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
mhs_can_drv.c
|
||||
© 2011 - 2023 by MHS-Elektronik GmbH & Co. KG, Germany
|
||||
Klaus Demlehner, klaus@mhs-elektronik.de
|
||||
@see www.mhs-elektronik.de
|
||||
|
||||
Based on Bionx data type descriptions from:
|
||||
|
||||
BigXionFlasher USB V 0.2.4 rev. 97
|
||||
© 2011-2013 by Thomas Koenig <info@bigxionflasher.org>
|
||||
@see www.bigxionflasher.org
|
||||
|
||||
Bionx Bike Info
|
||||
© 2018 Thorsten Schmidt (tschmidt@ts-soft.de)
|
||||
@see www.ts-soft.de
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
@see https://github.com/bikemike/bionx-bikeinfo
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
QString BCValue::formatValue( uint32_t value ) const
|
||||
{
|
||||
if( factor == 1 )
|
||||
@@ -89,5 +53,14 @@ QString BCValue::formatValue( uint32_t value ) const
|
||||
return QString::number(result, 'f', 2);
|
||||
}
|
||||
|
||||
void BCValue::dumpValue() const
|
||||
{
|
||||
|
||||
qDebug() << "DeviceID: " << deviceID << " Register: " << registerID << " state:" " << state << " << " label: " << label;
|
||||
qDebug() << "visibleValue: " << visibleValue << " min: " << min << " max: " << max << " factor: " << factor << " ValueType: " << (char)valueType << " ";
|
||||
qDebug() << "indexRow: " << indexRow << " isWord: " << isWord;
|
||||
qDebug();
|
||||
|
||||
}
|
||||
|
||||
/// ----
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -56,8 +56,6 @@
|
||||
-
|
||||
*/
|
||||
|
||||
|
||||
|
||||
using OptDouble = std::optional<double>;
|
||||
|
||||
// Enthält den gelesenen Wert oder einen Fehlerstring
|
||||
@@ -65,8 +63,6 @@ using TransmitResult = std::expected<uint32_t,QString>;
|
||||
// Funktionsobject, um Werte aus der Transmitterschicht zu holden
|
||||
//using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID )>;
|
||||
|
||||
|
||||
|
||||
class BCValue
|
||||
{
|
||||
|
||||
@@ -98,6 +94,7 @@ public:
|
||||
BCValue( BCDevice::ID deviceID_, BC::ID registerID_ );
|
||||
|
||||
QString formatValue( uint32_t value ) const;
|
||||
void dumpValue() const;
|
||||
|
||||
mutable States state{BCValue::State::ReadOnly};
|
||||
BCDevice::ID deviceID{BCDevice::ID::Invalid};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -82,17 +82,26 @@ void BCValueModel::takeValueList(BCValueList& newValueList)
|
||||
*/
|
||||
|
||||
void BCValueModel::onValueUpdated( int row, BCValue::State state, const QString& newVisisbleValue )
|
||||
{
|
||||
qDebug() << " BCValueModel::onValueUpdated update: " << newVisisbleValue;
|
||||
{
|
||||
if( row > -1 && row < _valueList.size() )
|
||||
{
|
||||
BCValuePtr value = _valueList[row];
|
||||
BCValue& value = *(_valueList[row].get());
|
||||
QModelIndex idx = index(row,1);
|
||||
value->state = state;
|
||||
if( !newVisisbleValue.isEmpty() && newVisisbleValue != value->visibleValue )
|
||||
|
||||
//qDebug();
|
||||
//qDebug() << " --- OLD:"<< newVisisbleValue;
|
||||
//value.dumpValue();
|
||||
|
||||
value.state = state;
|
||||
|
||||
if( !newVisisbleValue.isEmpty() && newVisisbleValue != value.visibleValue )
|
||||
{
|
||||
value->visibleValue = newVisisbleValue;
|
||||
value.visibleValue = newVisisbleValue;
|
||||
}
|
||||
|
||||
//qDebug() << " --- NEW: " << newVisisbleValue;
|
||||
//value.dumpValue();
|
||||
|
||||
// wir schicken auf jeden fall einen update request
|
||||
emit dataChanged(idx, idx, {Qt::DisplayRole, Qt::EditRole});
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -224,14 +224,13 @@ std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const B
|
||||
BCValuePtr newValuePtr = std::make_shared<BCValue>( deviceID, static_cast<BC::ID>(IDVal) );
|
||||
BCValue& newValue = *newValuePtr.get();
|
||||
|
||||
|
||||
setIfExists( params.Factor, newValue.factor );
|
||||
setIfExists( params.Min, newValue.min );
|
||||
setIfExists( params.Max, newValue.max );
|
||||
setIfExists( params.IsWord, newValue.isWord );
|
||||
|
||||
newValue.label = params.Label;
|
||||
newValue.label = params.UnitLabel;
|
||||
newValue.label = params.Label;
|
||||
newValue.unitLabel = params.UnitLabel;
|
||||
|
||||
if( s_valueTypes.contains( params.ValueType ) )
|
||||
newValue.valueType = s_valueTypes[params.ValueType];
|
||||
@@ -245,9 +244,10 @@ std::optional<BCValuePtr> BCXmlLoader::makeValue( BCDevice::ID deviceID, const B
|
||||
QString Max;
|
||||
QString IsWord;
|
||||
QString ValueType;
|
||||
*/
|
||||
*/
|
||||
|
||||
qDebug() << " --- created: " << params.Label;
|
||||
newValue.dumpValue();
|
||||
|
||||
return std::optional<BCValuePtr>( newValuePtr );
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<qresource prefix="/">
|
||||
<file alias="bikeinfo.xml">resources/bikeinfo.xml</file>
|
||||
<file alias="bionxcontrol.qss">resources/bionxcontrol.qss</file>
|
||||
<file alias="claude_dark_mode.qss">resources/claude_dark_mode.qss</file>
|
||||
<file alias="claude_light_mode.qss">resources/claude_light_mode.qss</file>
|
||||
<file alias="claude_dark_mode.qss">resources/claude_dark_mode.qss</file>
|
||||
<file alias="claude_light_mode.qss">resources/claude_light_mode.qss</file>
|
||||
<file alias="bionx_akku.png">resources/bionx_akku.png</file>
|
||||
<file alias="bionx_console.png">resources/bionx_console.png</file>
|
||||
<file alias="bionx_motor.png">resources/bionx_motor.png</file>
|
||||
@@ -13,6 +13,9 @@
|
||||
<file alias="splash.png">resources/splash.png</file>
|
||||
<file alias="connect.png">resources/connect.png</file>
|
||||
<file alias="connected.png">resources/connected.png</file>
|
||||
<file alias="disconnected.png">resources/disconnected.png</file>
|
||||
<file alias="disconnected.png">resources/disconnected.png</file>
|
||||
<file>resources/connect_white.svg</file>
|
||||
<file>resources/sync_green.svg</file>
|
||||
<file>resources/sync_yellow.svg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
#ifndef __CAN_DRV_H__
|
||||
#define __CAN_DRV_H__
|
||||
|
||||
#include "can_drv_config.h"
|
||||
#include "can_types.h"
|
||||
|
||||
#ifdef __WIN32__
|
||||
// ****** Windows
|
||||
#include <windows.h>
|
||||
#define DRV_CALLBACK_TYPE __stdcall
|
||||
#else
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#define DRV_CALLBACK_TYPE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* Define Makros */
|
||||
/***************************************************************/
|
||||
|
||||
// CAN <20>bertragungsgeschwindigkeit
|
||||
#define CAN_10K_BIT 10 // 10 kBit/s
|
||||
#define CAN_20K_BIT 20 // 20 kBit/s
|
||||
#define CAN_50K_BIT 50 // 50 kBit/s
|
||||
#define CAN_100K_BIT 100 // 100 kBit/s
|
||||
#define CAN_125K_BIT 125 // 125 kBit/s
|
||||
#define CAN_250K_BIT 250 // 250 kBit/s
|
||||
#define CAN_500K_BIT 500 // 500 kBit/s
|
||||
#define CAN_800K_BIT 800 // 800 kBit/s
|
||||
#define CAN_1M_BIT 1000 // 1 MBit/s
|
||||
#define CAN_1M5_BIT 1500 // 1,5 MBit/s
|
||||
#define CAN_2M_BIT 2000 // 2 MBit/s
|
||||
#define CAN_3M_BIT 3000 // 3 MBit/s
|
||||
#define CAN_4M_BIT 4000 // 4 MBit/s
|
||||
|
||||
// Time Stamp Mode
|
||||
#define TIME_STAMP_OFF 0 // keine Time-Stamps
|
||||
#define TIME_STAMP_SOFT 1 // Software Time-Stamps
|
||||
#define TIME_STAMP_HW_UNIX 2 // Hardware Time-Stamps, UNIX-Format
|
||||
#define TIME_STAMP_HW 3 // Hardware Time-Stamps
|
||||
#define TIME_STAMP_HW_SW_UNIX 4 // Hardware Time-Stamps verwenden wenn verf<72>gbar,
|
||||
// ansonsten Software Time-Stamps
|
||||
// Ab Treiber Version 4.08!
|
||||
|
||||
// CAN Bus Mode
|
||||
#define OP_CAN_NO_CHANGE 0 // Aktuellen Zustand nicht <20>ndern
|
||||
#define OP_CAN_START 1 // Startet den CAN-Bus
|
||||
#define OP_CAN_STOP 2 // Stopt den CAN-Bus
|
||||
#define OP_CAN_RESET 3 // Reset CAN Controller (BusOff l<>schen)
|
||||
#define OP_CAN_START_LOM 4 // Startet den CAN-Bus im Silent Mode (Listen Only Mode)
|
||||
#define OP_CAN_START_NO_RETRANS 5 // Startet den CAN-Bus im Automatic Retransmission disable Mode
|
||||
#define OP_CAN_ECU_FLASH_MODE 6 // Start im ECU Flash Mode
|
||||
|
||||
#define CAN_CMD_NONE 0x0000
|
||||
#define CAN_CMD_RXD_OVERRUN_CLEAR 0x0001
|
||||
#define CAN_CMD_RXD_FIFOS_CLEAR 0x0002
|
||||
#define CAN_CMD_TXD_OVERRUN_CLEAR 0x0004
|
||||
#define CAN_CMD_TXD_FIFOS_CLEAR 0x0008
|
||||
#define CAN_CMD_HW_FILTER_CLEAR 0x0010
|
||||
#define CAN_CMD_SW_FILTER_CLEAR 0x0020
|
||||
#define CAN_CMD_TXD_PUFFERS_CLEAR 0x0040
|
||||
// <*> neu
|
||||
#define CAN_CMD_START_DATA_TRANSFER 0x1000
|
||||
#define CAN_CMD_CANCEL_DATA_TRANSFER 0x2000
|
||||
#define CAN_CMD_START_TEST 0xE000
|
||||
#define CAN_CMD_STOP_TEST 0xF000
|
||||
|
||||
#define CAN_CMD_FIFOS_CLEAR 0x000F
|
||||
#define CAN_CMD_ALL_CLEAR 0x0FFF
|
||||
|
||||
|
||||
// DrvStatus
|
||||
#define DRV_NOT_LOAD 0 // Die Treiber DLL wurde noch nicht geladen
|
||||
#define DRV_STATUS_NOT_INIT 1 // Treiber noch nicht Initialisiert (Funktion "CanInitDrv" noch nicht aufgerufen)
|
||||
#define DRV_STATUS_INIT 2 // Treiber erfolgrich Initialisiert
|
||||
#define DRV_STATUS_PORT_NOT_OPEN 3 // Die Schnittstelle wurde nicht ge<67>ffnet
|
||||
#define DRV_STATUS_PORT_OPEN 4 // Die Schnittstelle wurde ge<67>ffnet
|
||||
#define DRV_STATUS_DEVICE_FOUND 5 // Verbindung zur Hardware wurde Hergestellt
|
||||
#define DRV_STATUS_CAN_OPEN 6 // Device wurde ge<67>ffnet und erfolgreich Initialisiert
|
||||
#define DRV_STATUS_CAN_RUN_TX 7 // CAN Bus RUN nur Transmitter (wird nicht verwendet !)
|
||||
#define DRV_STATUS_CAN_RUN 8 // CAN Bus RUN
|
||||
|
||||
// CanStatus
|
||||
#define CAN_STATUS_OK 0 // CAN-Controller: Ok
|
||||
#define CAN_STATUS_ERROR 1 // CAN-Controller: CAN Error
|
||||
#define CAN_STATUS_WARNING 2 // CAN-Controller: Error warning
|
||||
#define CAN_STATUS_PASSIV 3 // CAN-Controller: Error passiv
|
||||
#define CAN_STATUS_BUS_OFF 4 // CAN-Controller: Bus Off
|
||||
#define CAN_STATUS_UNBEKANNT 5 // CAN-Controller: Status Unbekannt
|
||||
|
||||
// Neu f<>r Low-Speed CAN, TJA1055 Fehler
|
||||
#define BUS_FAILURE 0x10
|
||||
|
||||
// Fifo Status
|
||||
#define FIFO_OK 0 // Fifo-Status: Ok
|
||||
#define FIFO_HW_OVERRUN 1 // Fifo-Status: Hardware Fifo <20>berlauf
|
||||
#define FIFO_SW_OVERRUN 2 // Fifo-Status: Software Fifo <20>berlauf
|
||||
#define FIFO_HW_SW_OVERRUN 3 // Fifo-Status: Hardware & Software Fifo <20>berlauf
|
||||
#define FIFO_STATUS_UNBEKANNT 4 // Fifo-Status: Unbekannt
|
||||
|
||||
// Makros f<>r SetEvent
|
||||
#define EVENT_ENABLE_PNP_CHANGE 0x0001
|
||||
#define EVENT_ENABLE_STATUS_CHANGE 0x0002
|
||||
#define EVENT_ENABLE_RX_FILTER_MESSAGES 0x0004
|
||||
#define EVENT_ENABLE_RX_MESSAGES 0x0008
|
||||
#define EVENT_ENABLE_ALL 0x00FF
|
||||
|
||||
#define EVENT_DISABLE_PNP_CHANGE 0x0100
|
||||
#define EVENT_DISABLE_STATUS_CHANGE 0x0200
|
||||
#define EVENT_DISABLE_RX_FILTER_MESSAGES 0x0400
|
||||
#define EVENT_DISABLE_RX_MESSAGES 0x0800
|
||||
#define EVENT_DISABLE_ALL 0xFF00
|
||||
|
||||
// <*> Neu
|
||||
#define TCAN_LOG_FLAG_MESSAGE 0x00000001
|
||||
#define TCAN_LOG_FLAG_STATUS 0x00000002
|
||||
#define TCAN_LOG_FLAG_RX_MSG 0x00000004
|
||||
#define TCAN_LOG_FLAG_TX_MSG 0x00000008
|
||||
#define TCAN_LOG_FLAG_API_CALL 0x00000010
|
||||
#define TCAN_LOG_API_CALL_RX 0x00000020
|
||||
#define TCAN_LOG_API_CALL_TX 0x00000040
|
||||
#define TCAN_LOG_API_CALL_STATUS 0x00000080
|
||||
#define TCAN_LOG_FLAG_ERROR 0x00000100
|
||||
#define TCAN_LOG_FLAG_WARN 0x00000200
|
||||
#define TCAN_LOG_FLAG_ERR_MSG 0x00000400
|
||||
#define TCAN_LOG_FLAG_OV_MSG 0x00000800
|
||||
#define TCAN_LOG_USB 0x00008000 // <*> neu
|
||||
#define TCAN_LOG_FLAG_DEBUG 0x08000000
|
||||
#define TCAN_LOG_FLAG_WITH_TIME 0x40000000
|
||||
#define TCAN_LOG_FLAG_DISABLE_SYNC 0x80000000
|
||||
|
||||
/***************************************************************/
|
||||
/* Typen */
|
||||
/***************************************************************/
|
||||
|
||||
/******************************************/
|
||||
/* Device Status */
|
||||
/******************************************/
|
||||
#pragma pack(push, 1)
|
||||
struct TDeviceStatus
|
||||
{
|
||||
int32_t DrvStatus; // Treiber Status (Device close / Device open / CAN Bus RUN)
|
||||
unsigned char CanStatus; // Status des CAN Controllers (Ok / ... / Error passiv / Bus off)
|
||||
unsigned char FifoStatus; // Fifo Status (Ok / ... / Hard. u. Soft. FIFO <20>berlauf)
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#ifdef CAN_API_TRUE_FUNC
|
||||
|
||||
int32_t CanInitDriver(char *options);
|
||||
void CanDownDriver(void);
|
||||
int32_t CanSetOptions(char *options);
|
||||
int32_t CanDeviceOpen(uint32_t index, char *parameter);
|
||||
int32_t CanDeviceClose(uint32_t index);
|
||||
|
||||
int32_t CanSetMode(uint32_t index, unsigned char can_op_mode, uint16_t can_command);
|
||||
|
||||
int32_t CanTransmit(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
void CanTransmitClear(uint32_t index);
|
||||
uint32_t CanTransmitGetCount(uint32_t index);
|
||||
int32_t CanTransmitSet(uint32_t index, uint16_t cmd, uint32_t time);
|
||||
int32_t CanReceive(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
void CanReceiveClear(uint32_t index);
|
||||
uint32_t CanReceiveGetCount(uint32_t index);
|
||||
|
||||
int32_t CanSetSpeed(uint32_t index, uint16_t speed);
|
||||
int32_t CanSetSpeedUser(uint32_t index, uint32_t value);
|
||||
char *CanDrvInfo(void);
|
||||
char *CanDrvHwInfo(uint32_t index);
|
||||
int32_t CanSetFilter(uint32_t index, struct TMsgFilter *msg_filter);
|
||||
int32_t CanGetDeviceStatus(uint32_t index, struct TDeviceStatus *status);
|
||||
void CanSetPnPEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index, int32_t status));
|
||||
void CanSetStatusEventCallback(void (DRV_CALLBACK_TYPE *event)
|
||||
(uint32_t index, struct TDeviceStatus *device_status));
|
||||
void CanSetRxEventCallback(void (DRV_CALLBACK_TYPE *event)(uint32_t index,
|
||||
struct TCanMsg *msg, int32_t count));
|
||||
|
||||
void CanSetEvents(uint16_t events);
|
||||
uint32_t CanEventStatus(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if !(defined(CAN_API_TRUE_FUNC)) || defined(CAN_DRV_INCLUDE)
|
||||
/***************************************************************/
|
||||
/* Funktionstypen */
|
||||
/***************************************************************/
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanInitDriver)(char *options);
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanDownDriver)(void);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanSetOptions)(char *options);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanDeviceOpen)(uint32_t index, char *parameter);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanDeviceClose)(uint32_t index);
|
||||
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanSetMode)(uint32_t index, unsigned char can_op_mode,
|
||||
uint16_t can_command);
|
||||
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanTransmit)(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanTransmitClear)(uint32_t index);
|
||||
typedef uint32_t (DRV_CALLBACK_TYPE *TCanTransmitGetCount)(uint32_t index);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanTransmitSet)(uint32_t index, uint16_t cmd, uint32_t time);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanReceive)(uint32_t index, struct TCanMsg *msg, int32_t count);
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanReceiveClear)(uint32_t index);
|
||||
typedef uint32_t (DRV_CALLBACK_TYPE *TCanReceiveGetCount)(uint32_t index);
|
||||
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanSetSpeed)(uint32_t index, uint16_t speed);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanSetSpeedUser)(uint32_t index, uint32_t value);
|
||||
typedef char * (DRV_CALLBACK_TYPE *TCanDrvInfo)(void);
|
||||
typedef char * (DRV_CALLBACK_TYPE *TCanDrvHwInfo)(uint32_t index);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanSetFilter)(uint32_t index, struct TMsgFilter *msg_filter);
|
||||
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanGetDeviceStatus)(uint32_t index, struct TDeviceStatus *status);
|
||||
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanSetPnPEventCallback)(void (DRV_CALLBACK_TYPE *event)
|
||||
(uint32_t index, int32_t status));
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanSetStatusEventCallback)(void (DRV_CALLBACK_TYPE *event)
|
||||
(uint32_t index, struct TDeviceStatus *device_status));
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanSetRxEventCallback)(void (DRV_CALLBACK_TYPE *event)
|
||||
(uint32_t index, struct TCanMsg *msg, int32_t count));
|
||||
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanSetEvents)(uint16_t events);
|
||||
typedef uint32_t (DRV_CALLBACK_TYPE *TCanEventStatus)(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef CAN_API_TRUE_FUNC
|
||||
/***************************************************************/
|
||||
/* Tiny-CAN API Funktionen */
|
||||
/***************************************************************/
|
||||
|
||||
extern TCanInitDriver CanInitDriver;
|
||||
extern TCanDownDriver CanDownDriver;
|
||||
extern TCanSetOptions CanSetOptions;
|
||||
extern TCanDeviceOpen CanDeviceOpen;
|
||||
extern TCanDeviceClose CanDeviceClose;
|
||||
|
||||
extern TCanSetMode CanSetMode;
|
||||
|
||||
extern TCanTransmit CanTransmit;
|
||||
extern TCanTransmitClear CanTransmitClear;
|
||||
extern TCanTransmitGetCount CanTransmitGetCount;
|
||||
extern TCanTransmitSet CanTransmitSet;
|
||||
extern TCanReceive CanReceive;
|
||||
extern TCanReceiveClear CanReceiveClear;
|
||||
extern TCanReceiveGetCount CanReceiveGetCount;
|
||||
|
||||
extern TCanSetSpeed CanSetSpeed;
|
||||
extern TCanSetSpeedUser CanSetSpeedUser;
|
||||
|
||||
extern TCanDrvInfo CanDrvInfo;
|
||||
extern TCanDrvHwInfo CanDrvHwInfo;
|
||||
extern TCanSetFilter CanSetFilter;
|
||||
|
||||
extern TCanGetDeviceStatus CanGetDeviceStatus;
|
||||
|
||||
extern TCanSetPnPEventCallback CanSetPnPEventCallback;
|
||||
extern TCanSetStatusEventCallback CanSetStatusEventCallback;
|
||||
extern TCanSetRxEventCallback CanSetRxEventCallback;
|
||||
|
||||
extern TCanSetEvents CanSetEvents;
|
||||
extern TCanEventStatus CanEventStatus;
|
||||
|
||||
#endif
|
||||
|
||||
/***************************************************************/
|
||||
/* Funktionen Treiber laden/entladen */
|
||||
/***************************************************************/
|
||||
int32_t LoadDriver(const char *file_name);
|
||||
void UnloadDriver(void);
|
||||
|
||||
#include "can_drv_ex.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef __CAN_DRV_CONFIG_H__
|
||||
#define __CAN_DRV_CONFIG_H__
|
||||
|
||||
#ifndef STRICT_CAN_FD_SUPPORT
|
||||
//#define STRICT_CAN_FD_SUPPORT
|
||||
#endif
|
||||
|
||||
#ifndef CAN_API_TRUE_FUNC
|
||||
#define CAN_API_TRUE_FUNC
|
||||
#endif
|
||||
|
||||
#ifndef DRV_REF_LOCKING
|
||||
#define DRV_REF_LOCKING
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,420 +0,0 @@
|
||||
#ifndef __CAN_DRV_EX_H__
|
||||
#define __CAN_DRV_EX_H__
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ERR_NO_CAN_DRIVER_LOAD -1000000
|
||||
|
||||
|
||||
#define DEV_LIST_SHOW_TCAN_ONLY 0x01
|
||||
#define DEV_LIST_SHOW_UNCONNECT 0x02
|
||||
|
||||
/***************************************************************/
|
||||
/* Define Makros */
|
||||
/***************************************************************/
|
||||
#define CAN_FEATURE_LOM 0x0001 // Silent Mode (LOM = Listen only Mode)
|
||||
#define CAN_FEATURE_ARD 0x0002 // Automatic Retransmission disable
|
||||
#define CAN_FEATURE_TX_ACK 0x0004 // TX ACK (Gesendete Nachrichten best<73>tigen)
|
||||
#define CAN_FEATURE_ERROR_MSGS 0x0008 // Error Messages Support
|
||||
#define CAN_FEATURE_FD_HARDWARE 0x0010 // CAN-FD Hardware
|
||||
#define CAN_FEATURE_FIFO_OV_MODE 0x0020 // FIFO OV Mode (Auto Clear, OV CAN Messages)
|
||||
#define CAN_FEATURE_ECU_FLASH 0x0040 // Hardware beschleunigung f<>r ISO-TP ECU-Flash programmierung
|
||||
#define CAN_FEATURE_CAN_TEST 0x4000 // Tiny-CAN Tester Firmware
|
||||
#define CAN_FEATURE_HW_TIMESTAMP 0x8000 // Hardware Time Stamp
|
||||
|
||||
// (V)alue (T)ype
|
||||
#define VT_BYTE 0x01
|
||||
#define VT_UBYTE 0x02
|
||||
#define VT_WORD 0x03
|
||||
#define VT_UWORD 0x04
|
||||
#define VT_LONG 0x05
|
||||
#define VT_ULONG 0x06
|
||||
|
||||
#define VT_BYTE_ARRAY 0x07
|
||||
#define VT_UBYTE_ARRAY 0x08
|
||||
#define VT_WORD_ARRAY 0x09
|
||||
#define VT_UWORD_ARRAY 0x0A
|
||||
#define VT_LONG_ARRAY 0x0B
|
||||
#define VT_ULONG_ARRAY 0x0C
|
||||
|
||||
#define VT_BYTE_RANGE_ARRAY 0x0D
|
||||
#define VT_UBYTE_RANGE_ARRAY 0x0E
|
||||
#define VT_WORD_RANGE_ARRAY 0x0F
|
||||
#define VT_UWORD_RANGE_ARRAY 0x10
|
||||
#define VT_LONG_RANGE_ARRAY 0x11
|
||||
#define VT_ULONG_RANGE_ARRAY 0x12
|
||||
|
||||
#define VT_HBYTE 0x40
|
||||
#define VT_HWORD 0x41
|
||||
#define VT_HLONG 0x42
|
||||
|
||||
#define VT_STREAM 0x80
|
||||
#define VT_STRING 0x81
|
||||
#define VT_POINTER 0x82
|
||||
#define VT_REVISION 0x83
|
||||
#define VT_DATE 0x84
|
||||
|
||||
// MHS (EV)ent (S)ource
|
||||
#define MHS_EVS_STATUS 1
|
||||
#define MHS_EVS_PNP 2
|
||||
#define MHS_EVS_OBJECT 3
|
||||
|
||||
#define MHS_EVS_DIN 4
|
||||
#define MHS_EVS_ENC 5
|
||||
#define MHS_EVS_KEY 6
|
||||
|
||||
|
||||
#define MHS_TERMINATE 0x80000000
|
||||
|
||||
|
||||
// <*> neu
|
||||
#define CAN_DATA_ST_IDLE 0
|
||||
#define CAN_DATA_ST_RUN 1
|
||||
#define CAN_DATA_ST_FINISH 2
|
||||
#define CAN_DATA_ST_ERR_ACK_TIMEOUT -1
|
||||
#define CAN_DATA_ST_ERR_NACK -2
|
||||
#define CAN_DATA_ST_ERR_OVERFLOW -3
|
||||
#define CAN_DATA_ST_ERR_ISOTP -4
|
||||
|
||||
// ISO-TP Flags
|
||||
#define CAN_DATA_ISOTP_29BIT_ID 0x01
|
||||
#define CAN_DATA_ISOTP_EXTEND_ADDR 0x02
|
||||
#define CAN_DATA_ISOTP_TX_PADDING 0x04
|
||||
#define CAN_DATA_ISOTP_LISTEN_MODE 0x08
|
||||
|
||||
|
||||
// <*> neu
|
||||
#define TCAN_INFO_KEY_HW_SNR 0x00000000 // Hardware Snr
|
||||
#define TCAN_INFO_KEY_HW_ID_STR 0x00000001 // Hardware ID String
|
||||
#define TCAN_INFO_KEY_HW_BIOS_STR 0x00000002 // Bios ID String
|
||||
#define TCAN_INFO_KEY_HW_REVISION 0x00000003 // Hardware Revision
|
||||
#define TCAN_INFO_KEY_HW_DATE 0x00000004 // Fertigungsdatum
|
||||
#define TCAN_INFO_KEY_HW_VARIANT_STR 0x00000005 // Hardware Variante
|
||||
|
||||
#define TCAN_INFO_KEY_HW_CAN_COUNT 0x00008000 // Anzahl CAN Interfaces
|
||||
#define TCAN_INFO_KEY_HW_CAN_DRV 0x00008010 // Treiber
|
||||
#define TCAN_INFO_KEY_HW_CAN_OPTO 0x00008020 // Opto
|
||||
#define TCAN_INFO_KEY_HW_CAN_TERM 0x00008030 // Term
|
||||
#define TCAN_INFO_KEY_HW_CAN_HS 0x00008040 // HighSpeed
|
||||
#define TCAN_INFO_KEY_HW_I2C_CNT 0x00008100 // Anzahl I2C Interfaces
|
||||
#define TCAN_INFO_KEY_HW_SPI_CNT 0x00008200 // Anzahl SPI Interfaces
|
||||
|
||||
#define TCAN_INFO_KEY_FW_ID 0x00001000 // ID
|
||||
#define TCAN_INFO_KEY_FW_ID_STR 0x00001001 // ID String
|
||||
#define TCAN_INFO_KEY_FW_VERSION 0x00001002 // Version
|
||||
#define TCAN_INFO_KEY_FW_VERSION_STR 0x00001003 // Version String
|
||||
#define TCAN_INFO_KEY_FW_AUTOR 0x00001004 // Autor
|
||||
#define TCAN_INFO_KEY_FW_OPTIOS 0x00001005 // Optionen
|
||||
#define TCAN_INFO_KEY_FW_SNR 0x00001006 // Snr
|
||||
|
||||
#define TCAN_INFO_KEY_FW_CAN_FLAGS 0x00008001 // CAN Features Flags
|
||||
#define TCAN_INFO_KEY_FW_CAN_FLAGS2 0x00008002 // CAN Features Flags2 // <*>
|
||||
#define TCAN_INFO_KEY_FW_CAN_CLOCK1 0x00008003
|
||||
#define TCAN_INFO_KEY_FW_CAN_CLOCK2 0x00008004
|
||||
#define TCAN_INFO_KEY_FW_CAN_CLOCK3 0x00008005
|
||||
#define TCAN_INFO_KEY_FW_CAN_CLOCK4 0x00008006
|
||||
#define TCAN_INFO_KEY_FW_CAN_CLOCK5 0x00008007
|
||||
#define TCAN_INFO_KEY_FW_CAN_CLOCK6 0x00008008
|
||||
#define TCAN_INFO_KEY_FW_PUFFER_CNT 0x00008050 // Anzahl Interval Puffer
|
||||
#define TCAN_INFO_KEY_FW_FILTER_CNT 0x00008060 // Anzahl Filter
|
||||
|
||||
#define TCAN_INFO_KEY_OPEN_INDEX 0x01000001
|
||||
#define TCAN_INFO_KEY_HARDWARE_ID 0x01000002
|
||||
#define TCAN_INFO_KEY_HARDWARE 0x01000003
|
||||
#define TCAN_INFO_KEY_VENDOR 0x01000004
|
||||
|
||||
#define TCAN_INFO_KEY_DEVICE_NAME 0x01000005
|
||||
#define TCAN_INFO_KEY_SERIAL_NUMBER 0x01000006
|
||||
|
||||
#define TCAN_INFO_KEY_CAN_FEATURES 0x01000007
|
||||
#define TCAN_INFO_KEY_CAN_CHANNELS 0x01000008
|
||||
#define TCAN_INFO_KEY_RX_FILTER_CNT 0x01000009
|
||||
#define TCAN_INFO_KEY_TX_BUFFER_CNT 0x0100000A
|
||||
#define TCAN_INFO_KEY_CAN_CLOCKS 0x0100000B
|
||||
#define TCAN_INFO_KEY_CAN_CLOCK1 0x0100000C
|
||||
#define TCAN_INFO_KEY_CAN_CLOCK2 0x0100000D
|
||||
#define TCAN_INFO_KEY_CAN_CLOCK3 0x0100000E
|
||||
#define TCAN_INFO_KEY_CAN_CLOCK4 0x0100000F
|
||||
#define TCAN_INFO_KEY_CAN_CLOCK5 0x01000010
|
||||
#define TCAN_INFO_KEY_CAN_CLOCK6 0x01000011
|
||||
|
||||
|
||||
#define TCAN_INFO_KEY_API_VERSION 0x02000001
|
||||
#define TCAN_INFO_KEY_DLL 0x02000002
|
||||
#define TCAN_INFO_KEY_CFG_APP 0x02000003
|
||||
|
||||
/***************************************************************/
|
||||
/* Typen */
|
||||
/***************************************************************/
|
||||
#pragma pack(push, 1)
|
||||
struct TModulFeatures
|
||||
{
|
||||
uint32_t CanClock; // Clock-Frequenz des CAN-Controllers, muss nicht mit
|
||||
// der Clock-Frequenz des Mikrocontrollers <20>bereinstimmen
|
||||
uint32_t Flags; // Unterst<73>tzte Features des Moduls:
|
||||
// Bit 0 -> Silent Mode (LOM = Listen only Mode)
|
||||
// 1 -> Automatic Retransmission disable
|
||||
// 2 -> TX ACK (Gesendete Nachrichten best<73>tigen)
|
||||
// 15 -> Hardware Time Stamp
|
||||
uint32_t CanChannelsCount; // Anzahl der CAN Schnittstellen, reserviert f<>r
|
||||
// zuk<75>nftige Module mit mehr als einer Schnittstelle
|
||||
uint32_t HwRxFilterCount; // Anzahl der zur Verf<72>gung stehenden Receive-Filter
|
||||
uint32_t HwTxPufferCount; // Anzahl der zur Verf<72>gung stehenden Transmit Puffer mit Timer
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TCanDevicesList
|
||||
{
|
||||
uint32_t TCanIdx; // Ist das Device ge<67>ffnet ist der Wert auf dem Device-Index
|
||||
// gesetzt, ansonsten ist der Wert auf "INDEX_INVALID" gesetzt.
|
||||
uint32_t HwId; // Ein 32 Bit Schl<68>ssel der die Hardware eindeutig Identifiziert.
|
||||
// Manche Module m<>ssen erst ge<67>ffnet werden damit dieser Wert
|
||||
// gesetzt wird
|
||||
char DeviceName[255]; // Nur Linux: entspricht den Device Namen des USB-Devices,
|
||||
// z.B. /dev/ttyUSB0
|
||||
char SerialNumber[16]; // Seriennummer des Moduls
|
||||
char Description[64]; // Modul Bezeichnung, z.B. "Tiny-CAN IV-XL",
|
||||
// muss in den USB-Controller programmiert sein,
|
||||
// was zur Zeit nur bei den Modulen Tiny-CAN II-XL,
|
||||
// IV-XL u. M1 der Fall ist.
|
||||
struct TModulFeatures ModulFeatures; // Unterst<73>tzte Features des Moduls, nur g<>ltig
|
||||
// wenn HwId > 0
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TCanDeviceInfo
|
||||
{
|
||||
uint32_t HwId; // Ein 32 Bit Schl<68>ssel der die Hardware eindeutig Identifiziert.
|
||||
uint32_t FirmwareVersion; // Version der Firmware des Tiny-CAN Moduls
|
||||
uint32_t FirmwareInfo; // Informationen zum Stand der Firmware Version
|
||||
// 0 = Unbekannt
|
||||
// 1 = Firmware veraltet, Device kann nicht ge<67>ffnet werden
|
||||
// 2 = Firmware veraltet, Funktionsumfang eingeschr<68>nkt
|
||||
// 3 = Firmware veraltet, keine Einschr<68>nkungen
|
||||
// 4 = Firmware auf Stand
|
||||
// 5 = Firmware neuer als Erwartet
|
||||
char SerialNumber[16]; // Seriennummer des Moduls
|
||||
char Description[64]; // Modul Bezeichnung, z.B. "Tiny-CAN IV-XL"
|
||||
struct TModulFeatures ModulFeatures; // Unterst<73>tzte Features des Moduls
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TCanInfoVar // <*> ge<67>ndert von TInfoVar in TCanInfoVar
|
||||
{
|
||||
uint32_t Key; // Variablen Schl<68>ssel
|
||||
uint32_t Type; // Variablen Type
|
||||
uint32_t Size; // (Max)Gr<47><72>e der Variable in Byte
|
||||
char Data[255]; // Wert der Variable
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TCanInfoVarList
|
||||
{
|
||||
uint32_t Size;
|
||||
struct TCanInfoVar *List;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct _TMhsEvent TMhsEvent;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct _TMhsEvent
|
||||
{
|
||||
volatile uint32_t Events;
|
||||
volatile uint32_t EventsMask;
|
||||
volatile int32_t Waiting;
|
||||
#ifdef __WIN32__
|
||||
// ****** Windows
|
||||
uint32_t WinEventCount;
|
||||
HANDLE WinEvent[3];
|
||||
CRITICAL_SECTION EventLock;
|
||||
#else
|
||||
// ****** Linux
|
||||
pthread_cond_t Cond;
|
||||
pthread_mutex_t Mutex;
|
||||
#endif
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
/***************************************************************/
|
||||
/* Callback Funktionstypen */
|
||||
/***************************************************************/
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanGetDataBlockCB)(uint8_t *tx_data, uint16_t tx_limit, void *user_data);
|
||||
|
||||
#ifdef CAN_API_TRUE_FUNC
|
||||
|
||||
int32_t CanExGetDeviceCount(int32_t flags);
|
||||
int32_t CanExGetDeviceList(struct TCanDevicesList **devices_list, int32_t flags);
|
||||
int32_t CanExGetDeviceListPerform(int32_t flags);
|
||||
int32_t CanExGetDeviceListGet(struct TCanDevicesList *item);
|
||||
|
||||
int32_t CanExGetDeviceInfo(uint32_t index, struct TCanDeviceInfo *device_info,
|
||||
struct TCanInfoVar **hw_info, uint32_t *hw_info_size);
|
||||
int32_t CanExGetDeviceInfoPerform(uint32_t index, struct TCanDeviceInfo *device_info);
|
||||
int32_t CanExGetDeviceInfoGet(struct TCanInfoVar *item);
|
||||
void CanExDataFree(void **data);
|
||||
int32_t CanExCreateDevice(uint32_t *index, char *options);
|
||||
int32_t CanExDestroyDevice(uint32_t *index);
|
||||
int32_t CanExCreateFifo(uint32_t index, uint32_t size, TMhsEvent *event_obj, uint32_t event, uint32_t channels);
|
||||
int32_t CanExBindFifo(uint32_t fifo_index, uint32_t device_index, uint32_t bind);
|
||||
TMhsEvent *CanExCreateEvent(void);
|
||||
int32_t CanExSetObjEvent(uint32_t index, uint32_t source, TMhsEvent *event_obj, uint32_t event);
|
||||
void CanExSetEvent(TMhsEvent *event_obj, uint32_t event);
|
||||
void CanExSetEventAll(uint32_t event);
|
||||
void CanExResetEvent(TMhsEvent *event_obj, uint32_t event);
|
||||
uint32_t CanExWaitForEvent(TMhsEvent *event_obj, uint32_t timeout);
|
||||
int32_t CanExInitDriver(char *options);
|
||||
int32_t CanExSetOptions(uint32_t index, char *options);
|
||||
int32_t CanExSetAsByte(uint32_t index, const char *name, char value);
|
||||
int32_t CanExSetAsWord(uint32_t index, const char *name, int16_t value);
|
||||
int32_t CanExSetAsLong(uint32_t index, const char *name, int32_t value);
|
||||
int32_t CanExSetAsUByte(uint32_t index, const char *name, unsigned char value);
|
||||
int32_t CanExSetAsUWord(uint32_t index, const char *name, uint16_t value);
|
||||
int32_t CanExSetAsULong(uint32_t index, const char *name, uint32_t value);
|
||||
int32_t CanExSetAsString(uint32_t index, const char *name, char *value);
|
||||
int32_t CanExGetAsByte(uint32_t index, const char *name, char *value);
|
||||
int32_t CanExGetAsWord(uint32_t index, const char *name, int16_t *value);
|
||||
int32_t CanExGetAsLong(uint32_t index, const char *name, int32_t *value);
|
||||
int32_t CanExGetAsUByte(uint32_t index, const char *name, unsigned char *value);
|
||||
int32_t CanExGetAsUWord(uint32_t index, const char *name, uint16_t *value);
|
||||
int32_t CanExGetAsULong(uint32_t index, const char *name, uint32_t *value);
|
||||
int32_t CanExGetAsString(uint32_t index, const char *name, char **str);
|
||||
int32_t CanExGetAsStringCopy(uint32_t index, const char *name, char *dest, uint32_t *dest_size);
|
||||
// **** CAN-FD
|
||||
int32_t CanFdTransmit(uint32_t index, struct TCanFdMsg *fd_msg, int32_t count);
|
||||
int32_t CanFdReceive(uint32_t index, struct TCanFdMsg *fd_msg, int32_t count);
|
||||
// *** <*> neu
|
||||
int32_t CanExSetAsData(uint32_t index, const char *name, void *data, uint32_t size);
|
||||
int32_t CanExSetDataPtr(uint32_t index, const char *name, void *data_ptr, uint32_t size);
|
||||
int32_t CanExSetDataBlockCB(uint32_t index, TCanGetDataBlockCB func, void *user_data);
|
||||
|
||||
int32_t CanExGetInfoList(uint32_t dev_idx, const char *name, struct TCanInfoVarList **devices_info, int32_t flags); // <*> neu
|
||||
int32_t CanExGetInfoListPerform(uint32_t dev_idx, const char *name, int32_t flags);
|
||||
int32_t CanExGetInfoListGet(uint32_t list_idx, struct TCanInfoVar *item);
|
||||
|
||||
#endif
|
||||
|
||||
#if !(defined(CAN_API_TRUE_FUNC)) || defined(CAN_DRV_INCLUDE)
|
||||
|
||||
/***************************************************************/
|
||||
/* Funktionstypen */
|
||||
/***************************************************************/
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetDeviceCount)(int32_t flags);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetDeviceList)(struct TCanDevicesList **devices_list, int32_t flags);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetDeviceListPerform)(int32_t flags);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetDeviceListGet)(struct TCanDevicesList *item);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetDeviceInfo)(uint32_t index, struct TCanDeviceInfo *device_info,
|
||||
struct TCanInfoVar **hw_info, uint32_t *hw_info_size);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetDeviceInfoPerform)(uint32_t index, struct TCanDeviceInfo *device_info);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetDeviceInfoGet)(struct TCanInfoVar *item);
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanExDataFree)(void **data);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExCreateDevice)(uint32_t *index, char *options);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExDestroyDevice)(uint32_t *index);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExCreateFifo)(uint32_t index, uint32_t size, TMhsEvent *event_obj,
|
||||
uint32_t event, uint32_t channels);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExBindFifo)(uint32_t fifo_index, uint32_t device_index,
|
||||
uint32_t bind);
|
||||
typedef TMhsEvent * (DRV_CALLBACK_TYPE *TCanExCreateEvent)(void);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetObjEvent)(uint32_t index, uint32_t source, TMhsEvent *event_obj, uint32_t event);
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanExSetEvent)(TMhsEvent *event_obj, uint32_t event);
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanExSetEventAll)(uint32_t event);
|
||||
typedef void (DRV_CALLBACK_TYPE *TCanExResetEvent)(TMhsEvent *event_obj, uint32_t event);
|
||||
typedef uint32_t (DRV_CALLBACK_TYPE *TCanExWaitForEvent)(TMhsEvent *event_obj, uint32_t timeout);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExInitDriver)(char *options);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetOptions)(uint32_t index, const char *options);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsByte)(uint32_t index, const char *name, char value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsWord)(uint32_t index, const char *name, int16_t value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsLong)(uint32_t index, const char *name, int32_t value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsUByte)(uint32_t index, const char *name, unsigned char value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsUWord)(uint32_t index, const char *name, uint16_t value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsULong)(uint32_t index, const char *name, uint32_t value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsString)(uint32_t index, const char *name, char *value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsByte)(uint32_t index, const char *name, char *value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsWord)(uint32_t index, const char *name, int16_t *value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsLong)(uint32_t index, const char *name, int32_t *value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsUByte)(uint32_t index, const char *name, unsigned char *value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsUWord)(uint32_t index, const char *name, uint16_t *value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsULong)(uint32_t index, const char *name, uint32_t *value);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsString)(uint32_t index, const char *name, char **str);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetAsStringCopy)(uint32_t index, const char *name, char *dest, uint32_t *dest_size);
|
||||
// ****** CAN-FD
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanFdTransmit)(uint32_t index, struct TCanFdMsg *fd_msg, int32_t count);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanFdReceive)(uint32_t index, struct TCanFdMsg *fd_msg, int32_t count);
|
||||
// ***** <*>
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetAsData)(uint32_t index, const char *name, void *data, uint32_t size);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetDataPtr)(uint32_t index, const char *name, void *data_ptr, uint32_t size);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExSetDataBlockCB)(uint32_t index, TCanGetDataBlockCB func, void *user_data);
|
||||
// ***** <*> neu 2
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetInfoList)(uint32_t dev_idx, const char *name, struct TCanInfoVarList **devices_info, int32_t flags); // <*> neu
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetInfoListPerform)(uint32_t dev_idx, const char *name, int32_t flags);
|
||||
typedef int32_t (DRV_CALLBACK_TYPE *TCanExGetInfoListGet)(uint32_t list_idx, struct TCanInfoVar *item);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef CAN_API_TRUE_FUNC
|
||||
/***************************************************************/
|
||||
/* Tiny-CAN API Funktionen */
|
||||
/***************************************************************/
|
||||
extern TCanExGetDeviceCount CanExGetDeviceCount;
|
||||
extern TCanExGetDeviceList CanExGetDeviceList;
|
||||
extern TCanExGetDeviceListPerform CanExGetDeviceListPerform;
|
||||
extern TCanExGetDeviceListGet CanExGetDeviceListGet;
|
||||
extern TCanExGetDeviceInfo CanExGetDeviceInfo;
|
||||
extern TCanExGetDeviceInfoPerform CanExGetDeviceInfoPerform;
|
||||
extern TCanExGetDeviceInfoGet CanExGetDeviceInfoGet;
|
||||
extern TCanExDataFree CanExDataFree;
|
||||
extern TCanExCreateDevice CanExCreateDevice;
|
||||
extern TCanExDestroyDevice CanExDestroyDevice;
|
||||
extern TCanExCreateFifo CanExCreateFifo;
|
||||
extern TCanExBindFifo CanExBindFifo;
|
||||
extern TCanExCreateEvent CanExCreateEvent;
|
||||
extern TCanExSetObjEvent CanExSetObjEvent;
|
||||
extern TCanExSetEvent CanExSetEvent;
|
||||
extern TCanExSetEventAll CanExSetEventAll;
|
||||
extern TCanExResetEvent CanExResetEvent;
|
||||
extern TCanExWaitForEvent CanExWaitForEvent;
|
||||
extern TCanExInitDriver CanExInitDriver;
|
||||
extern TCanExSetOptions CanExSetOptions;
|
||||
extern TCanExSetAsByte CanExSetAsByte;
|
||||
extern TCanExSetAsWord CanExSetAsWord;
|
||||
extern TCanExSetAsLong CanExSetAsLong;
|
||||
extern TCanExSetAsUByte CanExSetAsUByte;
|
||||
extern TCanExSetAsUWord CanExSetAsUWord;
|
||||
extern TCanExSetAsULong CanExSetAsULong;
|
||||
extern TCanExSetAsString CanExSetAsString;
|
||||
extern TCanExGetAsByte CanExGetAsByte;
|
||||
extern TCanExGetAsWord CanExGetAsWord;
|
||||
extern TCanExGetAsLong CanExGetAsLong;
|
||||
extern TCanExGetAsUByte CanExGetAsUByte;
|
||||
extern TCanExGetAsUWord CanExGetAsUWord;
|
||||
extern TCanExGetAsULong CanExGetAsULong;
|
||||
extern TCanExGetAsString CanExGetAsString;
|
||||
extern TCanExGetAsStringCopy CanExGetAsStringCopy;
|
||||
|
||||
// ****** CAN-FD
|
||||
extern TCanFdTransmit CanFdTransmit;
|
||||
extern TCanFdReceive CanFdReceive;
|
||||
// **** <*> neu
|
||||
extern TCanExSetAsData CanExSetAsData;
|
||||
extern TCanExSetDataPtr CanExSetDataPtr;
|
||||
extern TCanExSetDataBlockCB CanExSetDataBlockCB;
|
||||
|
||||
extern TCanExGetInfoList CanExGetInfoList;
|
||||
extern TCanExGetInfoListPerform CanExGetInfoListPerform;
|
||||
extern TCanExGetInfoListGet CanExGetInfoListGet;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,385 +0,0 @@
|
||||
#ifndef __CAN_TYPES_H__
|
||||
#define __CAN_TYPES_H__
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#ifndef __WIN32__
|
||||
#define __WIN32__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
// Windows
|
||||
#if !defined(WINVER)
|
||||
#define WINVER 0x0500
|
||||
#endif
|
||||
#if !defined(_WIN32_IE)
|
||||
#define _WIN32_IE 0x0501
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#if defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER >= 1900)
|
||||
#include <stdint.h>
|
||||
#else
|
||||
typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
#endif
|
||||
#else
|
||||
// Linux & Mac
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#ifndef M_FORCE_INLINE
|
||||
#define M_FORCE_INLINE static __inline__ __attribute__((__always_inline__,__gnu_inline__))
|
||||
//inline __attribute__((always_inline)) <*>
|
||||
#endif
|
||||
#else
|
||||
#ifndef M_FORCE_INLINE
|
||||
#define M_FORCE_INLINE static __forceinline
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define INDEX_INVALID 0xFFFFFFFF
|
||||
|
||||
#define INDEX_FIFO_PUFFER_MASK 0x0000FFFF
|
||||
#define INDEX_SOFT_FLAG 0x02000000
|
||||
// #define INDEX_RXD_TXT_FLAG 0x01000000 <*>
|
||||
#define INDEX_TXT_FLAG 0x01000000
|
||||
#define INDEX_CAN_KANAL_MASK 0x000F0000
|
||||
#define INDEX_CAN_DEVICE_MASK 0x00F00000
|
||||
|
||||
#define INDEX_FIFO_VIRTUAL 0x80000000
|
||||
#define INDEX_USER_MASK 0xFC000000
|
||||
|
||||
#define INDEX_CAN_KANAL_A 0x00000000
|
||||
#define INDEX_CAN_KANAL_B 0x00010000
|
||||
|
||||
/***************************************************************/
|
||||
/* Typen */
|
||||
/***************************************************************/
|
||||
|
||||
/******************************************/
|
||||
/* CAN Message Type */
|
||||
/******************************************/
|
||||
#define MsgFlags Flags.Long
|
||||
#define MsgLen Flags.Flag.Len
|
||||
#define MsgRTR Flags.Flag.RTR
|
||||
#define MsgEFF Flags.Flag.EFF
|
||||
#define MsgTxD Flags.Flag.TxD
|
||||
#define MsgErr Flags.Flag.Error
|
||||
#define MsgSource Flags.Flag.Source
|
||||
#define MsgFilHit Flags.Flag.FilHit
|
||||
#define MsgOV Flags.Flag.OV
|
||||
#define MsgData Data.Bytes
|
||||
|
||||
/*
|
||||
Byte
|
||||
|
||||
0 -> LEC Last Error Code
|
||||
1 = Stuff Error More than 5 equal bits in a sequence have occurred in a part of a
|
||||
received message where this is not allowed.
|
||||
2 = Form Error A fixed format part of a received frame has the wrong format.
|
||||
3 = AckError The message this CAN Core transmitted was not acknowledged by another node.
|
||||
4 = Bit1Error During the transmission of a message (with the exception of the
|
||||
arbitration field), the device wanted to send a recessive level (bit of logical
|
||||
value '1'), but the monitored busvalue was dominant.
|
||||
5 = Bit0Error During the transmission of a message (or acknowledge bit or active error
|
||||
flag, or overload flag), the device wanted to send a dominant level (data or
|
||||
identifier bit logical value '0'), but the monitored Bus value was recessive.
|
||||
During busoff recovery this status is set each time a sequence of 11 recessive bits
|
||||
has been monitored. This enables the CPU to monitor the proceeding of the busoff
|
||||
recovery sequence (indicating the bus is not stuck at dominant level or continuously
|
||||
disturbed).
|
||||
6 = CRCError The CRC check sum was incorrect in the message received, the CRC received
|
||||
for an incoming message does not match with the calculated CRC for the received data.
|
||||
1 -> Bus Status (Bit 0 - 3)
|
||||
0 = Ok
|
||||
1 = Error Warning
|
||||
2 = Error Passiv
|
||||
3 = Bus Off
|
||||
Bus-Failure -> Bit4
|
||||
2 -> Receive Error Counter
|
||||
3 -> Transmit Error Counter
|
||||
|
||||
<*> Neu
|
||||
OV -> FIFO Overflow Frame
|
||||
|
||||
Byte 0
|
||||
0 -> Source
|
||||
1 = CAN Controller
|
||||
2 = CAN Hardware
|
||||
3 = API
|
||||
1,2 -> Messages Lost <*> muss noch implementiert werden
|
||||
|
||||
*/
|
||||
|
||||
struct TCanFlagsBits
|
||||
{
|
||||
unsigned Len:4; // DLC -> Datenl<6E>nge 0 - 8 Byte
|
||||
unsigned TxD:1; // TxD -> 1 = Tx CAN Nachricht, 0 = Rx CAN Nachricht
|
||||
// Eine Erfolgreich versendete Nachricht wird als Best<73>tigung
|
||||
// ins Empfangsfifo zur<75>ckgeschrieben
|
||||
// Nicht alle Module unterst<73>tzen diese Funktion u. das
|
||||
// Feature muss aktiveirt sein
|
||||
unsigned Error:1; // Error -> 1 = CAN Bus Fehler Nachricht
|
||||
// Nicht alle Module unterst<73>tzen diese Funktion u. das
|
||||
// Feature muss aktiveirt sein
|
||||
unsigned RTR:1; // Remote Transmition Request bit -> Kennzeichnet eine RTR Nachricht
|
||||
unsigned EFF:1; // Extended Frame Format bit -> 1 = 29 Bit Id's, 0 = 11 Bit Id's
|
||||
unsigned Source:8; // Quelle der Nachricht (Device)
|
||||
// Neu
|
||||
unsigned FilHit:1; // FilHit -> 1 = Filter Hit
|
||||
unsigned OV:1; // <*> Neu FIFO Overflow
|
||||
unsigned Res1:1;
|
||||
unsigned Res3:1;
|
||||
unsigned Res4:4;
|
||||
unsigned Res5:8;
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union TCanFlags
|
||||
{
|
||||
struct TCanFlagsBits Flag;
|
||||
uint32_t Long;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union TCanData
|
||||
{
|
||||
char Chars[8];
|
||||
unsigned char Bytes[8];
|
||||
uint16_t Words[4];
|
||||
uint32_t Longs[2];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TTime
|
||||
{
|
||||
uint32_t Sec;
|
||||
uint32_t USec;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TCanMsg
|
||||
{
|
||||
uint32_t Id;
|
||||
union TCanFlags Flags;
|
||||
union TCanData Data;
|
||||
struct TTime Time;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
/******************************************/
|
||||
/* CAN FD */
|
||||
/******************************************/
|
||||
#define MsgFD Flags.Flag.FD // FD Format
|
||||
#define MsgBRS Flags.Flag.BRS // Bit Rate Switch
|
||||
|
||||
struct TCanFdFlagsBits
|
||||
{
|
||||
unsigned Source:8; // Quelle der Nachricht (Device)
|
||||
unsigned Len:8; // DLC -> Datenl<6E>nge 0 - 8 Byte
|
||||
|
||||
unsigned TxD:1; // TxD -> 1 = Tx CAN Nachricht, 0 = Rx CAN Nachricht
|
||||
// Eine Erfolgreich versendete Nachricht wird als Best<73>tigung
|
||||
// ins Empfangsfifo zur<75>ckgeschrieben
|
||||
// Nicht alle Module unterst<73>tzen diese Funktion u. das
|
||||
// Feature muss aktiveirt sein
|
||||
unsigned Error:1; // Error -> 1 = CAN Bus Fehler Nachricht
|
||||
// Nicht alle Module unterst<73>tzen diese Funktion u. das
|
||||
// Feature muss aktiveirt sein
|
||||
unsigned RTR:1; // Remote Transmition Request bit -> Kennzeichnet eine RTR Nachricht
|
||||
unsigned EFF:1; // Extended Frame Format bit -> 1 = 29 Bit Id's, 0 = 11 Bit Id's
|
||||
unsigned FD:1; // CAN-FD Frame
|
||||
unsigned BRS:1; // Bit Rate Switch
|
||||
unsigned Res0:1;
|
||||
unsigned OV:1; // <*> Neu FIFO Overflow
|
||||
|
||||
unsigned Res2:1;
|
||||
unsigned Res3:1;
|
||||
unsigned Res4:1;
|
||||
unsigned Res5:1;
|
||||
unsigned Res6:1;
|
||||
unsigned Res7:1;
|
||||
unsigned Res8:1;
|
||||
unsigned FilHit:1; // FilHit -> 1 = Filter Hit
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union TCanFdFlags
|
||||
{
|
||||
struct TCanFdFlagsBits Flag;
|
||||
uint32_t Long;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union TCanFdData
|
||||
{
|
||||
char Chars[64];
|
||||
unsigned char Bytes[64];
|
||||
uint16_t Words[32];
|
||||
uint32_t Longs[16];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TCanFdMsg
|
||||
{
|
||||
uint32_t Id;
|
||||
union TCanFdFlags Flags;
|
||||
union TCanFdData Data;
|
||||
struct TTime Time;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
/******************************************/
|
||||
/* CAN Message Filter Type */
|
||||
/******************************************/
|
||||
#define FilFlags Flags.Long
|
||||
#define FilRTR Flags.Flag.RTR
|
||||
#define FilEFF Flags.Flag.EFF
|
||||
#define FilMode Flags.Flag.Mode
|
||||
#define FilIdMode Flags.Flag.IdMode
|
||||
#define FilEnable Flags.Flag.Enable
|
||||
|
||||
// * = Reserviert, zur Zeit noch unbenutzt
|
||||
|
||||
struct TMsgFilterFlagsBits
|
||||
{
|
||||
// 1. Byte
|
||||
unsigned Len:4; // * Dlc
|
||||
unsigned Res:2; // Reserviert
|
||||
unsigned RTR:1; // Remote Transmition Request
|
||||
unsigned EFF:1; // Extended Frame Format
|
||||
// 2. Byte
|
||||
unsigned IdMode:2; // 0 = Maske & Code
|
||||
// 1 = Start & Stop
|
||||
// 2 = Single Id
|
||||
unsigned DLCCheck:1; // *
|
||||
unsigned DataCheck:1; // *
|
||||
unsigned Res1:4;
|
||||
// 3. Byte
|
||||
unsigned Res2:8;
|
||||
// 4. Byte
|
||||
unsigned Type:4; // 0 = Single Puffer
|
||||
unsigned Res3:2;
|
||||
unsigned Mode:1; // 0 = Message entfernen
|
||||
// 1 = Message nicht entfernen
|
||||
unsigned Enable:1; // 0 = Filter sperren
|
||||
// 1 = Filter freigeben
|
||||
};
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union TMsgFilterFlags
|
||||
{
|
||||
struct TMsgFilterFlagsBits Flag;
|
||||
uint32_t Long;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct TMsgFilter
|
||||
{ // IdMode -> Maske & Code | Start & Stop | Single Id
|
||||
// --------------------------+--------------+-----------
|
||||
uint32_t Maske; // Filter-Id -> Maske | Stop |
|
||||
uint32_t Code; // Filter-Id -> Code | Start | Id
|
||||
union TMsgFilterFlags Flags;
|
||||
union TCanData Data; // *
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
struct TCanIndexSource
|
||||
{
|
||||
// 1. u. 2 Byte
|
||||
unsigned SubIndex:16;
|
||||
// 3. Byte
|
||||
unsigned Source:8;
|
||||
// 4. Byte
|
||||
unsigned TxD:1;
|
||||
unsigned Soft:1;
|
||||
unsigned User:5;
|
||||
unsigned Virtual:1;
|
||||
};
|
||||
|
||||
struct TCanIndexBits
|
||||
{
|
||||
// 1. u. 2 Byte
|
||||
unsigned SubIndex:16;
|
||||
// 3. Byte
|
||||
unsigned Channel:4;
|
||||
unsigned Device:4;
|
||||
// 4. Byte
|
||||
unsigned TxD:1;
|
||||
unsigned Soft:1;
|
||||
unsigned User:5;
|
||||
unsigned Virtual:1;
|
||||
};
|
||||
|
||||
union TCanIndex
|
||||
{
|
||||
struct TCanIndexBits Item;
|
||||
struct TCanIndexSource SrcItem;
|
||||
uint32_t Long;
|
||||
};
|
||||
|
||||
|
||||
|
||||
M_FORCE_INLINE void CanFdToCan(struct TCanMsg *dst, const struct TCanFdMsg *src)
|
||||
{
|
||||
uint8_t len;
|
||||
|
||||
dst->Id = src->Id;
|
||||
len = src->MsgLen;
|
||||
dst->MsgFlags = (src->MsgFlags >> 12) & 0x000000F0;
|
||||
if (len > 8)
|
||||
len = 8;
|
||||
dst->MsgLen = len;
|
||||
dst->MsgSource = src->MsgSource;
|
||||
dst->MsgFilHit = src->MsgFilHit;
|
||||
dst->Data.Longs[0] = src->Data.Longs[0];
|
||||
dst->Data.Longs[1] = src->Data.Longs[1];
|
||||
dst->Time.Sec = src->Time.Sec;
|
||||
dst->Time.USec = src->Time.USec;
|
||||
}
|
||||
|
||||
|
||||
M_FORCE_INLINE void CanToCanFd(struct TCanFdMsg *dst, const struct TCanMsg *src)
|
||||
{
|
||||
dst->Id = src->Id;
|
||||
dst->MsgFlags = (src->MsgFlags << 12) & 0x000F0000;
|
||||
dst->MsgLen = src->MsgLen;
|
||||
dst->MsgSource = src->MsgSource;
|
||||
dst->MsgFilHit = src->MsgFilHit;
|
||||
dst->Data.Longs[0] = src->Data.Longs[0];
|
||||
dst->Data.Longs[1] = src->Data.Longs[1];
|
||||
dst->Time.Sec = src->Time.Sec;
|
||||
dst->Time.USec = src->Time.USec;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
BIN
doc/Challenges.docx
Normal file
56
doc/Install.on.pi.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
Nachinstallieren:
|
||||
|
||||
Qt6
|
||||
|
||||
...
|
||||
|
||||
|
||||
IconFont:
|
||||
|
||||
|
||||
sudo apt install fonts-noto-color-emoji
|
||||
|
||||
|
||||
UpdateDB:
|
||||
|
||||
...
|
||||
|
||||
paket modemmanager stört:
|
||||
|
||||
apt list --installed modemmanager
|
||||
dpkg -s modemmanager
|
||||
|
||||
systemctl status ModemManager
|
||||
sudo systemctl stop ModemManager
|
||||
sudo systemctl disable ModemManager
|
||||
sudo apt purge modemmanager
|
||||
|
||||
// ---
|
||||
|
||||
https://github.com/MHS-Elektronik/OBD-Display
|
||||
|
||||
sudo chgrp pi /opt
|
||||
sudo chmod -R 775 /opt
|
||||
cd /opt
|
||||
mv /home/pi/tiny_can_raspberry_790.tar.gz .
|
||||
tar -xzvf tiny_can_raspberry_790.tar.gz
|
||||
rm tiny_can_raspberry_790.tar.gz
|
||||
|
||||
|
||||
|
||||
RANT
|
||||
|
||||
--- STRUKTUR
|
||||
|
||||
Denglish -> Comments, Bezeichnungen 'aligned', 'given'
|
||||
Weltsprache, mag ja sein,
|
||||
|
||||
Schlimmer: Doku & Bücher -> c++, qt, OO nicht verstanden
|
||||
|
||||
includes_ pfade hartcodiert statt im Makefile -> Kunstfehler
|
||||
Projecte willkürlich verstreut
|
||||
|
||||
Respektlose Schlampigkeit: copy & paste: es werden sogar die Artefakte des MKS mitkopiert ->
|
||||
---
|
||||
|
||||
---
|
||||
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
@@ -1,7 +1,52 @@
|
||||
Challenges
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
BionxControl
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
xtree
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
znode
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
libPigPio
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
supportware
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
raDIYo
|
||||
|
||||
Aufgabe:
|
||||
|
||||
@@ -9,34 +54,7 @@ Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
miniCash.connect
|
||||
|
||||
Aufgabe:
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/*******************************************************************************/
|
||||
/* Interface zur Tiny-CAN API */
|
||||
/* --------------------------------------------------------------------------- */
|
||||
/* Beschreibung : Laden einer Treiber Lib */
|
||||
/* */
|
||||
/* Version : 2.10 */
|
||||
/* Datei Name : can_drv_win.c */
|
||||
/* --------------------------------------------------------------------------- */
|
||||
/* Datum : 18.09.15 */
|
||||
/* Copyright : (C) 2011 - 2015 by MHS-Elektronik GmbH & Co. KG, Germany */
|
||||
/* www.mhs-elektronik.de */
|
||||
/* Autor : Demlehner Klaus, info@mhs-elektronik.de */
|
||||
/*******************************************************************************/
|
||||
#include "mhs_can_drv.c"
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/*******************************************************************************/
|
||||
/* Interface zur Tiny-CAN API */
|
||||
/* --------------------------------------------------------------------------- */
|
||||
/* Beschreibung : Laden einer Treiber DLL */
|
||||
/* */
|
||||
/* Version : 2.10 */
|
||||
/* Datei Name : can_drv_win.c */
|
||||
/* --------------------------------------------------------------------------- */
|
||||
/* Datum : 18.09.15 */
|
||||
/* Copyright : (C) 2011 - 2015 by MHS-Elektronik GmbH & Co. KG, Germany */
|
||||
/* www.mhs-elektronik.de */
|
||||
/* Autor : Demlehner Klaus, info@mhs-elektronik.de */
|
||||
/*******************************************************************************/
|
||||
#include "mhs_can_drv.c"
|
||||
|
||||
|
||||
|
||||
21
main.cpp
@@ -1,7 +1,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
BionxControl
|
||||
Copyright © 2025 christoph holzheuer
|
||||
© 2025 -2026 christoph holzheuer
|
||||
christoph.holzheuer@gmail.com
|
||||
|
||||
Using:
|
||||
@@ -39,32 +39,15 @@
|
||||
|
||||
#include <bcmainwindow.h>
|
||||
|
||||
#include <expected>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
|
||||
|
||||
bool setApplicationStyleSheet( QAnyStringView path )
|
||||
{
|
||||
QFile styleFile( path.toString() );
|
||||
if (styleFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
{
|
||||
QString style = styleFile.readAll();
|
||||
qApp->setStyleSheet(style);
|
||||
styleFile.close();
|
||||
return true;
|
||||
}
|
||||
qWarning() << "Konnte Stylesheet nicht laden:" << styleFile.errorString();
|
||||
return true;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
QApplication app(argc, argv);
|
||||
//setApplicationStyleSheet( ":/claude_light_mode.qss"_L1 );
|
||||
/*
|
||||
/*
|
||||
app.setStyleSheet(R"(
|
||||
QWidget {
|
||||
background-color: #F3F3F3;
|
||||
|
||||
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 4.2 KiB |
BIN
resources/TinyCan_812.exe
Normal file
@@ -1,24 +1,17 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
|
||||
<!--
|
||||
QString ID;
|
||||
QString Label;
|
||||
QString UnitLabel;
|
||||
QString Factor;
|
||||
QString Min;
|
||||
QString Max;
|
||||
QString IsWord;
|
||||
QString ValueType;
|
||||
-->
|
||||
<Bike name='franken-wheeler'>
|
||||
|
||||
<Device Type="Console">
|
||||
<Value ID='Cons_Rev_Hw' Label='Hardware Version' />
|
||||
<Value ID='Cons_Rev_Sw' Label='Software Version' />
|
||||
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' IsWord='1'/>
|
||||
|
||||
<Value ID='Cons_Sn_Product_Hi' Label='Product Number' IsWord='1'/>
|
||||
<Value ID='Cons_Sn_Oem_Hi' Label='OEM Number' IsWord='1' />
|
||||
|
||||
<Value ID='Cons_Assist_Initlevel' Label='Assistance Init Level' Min='0' Max='4'/>
|
||||
|
||||
|
||||
<Value ID='Cons_Assist_Level_1' Label='Assistance Level 1' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
|
||||
<Value ID='Cons_Assist_Level_2' Label='Assistance Level 2' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
|
||||
<Value ID='Cons_Assist_Level_3' Label='Assistance Level 3' Factor='1.5625' UnitLabel='%' Min='0' Max='400' />
|
||||
@@ -37,6 +30,7 @@ QString ValueType;
|
||||
<Value ID='Cons_Assist_Mountain_Cap' Label='Mountain Cap' UnitLabel='%' Factor='1.5625' />
|
||||
</Device>
|
||||
|
||||
<!--
|
||||
<Device Type="Motor">
|
||||
<Value ID='Motor_Rev_Hw' Label='Hardware Version' />
|
||||
<Value ID='Motor_Rev_Sw' Label='Software Version' />
|
||||
@@ -52,7 +46,7 @@ QString ValueType;
|
||||
<Value ID='Battery_Rev_Hw' Label='Hardware Version' />
|
||||
<Value ID='Battery_Rev_Sw' Label='Software Version' />
|
||||
</Device>
|
||||
|
||||
-->
|
||||
</Bike>
|
||||
|
||||
<!--
|
||||
|
||||