You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
3.8 KiB
C

#include <avr/io.h>
#include <avr/interrupt.h>
#include "encoder.h"
int8_t DrehgeberPosition;
int8_t DrehgeberMax = 127;
int8_t DrehgeberMin = -127;
#define DDR(x) (*(&x-1))
#define Port(x) (*(&x))
#define PIN(x) (*(&x-2))
#define PHASE_A PIN(ENC_A_PORT) & (1<<ENC_A_PIN)
#define PHASE_B PIN(ENC_B_PORT) & (1<<ENC_B_PIN)
#define BUTTONPRESSED (!(PIN(ENC_T_PORT) & (1<<ENC_T_PIN)))
#define BUTTON_DEBOUNCETIME_MS 30
#define BUTTON_PRESSEDLONG_MS 1000
volatile int8_t enc_delta;
static int8_t last;
volatile int16_t iButtonPressedCounter = 0;
volatile int16_t iButtonDebounceCycles = 0;
volatile int16_t iButtonPressedLongCycles = 0;
typedef enum EButtonState
{
ButtonState_Unpressed,
ButtonState_Pressed,
ButtonState_Hold,
ButtonState_Released
}tEButtonState;
volatile tEButtonState buttonState = ButtonState_Unpressed;
volatile tEButtonPressedState buttonPressed = ButtonPressed_Unpressed;
void EncoderInit(void)
{
int8_t new;
new = 0;
if(PHASE_A)
new = 3;
if(PHASE_B)
new ^= 1;
last = new;
enc_delta = 0;
iButtonDebounceCycles = BUTTON_DEBOUNCETIME_MS;
iButtonPressedLongCycles = BUTTON_PRESSEDLONG_MS;
}
/** \brief EncoderPolling
* Abfrage des Drehencoders und des Tasters
* Wird vom Timer 0 alle 5ms aufgerufen
*/
void EncoderPolling(void)
{
int8_t new, diff;
new = 0;
if(PHASE_A) new = 3;
if(PHASE_B) new ^= 1;
diff = last - new;
if(diff & 1) {
last = new;
enc_delta += (diff & 2) - 1;
}
switch(buttonState)
{
case ButtonState_Unpressed:
if(BUTTONPRESSED) buttonState = ButtonState_Pressed;
break;
case ButtonState_Pressed:
buttonState = ButtonState_Hold;
break;
case ButtonState_Hold:
iButtonPressedCounter++;
if(iButtonPressedCounter >= iButtonDebounceCycles && (! BUTTONPRESSED))
{
buttonState = ButtonState_Released;
if(buttonPressed != ButtonPressed_Long) buttonPressed = ButtonPressed_Short;
}
if(iButtonPressedCounter >= iButtonPressedLongCycles)
{
buttonPressed = ButtonPressed_Long;
}
break;
case ButtonState_Released:
iButtonPressedCounter = 0;
buttonState = ButtonState_Unpressed;
break;
}
}
#if defined (SingleStep)
int8_t EncodeRead(void)
{
int8_t val;
cli();
val = enc_delta;
enc_delta = 0;
sei();
return val;
}
#elif defined (TwoStep)
int8_t EncodeRead(void)
{
int8_t val;
cli();
val = enc_delta;
enc_delta = val & 1;
sei();
return val >> 1;
}
#elif defined (FourStep)
int8_t EncodeRead(void)
{
int8_t val;
cli();
val = enc_delta;
enc_delta = val & 3;
sei();
return val >> 2;
}
#endif
int8_t EncoderRead(char Ueberlauf)
{
DrehgeberPosition += EncodeRead();
if(DrehgeberPosition > DrehgeberMax)
{
if(Ueberlauf)
DrehgeberPosition = DrehgeberPosition - DrehgeberMax + DrehgeberMin - 1;
else
DrehgeberPosition = DrehgeberMax;
}
if(DrehgeberPosition < DrehgeberMin)
{
if(Ueberlauf)
DrehgeberPosition = DrehgeberPosition + DrehgeberMax - DrehgeberMin + 1;
else
DrehgeberPosition = DrehgeberMin;
}
return(DrehgeberPosition);
}
void EncoderWrite(int8_t EncoderPos)
{
DrehgeberPosition = EncoderPos;
}
void EncoderMinMax(int8_t EncoderMin, int8_t EncoderMax)
{
DrehgeberMin = EncoderMin;
DrehgeberMax = EncoderMax;
if(DrehgeberPosition > DrehgeberMax) DrehgeberPosition = DrehgeberMax;
if(DrehgeberPosition < DrehgeberMin) DrehgeberPosition = DrehgeberMin;
}
tEButtonPressedState EncoderGetButtonState(void)
{
tEButtonPressedState retVal = buttonPressed;
buttonPressed = ButtonPressed_Unpressed;
return retVal;
}