first re-commit.
This commit is contained in:
279
SWPiGPIO.cpp
Normal file
279
SWPiGPIO.cpp
Normal file
@@ -0,0 +1,279 @@
|
||||
/***************************************************************************
|
||||
|
||||
source::worx PiGPIO
|
||||
Copyright © 2022 c.holzheuer
|
||||
chris@sourceworx.org
|
||||
|
||||
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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QDebug>
|
||||
|
||||
#include <SWPiGPIO.h>
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
|
||||
#include <cstdint>
|
||||
//#include <pigpio.h>
|
||||
//#include "/usr/include/pigpio.h"
|
||||
|
||||
#include <pigpiod_if2.h>
|
||||
|
||||
PiGPIO::PiGPIO()
|
||||
{
|
||||
//::gpioInitialise();
|
||||
// Connect to Pi.
|
||||
constexpr char* optHost = nullptr;
|
||||
constexpr char* optPort = nullptr;
|
||||
PI = ::pigpio_start( optHost, optPort );
|
||||
qDebug() << " -- PiGPIO::PiGPIO(): " << PI;
|
||||
if( PI < 0 )
|
||||
qDebug() << "-- PiGPIO::PiGPIO() FAIL";
|
||||
}
|
||||
|
||||
|
||||
PiGPIO::~PiGPIO()
|
||||
{
|
||||
::pigpio_stop( PI );
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Implementierung für Linux
|
||||
*/
|
||||
|
||||
PiGRotaryDial::PiGRotaryDial( unsigned dialA, unsigned dialB, unsigned button, QObject* parent )
|
||||
: QObject( parent ),
|
||||
_dialA( dialA ), _dialB( dialB ), _button( button )
|
||||
|
||||
{
|
||||
|
||||
_Pi = PiGPIO::Instance().PI;
|
||||
|
||||
//_mode = mode;
|
||||
//_cb = cb_func;
|
||||
_levA = 0;
|
||||
_levB = 0;
|
||||
_step = 0;
|
||||
|
||||
::set_mode( _Pi, _dialA, PI_INPUT );
|
||||
::set_mode( _Pi, _dialB, PI_INPUT );
|
||||
::set_mode( _Pi, _button, PI_INPUT );
|
||||
|
||||
// pull up is needed as encoder common is grounded
|
||||
|
||||
::set_pull_up_down( _Pi, _dialA, PI_PUD_UP );
|
||||
::set_pull_up_down( _Pi, _dialB, PI_PUD_UP );
|
||||
::set_pull_up_down( _Pi, _button, PI_PUD_UP );
|
||||
|
||||
_glitch = 1000;
|
||||
|
||||
::set_glitch_filter( _Pi, _dialA, _glitch );
|
||||
::set_glitch_filter( _Pi, _dialB, _glitch );
|
||||
::set_glitch_filter( _Pi, _button, _glitch );
|
||||
|
||||
_oldState = ( ::gpio_read( _Pi, _dialA ) << 1) | ::gpio_read( _Pi, _dialB );
|
||||
|
||||
// monitor encoder level changes
|
||||
//int callback_ex(int pi, unsigned user_gpio, unsigned edge, CBFuncEx_t f, void *userdata)
|
||||
// typedef void (*CBFuncEx_t)(int pi, unsigned user_gpio, unsigned level, uint32_t tick, void * userdata);
|
||||
_callbackIdA = ::callback_ex( _Pi, _dialA, EITHER_EDGE, PiGPIOPulse, this );
|
||||
_callbackIdB = ::callback_ex( _Pi, _dialB, EITHER_EDGE, PiGPIOPulse, this );
|
||||
_callbackIdC = ::callback_ex( _Pi, _button, EITHER_EDGE, PiGPIOPulse, this );
|
||||
}
|
||||
|
||||
|
||||
PiGRotaryDial::~PiGRotaryDial()
|
||||
{
|
||||
|
||||
if( _callbackIdA >= 0 )
|
||||
{
|
||||
::callback_cancel( _callbackIdA );
|
||||
_callbackIdA = -1;
|
||||
}
|
||||
|
||||
if( _callbackIdB >= 0 )
|
||||
{
|
||||
::callback_cancel( _callbackIdB );
|
||||
_callbackIdB = -1;
|
||||
}
|
||||
|
||||
if( _callbackIdC >= 0 )
|
||||
{
|
||||
::callback_cancel( _callbackIdC );
|
||||
_callbackIdC = -1;
|
||||
}
|
||||
|
||||
::set_glitch_filter( _Pi, _dialA, 0 );
|
||||
::set_glitch_filter( _Pi, _dialB, 0 );
|
||||
::set_glitch_filter( _Pi, _button, 0 );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PiGRotaryDial::setGlitchFilter( int glitch )
|
||||
{
|
||||
if( _glitch == glitch )
|
||||
return;
|
||||
_glitch = glitch;
|
||||
::set_glitch_filter( _Pi, _dialA, glitch );
|
||||
::set_glitch_filter( _Pi, _dialB, glitch );
|
||||
::set_glitch_filter( _Pi, _button, glitch );
|
||||
}
|
||||
|
||||
|
||||
void PiGRotaryDial::pulse( unsigned gpio, unsigned level )
|
||||
{
|
||||
|
||||
|
||||
if( level == PI_TIMEOUT )
|
||||
return;
|
||||
if( gpio == _button )
|
||||
return handleClick( level );
|
||||
|
||||
if( gpio == _dialA )
|
||||
_levA = level;
|
||||
else
|
||||
_levB = level;
|
||||
|
||||
// sourceworx proudly presents:
|
||||
// den primitivstmöglichen Auslese-algorithmus
|
||||
// für Rotary-Dials.
|
||||
// Die klugen Varianten stehen hier:
|
||||
// https://www.best-microcontroller-projects.com/rotary-encoder.html
|
||||
// https://web.engr.oregonstate.edu/~traylor/ece473/student_projects/ReadingEncoderSwitches.pdf
|
||||
|
||||
// wenn sich was geändert hatte ...
|
||||
if( gpio == _dialB && level == 1 )
|
||||
{
|
||||
// bestimmt der andere Kontakt die
|
||||
// die Drehrichtung
|
||||
|
||||
int delta = _levA ? -1 : +1;
|
||||
//qDebug() << "###### EMIT: " << delta;
|
||||
emit deltaChanged( delta );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PiGRotaryDial::handleClick( unsigned level )
|
||||
{
|
||||
if( !_pressed && level == 0 )
|
||||
{
|
||||
_pressed = true;
|
||||
return;
|
||||
}
|
||||
if( _pressed && level == 1 )
|
||||
{
|
||||
_pressed = false;
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // Q_OS_LINUX
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
source::worx PiGPIO
|
||||
Copyright © 2022 c.holzheuer
|
||||
chris@sourceworx.org
|
||||
|
||||
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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
|
||||
|
||||
PiGPIO::PiGPIO()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PiGPIO::~PiGPIO()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PiGRotaryDial::PiGRotaryDial( unsigned dialA, unsigned dialB, unsigned button, QObject* parent )
|
||||
: QObject( parent ),
|
||||
_dialA( dialA ), _dialB( dialB ), _button( button )
|
||||
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PiGRotaryDial::~PiGRotaryDial()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PiGRotaryDial::setGlitchFilter( int )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PiGRotaryDial::pulse( unsigned, unsigned )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif //Q_OS_WIN
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
source::worx PiGPIO
|
||||
Copyright © 2022 c.holzheuer
|
||||
chris@sourceworx.org
|
||||
|
||||
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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
|
||||
void PiGRotaryDial::PiGPIOPulse( int pi, unsigned gpio, unsigned level, uint32_t tick, void *user )
|
||||
{
|
||||
|
||||
Q_UNUSED( pi );
|
||||
Q_UNUSED( tick );
|
||||
|
||||
// Need a static callback to link with C.
|
||||
PiGRotaryDial* mySelf = static_cast<PiGRotaryDial*>( user );
|
||||
if( mySelf )
|
||||
mySelf->pulse( gpio, level ); // Call the instance callback.
|
||||
}
|
||||
|
||||
/*
|
||||
void PiGRotaryDial::setPosition( int position )
|
||||
{
|
||||
_step = position * 4;
|
||||
}
|
||||
|
||||
|
||||
int PiGRotaryDial::position()
|
||||
{
|
||||
return _step / 4;
|
||||
}
|
||||
*/
|
Reference in New Issue
Block a user