2021-02-10 16:25:25 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "hardware/pio.h"
|
2022-04-13 20:12:44 +01:00
|
|
|
#include "common/pimoroni_common.hpp"
|
2021-02-10 16:25:25 +00:00
|
|
|
#include "capture.hpp"
|
|
|
|
|
|
|
|
namespace pimoroni {
|
|
|
|
|
2022-04-13 20:12:44 +01:00
|
|
|
struct bool_pair {
|
|
|
|
union {
|
|
|
|
bool first;
|
|
|
|
bool a;
|
|
|
|
};
|
|
|
|
union {
|
|
|
|
bool second;
|
|
|
|
bool b;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool_pair() : first(false), second(false) {}
|
|
|
|
bool_pair(bool first, bool second) : first(first), second(second) {}
|
|
|
|
};
|
|
|
|
|
2021-02-10 16:25:25 +00:00
|
|
|
class Encoder {
|
|
|
|
//--------------------------------------------------
|
|
|
|
// Constants
|
|
|
|
//--------------------------------------------------
|
|
|
|
public:
|
|
|
|
static constexpr float DEFAULT_COUNTS_PER_REV = 24;
|
|
|
|
static const uint16_t DEFAULT_COUNT_MICROSTEPS = false;
|
2022-04-13 11:29:40 +01:00
|
|
|
static const uint16_t DEFAULT_FREQ_DIVIDER = 1;
|
2021-02-10 16:25:25 +00:00
|
|
|
|
|
|
|
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,
|
|
|
|
};
|
2022-04-13 20:12:44 +01:00
|
|
|
|
|
|
|
|
2021-02-10 16:25:25 +00:00
|
|
|
//--------------------------------------------------
|
|
|
|
// Variables
|
|
|
|
//--------------------------------------------------
|
|
|
|
private:
|
2022-04-13 20:12:44 +01:00
|
|
|
PIO pio;
|
|
|
|
uint sm;
|
|
|
|
pin_pair enc_pins;
|
|
|
|
uint pin_c;
|
2021-02-10 16:25:25 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
//--------------------------------------------------
|
2022-04-13 11:29:40 +01:00
|
|
|
|
2022-04-13 20:12:44 +01:00
|
|
|
volatile bool enc_state_a = false;
|
|
|
|
volatile bool enc_state_b = false;
|
|
|
|
volatile int32_t enc_count = 0;
|
2021-02-10 16:25:25 +00:00
|
|
|
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;
|
|
|
|
|
2022-04-13 20:12:44 +01:00
|
|
|
bool initialised = false;
|
|
|
|
|
2021-02-10 16:25:25 +00:00
|
|
|
|
|
|
|
//--------------------------------------------------
|
|
|
|
// Statics
|
|
|
|
//--------------------------------------------------
|
2022-04-13 20:12:44 +01:00
|
|
|
static Encoder* encoders[NUM_PIOS][NUM_PIO_STATE_MACHINES];
|
|
|
|
static uint8_t claimed_sms[NUM_PIOS];
|
|
|
|
static uint pio_program_offset[NUM_PIOS];
|
|
|
|
static void pio_interrupt_handler(uint pio_idx);
|
|
|
|
static void pio0_interrupt_handler();
|
|
|
|
static void pio1_interrupt_handler();
|
2021-02-10 16:25:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------
|
|
|
|
// Constructors/Destructor
|
|
|
|
//--------------------------------------------------
|
|
|
|
public:
|
|
|
|
Encoder() {}
|
2022-04-13 20:12:44 +01:00
|
|
|
Encoder(PIO pio, uint sm, const pin_pair &pins, uint pin_c = PIN_UNUSED,
|
2021-02-10 16:25:25 +00:00
|
|
|
float counts_per_revolution = DEFAULT_COUNTS_PER_REV, bool count_microsteps = DEFAULT_COUNT_MICROSTEPS,
|
|
|
|
uint16_t freq_divider = DEFAULT_FREQ_DIVIDER);
|
|
|
|
~Encoder();
|
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------
|
|
|
|
// Methods
|
|
|
|
//--------------------------------------------------
|
2022-04-13 20:12:44 +01:00
|
|
|
public:
|
2021-02-10 16:25:25 +00:00
|
|
|
bool init();
|
|
|
|
|
2022-04-13 20:12:44 +01:00
|
|
|
// For print access in micropython
|
|
|
|
pin_pair pins() const;
|
|
|
|
|
|
|
|
bool_pair state() const;
|
|
|
|
int32_t count() const;
|
|
|
|
float revolutions() const;
|
|
|
|
float angle_degrees() const;
|
|
|
|
float angle_radians() const;
|
|
|
|
|
|
|
|
float frequency() const;
|
|
|
|
float revolutions_per_second() const;
|
|
|
|
float revolutions_per_minute() const;
|
|
|
|
float degrees_per_second() const;
|
|
|
|
float radians_per_second() const;
|
2021-02-10 16:25:25 +00:00
|
|
|
|
|
|
|
void zero_count();
|
2022-04-13 20:12:44 +01:00
|
|
|
Capture perform_capture(); //TODO rename capture to snapshot
|
2021-02-10 16:25:25 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
void microstep_up(int32_t time_since);
|
|
|
|
void microstep_down(int32_t time_since);
|
|
|
|
void check_for_transition();
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|