/* * peripherals_encoder.hpp * * Created on: Apr 11, 2021 * Author: erki */ #ifndef PERIPHERALS_ENCODER_HPP_ #define PERIPHERALS_ENCODER_HPP_ #include #include namespace Peripherals { class Encoder { public: enum class Dirs : std::uint8_t { FORWARD, BACKWARD }; Encoder() = delete; explicit Encoder(TIM_HandleTypeDef* htim, const std::uint32_t channels) : _htim(htim), _channels(channels) {} Encoder(const Encoder&) = delete; Encoder(Encoder&&) = delete; Encoder& operator=(const Encoder&) = delete; Encoder& operator=(Encoder&&) = delete; void start() { HAL_TIM_Encoder_Start_IT(_htim, _channels); } void stop() { HAL_TIM_Encoder_Stop_IT(_htim, _channels); } void reset() { __HAL_TIM_SET_COUNTER(_htim, 0); _full_revolutions = 0; } void setRevolutionTickCount(const std::uint16_t& count) { __HAL_TIM_SET_COMPARE(_htim, _channels, count); } std::uint16_t getCurrentClicks() const { const std::uint16_t val = __HAL_TIM_GET_COUNTER(_htim); return val >> 1; } std::int32_t getFullRevolutions() const { return _full_revolutions; } Dirs getDireection() const { return _direction; } // Should be called somewhat regularly. void update() { const std::uint16_t current = __HAL_TIM_GET_COUNTER(_htim); if (current > _last_read) _direction = Dirs::FORWARD; else _direction = Dirs::BACKWARD; _last_read = current; } void timerUpdateEvent() { if (_direction == Dirs::FORWARD) { _full_revolutions++; } else { _full_revolutions--; } _last_read = 0; } private: TIM_HandleTypeDef* _htim; std::uint32_t _channels; Dirs _direction = Dirs::FORWARD; std::int32_t _full_revolutions = 0; std::uint16_t _last_read = 0; }; }// namespace Peripherals #endif /* PERIPHERALS_ENCODER_HPP_ */