Added support for KY-040 rotary encoder to replace browse up/down/select buttons; all code

changes were annotated with //ROTARY: for easy review;
This commit is contained in:
George Belmont 2019-09-06 07:13:58 -04:00
parent c71fe6e1dc
commit b409732ddd
9 changed files with 687 additions and 4 deletions

View File

@ -1,6 +1,6 @@
OBJS = armc-start.o armc-cstartup.o armc-cstubs.o armc-cppstubs.o \ OBJS = armc-start.o armc-cstartup.o armc-cstubs.o armc-cppstubs.o \
exception.o main.o rpi-aux.o rpi-i2c.o rpi-mailbox-interface.o rpi-mailbox.o \ exception.o main.o rpi-aux.o rpi-i2c.o rpi-mailbox-interface.o rpi-mailbox.o \
rpi-gpio.o rpi-interrupts.o cache.o ff.o interrupt.o Keyboard.o performance.o \ rpi-gpio.o rpi-interrupts.o dmRotary.o cache.o ff.o interrupt.o Keyboard.o performance.o \
Drive.o Pi1541.o DiskImage.o iec_bus.o iec_commands.o m6502.o m6522.o \ Drive.o Pi1541.o DiskImage.o iec_bus.o iec_commands.o m6502.o m6522.o \
gcr.o prot.o lz.o emmc.o diskio.o options.o Screen.o SSD1306.o ScreenLCD.o \ gcr.o prot.o lz.o emmc.o diskio.o options.o Screen.o SSD1306.o ScreenLCD.o \
Timer.o FileBrowser.o DiskCaddy.o ROMs.o InputMappings.o xga_font_data.o m8520.o wd177x.o Pi1581.o SpinLock.o Timer.o FileBrowser.o DiskCaddy.o ROMs.o InputMappings.o xga_font_data.o m8520.o wd177x.o Pi1581.o SpinLock.o

View File

@ -107,3 +107,24 @@ GraphIEC = 1
//buttonDown = 3 //buttonDown = 3
//buttonBack = 4 //buttonBack = 4
//buttonInsert = 5 //buttonInsert = 5
//ROTARY:
//
// KY-040 Rotary Encoder Support
//
// If you would like to use a KY-040 Rotary Encoder for browse menu up/down
// and select, you can enable it here. Connect as follows:
//
// GPIO 22 - Menu up - Encoder pin A (CLK)
// GPIO 23 - Menu down - Encoder pin B (DT)
// GPIO 27 - Enter/Select - Encoder pushbutton (SW)
//
// ** Using an encoder is incompatible with the button remapping. You must
// use the default values of Enter=1, Up=2, Down=3, Back=4 and Insert=5.
//
// ** This has only been tested using a Raspberry Pi 3. Earlier models may
// or may not work as expected!
//
// Please see dmRotary.h for full implementation details.
//
//RotaryEncoderEnable = 1

285
src/dmRotary.cpp Normal file
View File

