Added missing file manual to repo
This commit is contained in:
56
bc.cpp
Normal file
56
bc.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
#include <QElapsedTimer>
|
||||
#include <QApplication>
|
||||
#include <QChar>
|
||||
|
||||
#include <bc.h>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
namespace bc
|
||||
{
|
||||
|
||||
void delay_seconds( uint32_t tval )
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::seconds( tval ) );
|
||||
}
|
||||
|
||||
|
||||
void delay_millis( uint32_t tval )
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds( tval ) );
|
||||
}
|
||||
|
||||
|
||||
void delay_micros( uint32_t tval )
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::microseconds( tval ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Macht aus int x den String 000x zum schönaussehen.
|
||||
* @param count der Wert
|
||||
* @param len die voranzustellenden Nullen
|
||||
*
|
||||
* Macht aus int x den String 000x zum schönaussehen.
|
||||
*
|
||||
*/
|
||||
|
||||
QString formatInt( int count, int len )
|
||||
{
|
||||
QString result( "%0" );
|
||||
result = result.arg( count, len, 10, QChar( '0' ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void processEventsFor(int milliseconds)
|
||||
{
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
while (timer.elapsed() < milliseconds) {
|
||||
QApplication::processEvents(QEventLoop::AllEvents, 50);
|
||||
}
|
||||
}
|
||||
} // namespace cbc
|
||||
88
bccandriver.cpp
Normal file
88
bccandriver.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include <bccandriver.h>
|
||||
|
||||
|
||||
|
||||
BCCanDriver::BCCanDriver(QObject* parent )
|
||||
: QObject{ parent }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BCCanDriver::dState BCCanDriver::getState()
|
||||
{
|
||||
return _driverState;
|
||||
}
|
||||
|
||||
void BCCanDriver::setState( dState newState )
|
||||
{
|
||||
_driverState = newState;
|
||||
}
|
||||
|
||||
QString BCCanDriver::stateLabel( dState state )
|
||||
{
|
||||
switch( (int) state )
|
||||
{
|
||||
case sDriverError:
|
||||
return stDriverError;
|
||||
|
||||
case sIdle:
|
||||
return stIdle;
|
||||
|
||||
case sLoaded:
|
||||
return stLoaded;
|
||||
|
||||
case sReady:
|
||||
return stReady;
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @brief Der Slot, der das Initialisieren des Treibers auslöst.
|
||||
* Teilt sich in die zwei Etappen
|
||||
* - Driver dll laden
|
||||
* - Driver mit der Console verbinden
|
||||
* D.h. initDriver kann als Wiedereinstiegspunkt
|
||||
* verwendet werden, falls der Treiber geladen wurde,
|
||||
* aber die Console noch nicht eingeschaltet war.
|
||||
*/
|
||||
|
||||
void BCCanDriver::onStartDriver()
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
// erstmal die Dll Laden: State::sIdle -> State::sLoaded
|
||||
if( BCCanDriver::sIdle == _driverState )
|
||||
_driverState = loadDriver();
|
||||
|
||||
emit stateChanged( (int) _driverState );
|
||||
|
||||
// DLL geladen, Verbindungsversuch
|
||||
_driverState = initDriver();
|
||||
|
||||
// Wir haben was erreicht
|
||||
emit stateChanged( (int) _driverState );
|
||||
}
|
||||
catch( std::exception& except )
|
||||
{
|
||||
//::CanDownDriver();
|
||||
//::UnloadDriver();
|
||||
|
||||
emit errorOccured( except.what() );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
void BCCanDriver::onLoadItem( CBCItem& item )
|
||||
{
|
||||
|
||||
item.setValue( 99.99 );
|
||||
emit itemLoaded( item );
|
||||
}
|
||||
*/
|
||||
113
bccandriver.h
Normal file
113
bccandriver.h
Normal file
@@ -0,0 +1,113 @@
|
||||
#ifndef BCCANDRIVER_H
|
||||
#define BCCANDRIVER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <bc.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 BCCanDriverStatus;
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* Die hier relevante Implementierung über das TinyCan System
|
||||
* findet sich in der Unterklasse 'BCCanDriverTinyCan'.
|
||||
*
|
||||
* @see BCCanDriverTinyCan
|
||||
*/
|
||||
|
||||
|
||||
class BCCanDriver : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
typedef enum
|
||||
{
|
||||
sDriverError = 0,
|
||||
sIdle,
|
||||
sLoaded,
|
||||
sReady,
|
||||
dStateSize
|
||||
} dState;
|
||||
|
||||
[[maybe_unused]] constexpr static const char* stDriverError = "Error";
|
||||
[[maybe_unused]] constexpr static const char* stIdle = "[not loaded]";
|
||||
[[maybe_unused]] constexpr static const char* stLoaded = "[not connected]";
|
||||
[[maybe_unused]] constexpr static const char* stReady = "Ready";
|
||||
|
||||
static QString stateLabel( dState state );
|
||||
|
||||
explicit BCCanDriver( QObject* parent = nullptr );
|
||||
virtual ~BCCanDriver() = default;
|
||||
|
||||
dState getState();
|
||||
|
||||
virtual BCCanDriver::dState loadDriver() = 0;
|
||||
virtual BCCanDriver::dState initDriver() = 0;
|
||||
|
||||
virtual uint getValue( BCDevice::ID dev, BC::ID reg ) = 0;
|
||||
virtual void setValue( BCDevice::ID dev, BC::ID reg, int value ) = 0;
|
||||
|
||||
signals:
|
||||
|
||||
void errorOccured( const QString& errMsg );
|
||||
void statusHint( const QString& msg );
|
||||
|
||||
void stateChanged( int state );
|
||||
void itemReady( const QString& label );
|
||||
void itemLoaded( CBCItem& item );
|
||||
|
||||
public slots:
|
||||
|
||||
void onStartDriver();
|
||||
//void onLoadItem( CBCItem& item );
|
||||
|
||||
protected:
|
||||
|
||||
void setState( dState newState );
|
||||
|
||||
dState _driverState = sIdle;
|
||||
|
||||
int _retries = 5;
|
||||
int _timeOuts = 20;
|
||||
|
||||
};
|
||||
|
||||
#endif // BCCANDRIVER_H
|
||||
219
bccandrivertinycan.cpp
Normal file
219
bccandrivertinycan.cpp
Normal file
@@ -0,0 +1,219 @@
|
||||
#include <bccandrivertinycan.h>
|
||||
|
||||
|
||||
//#define UNLIMITED_SPEED_VALUE 70 /* Km/h */
|
||||
//#define UNLIMITED_MIN_SPEED_VALUE 30 /* Km/h */
|
||||
//#define MAX_THROTTLE_SPEED_VALUE 70 /* Km/h */
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
#include <bccandrivertinycan.h>
|
||||
|
||||
|
||||
#include <can_drv.h>
|
||||
//#include "mhstcan.h"
|
||||
|
||||
BCCanDriverTinyCan::BCCanDriverTinyCan( QObject* parent )
|
||||
: BCCanDriver(parent )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
BCCanDriver::dState BCCanDriverTinyCan::loadDriver()
|
||||
{
|
||||
|
||||
//qDebug() << "CanBusControl " << cbc::Version << '\n' << "based on BigXionFlasher (c) 2011-2013 by Thomas Koenig <info@bigxionflasher.org> - www.bigxionflasher.org";
|
||||
|
||||
struct ::TDeviceStatus status;
|
||||
|
||||
if( ::LoadDriver( NULL ) < 0 )
|
||||
throw std::runtime_error( "Driver Error: 'LoadDriver'" );
|
||||
|
||||
if( ::CanInitDriver( NULL ) < 0 )
|
||||
throw std::runtime_error( "Driver Error: 'InitDriver'" );
|
||||
|
||||
if( ::CanDeviceOpen( 0, NULL ) < 0 )
|
||||
throw std::runtime_error( "Driver Error: 'DeviceOpen'" );
|
||||
|
||||
::CanSetSpeed( 0, CAN_125K_BIT );
|
||||
::CanSetMode( 0, OP_CAN_START, CAN_CMD_ALL_CLEAR );
|
||||
::CanGetDeviceStatus( 0, &status );
|
||||
|
||||
if( status.DrvStatus < DRV_STATUS_CAN_OPEN )
|
||||
throw std::runtime_error( "Driver Error: could not open device." );
|
||||
|
||||
if( status.CanStatus == CAN_STATUS_BUS_OFF )
|
||||
{
|
||||
::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE );
|
||||
throw std::runtime_error( "Driver Error: CAN Status 'BusOff'" );
|
||||
}
|
||||
|
||||
setState(BCCanDriver::sLoaded);
|
||||
|
||||
return BCCanDriver::sLoaded;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
try
|
||||
{
|
||||
loadDriver();
|
||||
initBCDevice::ID::Console();
|
||||
}
|
||||
|
||||
catch( std::exception& except )
|
||||
{
|
||||
::CanDownDriver();
|
||||
::UnloadDriver();
|
||||
|
||||
// re-throw
|
||||
throw std::runtime_error( except.what() );
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
BCCanDriver::dState BCCanDriverTinyCan::initDriver()
|
||||
{
|
||||
|
||||
qDebug() << "XXX BCCanDriverTinyCan::Driver Init: putting BCDevice::ID::Console in slave mode ... ";
|
||||
// BCDevice::ID::Console already in slave mode. good!
|
||||
if( getValue( BCDevice::ID::Console, BC::ID::Cons_Status_Slave ) )
|
||||
return BCCanDriver::sReady;
|
||||
|
||||
qDebug() << "BCCanDriverTinyCan::BCCanDriverTinyCan::XXX Driver Init: putting BCDevice::ID::Console in slave mode ... ";
|
||||
|
||||
unsigned int retry = _timeOuts;
|
||||
emit statusHint( "Driver Init: putting BCDevice::ID::Console in slave mode ... " );
|
||||
|
||||
int isSlave = 0;
|
||||
do
|
||||
{
|
||||
setValue( BCDevice::ID::Console, BC::ID::Cons_Status_Slave, 1 );
|
||||
isSlave = getValue( BCDevice::ID::Console, BC::ID::Cons_Status_Slave );
|
||||
bc::delay_millis( 200 );
|
||||
|
||||
} while( retry-- && !isSlave );
|
||||
|
||||
bc::delay_millis( 500 ); // give the Console some time to settle
|
||||
//if( !isSlave )
|
||||
emit statusHint( QString("putting BCDevice::ID::Console in slave mode ") + (isSlave ? "done" : "failed") );
|
||||
// ist das jetzt irgendwie schlimm, wenn wir keine slave BCDevice::ID::Console haben
|
||||
//return isSlave ? BCCanDriver::connected
|
||||
|
||||
return BCCanDriver::sReady;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//unsigned int BCCanDriverTinyCan::getValue( unsigned char receipient, unsigned char reg )
|
||||
uint BCCanDriverTinyCan::getValue(BCDevice::ID deviceID, BC::ID registerID )
|
||||
{
|
||||
|
||||
struct TCanMsg msg;
|
||||
|
||||
uint32_t device = static_cast<uint32_t>(deviceID);
|
||||
uint32_t reg = static_cast<uint32_t>(registerID);
|
||||
|
||||
// msg verpacken
|
||||
msg.MsgFlags = 0L;
|
||||
msg.Id = device;
|
||||
msg.MsgLen = 2;
|
||||
msg.MsgData[0] = 0x00;
|
||||
msg.MsgData[1] = reg;
|
||||
|
||||
// msg verschicken
|
||||
::CanTransmit( 0, &msg, 1 );
|
||||
|
||||
int retries = _retries;
|
||||
// _timeOuts (== 20) mal cTIMEOUT_MS (== 10 ms ) Versuche ...
|
||||
int timeOuts = _timeOuts;
|
||||
|
||||
// ... warten bis der Sendepuffer leer ist
|
||||
while( timeOuts-- && ::CanTransmitGetCount( 0 ) )
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if( timeOuts == -1 )
|
||||
throw std::runtime_error( "getValue error: could not send value" );
|
||||
|
||||
retry:
|
||||
|
||||
// _timeOuts (== 20) mal cTIMEOUT_MS (== 10 ms ) Versuche ...
|
||||
timeOuts = _timeOuts;
|
||||
// ... warten, bis der Empfangspuffer nicht mehr leer ist
|
||||
while( timeOuts-- && !::CanReceiveGetCount( 0 ) )
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if( timeOuts == -1 )
|
||||
throw std::runtime_error( "getValue error: no response from node" );
|
||||
|
||||
// message empfangen
|
||||
int err = ::CanReceive( 0, &msg, 1 );
|
||||
qDebug() << "HÄÄ ?" << err << "reg: "<< reg <<" timeOuts: " << timeOuts;
|
||||
|
||||
if( err < 0 )
|
||||
//throw std::runtime_error( "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];
|
||||
|
||||
//if( err > 0 )
|
||||
if( --retries && ( msg.Id != BIB || msg.MsgLen != 4 || msg.MsgData[1] != reg ) )
|
||||
goto retry;
|
||||
|
||||
if( !timeOuts )
|
||||
throw std::runtime_error( "CAN --response errror" );
|
||||
|
||||
return (unsigned int) msg.MsgData[3];
|
||||
|
||||
}
|
||||
|
||||
|
||||
// void BCCanDriverTinyCan::setValue( unsigned char receipient, unsigned char reg, unsigned char value )
|
||||
void BCCanDriverTinyCan::setValue(BCDevice::ID deviceID, BC::ID registerID, int value )
|
||||
{
|
||||
|
||||
qDebug() << "SaveItem( BCCanDriverTinyCan::CBCItem& item ): ";
|
||||
|
||||
uint32_t device = static_cast<uint32_t>(deviceID);
|
||||
uint32_t reg = static_cast<uint32_t>(registerID);
|
||||
|
||||
struct TCanMsg msg;
|
||||
int timeout_count = cTIMEOUT_COUNT;
|
||||
|
||||
msg.MsgFlags = 0L;
|
||||
msg.Id = device;
|
||||
msg.MsgLen = 4;
|
||||
msg.MsgData[0] = 0x00;
|
||||
msg.MsgData[1] = reg;
|
||||
msg.MsgData[2] = 0x00;
|
||||
msg.MsgData[3] = value;
|
||||
|
||||
::CanTransmit( 0, &msg, 1 );
|
||||
|
||||
while( timeout_count-- && ::CanTransmitGetCount( 0 ) )
|
||||
bc::delay_millis( cTIMEOUT_MS );
|
||||
|
||||
if( timeout_count == -1 )
|
||||
emit statusHint( QString( "error: could not send value to %1" ).arg( device ) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void BCCanDriverTinyCan::awaitReceiveBuf( int timeout )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BCCanDriverTinyCan::awaitSendBuf(int timeout )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
47
bccandrivertinycan.h
Normal file
47
bccandrivertinycan.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef BCCANDRIVERTINYCAN_H
|
||||
#define BCCANDRIVERTINYCAN_H
|
||||
|
||||
#include <bccandriver.h>
|
||||
|
||||
class BCCanDriverTinyCan : public BCCanDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCCanDriverTinyCan( QObject* parent=nullptr );
|
||||
virtual ~BCCanDriverTinyCan() = default;
|
||||
|
||||
BCCanDriver::dState loadDriver() override;
|
||||
BCCanDriver::dState initDriver() override;
|
||||
|
||||
uint getValue( BCDevice::ID dev, BC::ID reg ) override;
|
||||
void setValue( BCDevice::ID dev, BC::ID reg, int value ) override;
|
||||
|
||||
QString getNodeName( unsigned char id );
|
||||
|
||||
protected:
|
||||
|
||||
// typen?
|
||||
//void setValue( unsigned char receipient, unsigned char reg, unsigned char value );
|
||||
//unsigned int getValue( unsigned char receipient, unsigned char reg );
|
||||
|
||||
void awaitReceiveBuf( int timeout );
|
||||
void awaitSendBuf(int timeout );
|
||||
|
||||
const char* CBCDLL_LIN = "libmhstcan.so";
|
||||
const char* CBCDLL_WIN = "mhstcan.dll";
|
||||
|
||||
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 // BCCANDRIVERTINYCAN_H
|
||||
131
bctransmitter.cpp
Normal file
131
bctransmitter.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include <QThread>
|
||||
#include <QDebug>
|
||||
|
||||
#include <bctransmitter.h>
|
||||
|
||||
|
||||
BCTransmitter::BCTransmitter(QObject *parent)
|
||||
: QObject(parent), _isBusy(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void BCTransmitter::onToggleConnectionState( bool connect )
|
||||
{
|
||||
if( connect )
|
||||
{
|
||||
if( BCCanDriver::sIdle == _canDriver.getState() )
|
||||
_canDriver.onStartDriver();
|
||||
|
||||
int hwVersion = _canDriver.getValue( BCDevice::ID::Console, BC::ID::Cons_Rev_Hw);
|
||||
|
||||
if (hwVersion == 0)
|
||||
{
|
||||
qDebug() << "Console not responding";
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
swVersion = getValue(CONSOLE, CONSOLE_REF_SW);
|
||||
printf( "Console information:" _NL
|
||||
" hardware version ........: %02d" _NL
|
||||
" software version ........: %02d" _NL
|
||||
" assistance level ........: %d" _NL,
|
||||
hwVersion, swVersion,
|
||||
getValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL)
|
||||
);
|
||||
|
||||
if (!gNoSerialNumbers)
|
||||
printf( " part number .............: %05d" _NL
|
||||
" item number .............: %05d" _NL _NL,
|
||||
((getValue(CONSOLE, CONSOLE_SN_PN_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_PN_LO)),
|
||||
((getValue(CONSOLE, CONSOLE_SN_ITEM_HI) << 8) + getValue(CONSOLE, CONSOLE_SN_ITEM_LO))
|
||||
);
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
qDebug() << " ---HAIL to the kings: " << hwVersion;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BCTransmitter::enqueueValueCommand(BC::OpID opID, const BCValue& value)
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
_valueQueue.enqueue( std::ref(value) );
|
||||
|
||||
// Logging (Thread-safe via Signal)
|
||||
//emit messageLogged(QString("Command %1 queued.").arg(cmd.label));
|
||||
|
||||
// wir wollen nicht den ganzen Value verschicken, erstrecht
|
||||
// wollen wir den Value in verschiedenen Threads gleichzeitig
|
||||
// in die Hand nehmen, also hantieren wir nur mit den Inidizes.
|
||||
|
||||
// Trigger processing im Event-Loop des Worker Threads
|
||||
// invokeMethod mit QueuedConnection entkoppelt den Aufruf,
|
||||
// damit enqueueValueCommand sofort zurückkehrt (non-blocking für den Aufrufer).
|
||||
|
||||
//QMetaObject::invokeMethod(this, "processValueCommand", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(this, [this, opID]()
|
||||
{
|
||||
this->processValueCommand(opID);
|
||||
}, Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
void BCTransmitter::processValueCommand( BC::OpID opID )
|
||||
{
|
||||
|
||||
if (_isBusy)
|
||||
return;
|
||||
|
||||
_isBusy = true;
|
||||
|
||||
while (true)
|
||||
{
|
||||
BCValue currentValue;
|
||||
{
|
||||
QMutexLocker locker(&_mutex);
|
||||
if (_valueQueue.isEmpty())
|
||||
{
|
||||
_isBusy = false;
|
||||
break; // Schleife verlassen, warten auf neue Events
|
||||
}
|
||||
currentValue =_valueQueue.dequeue();
|
||||
} // Mutex wird hier freigegeben! WICHTIG: Execute ohne Lock!
|
||||
|
||||
std::optional<uint32_t> result;
|
||||
// 3. Ausführung (Dauert potentiell lange)
|
||||
if( opID == BC::OpID::ReadValue )
|
||||
result = executeRead(currentValue);
|
||||
else if( opID == BC::OpID::WriteValue )
|
||||
result = executeRead(currentValue);
|
||||
|
||||
//emit commandFinished(cmd.id, true);
|
||||
//emit commandFinished(0, true);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<uint32_t> BCTransmitter::executeRead(const BCValue& value)
|
||||
{
|
||||
|
||||
std::optional<uint32_t> result;
|
||||
switch( value.deviceID )
|
||||
{
|
||||
// hier lacht der blaue riesenhase!
|
||||
case BCDevice::ID::Invalid:
|
||||
case BCDevice::ID::Console:
|
||||
case BCDevice::ID::Console_Master:
|
||||
case BCDevice::ID::Battery:
|
||||
case BCDevice::ID::Motor:
|
||||
case BCDevice::ID::BIB:
|
||||
case BCDevice::ID::Sensor:
|
||||
break;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
std::optional<uint32_t> BCTransmitter::executeWrite(const BCValue& value)
|
||||
{
|
||||
|
||||
}
|
||||
47
bctransmitter.h
Normal file
47
bctransmitter.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef BCTRANSMITTER_H
|
||||
#define BCTRANSMITTER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QQueue>
|
||||
#include <QMutex>
|
||||
#include <functional>
|
||||
#include <atomic>
|
||||
|
||||
#include <bcvalue.h>
|
||||
#include <bccandrivertinycan.h>
|
||||
|
||||
class BCTransmitter : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCTransmitter(QObject *parent = nullptr);
|
||||
|
||||
public slots:
|
||||
|
||||
void onToggleConnectionState( bool connect );
|
||||
void enqueueValueCommand(BC::OpID opID, const BCValue& value);
|
||||
void processValueCommand(BC::OpID opID);
|
||||
|
||||
signals:
|
||||
|
||||
void commandFinished(int id, bool success);
|
||||
void messageLogged(const QString& msg);
|
||||
|
||||
private:
|
||||
|
||||
std::optional<uint32_t> executeRead(const BCValue& value);
|
||||
std::optional<uint32_t> executeWrite(const BCValue& value);
|
||||
|
||||
using BCValueQueue = QQueue<std::reference_wrapper<const BCValue>>;
|
||||
|
||||
BCValueQueue _valueQueue;
|
||||
QMutex _mutex;
|
||||
std::atomic<bool> _isBusy{ false };
|
||||
|
||||
BCCanDriverTinyCan _canDriver;
|
||||
};
|
||||
|
||||
|
||||
#endif // BCTRANSMITTER_H
|
||||
Reference in New Issue
Block a user