126 lines
3.9 KiB
C++
126 lines
3.9 KiB
C++
|
#pragma once
|
||
|
|
||
|
#include "hardware/pio.h"
|
||
|
#include "capture.hpp"
|
||
|
|
||
|
namespace pimoroni {
|
||
|
|
||
|
class Encoder {
|
||
|
//--------------------------------------------------
|
||
|
// Constants
|
||
|
//--------------------------------------------------
|
||
|
public:
|
||
|
static constexpr float DEFAULT_COUNTS_PER_REV = 24;
|
||
|
static const uint16_t DEFAULT_COUNT_MICROSTEPS = false;
|
||
|
static const uint16_t DEFAULT_FREQ_DIVIDER = 1;
|
||
|
static const uint8_t PIN_UNUSED = UINT8_MAX;
|
||
|
|
||
|
private:
|
||
|
static const uint32_t STATE_A_MASK = 0x80000000;
|
||
|
static const uint32_t STATE_B_MASK = 0x40000000;
|
||
|
static const uint32_t STATE_A_LAST_MASK = 0x20000000;
|
||
|
static const uint32_t STATE_B_LAST_MASK = 0x10000000;
|
||
|
|
||
|
static const uint32_t STATES_MASK = STATE_A_MASK | STATE_B_MASK |
|
||
|
STATE_A_LAST_MASK | STATE_B_LAST_MASK;
|
||
|
|
||
|
static const uint32_t TIME_MASK = 0x0fffffff;
|
||
|
|
||
|
static const uint8_t MICROSTEP_0 = 0b00;
|
||
|
static const uint8_t MICROSTEP_1 = 0b10;
|
||
|
static const uint8_t MICROSTEP_2 = 0b11;
|
||
|
static const uint8_t MICROSTEP_3 = 0b01;
|
||
|
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// Enums
|
||
|
//--------------------------------------------------
|
||
|
private:
|
||
|
enum Direction {
|
||
|
NO_DIR = 0,
|
||
|
CLOCKWISE = 1,
|
||
|
COUNTERCLOCK = -1,
|
||
|
};
|
||
|
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// Variables
|
||
|
//--------------------------------------------------
|
||
|
private:
|
||
|
const PIO enc_pio = pio0;
|
||
|
const uint8_t pinA = PIN_UNUSED;
|
||
|
const uint8_t pinB = PIN_UNUSED;
|
||
|
const uint8_t pinC = PIN_UNUSED;
|
||
|
|
||
|
const float counts_per_revolution = DEFAULT_COUNTS_PER_REV;
|
||
|
const bool count_microsteps = DEFAULT_COUNT_MICROSTEPS;
|
||
|
const uint16_t freq_divider = DEFAULT_FREQ_DIVIDER;
|
||
|
const float clocks_per_time = 0;
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
|
||
|
uint enc_sm = 0;
|
||
|
uint enc_offset = 0;
|
||
|
|
||
|
volatile bool stateA = false;
|
||
|
volatile bool stateB = false;
|
||
|
volatile int32_t count = 0;
|
||
|
volatile int32_t time_since = 0;
|
||
|
volatile Direction last_travel_dir = NO_DIR;
|
||
|
volatile int32_t microstep_time = 0;
|
||
|
volatile int32_t cumulative_time = 0;
|
||
|
|
||
|
int32_t count_offset = 0;
|
||
|
int32_t last_captured_count = 0;
|
||
|
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// Statics
|
||
|
//--------------------------------------------------
|
||
|
public:
|
||
|
static Encoder* pio_encoders[NUM_PIOS][NUM_PIO_STATE_MACHINES];
|
||
|
static uint8_t pio_claimed_sms[NUM_PIOS];
|
||
|
static void pio0_interrupt_callback();
|
||
|
static void pio1_interrupt_callback();
|
||
|
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// Constructors/Destructor
|
||
|
//--------------------------------------------------
|
||
|
public:
|
||
|
Encoder() {}
|
||
|
Encoder(PIO pio, uint8_t pinA, uint8_t pinB, uint8_t pinC = PIN_UNUSED,
|
||
|
float counts_per_revolution = DEFAULT_COUNTS_PER_REV, bool count_microsteps = DEFAULT_COUNT_MICROSTEPS,
|
||
|
uint16_t freq_divider = DEFAULT_FREQ_DIVIDER);
|
||
|
~Encoder();
|
||
|
|
||
|
|
||
|
//--------------------------------------------------
|
||
|
// Methods
|
||
|
//--------------------------------------------------
|
||
|
public:
|
||
|
bool init();
|
||
|
|
||
|
bool get_state_a() const;
|
||
|
bool get_state_b() const;
|
||
|
int32_t get_count() const;
|
||
|
float get_revolutions() const;
|
||
|
float get_angle_degrees() const;
|
||
|
float get_angle_radians() const;
|
||
|
|
||
|
float get_frequency() const;
|
||
|
float get_revolutions_per_second() const;
|
||
|
float get_revolutions_per_minute() const;
|
||
|
float get_degrees_per_second() const;
|
||
|
float get_radians_per_second() const;
|
||
|
|
||
|
void zero_count();
|
||
|
Capture perform_capture();
|
||
|
|
||
|
private:
|
||
|
void microstep_up(int32_t time_since);
|
||
|
void microstep_down(int32_t time_since);
|
||
|
void check_for_transition();
|
||
|
};
|
||
|
|
||
|
}
|