2021-05-11 12:00:12 +00:00
|
|
|
#include "breakout_encoder.hpp"
|
2021-05-11 16:18:43 +00:00
|
|
|
#include <algorithm>
|
2021-05-11 12:00:12 +00:00
|
|
|
|
|
|
|
namespace pimoroni {
|
|
|
|
|
2021-05-11 16:18:43 +00:00
|
|
|
bool BreakoutEncoder::init(bool skip_chip_id_check) {
|
|
|
|
bool success = false;
|
|
|
|
if(ioe.init(skip_chip_id_check)) {
|
|
|
|
|
|
|
|
if(interrupt_pin != PIN_UNUSED)
|
|
|
|
ioe.enable_interrupt_out(true);
|
|
|
|
|
|
|
|
ioe.setup_rotary_encoder(ENC_CHANNEL, ENC_TERM_A, ENC_TERM_B, ENC_TERM_C);
|
|
|
|
|
|
|
|
// Calculate a period large enough to get 0-255 steps at the desired brightness
|
|
|
|
uint16_t period = (uint16_t)(255.0f / brightness);
|
|
|
|
|
|
|
|
ioe.set_pwm_period(period);
|
|
|
|
ioe.set_pwm_control(2); // PWM as fast as we can to avoid LED flicker
|
|
|
|
|
|
|
|
ioe.set_mode(LED_R, IOExpander::PIN_PWM, false, INVERT_OUTPUT);
|
|
|
|
ioe.set_mode(LED_G, IOExpander::PIN_PWM, false, INVERT_OUTPUT);
|
|
|
|
ioe.set_mode(LED_B, IOExpander::PIN_PWM, false, INVERT_OUTPUT);
|
|
|
|
|
|
|
|
success = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
|
|
|
i2c_inst_t* BreakoutEncoder::get_i2c() const {
|
|
|
|
return ioe.get_i2c();
|
|
|
|
}
|
|
|
|
|
|
|
|
int BreakoutEncoder::get_sda() const {
|
|
|
|
return ioe.get_sda();
|
|
|
|
}
|
|
|
|
|
|
|
|
int BreakoutEncoder::get_scl() const {
|
|
|
|
return ioe.get_scl();
|
|
|
|
}
|
|
|
|
|
|
|
|
int BreakoutEncoder::get_int() const {
|
|
|
|
return ioe.get_int();
|
|
|
|
}
|
|
|
|
|
2021-05-11 20:58:44 +00:00
|
|
|
void BreakoutEncoder::set_address(uint8_t address) {
|
|
|
|
ioe.set_address(address);
|
2021-05-11 16:18:43 +00:00
|
|
|
}
|
2021-05-12 19:03:50 +00:00
|
|
|
|
|
|
|
bool BreakoutEncoder::get_interrupt_flag() {
|
|
|
|
return ioe.get_interrupt_flag();
|
|
|
|
}
|
|
|
|
|
|
|
|
void BreakoutEncoder::clear_interrupt_flag() {
|
|
|
|
ioe.clear_interrupt_flag();
|
|
|
|
}
|
2021-05-11 16:18:43 +00:00
|
|
|
|
2021-05-12 17:27:03 +00:00
|
|
|
BreakoutEncoder::Direction BreakoutEncoder::get_direction() {
|
|
|
|
return direction;
|
2021-05-11 16:18:43 +00:00
|
|
|
}
|
|
|
|
|
2021-05-12 17:27:03 +00:00
|
|
|
void BreakoutEncoder::set_direction(Direction direction) {
|
|
|
|
this->direction = direction;
|
2021-05-11 16:18:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BreakoutEncoder::set_brightness(float brightness) {
|
|
|
|
this->brightness = std::min(std::max(brightness, 0.01f), 1.0f);
|
|
|
|
|
|
|
|
// Calculate a period large enough to get 0-255 steps at the desired brightness
|
|
|
|
uint16_t period = (uint16_t)(255.0f / this->brightness);
|
|
|
|
|
|
|
|
ioe.set_pwm_period(period);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BreakoutEncoder::set_led(uint8_t r, uint8_t g, uint8_t b) {
|
|
|
|
ioe.output(LED_R, r, false); // Hold off pwm load until the last
|
|
|
|
ioe.output(LED_G, g, false); // Hold off pwm load until the last
|
|
|
|
ioe.output(LED_B, b); // Loads all 3 pwms
|
|
|
|
}
|
|
|
|
|
|
|
|
bool BreakoutEncoder::available() {
|
|
|
|
return (ioe.get_interrupt_flag() > 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
int16_t BreakoutEncoder::read() {
|
|
|
|
int16_t count = ioe.read_rotary_encoder(ENC_CHANNEL);
|
2021-05-12 17:27:03 +00:00
|
|
|
if(direction != DIRECTION_CW)
|
2021-05-11 16:18:43 +00:00
|
|
|
count = 0 - count;
|
|
|
|
|
|
|
|
ioe.clear_interrupt_flag();
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
}
|