pimoroni-pico/libraries/breakout_potentiometer/breakout_potentiometer.cpp

113 lines
3.3 KiB
C++

#include "breakout_potentiometer.hpp"
#include <algorithm>
namespace pimoroni {
bool BreakoutPotentiometer::init(bool skip_chip_id_check) {
bool success = false;
if(ioe.init(skip_chip_id_check)) {
ioe.set_mode(POT_TERM_A, IOExpander::PIN_OUT);
ioe.set_mode(POT_TERM_B, IOExpander::PIN_OUT);
ioe.set_mode(POT_INPUT, IOExpander::PIN_ADC);
if(direction == DIRECTION_CW) {
// Clockwise increasing
ioe.output(POT_TERM_A, IOExpander::LOW);
ioe.output(POT_TERM_B, IOExpander::HIGH);
}
else {
// Counter clockwise increasing
ioe.output(POT_TERM_A, IOExpander::HIGH);
ioe.output(POT_TERM_B, IOExpander::LOW);
}
// 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* BreakoutPotentiometer::get_i2c() const {
return ioe.get_i2c();
}
int BreakoutPotentiometer::get_address() const {
return ioe.get_address();
}
int BreakoutPotentiometer::get_sda() const {
return ioe.get_sda();
}
int BreakoutPotentiometer::get_scl() const {
return ioe.get_scl();
}
int BreakoutPotentiometer::get_int() const {
return ioe.get_int();
}
void BreakoutPotentiometer::set_address(uint8_t address) {
ioe.set_address(address);
}
float BreakoutPotentiometer::get_adc_vref() {
return ioe.get_adc_vref();
}
void BreakoutPotentiometer::set_adc_vref(float vref) {
ioe.set_adc_vref(vref);
}
BreakoutPotentiometer::Direction BreakoutPotentiometer::get_direction() {
return direction;
}
void BreakoutPotentiometer::set_direction(Direction direction) {
if(direction == DIRECTION_CW) {
// Clockwise increasing
ioe.output(POT_TERM_A, IOExpander::LOW);
ioe.output(POT_TERM_B, IOExpander::HIGH);
}
else {
// Counter clockwise increasing
ioe.output(POT_TERM_A, IOExpander::HIGH);
ioe.output(POT_TERM_B, IOExpander::LOW);
}
this->direction = direction;
}
void BreakoutPotentiometer::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 BreakoutPotentiometer::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
}
float BreakoutPotentiometer::read(uint32_t adc_timeout) {
return (ioe.input_as_voltage(POT_INPUT, adc_timeout) / ioe.get_adc_vref());
}
int16_t BreakoutPotentiometer::read_raw(uint32_t adc_timeout) {
return ioe.input(POT_INPUT, adc_timeout);
}
}