DonCon2040/include/peripherals/Drum.h

118 lines
2.8 KiB
C
Raw Permalink Normal View History

2023-04-10 13:04:38 +02:00
#ifndef _PERIPHERALS_DRUM_H_
#define _PERIPHERALS_DRUM_H_
#include "utils/InputState.h"
2023-08-09 22:29:27 +02:00
#include "hardware/spi.h"
#include <mcp3204/Mcp3204Dma.h>
2023-08-09 22:29:27 +02:00
#include <array>
2023-04-10 13:04:38 +02:00
#include <map>
2023-08-09 22:29:27 +02:00
#include <memory>
2023-04-10 13:04:38 +02:00
#include <stdint.h>
namespace Doncon::Peripherals {
class Drum {
public:
struct Config {
struct Thresholds {
uint16_t don_left;
uint16_t ka_left;
uint16_t don_right;
uint16_t ka_right;
};
2023-08-09 22:29:27 +02:00
struct AdcInputs {
2023-05-13 15:27:43 +02:00
uint8_t don_left;
uint8_t ka_left;
uint8_t don_right;
uint8_t ka_right;
2023-08-09 22:29:27 +02:00
};
2023-04-10 13:04:38 +02:00
2023-08-09 22:29:27 +02:00
AdcInputs adc_inputs;
Thresholds trigger_thresholds;
2023-07-02 23:48:33 +02:00
uint8_t sample_count;
2023-05-13 15:27:43 +02:00
uint16_t debounce_delay_ms;
2023-12-03 17:17:01 +01:00
uint32_t roll_counter_timeout_ms;
2023-08-09 22:29:27 +02:00
bool use_external_adc;
struct Spi {
uint8_t mosi_pin;
uint8_t miso_pin;
uint8_t sclk_pin;
uint8_t scsn_pin;
uint8_t level_shifter_enable_pin;
2023-08-09 22:29:27 +02:00
spi_inst_t *block;
uint speed_hz;
} external_adc_spi_config;
2023-04-10 13:04:38 +02:00
};
private:
enum class Id {
2023-05-13 15:27:43 +02:00
DON_LEFT,
KA_LEFT,
DON_RIGHT,
KA_RIGHT,
2023-04-10 13:04:38 +02:00
};
class Pad {
private:
2023-08-09 22:29:27 +02:00
uint8_t channel;
2023-04-10 13:04:38 +02:00
uint32_t last_change;
bool active;
public:
Pad(const uint8_t channel);
2023-04-10 13:04:38 +02:00
2023-08-09 22:29:27 +02:00
uint8_t getChannel() const { return channel; };
2023-04-10 13:04:38 +02:00
bool getState() const { return active; };
void setState(const bool state, const uint16_t debounce_delay);
2023-04-10 13:04:38 +02:00
};
2023-08-09 22:29:27 +02:00
class AdcInterface {
public:
// Those are expected to be 12bit values
virtual std::array<uint16_t, 4> read() = 0;
2023-08-09 22:29:27 +02:00
};
class InternalAdc : public AdcInterface {
public:
InternalAdc(const Config::AdcInputs &adc_inputs);
virtual std::array<uint16_t, 4> read() final;
2023-08-09 22:29:27 +02:00
};
class ExternalAdc : public AdcInterface {
private:
Mcp3204Dma m_mcp3204;
2023-08-09 22:29:27 +02:00
public:
ExternalAdc(const Config::Spi &spi_config);
virtual std::array<uint16_t, 4> read() final;
2023-08-09 22:29:27 +02:00
};
2023-04-10 13:04:38 +02:00
Config m_config;
2023-08-09 22:29:27 +02:00
std::unique_ptr<AdcInterface> m_adc;
2023-04-10 13:04:38 +02:00
std::map<Id, Pad> m_pads;
2023-05-13 15:27:43 +02:00
private:
2023-12-03 17:17:01 +01:00
void updateRollCounter(Utils::InputState &input_state);
void updateDigitalInputState(Utils::InputState &input_state, const std::map<Id, uint16_t> &raw_values);
void updateAnalogInputState(Utils::InputState &input_state, const std::map<Id, uint16_t> &raw_values);
2023-07-02 23:48:33 +02:00
std::map<Id, uint16_t> sampleInputs();
2023-05-13 15:27:43 +02:00
2023-04-10 13:04:38 +02:00
public:
Drum(const Config &config);
void updateInputState(Utils::InputState &input_state);
void setDebounceDelay(const uint16_t delay);
2023-08-09 22:29:27 +02:00
void setThresholds(const Config::Thresholds &thresholds);
2023-04-10 13:04:38 +02:00
};
} // namespace Doncon::Peripherals
#endif // _PERIPHERALS_DRUM_H_