Rework driver code, again.
This commit is contained in:
23
bcdriver.cpp
23
bcdriver.cpp
@@ -61,8 +61,8 @@ BCDriver::DriverState BCDriver::getState() const
|
||||
|
||||
void BCDriverDummy::onStartDriver()
|
||||
{
|
||||
_driverState = DriverState::Ready;
|
||||
emit driverStateChanged( DriverState::Ready, "Driver Ready." );
|
||||
_driverState = DriverState::DeviceReady;
|
||||
emit driverStateChanged( DriverState::DeviceReady, "Driver Ready." );
|
||||
}
|
||||
/*
|
||||
try
|
||||
@@ -101,22 +101,21 @@ BCDriverDummy::BCDriverDummy( QObject* parent )
|
||||
}
|
||||
|
||||
|
||||
uint32_t BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
BCDriver::TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
{
|
||||
if( getState() != DriverState::Ready)
|
||||
throw BCException( "readRawValue error: driver not loaded." );
|
||||
|
||||
uint32_t myRandomByte = static_cast<uint32_t>(QRandomGenerator::global()->bounded(256));
|
||||
Q_UNUSED(deviceID)
|
||||
Q_UNUSED(registerID)
|
||||
qDebug() << " --- DriverState: " << _driverState;
|
||||
uint8_t myRandomByte = static_cast<uint8_t>(QRandomGenerator::global()->bounded(256));
|
||||
return myRandomByte;
|
||||
}
|
||||
|
||||
void BCDriverDummy::writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const
|
||||
BCDriver::TransmitResult BCDriverDummy::writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const
|
||||
{
|
||||
if( getState() != DriverState::Ready)
|
||||
throw BCException( "readRawValue error: driver not loaded." );
|
||||
|
||||
Q_UNUSED(deviceID)
|
||||
Q_UNUSED(registerID)
|
||||
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
22
bcdriver.h
22
bcdriver.h
@@ -34,7 +34,7 @@
|
||||
#define BCDRIVER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <expected>
|
||||
#include <bc.h>
|
||||
|
||||
/*
|
||||
@@ -75,7 +75,7 @@ class BCDriverStatus;
|
||||
* @Abstrakte Basisklasse für alle CAN-Bus Treiber.
|
||||
* Das Bionx CAN-Bus System kann auf verschiedenen Wegen
|
||||
* angesprochen werden, etwa den über BBI USB2CAN Controller,
|
||||
* über den TinyCAN Adapter oder ggf. über einen EL327 Stecker.
|
||||
* über den TinyCAN Adapter oder ggf. über einen ELM327 Stecker.
|
||||
*
|
||||
* Die hier relevante Implementierung über das TinyCan System
|
||||
* findet sich in der Unterklasse 'BCDriverTinyCan'.
|
||||
@@ -90,6 +90,9 @@ class BCDriver : public QObject
|
||||
|
||||
public:
|
||||
|
||||
// Die möglichen Zustände beim Laden
|
||||
// des CAN-Bus Treibers.
|
||||
|
||||
enum class DriverState
|
||||
{
|
||||
NotPresent,
|
||||
@@ -97,17 +100,22 @@ public:
|
||||
Loaded,
|
||||
Initialized,
|
||||
Opened, // bis hierher: dll vorhanden, Treiber geladen
|
||||
Ready // hier: devices connectable
|
||||
DeviceReady // hier: devices connectable
|
||||
};
|
||||
Q_ENUM(DriverState)
|
||||
|
||||
// Enthält den Treiberzustand oder einen Fehlerstring
|
||||
using DriverStateResult = std::expected<DriverState,QString>;
|
||||
// Enthält den gelesenen Wert oder einen Fehlerstring
|
||||
using TransmitResult = std::expected<uint8_t,QString>;
|
||||
|
||||
explicit BCDriver( QObject* parent = nullptr );
|
||||
virtual ~BCDriver() = default;
|
||||
|
||||
DriverState getState() const;
|
||||
|
||||
virtual uint32_t readRawByte( uint32_t deviceID, uint8_t registerID ) const = 0;
|
||||
virtual void writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const = 0;
|
||||
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:
|
||||
|
||||
@@ -132,8 +140,8 @@ public:
|
||||
|
||||
explicit BCDriverDummy( QObject* parent = nullptr );
|
||||
|
||||
uint32_t readRawByte( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
void writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const 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:
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <bcdrivertinycan.h>
|
||||
#include <can_drv.h>
|
||||
|
||||
#include <expected>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -57,16 +57,15 @@ void BCDriverTinyCan::onStartDriver()
|
||||
void BCDriverTinyCan::loadDriver()
|
||||
{
|
||||
|
||||
using Result=std::expected<DriverState,QString>;
|
||||
|
||||
auto callLoadDriver = []() -> Result
|
||||
auto callLoadDriver = []() -> DriverStateResult
|
||||
{
|
||||
if( ::LoadDriver( NULL ) < 0 )
|
||||
return std::unexpected(QString("Driver Error: 'LoadDriver'"));
|
||||
return DriverState::Loaded;
|
||||
};
|
||||
|
||||
auto callInitDriver = [](DriverState state) -> Result
|
||||
auto callInitDriver = [](DriverState state) -> DriverStateResult
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
if( ::CanInitDriver( NULL ) < 0 )
|
||||
@@ -74,7 +73,7 @@ void BCDriverTinyCan::loadDriver()
|
||||
return DriverState::Initialized;
|
||||
};
|
||||
|
||||
auto callOpenDevice = [](DriverState state) -> Result
|
||||
auto callOpenDevice = [](DriverState state) -> DriverStateResult
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
if( ::CanDeviceOpen( 0, NULL ) < 0 )
|
||||
@@ -122,27 +121,27 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
|
||||
// Console already in slave mode. good!
|
||||
if( readRawByte( console, slaveFlag ) )
|
||||
return DriverState::Ready;
|
||||
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 ... " );
|
||||
uint32_t isSlave = 0;
|
||||
TransmitResult isSlave = 0;
|
||||
do
|
||||
{
|
||||
writeRawByte( console, slaveFlag, 1 );
|
||||
isSlave = readRawByte( console, slaveFlag );
|
||||
isSlave = readRawByte( console, slaveFlag );
|
||||
bc::delay_millis( 200 );
|
||||
|
||||
} while( retry-- && !isSlave );
|
||||
} while( retry-- && !(*isSlave) );
|
||||
|
||||
bc::delay_millis( 500 ); // give the Console some time to settle
|
||||
//if( !isSlave )
|
||||
//emit statusHint( QString("putting Console in slave mode ") + (isSlave ? "done" : "failed") );
|
||||
|
||||
// ist das jetzt irgendwie schlimm, wenn wir keine slave Console haben
|
||||
return isSlave ? DriverState::Ready : DriverState::Opened;
|
||||
return isSlave ? DriverState::DeviceReady : DriverState::Opened;
|
||||
|
||||
}
|
||||
|
||||
@@ -165,12 +164,18 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
|
||||
|
||||
|
||||
uint32_t BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
BCDriver::TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
{
|
||||
|
||||
if( getState() != DriverState::Ready)
|
||||
throw BCException( "readRawValue error: driver not loaded." );
|
||||
//TransmitResult
|
||||
qDebug() << " --- DriverState: " << _driverState;
|
||||
|
||||
/*
|
||||
Nicht hier!
|
||||
if( getState() != DriverState::DeviceReady)
|
||||
//throw BCException( "readRawValue error: driver not loaded." );
|
||||
return std::nullopt;
|
||||
*/
|
||||
::TCanMsg msg;
|
||||
|
||||
// msg verpacken
|
||||
@@ -192,7 +197,7 @@ uint32_t BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t registerID ) c
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if( timeOuts == -1 )
|
||||
throw BCException( "readRawValue error: could not send value" );
|
||||
return std::unexpected(QString("readRawValue error: could not send value" ));
|
||||
|
||||
retry:
|
||||
|
||||
@@ -203,7 +208,7 @@ retry:
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if( timeOuts == -1 )
|
||||
throw BCException( "getValue error: no response from node" );
|
||||
return std::unexpected(QString("getValue error: no response from node" ));
|
||||
|
||||
// message empfangen
|
||||
int err = ::CanReceive( 0, &msg, 1 );
|
||||
@@ -222,22 +227,23 @@ retry:
|
||||
goto retry;
|
||||
|
||||
if( !timeOuts )
|
||||
throw BCException( "CAN --response errror" );
|
||||
return std::unexpected(QString("CAN response errror: timeout" ));
|
||||
|
||||
return (uint32_t) msg.MsgData[3];
|
||||
return (uint8_t) msg.MsgData[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
// void BCDriverTinyCan::setValue( unsigned char receipient, unsigned char reg, unsigned char value )
|
||||
void BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8_t value ) const
|
||||
BCDriver::TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8_t value ) const
|
||||
{
|
||||
|
||||
if( getState() != DriverState::Ready)
|
||||
/*
|
||||
Nicht hier!
|
||||
if( getState() != DriverState::DeviceReady)
|
||||
throw BCException( "writeRawValue error: driver not loaded." );
|
||||
|
||||
*/
|
||||
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;
|
||||
return;
|
||||
|
||||
::TCanMsg msg;
|
||||
int timeout_count = cTIMEOUT_COUNT;
|
||||
@@ -256,7 +262,8 @@ void BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if( timeout_count == -1 )
|
||||
emit driverStateChanged( _driverState, QString( "error: could not send value to %1" ).arg( deviceID ) );
|
||||
return std::unexpected(QString("error: could not send value to %1" ).arg( deviceID ) );
|
||||
|
||||
return 1; // als 'true'
|
||||
}
|
||||
|
||||
|
||||
@@ -44,11 +44,14 @@ public:
|
||||
explicit BCDriverTinyCan( QObject* parent=nullptr );
|
||||
virtual ~BCDriverTinyCan() = default;
|
||||
|
||||
uint32_t readRawByte ( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
void writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
QString getNodeName( unsigned char id );
|
||||
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
void onStartDriver() override;
|
||||
|
||||
@@ -46,14 +46,18 @@
|
||||
BCMainWindow::BCMainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
{
|
||||
// WICHTIG: Registriere sowohl das Struct als auch die LISTE des Structs
|
||||
// __fix! in der Form nötig?
|
||||
qRegisterMetaType<BCValue>("BCValue");
|
||||
qRegisterMetaType<QList<BCValue>>("BCValueList");
|
||||
|
||||
setupUi(this);
|
||||
|
||||
// BESTE PRAXIS: QTimer::singleShot mit Lambda
|
||||
QTimer::singleShot(0, this, [this]() {
|
||||
// Wir schreiben den 'initMainWindow()' Aufruf mit Hilfe des
|
||||
// timers in die Event-Queue, damit er erst ausgeführt wird,
|
||||
// wenn das Fenster sichtbar ist.
|
||||
|
||||
QTimer::singleShot(0, this, [this]()
|
||||
{
|
||||
initMainWindow();
|
||||
});
|
||||
|
||||
@@ -88,13 +92,12 @@ void BCMainWindow::setHeaderLabel( const QString& headerText)
|
||||
void BCMainWindow::initMainWindow()
|
||||
{
|
||||
|
||||
// Lambda um die buttons mit ihren Actions zu verbinden
|
||||
auto configureAction = [&]( QToolButton* button, QAction* action, BCDevice::ID deviceID )
|
||||
{
|
||||
|
||||
// Action an den Button binden
|
||||
button->setDefaultAction( action);
|
||||
// old school, not used
|
||||
//connect( action, &QAction::triggered, this, &BCMainWindow::onActionButtonTriggered );
|
||||
//connect( action, &QAction::toggled, this, &BCMainWindow::onActionButtonToggled );
|
||||
|
||||
// new way: die DeviceID muss aber explizit vom Lambda eingefanden werden.
|
||||
connect( action, &QAction::triggered, this, [this,deviceID]()
|
||||
@@ -114,11 +117,11 @@ void BCMainWindow::initMainWindow()
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Wir wollen die Devices den Views zuordnen können
|
||||
_devicePanels[BCDevice::ID::Console] = _consolePanel;
|
||||
_devicePanels[BCDevice::ID::Battery] = _batteryPanel;
|
||||
_devicePanels[BCDevice::ID::Motor] = _motorPanel;
|
||||
_devicePanels[BCDevice::ID::Pimp] = _pimpPanel;
|
||||
|
||||
// Die actions an die Buttons binden
|
||||
configureAction(_motorButton, _motorAction, BCDevice::ID::Motor );
|
||||
@@ -161,7 +164,7 @@ void BCMainWindow::initMainWindow()
|
||||
|
||||
_worker.start();
|
||||
|
||||
bc::processEventsFor(2000);
|
||||
|
||||
|
||||
// die Daten des eBikes laden
|
||||
_dataManager.loadXmlBikeData(":/bikeinfo.xml"_L1);
|
||||
|
||||
@@ -95,6 +95,7 @@ class ThemeSwitchButton : public QPushButton
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit ThemeSwitchButton(QWidget *parent = nullptr)
|
||||
: QPushButton(parent), m_isDarkMode(true)
|
||||
{
|
||||
@@ -103,9 +104,9 @@ public:
|
||||
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"(
|
||||
// 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;
|
||||
@@ -113,7 +114,7 @@ public:
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: rgba(128, 128, 128, 30); // Leichter Hover-Effekt
|
||||
border-radius: 4px;
|
||||
border-radius: 24px;
|
||||
}
|
||||
)");
|
||||
|
||||
|
||||
@@ -47,12 +47,11 @@ void BCTransmitter::onToggleConnectionState( bool connect )
|
||||
{
|
||||
if( connect )
|
||||
{
|
||||
if( _canDriver->getState() != BCDriver::DriverState::Ready )
|
||||
if( _canDriver->getState() != BCDriver::DriverState::DeviceReady )
|
||||
_canDriver->onStartDriver();
|
||||
|
||||
// __fix!
|
||||
uint32_t hwVersion = _canDriver->readRawByte( (uint32_t)BCDevice::ID::Console, (uint8_t)BC::ID::Cons_Rev_Hw);
|
||||
|
||||
BCDriver::TransmitResult hwVersion = _canDriver->readRawByte( (uint32_t)BCDevice::ID::Console, (uint8_t)BC::ID::Cons_Rev_Hw);
|
||||
if(!hwVersion)
|
||||
{
|
||||
qDebug() << "Console not responding";
|
||||
@@ -63,7 +62,7 @@ void BCTransmitter::onToggleConnectionState( bool connect )
|
||||
|
||||
}
|
||||
|
||||
qDebug() << " ---HAIL to the kings: " << hwVersion;
|
||||
qDebug() << " ---HAIL to the kings: " << hwVersion.value();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,9 +140,9 @@ void BCTransmitter::processValueOp( BCValue::OpID opID )
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t BCTransmitter::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
uint8_t BCTransmitter::readByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
{
|
||||
uint32_t result{};
|
||||
BCDriver::TransmitResult result;
|
||||
try
|
||||
{
|
||||
result = _canDriver->readRawByte( deviceID, registerID );
|
||||
@@ -152,11 +151,11 @@ uint32_t BCTransmitter::readRawByte( uint32_t deviceID, uint8_t registerID ) c
|
||||
{
|
||||
qDebug() << " -- OUCH: read exception: " << exception.what();
|
||||
}
|
||||
return result;
|
||||
return result.value();
|
||||
|
||||
}
|
||||
|
||||
void BCTransmitter::writeRawByte( uint32_t deviceID, uint8_t registerID , uint8_t value ) const
|
||||
void BCTransmitter::writeByte( uint32_t deviceID, uint8_t registerID , uint8_t value ) const
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
|
||||
explicit BCTransmitter(QObject *parent = nullptr);
|
||||
|
||||
uint32_t readRawByte( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
void writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
uint8_t readByte( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
void writeByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
public slots:
|
||||
|
||||
|
||||
@@ -66,8 +66,8 @@ class BCAbstractTransmitter
|
||||
|
||||
public:
|
||||
|
||||
virtual uint32_t readRawByte( uint32_t deviceID, uint8_t registerID ) const = 0;
|
||||
virtual void writeRawByte( uint32_t deviceID, uint8_t registerID , uint8_t value_ ) const = 0;
|
||||
virtual uint8_t readByte ( uint32_t deviceID, uint8_t registerID ) const = 0;
|
||||
virtual void writeByte( uint32_t deviceID, uint8_t registerID, uint8_t value_ ) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ BCValueTypeByte::BCValueTypeByte( QString unitLabel_, double factor_, optDouble
|
||||
|
||||
QString BCValueTypeByte::createStringValue( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID ) const
|
||||
{
|
||||
uint32_t result = transmitter.readRawByte( deviceID, registerID );
|
||||
uint8_t result = transmitter.readByte( deviceID, registerID );
|
||||
return formatValue( result );
|
||||
}
|
||||
|
||||
@@ -124,9 +124,9 @@ QString BCValueTypeWord::createStringValue( const BCAbstractTransmitter& transmi
|
||||
{
|
||||
//getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)),
|
||||
// hi byte
|
||||
uint32_t result = transmitter.readRawByte( deviceID, registerID ) << 8;
|
||||
uint8_t result = transmitter.readByte( deviceID, registerID ) << 8;
|
||||
// low byte, use followup register: +1
|
||||
result += transmitter.readRawByte( deviceID, registerID+1 );
|
||||
result += transmitter.readByte( deviceID, registerID+1 );
|
||||
|
||||
return formatValue( result );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user