@ -0,0 +1,285 @@
/*
* dmRotary.cpp - A simple decoder to use a KY-040 rotary encoder for browse
* naviation in Pi1541.
*
* Copyright © 2019 devMash.com
*
* https://devMash.com
* https://github.com/devMashHub
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the Software), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#include "dmRotary.h"
//------------------------------------------------------------------------------
// Initialize
//
void RotaryEncoder::Initialize(rpi_gpio_pin_t clockGpioPin, rpi_gpio_pin_t dataGpioPin, rpi_gpio_pin_t switchGpioPin)
{
#ifdef DM_ROTARY_DEBUG
char message[1024] = "";
WriteToMiniUart("##########\r\n\r\n");
WriteToMiniUart("RotaryEncoder::Initialize()\r\n");
sprintf(message, " clockGpioPin = %d dataGpioPin = %d switchGpioPin = %d\r\n\r\n", clockGpioPin, dataGpioPin, switchGpioPin);
WriteToMiniUart(message);
#endif
//Store specified pins for polling method
_clockPin.SetGpioPin(clockGpioPin);
_dataPin.SetGpioPin(dataGpioPin);
_switchPin.SetGpioPin(switchGpioPin);
//Set pins for input
RPI_SetGpioInput(clockGpioPin);
RPI_SetGpioInput(dataGpioPin);
RPI_SetGpioInput(switchGpioPin);
//Enable pull-ups
unsigned controlSignal = 2;
unsigned gpioPinMask = _clockPin.GetGpioPinMask() | _dataPin.GetGpioPinMask() | _switchPin.GetGpioPinMask();
SetGpioPullUpDown(controlSignal, gpioPinMask);
}
//------------------------------------------------------------------------------
// Poll
//
rotary_result_t RotaryEncoder::Poll()
{
//Read physical pin levels (GPLEV0 is pins 0 to 31)
unsigned gplev0 = read32(ARM_GPIO_GPLEV0);
return Poll(gplev0);
}
//------------------------------------------------------------------------------
// Poll
//
rotary_result_t RotaryEncoder::Poll(unsigned gplev0)
{
rotary_result_t result = NoChange;
#ifdef DM_ROTARY_DEBUG
char message[1024] = "";
#endif
//Decode switch
if (result == NoChange)
{
//Debounce switch and determine state
_switchPin.Update((gplev0 & _switchPin.GetGpioPinMask()) == 0);
bool switchState = _switchPin.GetState();
//Detect switch state change
if (switchState != _currentSwitchState)
{
//Determine result
result = switchState ? ButtonDown : ButtonUp;
//Update switch state
_currentSwitchState = switchState;
}
}
//Decode rotation
if (result == NoChange)
{
//Debounce clock and determine state
_clockPin.Update((gplev0 & _clockPin.GetGpioPinMask()) == 0);
bool clockState = _clockPin.GetState();
//Debounce data and determine state
_dataPin.Update((gplev0 & _dataPin.GetGpioPinMask()) == 0);
bool dataState = _dataPin.GetState();
//Detect rotary state change
int rotaryState = (clockState << 1) | dataState;
if (rotaryState != _currentRotaryState)
{
//Update rotary sequence
_currentRotarySequence = (_currentRotarySequence << 2) | rotaryState;
if (rotaryState == 0)
{
switch (_currentRotarySequence)
{
//Detect positive (clockwise) rotation
//
// 0xb4 - 00 10 11 01 00 - Received and decoded perfect sequence
// 0x2c - 00 10 11 00 - Missed data but decoded unique sequence
// 0x34 - 00 11 01 00 - Missed data but decoded unique sequence
// 0xb8 - 00 10 11 10 00 - Invalid sequence, using best guess
//
case 0xb4:
case 0x2c:
case 0x34:
case 0xb8:
result = RotatePositive;
break;
//Detect negative (counter-clockwise) rotation
//
// 0x78 - 00 01 11 10 00 - Received and decoded perfect sequence
// 0x1c - 00 01 11 00 - Missed data but decoded unique sequence
// 0x38 - 00 11 10 00 - Missed data but decoded unique sequence
// 0x74 - 00 01 11 01 00 - Invalid sequence, using best guess
//
case 0x78:
case 0x1c:
case 0x38:
case 0x74:
result = RotateNegative;
break;
#ifdef DM_ROTARY_DEBUG
//Unable to decode sequence
//
// 0x0c - 00 11 00 - No way to determine rotation direction
//
default:
if (_currentRotarySequence != 0x0c)
{
sprintf(message, "decode failed: %x\r\n", _currentRotarySequence);
WriteToMiniUart(message);
}
break;
#endif
}
//Clear rotary sequence
_currentRotarySequence = 0;
}
//Update rotary state
_currentRotaryState = rotaryState;
}
}
#ifdef DM_ROTARY_DEBUG
switch (result)
{
case NoChange:
break;
case ButtonDown:
WriteToMiniUart("Button Down\r\n");
break;
case ButtonUp:
WriteToMiniUart("Button Up\r\n");
break;
case RotatePositive:
WriteToMiniUart("Clockwise\r\n");
break;
case RotateNegative:
WriteToMiniUart("Counter-Clockwise\r\n");
break;
}
#endif
return result;
}
//------------------------------------------------------------------------------
// SetGpioPullUpDown
//
void RotaryEncoder::SetGpioPullUpDown(unsigned controlSignal, unsigned gpioPinMask)
{
volatile int i;
int delayCycles = 150;
// Write to GPPUD to set the required control signal
//
// 01 = Enable Pull-Down 00 = Off (disable pull-up/down)
// 10 = Enable Pull-Up 11 = Reserved
//
write32(ARM_GPIO_GPPUD, controlSignal);
// Delay cycles (to provide the required set-up time for the control signal)
for (i = 0; i < delayCycles; i++) { }
// Write to GPPUDCLK0/1 to clock the control signal into the GPIO pads
//
// Note: Only the pads which receive a clock will be modified, all others will
// retain their previous state.
//
write32(ARM_GPIO_GPPUDCLK0, gpioPinMask);
// Delay cycles (to provide the required hold time for the control signal)
for (i = 0; i < delayCycles; i++) { }
// Write to GPPUD to remove the control signal
write32(ARM_GPIO_GPPUD, 0);
//Write to GPPUDCLK0/1 to remove the clock
write32(ARM_GPIO_GPPUDCLK0, 0);
}
#ifdef DM_ROTARY_DEBUG
//------------------------------------------------------------------------------
// WriteToMiniUart
//
void RotaryEncoder::WriteToMiniUart(char* pMessage)
{
while(*pMessage)
{
RPI_AuxMiniUartWrite(*pMessage++);
}
}
#endif

250
src/dmRotary.h Normal file
View File

@ -0,0 +1,250 @@
/*
* dmRrotary.h - A simple decoder to use a KY-040 rotary encoder for browse
* naviation in Pi1541.
*
* Copyright © 2019 devMash.com
*
* https://devMash.com
* https://github.com/devMashHub
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the Software), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#ifndef DM_ROTARY_H
#define DM_ROTARY_H
extern "C"
{
#include "rpi-aux.h"
#include "rpiHardware.h"
}
//Enable debugging messages on the mini uart
//#define DM_ROTARY_DEBUG
//------------------------------------------------------------------------------
// rotary_result_t
//
typedef enum {
NoChange = 0,
ButtonDown = 1,
ButtonUp = 2,
RotatePositive = 3, // clockwise rotation
RotateNegative = 4 // counter-clockwise rotation
} rotary_result_t;
//------------------------------------------------------------------------------
// RotaryPin
//
// NOTES:
//
// This helper class represents a single rotary encoder pin to encapsulate
// debouncing and state engine logic.
//
class RotaryPin
{
private:
rpi_gpio_pin_t _gpioPin = RPI_GPIO0;
int _count = 0;
int _threshold = 256; // I just like powers of two
bool _currentState = false;
public:
rpi_gpio_pin_t GetGpioPin() const { return _gpioPin; }
void SetGpioPin(rpi_gpio_pin_t value) { _gpioPin = value; }
unsigned GetGpioPinMask() { return (1 << _gpioPin); }
bool GetState() const { return _currentState; }
void Update(bool state)
{
_count += state ? 1 : -1;
bool newState = _currentState;
if (_count <= 0)
{
_count = 0;
newState = false;
}
else if (_count >= _threshold)
{
_count = _threshold;
newState = true;
}
_currentState = newState;
}
};
//------------------------------------------------------------------------------
// RotaryEncoder
//
// NOTES:
//
// The KY-040 rotary encoder has the following pins:
//
// CLK - Encoder pin A
// DT - Encoder pin B
// SW - Pushbutton switch
// VCC - Supply voltage
// GND - Ground
//
//
// Decoding the KY-040
//
// Determining which encoder pin changes state first is how the direction
// of rotation is determined. If CLK changes state first, the encoder
// is rotating in a positive (clockwise) direction. If DT changes state
// first, the encoder is rotating in a negative (counter-clockwise) direction.
//
// The entire rotation sequence can be represented as a predictable bit
// pattern by mapping the CLK state in the higher bit and mapping the DT
// state in the lower bit:
//
// Positive rotation - 00 -> 10 -> 11 -> 01 -> 00 (0xb4)
// Negative rotation - 00 -> 01 -> 11 -> 10 -> 00 (0x78)
//
// To decode, we simply monitor the CLK and DT and watch for one of these
// two patterns.
//
// However, in the real world, some pin transitions can be missed due to
// lag during the polling interval or contact bounce - resulting in less
// than perfect decode sequences. To combat against this, the code will
// also accept several permutations that are 'close enough':
//
// Positive (clockwise) rotation:
//
// 0xb4 - 00 10 11 01 00 - Received and decoded perfect sequence
// 0x2c - 00 10 11 00 - Missed data but decoded unique sequence
// 0x34 - 00 11 01 00 - Missed data but decoded unique sequence
// 0xb8 - 00 10 11 10 00 - Invalid but usually denotes positive
//
// Detect negative (counter-clockwise) rotation:
//
// 0x78 - 00 01 11 10 00 - Received and decoded perfect sequence
// 0x1c - 00 01 11 00 - Missed data but decoded unique sequence
// 0x38 - 00 11 10 00 - Missed data but decoded unique sequence
// 0x74 - 00 01 11 01 00 - Invalid but usually denotes negative
//
//
// Wiring the KY-040
//
// The GPIO pins used for the rotary encoder are specified when initializing
// the class. However, it is probably a good idea to reuse the same pins as
// the original Pi1541 pushbuttons:
//
// GPIO 22 - Menu up - Encoder pin A (CLK)
// GPIO 23 - Menu down - Encoder pin B (DT)
// GPIO 27 - Enter/Select - Encoder pushbutton (SW)
//
//
// USAGE:
//
// *** Please Note! I have only tried this with a Raspberry Pi 3. I have no
// reason to believe this wouldn't also work on an earlier model, but your
// results may vary!
//
// To use the RotaryEncoder, instance the class and initialize with the desired
// GPIO pins like this:
//
// //Initialize using CLK on GPIO22, DT on GPIO32 and SW on GPIO27
// RotaryEncoder rotaryEncoder;
// rotaryEncoder.Initialize(RPI_GPIO22, RPI_GPIO23, RPI_GPIO27);
//
// Monitor the encoder by calling the Poll() method during your main processing
// loop. The polling logic is constrained by only evaluating GPLEV0, which
// restricts usable pins to GPIO00 through GPIO31. An overloaded version of
// Poll() exists to accept a value representing GPLEV0 without having to
// perform a re-read (providing a small optimization when the current value of
// GPLEV0 is already available).
//
// // Read GPLEV0 and decode the rotary state
// rotary_result_t result = rotaryEncoder.Poll();
//
// or
//
// // Read GPLEV0 locally and decode the rotary state
// unsigned gplev0 = read32(ARM_GPIO_GPLEV0);
// { some other logic here }
// rotary_result_t result = rotaryEncoder.Poll(gplev0);
//
// Note, the Poll() logic depends on frequent polling of the encoder. Calling
// Poll() as often as possible/permissable will yield better decode results.
//
// Any event detected by the polling logic will be returned as the result
// from the polling method as a rotary_result_t. The controlling logic can
// then take whatever action is appropriate based on the result.
//
//
// HISTORY:
//
// 09/03/2019 - Initial implementation and notes
// 09/04/2019 - Integration into Pi1541 with shim logic to simulate 'original style' button presses
// 09/05/2019 - Code cleanup, improved documentation, options.txt logic, dynamic button indexes
//
class RotaryEncoder {
private:
// Switch data
RotaryPin _switchPin;
bool _currentSwitchState = false;
// Rotation data
RotaryPin _clockPin;
RotaryPin _dataPin;
int _currentRotaryState = 0;
int _currentRotarySequence = 0;
// Private methods
void SetGpioPullUpDown(unsigned controlSignal, unsigned gpioPinMask);
#ifdef DM_ROTARY_DEBUG
void WriteToMiniUart(char* pMessage);
#endif
public:
// Public methods
void Initialize(rpi_gpio_pin_t clkGpioPin, rpi_gpio_pin_t dtGpioPin, rpi_gpio_pin_t swGpioPin);
rotary_result_t Poll();
rotary_result_t Poll(unsigned gplev0);
};
#endif

View File

@ -73,17 +73,70 @@ u32 IEC_Bus::emulationModeCheckButtonIndex = 0;
unsigned IEC_Bus::gplev0; unsigned IEC_Bus::gplev0;
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
RotaryEncoder IEC_Bus::rotaryEncoder;
bool IEC_Bus::rotaryEncoderEnable;
//ROTARY: Modified for rotary encoder support - 09/05/2019 by Geo...
void IEC_Bus::ReadBrowseMode(void) void IEC_Bus::ReadBrowseMode(void)
{ {
gplev0 = read32(ARM_GPIO_GPLEV0); gplev0 = read32(ARM_GPIO_GPLEV0);
if (IEC_Bus::rotaryEncoderEnable == true)
{
int indexEnter = 0;
int indexUp = 1;
int indexDown = 2;
int indexBack = 3;
int indexInsert = 4;
//Poll the rotary encoder
//
// Note: If the rotary encoder returns any value other than 'NoChange' an
// event has been detected. We force the button state of the original
// input button registers to reflect the desired action, and allow the
// original processing logic to do it's work.
//
rotary_result_t rotaryResult = IEC_Bus::rotaryEncoder.Poll(gplev0);
switch (rotaryResult)
{
case ButtonDown:
SetButtonState(indexEnter, true);
break;
case RotateNegative:
SetButtonState(indexUp, true);
break;
case RotatePositive:
SetButtonState(indexDown, true);
break;
default:
SetButtonState(indexEnter, false);
SetButtonState(indexUp, false);
SetButtonState(indexDown, false);
break;
}
UpdateButton(indexBack, gplev0);
UpdateButton(indexInsert, gplev0);
}
else // Unmolested original logic
{
int index; int index;
for (index = 0; index < buttonCount; ++index) for (index = 0; index < buttonCount; ++index)
{ {
UpdateButton(index, gplev0); UpdateButton(index, gplev0);
} }
}
bool ATNIn = (gplev0 & PIGPIO_MASK_IN_ATN) == (invertIECInputs ? PIGPIO_MASK_IN_ATN : 0); bool ATNIn = (gplev0 & PIGPIO_MASK_IN_ATN) == (invertIECInputs ? PIGPIO_MASK_IN_ATN : 0);
if (PI_Atn != ATNIn) if (PI_Atn != ATNIn)
{ {

View File

@ -26,6 +26,9 @@
#include "rpi-gpio.h" #include "rpi-gpio.h"
#include "rpiHardware.h" #include "rpiHardware.h"
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
#include "dmRotary.h"
#define INPUT_BUTTON_DEBOUNCE_THRESHOLD 20000 #define INPUT_BUTTON_DEBOUNCE_THRESHOLD 20000
#define INPUT_BUTTON_REPEAT_THRESHOLD 460000 #define INPUT_BUTTON_REPEAT_THRESHOLD 460000
@ -308,6 +311,13 @@ public:
} }
RPI_GpioBase->GPPUD = 0; RPI_GpioBase->GPPUD = 0;
RPI_GpioBase->GPPUDCLK0 = 0; RPI_GpioBase->GPPUDCLK0 = 0;
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
if (IEC_Bus::rotaryEncoderEnable == true)
{
IEC_Bus::rotaryEncoder.Initialize(RPI_GPIO22, RPI_GPIO23, RPI_GPIO27);
}
} }
static inline void LetSRQBePulledHigh() static inline void LetSRQBePulledHigh()
@ -349,6 +359,47 @@ public:
} }
} }
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
//
// Note: This method serves as a shim to allow the rotary encoder
// logic to set a specific input button state (fooling the
// original logic into thinking a button was pressed or
// released).
//
static inline void SetButtonState(int index, bool state)
{
InputButtonPrev[index] = InputButton[index];
inputRepeatPrev[index] = inputRepeat[index];
if (state == true)
{
InputButton[index] = true;
validInputCount[index] = INPUT_BUTTON_DEBOUNCE_THRESHOLD;
inputRepeatThreshold[index] = INPUT_BUTTON_DEBOUNCE_THRESHOLD + INPUT_BUTTON_REPEAT_THRESHOLD;
inputRepeat[index]++;
validInputCount[index] = inputRepeatThreshold[index];
inputRepeat[index]++;
inputRepeatThreshold[index] += INPUT_BUTTON_REPEAT_THRESHOLD / inputRepeat[index];
}
else
{
InputButton[index] = false;
validInputCount[index] = 0;
inputRepeatThreshold[index] = INPUT_BUTTON_REPEAT_THRESHOLD;
inputRepeat[index] = 0;
inputRepeatPrev[index] = 0;
}
}
static void ReadBrowseMode(void); static void ReadBrowseMode(void);
static void ReadEmulationMode1541(void); static void ReadEmulationMode1541(void);
static void ReadButtonsEmulationMode(void); static void ReadButtonsEmulationMode(void);
@ -544,6 +595,12 @@ public:
ignoreReset = value; ignoreReset = value;
} }
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
static inline void SetRotaryEncoderEnable(bool value)
{
rotaryEncoderEnable = value;
}
// CA1 input ATN // CA1 input ATN
// If CA1 is ever set to output // If CA1 is ever set to output
// - CA1 will start to drive pb7 // - CA1 will start to drive pb7
@ -607,5 +664,10 @@ private:
static u32 inputRepeatThreshold[5]; static u32 inputRepeatThreshold[5];
static u32 inputRepeat[5]; static u32 inputRepeat[5];
static u32 inputRepeatPrev[5]; static u32 inputRepeatPrev[5];
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
static RotaryEncoder rotaryEncoder;
static bool rotaryEncoderEnable;
}; };
#endif #endif

View File

@ -1763,6 +1763,9 @@ extern "C"
IEC_Bus::SetInvertIECOutputs(options.InvertIECOutputs()); IEC_Bus::SetInvertIECOutputs(options.InvertIECOutputs());
IEC_Bus::SetIgnoreReset(options.IgnoreReset()); IEC_Bus::SetIgnoreReset(options.IgnoreReset());
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
IEC_Bus::SetRotaryEncoderEnable(options.RotaryEncoderEnable());
if (!options.SoundOnGPIO()) if (!options.SoundOnGPIO())
{ {
dmaSound = (u32*)malloc(Sample_bin_size * 4); dmaSound = (u32*)malloc(Sample_bin_size * 4);

View File

@ -156,6 +156,7 @@ Options::Options(void)
, buttonDown(3) , buttonDown(3)
, buttonBack(4) , buttonBack(4)
, buttonInsert(5) , buttonInsert(5)
, rotaryEncoderEnable(0) //ROTARY:
{ {
autoMountImageName[0] = 0; autoMountImageName[0] = 0;
@ -245,6 +246,7 @@ void Options::Process(char* buffer)
ELSE_CHECK_DECIMAL_OPTION(buttonDown) ELSE_CHECK_DECIMAL_OPTION(buttonDown)
ELSE_CHECK_DECIMAL_OPTION(buttonBack) ELSE_CHECK_DECIMAL_OPTION(buttonBack)
ELSE_CHECK_DECIMAL_OPTION(buttonInsert) ELSE_CHECK_DECIMAL_OPTION(buttonInsert)
ELSE_CHECK_DECIMAL_OPTION(rotaryEncoderEnable) //ROTARY:
else if ((strcasecmp(pOption, "AutoBaseName") == 0)) else if ((strcasecmp(pOption, "AutoBaseName") == 0))
{ {
strncpy(autoBaseName, pValue, 255); strncpy(autoBaseName, pValue, 255);

View File

@ -100,6 +100,9 @@ public:
inline unsigned int GetButtonBack() const { return buttonBack - 1; } inline unsigned int GetButtonBack() const { return buttonBack - 1; }
inline unsigned int GetButtonInsert() const { return buttonInsert - 1; } inline unsigned int GetButtonInsert() const { return buttonInsert - 1; }
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
inline unsigned int RotaryEncoderEnable() const { return rotaryEncoderEnable; }
// Page up and down will jump a different amount based on the maximum number rows displayed. // Page up and down will jump a different amount based on the maximum number rows displayed.
// Perhaps we should use some keyboard modifier to the the other screen? // Perhaps we should use some keyboard modifier to the the other screen?
inline unsigned int KeyboardBrowseLCDScreen() const { return keyboardBrowseLCDScreen; } inline unsigned int KeyboardBrowseLCDScreen() const { return keyboardBrowseLCDScreen; }
@ -175,5 +178,9 @@ private:
char ROMName1581[256]; char ROMName1581[256];
char newDiskType[32]; char newDiskType[32];
//ROTARY: Added for rotary encoder support - 09/05/2019 by Geo...
unsigned int rotaryEncoderEnable;
}; };
#endif #endif