kopia lustrzana https://github.com/pimoroni/pimoroni-pico
Renamed IOExpander and added Pot, Enc, and MICS specific classes
rodzic
acf011bba2
commit
05af3e86ba
|
@ -1,11 +1,11 @@
|
|||
add_subdirectory(esp32spi)
|
||||
add_subdirectory(ioexpander)
|
||||
add_subdirectory(ltp305)
|
||||
add_subdirectory(ltr559)
|
||||
add_subdirectory(sgp30)
|
||||
add_subdirectory(st7735)
|
||||
add_subdirectory(st7789)
|
||||
add_subdirectory(msa301)
|
||||
add_subdirectory(nuvoton)
|
||||
add_subdirectory(rv3028)
|
||||
add_subdirectory(trackball)
|
||||
add_subdirectory(vl53l1x)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
include(ioexpander.cmake)
|
|
@ -1,4 +1,4 @@
|
|||
set(DRIVER_NAME nuvoton)
|
||||
set(DRIVER_NAME ioexpander)
|
||||
add_library(${DRIVER_NAME} INTERFACE)
|
||||
|
||||
target_sources(${DRIVER_NAME} INTERFACE
|
|
@ -3,7 +3,7 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "nuvoton.hpp"
|
||||
#include "ioexpander.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
|
@ -220,61 +220,61 @@ namespace pimoroni {
|
|||
static const uint8_t ENC_CFG[4] = {reg::ENC_1_CFG, reg::ENC_2_CFG, reg::ENC_3_CFG, reg::ENC_4_CFG};
|
||||
static const uint8_t ENC_COUNT[4] = {reg::ENC_1_COUNT, reg::ENC_2_COUNT, reg::ENC_3_COUNT, reg::ENC_4_COUNT};
|
||||
|
||||
const uint8_t Nuvoton::Pin::PxM1[4] = {reg::P0M1, reg::P1M1, (uint8_t)-1, reg::P3M1};
|
||||
const uint8_t Nuvoton::Pin::PxM2[4] = {reg::P0M2, reg::P1M2, (uint8_t)-1, reg::P3M2};
|
||||
const uint8_t Nuvoton::Pin::Px[4] = {reg::P0, reg::P1, (uint8_t)-1, reg::P3};
|
||||
const uint8_t IOExpander::Pin::PxM1[4] = {reg::P0M1, reg::P1M1, (uint8_t)-1, reg::P3M1};
|
||||
const uint8_t IOExpander::Pin::PxM2[4] = {reg::P0M2, reg::P1M2, (uint8_t)-1, reg::P3M2};
|
||||
const uint8_t IOExpander::Pin::Px[4] = {reg::P0, reg::P1, (uint8_t)-1, reg::P3};
|
||||
|
||||
const uint8_t Nuvoton::Pin::PxS[4] = {reg::P0S, reg::P1S, (uint8_t)-1, reg::P3S};
|
||||
const uint8_t Nuvoton::Pin::MASK_P[4] = {reg::INT_MASK_P0, reg::INT_MASK_P1, (uint8_t)-1, reg::INT_MASK_P3};
|
||||
const uint8_t IOExpander::Pin::PxS[4] = {reg::P0S, reg::P1S, (uint8_t)-1, reg::P3S};
|
||||
const uint8_t IOExpander::Pin::MASK_P[4] = {reg::INT_MASK_P0, reg::INT_MASK_P1, (uint8_t)-1, reg::INT_MASK_P3};
|
||||
|
||||
const uint8_t Nuvoton::Pin::PWML[6] = {reg::PWM0L, reg::PWM1L, reg::PWM2L, reg::PWM3L, reg::PWM4L, reg::PWM5L};
|
||||
const uint8_t Nuvoton::Pin::PWMH[6] = {reg::PWM0H, reg::PWM1H, reg::PWM2H, reg::PWM3H, reg::PWM4H, reg::PWM5H};
|
||||
const uint8_t IOExpander::Pin::PWML[6] = {reg::PWM0L, reg::PWM1L, reg::PWM2L, reg::PWM3L, reg::PWM4L, reg::PWM5L};
|
||||
const uint8_t IOExpander::Pin::PWMH[6] = {reg::PWM0H, reg::PWM1H, reg::PWM2H, reg::PWM3H, reg::PWM4H, reg::PWM5H};
|
||||
|
||||
static const char* MODE_NAMES[3] = {"IO", "PWM", "ADC"};
|
||||
static const char* GPIO_NAMES[4] = {"QB", "PP", "IN", "OD"};
|
||||
static const char* STATE_NAMES[2] = {"LOW", "HIGH"};
|
||||
|
||||
Nuvoton::Pin::Pin(uint8_t port, uint8_t pin) :
|
||||
IOExpander::Pin::Pin(uint8_t port, uint8_t pin) :
|
||||
type(TYPE_IO), mode(0), port(port), pin(pin), adc_channel(0), pwm_channel(0),
|
||||
reg_m1(PxM1[port]), reg_m2(PxM2[port]), reg_p(Px[port]), reg_ps(PxS[port]), reg_int_mask_p(MASK_P[port]),
|
||||
reg_io_pwm(0), reg_pwml(0), reg_pwmh(0) {
|
||||
}
|
||||
|
||||
Nuvoton::Pin::Pin(uint8_t port, uint8_t pin, uint8_t pwm_channel, uint8_t reg_io_pwm) :
|
||||
IOExpander::Pin::Pin(uint8_t port, uint8_t pin, uint8_t pwm_channel, uint8_t reg_io_pwm) :
|
||||
type(TYPE_PWM), mode(0), port(port), pin(pin), adc_channel(0), pwm_channel(pwm_channel),
|
||||
reg_m1(PxM1[port]), reg_m2(PxM2[port]), reg_p(Px[port]), reg_ps(PxS[port]), reg_int_mask_p(MASK_P[port]),
|
||||
reg_io_pwm(reg_io_pwm), reg_pwml(PWML[pwm_channel]), reg_pwmh(PWMH[pwm_channel]) {
|
||||
}
|
||||
|
||||
Nuvoton::Pin::Pin(uint8_t port, uint8_t pin, uint8_t adc_channel) :
|
||||
IOExpander::Pin::Pin(uint8_t port, uint8_t pin, uint8_t adc_channel) :
|
||||
type(TYPE_ADC), mode(0), port(port), pin(pin), adc_channel(adc_channel), pwm_channel(0),
|
||||
reg_m1(PxM1[port]), reg_m2(PxM2[port]), reg_p(Px[port]), reg_ps(PxS[port]), reg_int_mask_p(MASK_P[port]),
|
||||
reg_io_pwm(0), reg_pwml(0), reg_pwmh(0) {
|
||||
}
|
||||
|
||||
Nuvoton::Pin::Pin(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_io_pwm) :
|
||||
IOExpander::Pin::Pin(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_io_pwm) :
|
||||
type(TYPE_ADC_OR_PWM), mode(0), port(port), pin(pin), adc_channel(adc_channel), pwm_channel(pwm_channel),
|
||||
reg_m1(PxM1[port]), reg_m2(PxM2[port]), reg_p(Px[port]), reg_ps(PxS[port]), reg_int_mask_p(MASK_P[port]),
|
||||
reg_io_pwm(reg_io_pwm), reg_pwml(PWML[pwm_channel]), reg_pwmh(PWMH[pwm_channel]) {
|
||||
}
|
||||
|
||||
Nuvoton::Pin Nuvoton::Pin::io(uint8_t port, uint8_t pin) {
|
||||
IOExpander::Pin IOExpander::Pin::io(uint8_t port, uint8_t pin) {
|
||||
return Pin(port, pin);
|
||||
}
|
||||
|
||||
Nuvoton::Pin Nuvoton::Pin::pwm(uint8_t port, uint8_t pin, uint8_t channel, uint8_t reg_iopwm) {
|
||||
IOExpander::Pin IOExpander::Pin::pwm(uint8_t port, uint8_t pin, uint8_t channel, uint8_t reg_iopwm) {
|
||||
return Pin(port, pin, channel, reg_iopwm);
|
||||
}
|
||||
|
||||
Nuvoton::Pin Nuvoton::Pin::adc(uint8_t port, uint8_t pin, uint8_t channel) {
|
||||
IOExpander::Pin IOExpander::Pin::adc(uint8_t port, uint8_t pin, uint8_t channel) {
|
||||
return Pin(port, pin, channel);
|
||||
}
|
||||
|
||||
Nuvoton::Pin Nuvoton::Pin::adc_or_pwm(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_iopwm) {
|
||||
IOExpander::Pin IOExpander::Pin::adc_or_pwm(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_iopwm) {
|
||||
return Pin(port, pin, adc_channel, pwm_channel, reg_iopwm);
|
||||
}
|
||||
|
||||
bool Nuvoton::Pin::mode_supported(uint8_t mode) {
|
||||
bool IOExpander::Pin::mode_supported(uint8_t mode) {
|
||||
bool supported = false;
|
||||
if((type & TYPE_PWM) && (mode == PIN_MODE_PWM)) {
|
||||
supported = true;
|
||||
|
@ -285,19 +285,19 @@ namespace pimoroni {
|
|||
return supported;
|
||||
}
|
||||
|
||||
Nuvoton::Pin::IOType Nuvoton::Pin::get_type() {
|
||||
IOExpander::Pin::IOType IOExpander::Pin::get_type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
uint8_t Nuvoton::Pin::get_mode() {
|
||||
uint8_t IOExpander::Pin::get_mode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
void Nuvoton::Pin::set_mode(uint8_t mode) {
|
||||
void IOExpander::Pin::set_mode(uint8_t mode) {
|
||||
this->mode = mode;
|
||||
}
|
||||
|
||||
Nuvoton::Nuvoton(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt, uint8_t address, uint32_t timeout, bool debug) :
|
||||
IOExpander::IOExpander(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt, uint8_t address, uint32_t timeout, bool debug) :
|
||||
i2c(i2c), sda(sda), scl(scl), interrupt(interrupt),
|
||||
address(address), timeout(timeout), debug(debug), vref(3.3f),
|
||||
encoder_offset{0,0,0,0},
|
||||
|
@ -318,11 +318,11 @@ namespace pimoroni {
|
|||
Pin::adc(1, 7, 0)} {
|
||||
}
|
||||
|
||||
Nuvoton::Nuvoton(uint8_t address, uint32_t timeout, bool debug) :
|
||||
Nuvoton(i2c0, DEFAULT_SDA_PIN, DEFAULT_SCL_PIN, DEFAULT_INT_PIN, address, timeout, debug) {
|
||||
IOExpander::IOExpander(uint8_t address, uint32_t timeout, bool debug) :
|
||||
IOExpander(i2c0, DEFAULT_SDA_PIN, DEFAULT_SCL_PIN, DEFAULT_INT_PIN, address, timeout, debug) {
|
||||
}
|
||||
|
||||
bool Nuvoton::init(bool skipChipIdCheck) {
|
||||
bool IOExpander::init(bool skipChipIdCheck) {
|
||||
bool succeeded = true;
|
||||
|
||||
i2c_init(i2c, 400000);
|
||||
|
@ -348,11 +348,27 @@ namespace pimoroni {
|
|||
return succeeded;
|
||||
}
|
||||
|
||||
uint16_t Nuvoton::get_chip_id() {
|
||||
i2c_inst_t* IOExpander::get_i2c() const {
|
||||
return i2c;
|
||||
}
|
||||
|
||||
int IOExpander::get_sda() const {
|
||||
return sda;
|
||||
}
|
||||
|
||||
int IOExpander::get_scl() const {
|
||||
return scl;
|
||||
}
|
||||
|
||||
int IOExpander::get_int() const {
|
||||
return interrupt;
|
||||
}
|
||||
|
||||
uint16_t IOExpander::get_chip_id() {
|
||||
return ((uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_H) << 8) | (uint16_t)i2c_reg_read_uint8(reg::CHIP_ID_L);
|
||||
}
|
||||
|
||||
void Nuvoton::set_addr(uint8_t address) {
|
||||
void IOExpander::set_addr(uint8_t address) {
|
||||
set_bit(reg::CTRL, 4);
|
||||
i2c_reg_write_uint8(reg::ADDR, address);
|
||||
this->address = address;
|
||||
|
@ -361,35 +377,35 @@ namespace pimoroni {
|
|||
clr_bit(reg::CTRL, 4);
|
||||
}
|
||||
|
||||
float Nuvoton::get_adc_vref() {
|
||||
float IOExpander::get_adc_vref() {
|
||||
return vref;
|
||||
}
|
||||
|
||||
void Nuvoton::set_adc_vref(float vref) {
|
||||
void IOExpander::set_adc_vref(float vref) {
|
||||
this->vref = vref;
|
||||
}
|
||||
|
||||
void Nuvoton::enable_interrupt_out(bool pin_swap) {
|
||||
void IOExpander::enable_interrupt_out(bool pin_swap) {
|
||||
set_bit(reg::INT, int_bit::OUT_EN);
|
||||
change_bit(reg::INT, int_bit::PIN_SWAP, pin_swap);
|
||||
}
|
||||
|
||||
void Nuvoton::disable_interrupt_out() {
|
||||
void IOExpander::disable_interrupt_out() {
|
||||
clr_bit(reg::INT, int_bit::OUT_EN);
|
||||
}
|
||||
|
||||
uint8_t Nuvoton::get_interrupt_flag() {
|
||||
uint8_t IOExpander::get_interrupt_flag() {
|
||||
if(interrupt != 0)
|
||||
return !gpio_get(interrupt);
|
||||
else
|
||||
return get_bit(reg::INT, int_bit::TRIGD);
|
||||
}
|
||||
|
||||
void Nuvoton::clear_interrupt_flag() {
|
||||
void IOExpander::clear_interrupt_flag() {
|
||||
clr_bit(reg::INT, int_bit::TRIGD);
|
||||
}
|
||||
|
||||
bool Nuvoton::set_pin_interrupt(uint8_t pin, bool enabled) {
|
||||
bool IOExpander::set_pin_interrupt(uint8_t pin, bool enabled) {
|
||||
bool succeeded = false;
|
||||
if(pin >= 1 && pin <= NUM_PINS) {
|
||||
Pin& io_pin = pins[pin - 1];
|
||||
|
@ -401,14 +417,14 @@ namespace pimoroni {
|
|||
return succeeded;
|
||||
}
|
||||
|
||||
void Nuvoton::set_interrupt_callback(void (*callback)()) {
|
||||
void IOExpander::set_interrupt_callback(void (*callback)()) {
|
||||
if(interrupt != 0 && callback != nullptr) {
|
||||
//attachInterrupt(digitalPinToInterrupt(_interruptPin), callback, FALLING);
|
||||
clear_interrupt_flag();
|
||||
}
|
||||
}
|
||||
|
||||
void Nuvoton::pwm_load(bool wait_for_load) {
|
||||
void IOExpander::pwm_load(bool wait_for_load) {
|
||||
//Load new period and duty registers into buffer
|
||||
uint32_t start_time = millis();
|
||||
set_bit(reg::PWMCON0, 6); //Set the "LOAD" bit of PWMCON0
|
||||
|
@ -425,11 +441,11 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
bool Nuvoton::pwm_loading() {
|
||||
bool IOExpander::pwm_loading() {
|
||||
return get_bit(reg::PWMCON0, 6);
|
||||
}
|
||||
|
||||
void Nuvoton::pwm_clear(bool wait_for_clear) {
|
||||
void IOExpander::pwm_clear(bool wait_for_clear) {
|
||||
uint32_t start_time = millis();
|
||||
set_bit(reg::PWMCON0, 4); //Set the "CLRPWM" bit of PWMCON0
|
||||
if(wait_for_clear) {
|
||||
|
@ -444,11 +460,11 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
bool Nuvoton::pwm_clearing() {
|
||||
bool IOExpander::pwm_clearing() {
|
||||
return get_bit(reg::PWMCON0, 4);
|
||||
}
|
||||
|
||||
bool Nuvoton::set_pwm_control(uint8_t divider) {
|
||||
bool IOExpander::set_pwm_control(uint8_t divider) {
|
||||
bool divider_good = true;
|
||||
uint8_t pwmdiv2 = 0;
|
||||
switch(divider) {
|
||||
|
@ -482,7 +498,7 @@ namespace pimoroni {
|
|||
return divider_good;
|
||||
}
|
||||
|
||||
void Nuvoton::set_pwm_period(uint16_t value, bool load) {
|
||||
void IOExpander::set_pwm_period(uint16_t value, bool load) {
|
||||
value &= 0xffff;
|
||||
i2c_reg_write_uint8(reg::PWMPL, (uint8_t)(value & 0xff));
|
||||
i2c_reg_write_uint8(reg::PWMPH, (uint8_t)(value >> 8));
|
||||
|
@ -491,11 +507,11 @@ namespace pimoroni {
|
|||
pwm_load();
|
||||
}
|
||||
|
||||
uint8_t Nuvoton::get_mode(uint8_t pin) {
|
||||
uint8_t IOExpander::get_mode(uint8_t pin) {
|
||||
return pins[pin - 1].get_mode();
|
||||
}
|
||||
|
||||
void Nuvoton::set_mode(uint8_t pin, uint8_t mode, bool schmitt_trigger, bool invert) {
|
||||
void IOExpander::set_mode(uint8_t pin, uint8_t mode, bool schmitt_trigger, bool invert) {
|
||||
if(pin < 1 || pin > NUM_PINS)
|
||||
{
|
||||
printf("ValueError: Pin should be in range 1-14.\n");
|
||||
|
@ -559,7 +575,7 @@ namespace pimoroni {
|
|||
i2c_reg_write_uint8(io_pin.reg_p, (initial_state << 3) | io_pin.pin);
|
||||
}
|
||||
|
||||
int16_t Nuvoton::input(uint8_t pin, uint32_t adc_timeout) {
|
||||
int16_t IOExpander::input(uint8_t pin, uint32_t adc_timeout) {
|
||||
if(pin < 1 || pin > NUM_PINS)
|
||||
{
|
||||
if(debug)
|
||||
|
@ -608,7 +624,7 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
float Nuvoton::input_as_voltage(uint8_t pin, uint32_t adc_timeout) {
|
||||
float IOExpander::input_as_voltage(uint8_t pin, uint32_t adc_timeout) {
|
||||
if(pin < 1 || pin > NUM_PINS)
|
||||
{
|
||||
if(debug)
|
||||
|
@ -658,7 +674,7 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
void Nuvoton::output(uint8_t pin, uint16_t value, bool load) {
|
||||
void IOExpander::output(uint8_t pin, uint16_t value, bool load) {
|
||||
if(pin < 1 || pin > NUM_PINS) {
|
||||
printf("Pin should be in range 1-14.");
|
||||
return;
|
||||
|
@ -677,14 +693,14 @@ namespace pimoroni {
|
|||
pwm_load();
|
||||
}
|
||||
else {
|
||||
if(value == 0) {
|
||||
if(value == LOW) {
|
||||
if(debug) {
|
||||
printf("Outputting LOW to pin: %d\n", pin);
|
||||
}
|
||||
|
||||
clr_bit(io_pin.reg_p, io_pin.pin);
|
||||
}
|
||||
else if(value == 1) {
|
||||
else if(value == HIGH) {
|
||||
if(debug) {
|
||||
printf("Outputting HIGH to pin: %d\n", pin);
|
||||
}
|
||||
|
@ -694,7 +710,7 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
void Nuvoton::setup_rotary_encoder(uint8_t channel, uint8_t pinA, uint8_t pinB, uint8_t pinC, bool count_microsteps) {
|
||||
void IOExpander::setup_rotary_encoder(uint8_t channel, uint8_t pinA, uint8_t pinB, uint8_t pinC, bool count_microsteps) {
|
||||
channel -= 1;
|
||||
set_mode(pinA, PIN_MODE_PU, true);
|
||||
set_mode(pinB, PIN_MODE_PU, true);
|
||||
|
@ -713,7 +729,7 @@ namespace pimoroni {
|
|||
i2c_reg_write_uint8(reg, 0x00);
|
||||
}
|
||||
|
||||
int16_t Nuvoton::read_rotary_encoder(uint8_t channel) {
|
||||
int16_t IOExpander::read_rotary_encoder(uint8_t channel) {
|
||||
channel -= 1;
|
||||
int16_t last = encoder_last[channel];
|
||||
uint8_t reg = ENC_COUNT[channel];
|
||||
|
@ -732,24 +748,24 @@ namespace pimoroni {
|
|||
return encoder_offset[channel] + value;
|
||||
}
|
||||
|
||||
uint8_t Nuvoton::i2c_reg_read_uint8(uint8_t reg) {
|
||||
uint8_t IOExpander::i2c_reg_read_uint8(uint8_t reg) {
|
||||
uint8_t value;
|
||||
i2c_write_blocking(i2c, address, ®, 1, true);
|
||||
i2c_read_blocking(i2c, address, (uint8_t *)&value, 1, false);
|
||||
return value;
|
||||
}
|
||||
|
||||
void Nuvoton::i2c_reg_write_uint8(uint8_t reg, uint8_t value) {
|
||||
void IOExpander::i2c_reg_write_uint8(uint8_t reg, uint8_t value) {
|
||||
uint8_t buffer[2] = {reg, value};
|
||||
i2c_write_blocking(i2c, address, buffer, 2, false);
|
||||
}
|
||||
|
||||
uint8_t Nuvoton::get_bit(uint8_t reg, uint8_t bit) {
|
||||
uint8_t IOExpander::get_bit(uint8_t reg, uint8_t bit) {
|
||||
//Returns the specified bit (nth position from right) from a register
|
||||
return i2c_reg_read_uint8(reg) & (1 << bit);
|
||||
}
|
||||
|
||||
void Nuvoton::set_bits(uint8_t reg, uint8_t bits) {
|
||||
void IOExpander::set_bits(uint8_t reg, uint8_t bits) {
|
||||
//Set the specified bits (using a mask) in a register.
|
||||
|
||||
//Deal with special case registers first
|
||||
|
@ -773,12 +789,12 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
void Nuvoton::set_bit(uint8_t reg, uint8_t bit) {
|
||||
void IOExpander::set_bit(uint8_t reg, uint8_t bit) {
|
||||
//Set the specified bit (nth position from right) in a register.
|
||||
set_bits(reg, (1 << bit));
|
||||
}
|
||||
|
||||
void Nuvoton::clr_bits(uint8_t reg, uint8_t bits) {
|
||||
void IOExpander::clr_bits(uint8_t reg, uint8_t bits) {
|
||||
bool reg_in_bit_addressed_regs = false;
|
||||
for(uint8_t i = 0; i < NUM_BIT_ADDRESSED_REGISTERS; i++) {
|
||||
if(BIT_ADDRESSED_REGS[i] == reg) {
|
||||
|
@ -799,12 +815,12 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
void Nuvoton::clr_bit(uint8_t reg, uint8_t bit) {
|
||||
void IOExpander::clr_bit(uint8_t reg, uint8_t bit) {
|
||||
//Clear the specified bit (nth position from right) in a register.
|
||||
clr_bits(reg, (1 << bit));
|
||||
}
|
||||
|
||||
void Nuvoton::change_bit(uint8_t reg, uint8_t bit, bool state) {
|
||||
void IOExpander::change_bit(uint8_t reg, uint8_t bit, bool state) {
|
||||
//Toggle one register bit on/off.
|
||||
if(state)
|
||||
set_bit(reg, bit);
|
||||
|
@ -812,7 +828,7 @@ namespace pimoroni {
|
|||
clr_bit(reg, bit);
|
||||
}
|
||||
|
||||
void Nuvoton::wait_for_flash(void) {
|
||||
void IOExpander::wait_for_flash(void) {
|
||||
//Wait for the IOE to finish writing non-volatile memory.
|
||||
unsigned long start_time = millis();
|
||||
while(get_interrupt_flag()) {
|
||||
|
@ -833,7 +849,7 @@ namespace pimoroni {
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t Nuvoton::millis() {
|
||||
uint32_t IOExpander::millis() {
|
||||
return to_ms_since_boot(get_absolute_time());
|
||||
}
|
||||
}
|
|
@ -5,24 +5,24 @@
|
|||
|
||||
namespace pimoroni {
|
||||
|
||||
class Nuvoton {
|
||||
class IOExpander {
|
||||
//--------------------------------------------------
|
||||
// Constants
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
//These values encode our desired pin function: IO, ADC, PWM
|
||||
//alongwide the GPIO MODE for that port and pin (section 8.1)
|
||||
//1st and 2nd bits encode the gpio state
|
||||
//3rd and 4th bits encode the IO mode (i.e. IO, PWM, ADC)
|
||||
//the 5th bit additionally encodes the default output state
|
||||
static const uint8_t PIN_MODE_IO = 0b00000; //General IO mode, IE: not ADC or PWM
|
||||
static const uint8_t PIN_MODE_QB = 0b00000; //Output, Quasi-Bidirectional mode
|
||||
static const uint8_t PIN_MODE_PP = 0b00001; //Output, Push-Pull mode
|
||||
static const uint8_t PIN_MODE_IN = 0b00010; //Input-only (high-impedance)
|
||||
static const uint8_t PIN_MODE_PU = 0b10000; //Input (with pull-up)
|
||||
static const uint8_t PIN_MODE_OD = 0b00011; //Output, Open-Drain mode
|
||||
static const uint8_t PIN_MODE_PWM = 0b00101; //PWM, Output, Push-Pull mode
|
||||
static const uint8_t PIN_MODE_ADC = 0b01010; //ADC, Input-only (high-impedance)
|
||||
// These values encode our desired pin function: IO, ADC, PWM
|
||||
// alongwide the GPIO MODE for that port and pin (section 8.1)
|
||||
// 1st and 2nd bits encode the gpio state
|
||||
// 3rd and 4th bits encode the IO mode (i.e. IO, PWM, ADC)
|
||||
// the 5th bit additionally encodes the default output state
|
||||
static const uint8_t PIN_MODE_IO = 0b00000; // General IO mode, IE: not ADC or PWM
|
||||
static const uint8_t PIN_MODE_QB = 0b00000; // Output, Quasi-Bidirectional mode
|
||||
static const uint8_t PIN_MODE_PP = 0b00001; // Output, Push-Pull mode
|
||||
static const uint8_t PIN_MODE_IN = 0b00010; // Input-only (high-impedance)
|
||||
static const uint8_t PIN_MODE_PU = 0b10000; // Input (with pull-up)
|
||||
static const uint8_t PIN_MODE_OD = 0b00011; // Output, Open-Drain mode
|
||||
static const uint8_t PIN_MODE_PWM = 0b00101; // PWM, Output, Push-Pull mode
|
||||
static const uint8_t PIN_MODE_ADC = 0b01010; // ADC, Input-only (high-impedance)
|
||||
|
||||
public:
|
||||
static const uint8_t DEFAULT_I2C_ADDRESS = 0x18;
|
||||
|
@ -33,15 +33,18 @@ namespace pimoroni {
|
|||
static const uint16_t CHIP_ID = 0xE26A;
|
||||
static const uint8_t CHIP_VERSION = 2;
|
||||
|
||||
static const uint8_t PIN_IN = PIN_MODE_IN; //0b00010
|
||||
static const uint8_t PIN_IN_PULL_UP = PIN_MODE_PU; //0b10000
|
||||
static const uint8_t PIN_IN_PU = PIN_MODE_PU; //0b10000
|
||||
static const uint8_t PIN_OUT = PIN_MODE_PP; //0b00001
|
||||
static const uint8_t PIN_PWM = PIN_MODE_PWM; //0b00101
|
||||
static const uint8_t PIN_ADC = PIN_MODE_ADC; //0b01010
|
||||
static const uint8_t PIN_IN = PIN_MODE_IN; // 0b00010
|
||||
static const uint8_t PIN_IN_PULL_UP = PIN_MODE_PU; // 0b10000
|
||||
static const uint8_t PIN_IN_PU = PIN_MODE_PU; // 0b10000
|
||||
static const uint8_t PIN_OUT = PIN_MODE_PP; // 0b00001
|
||||
static const uint8_t PIN_PWM = PIN_MODE_PWM; // 0b00101
|
||||
static const uint8_t PIN_ADC = PIN_MODE_ADC; // 0b01010
|
||||
|
||||
static const uint8_t NUM_PINS = 14;
|
||||
|
||||
static const uint16_t LOW = 0;
|
||||
static const uint16_t HIGH = 1;
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Subclasses
|
||||
|
@ -58,43 +61,43 @@ namespace pimoroni {
|
|||
TYPE_ADC = 0b10,
|
||||
TYPE_ADC_OR_PWM = 0b11
|
||||
};
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constants
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
//The PxM1 and PxM2 registers encode GPIO MODE
|
||||
//0 0 = Quasi-bidirectional
|
||||
//0 1 = Push-pull
|
||||
//1 0 = Input-only (high-impedance)
|
||||
//1 1 = Open-drain
|
||||
static const uint8_t PxM1[4]; //[reg::P0M1, reg::P1M1, -1, reg::P3M1]
|
||||
static const uint8_t PxM2[4]; //[reg::P0M2, reg::P1M2, -1, reg::P3M2]
|
||||
// The PxM1 and PxM2 registers encode GPIO MODE
|
||||
// 0 0 = Quasi-bidirectional
|
||||
// 0 1 = Push-pull
|
||||
// 1 0 = Input-only (high-impedance)
|
||||
// 1 1 = Open-drain
|
||||
static const uint8_t PxM1[4]; // [reg::P0M1, reg::P1M1, -1, reg::P3M1]
|
||||
static const uint8_t PxM2[4]; // [reg::P0M2, reg::P1M2, -1, reg::P3M2]
|
||||
|
||||
//The Px input register
|
||||
static const uint8_t Px[4]; //[reg::P0, reg::P1, -1, reg::P3]
|
||||
// The Px input register
|
||||
static const uint8_t Px[4]; // [reg::P0, reg::P1, -1, reg::P3]
|
||||
|
||||
//The PxS Schmitt trigger register
|
||||
static const uint8_t PxS[4]; //[reg::P0S, reg::P1S, -1, reg::P3S]
|
||||
static const uint8_t MASK_P[4]; //[reg::INT_MASK_P0, reg::INT_MASK_P1, -1, reg::INT_MASK_P3]
|
||||
// The PxS Schmitt trigger register
|
||||
static const uint8_t PxS[4]; // [reg::P0S, reg::P1S, -1, reg::P3S]
|
||||
static const uint8_t MASK_P[4]; // [reg::INT_MASK_P0, reg::INT_MASK_P1, -1, reg::INT_MASK_P3]
|
||||
|
||||
static const uint8_t PWML[6]; //[reg::PWM0L, reg::PWM1L, reg::PWM2L, reg::PWM3L, reg::PWM4L, reg::PWM5L]
|
||||
static const uint8_t PWMH[6]; //[reg::PWM0H, reg::PWM1H, reg::PWM2H, reg::PWM3H, reg::PWM4H, reg::PWM5H]
|
||||
static const uint8_t PWML[6]; // [reg::PWM0L, reg::PWM1L, reg::PWM2L, reg::PWM3L, reg::PWM4L, reg::PWM5L]
|
||||
static const uint8_t PWMH[6]; // [reg::PWM0H, reg::PWM1H, reg::PWM2H, reg::PWM3H, reg::PWM4H, reg::PWM5H]
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
const IOType type;
|
||||
const IOType type;
|
||||
uint8_t mode;
|
||||
public:
|
||||
const uint8_t port;
|
||||
const uint8_t pin;
|
||||
const uint8_t adc_channel;
|
||||
const uint8_t pwm_channel;
|
||||
|
||||
|
||||
const uint8_t reg_m1;
|
||||
const uint8_t reg_m2;
|
||||
const uint8_t reg_p;
|
||||
|
@ -110,24 +113,22 @@ namespace pimoroni {
|
|||
// Constructors
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
Pin(uint8_t port, uint8_t pin); //Constructor for IO pin
|
||||
Pin(uint8_t port, uint8_t pin, uint8_t pwm_channel, uint8_t reg_iopwm); //Constructor for PWM pin
|
||||
Pin(uint8_t port, uint8_t pin, uint8_t adc_channel); //Constructor for ADC pin
|
||||
Pin(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_iopwm); //Constructor for ADC or PWM pin
|
||||
Pin(uint8_t port, uint8_t pin); // Constructor for IO pin
|
||||
Pin(uint8_t port, uint8_t pin, uint8_t pwm_channel, uint8_t reg_iopwm); // Constructor for PWM pin
|
||||
Pin(uint8_t port, uint8_t pin, uint8_t adc_channel); // Constructor for ADC pin
|
||||
Pin(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_iopwm); // Constructor for ADC or PWM pin
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
static Pin io(uint8_t port, uint8_t pin); //Nicer function for creating an IO pin
|
||||
static Pin pwm(uint8_t port, uint8_t pin, uint8_t channel, uint8_t reg_iopwm); //Nicer function for creating a PWM pin
|
||||
static Pin adc(uint8_t port, uint8_t pin, uint8_t channel); //Nicer function for creating an ADC pin
|
||||
static Pin adc_or_pwm(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_iopwm); //Nicer function for creating an ADC or PWM pin
|
||||
static Pin io(uint8_t port, uint8_t pin); // Nicer function for creating an IO pin
|
||||
static Pin pwm(uint8_t port, uint8_t pin, uint8_t channel, uint8_t reg_iopwm); // Nicer function for creating a PWM pin
|
||||
static Pin adc(uint8_t port, uint8_t pin, uint8_t channel); // Nicer function for creating an ADC pin
|
||||
static Pin adc_or_pwm(uint8_t port, uint8_t pin, uint8_t adc_channel, uint8_t pwm_channel, uint8_t reg_iopwm); // Nicer function for creating an ADC or PWM pin
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
IOType get_type(void);
|
||||
IOType get_type(void);
|
||||
uint8_t get_mode(void);
|
||||
void set_mode(uint8_t mode);
|
||||
|
||||
|
@ -149,7 +150,7 @@ namespace pimoroni {
|
|||
|
||||
uint32_t timeout;
|
||||
bool debug;
|
||||
float vref;
|
||||
float vref;
|
||||
int16_t encoder_offset[4];;
|
||||
int16_t encoder_last[4];
|
||||
Pin pins[NUM_PINS];
|
||||
|
@ -159,8 +160,8 @@ namespace pimoroni {
|
|||
// Constructors/Destructor
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
Nuvoton(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt, uint8_t address = DEFAULT_I2C_ADDRESS, uint32_t timeout = 1, bool debug = false);
|
||||
Nuvoton(uint8_t address = DEFAULT_I2C_ADDRESS, uint32_t timeout = 1, bool debug = false);
|
||||
IOExpander(i2c_inst_t *i2c, uint8_t sda, uint8_t scl, uint8_t interrupt, uint8_t address = DEFAULT_I2C_ADDRESS, uint32_t timeout = 1, bool debug = false);
|
||||
IOExpander(uint8_t address = DEFAULT_I2C_ADDRESS, uint32_t timeout = 1, bool debug = false);
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
|
@ -169,53 +170,44 @@ namespace pimoroni {
|
|||
public:
|
||||
bool init(bool skip_chip_id_check = false);
|
||||
|
||||
//--------------------------------------------------
|
||||
// For print access in micropython
|
||||
i2c_inst_t* get_i2c() const;
|
||||
int get_sda() const;
|
||||
int get_scl() const;
|
||||
int get_int() const;
|
||||
|
||||
uint16_t get_chip_id();
|
||||
|
||||
|
||||
void set_addr(uint8_t address);
|
||||
|
||||
float get_adc_vref();
|
||||
void set_adc_vref(float vref);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
|
||||
void enable_interrupt_out(bool pin_swap = false);
|
||||
void disable_interrupt_out();
|
||||
|
||||
uint8_t get_interrupt_flag();
|
||||
void clear_interrupt_flag();
|
||||
|
||||
bool set_pin_interrupt(uint8_t pin, bool enabled);
|
||||
void set_interrupt_callback(void (*callback)());
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
void pwm_load(bool wait_for_load = true);
|
||||
bool pwm_loading();
|
||||
|
||||
void pwm_clear(bool wait_for_clear = true);
|
||||
bool pwm_clearing();
|
||||
|
||||
bool set_pwm_control(uint8_t divider);
|
||||
void set_pwm_period(uint16_t value, bool load = true);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
uint8_t get_mode(uint8_t pin);
|
||||
void set_mode(uint8_t pin, uint8_t mode, bool schmitt_trigger = false, bool invert = false);
|
||||
|
||||
int16_t input(uint8_t pin, uint32_t adc_timeout = 1);
|
||||
float input_as_voltage(uint8_t pin, uint32_t adc_timeout = 1);
|
||||
|
||||
|
||||
void output(uint8_t pin, uint16_t value, bool load = true);
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
void setup_rotary_encoder(uint8_t channel, uint8_t pinA, uint8_t pinB, uint8_t pinC = 0, bool count_microsteps = false);
|
||||
int16_t read_rotary_encoder(uint8_t channel);
|
||||
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
uint8_t i2c_reg_read_uint8(uint8_t reg);
|
||||
void i2c_reg_write_uint8(uint8_t reg, uint8_t value);
|
|
@ -1 +0,0 @@
|
|||
include(nuvoton.cmake)
|
|
@ -1,9 +1,12 @@
|
|||
add_subdirectory(breakout_dotmatrix)
|
||||
add_subdirectory(breakout_encoder)
|
||||
add_subdirectory(breakout_ltr559)
|
||||
add_subdirectory(breakout_colourlcd160x80)
|
||||
add_subdirectory(breakout_roundlcd)
|
||||
add_subdirectory(breakout_rgbmatrix5x5)
|
||||
add_subdirectory(breakout_matrix11x7)
|
||||
add_subdirectory(breakout_mics6814)
|
||||
add_subdirectory(breakout_potentiometer)
|
||||
add_subdirectory(breakout_trackball)
|
||||
add_subdirectory(breakout_sgp30)
|
||||
add_subdirectory(breakout_colourlcd240x240)
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
set(OUTPUT_NAME encoder_demo)
|
||||
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
demo.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_encoder)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,23 @@
|
|||
#include "pico/stdlib.h"
|
||||
|
||||
#include "breakout_encoder.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
BreakoutEncoder enc;
|
||||
|
||||
int main() {
|
||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||
|
||||
enc.init();
|
||||
|
||||
while(true) {
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, true);
|
||||
sleep_ms(1000);
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, false);
|
||||
sleep_ms(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
set(OUTPUT_NAME ioexpander_demo)
|
||||
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
demo.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_ioexpander)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,23 @@
|
|||
#include "pico/stdlib.h"
|
||||
|
||||
#include "breakout_ioexpander.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
BreakoutIOExpander ioe;
|
||||
|
||||
int main() {
|
||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||
|
||||
ioe.init();
|
||||
|
||||
while(true) {
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, true);
|
||||
sleep_ms(1000);
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, false);
|
||||
sleep_ms(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
set(OUTPUT_NAME mics6814_demo)
|
||||
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
demo.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_mics6814)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,23 @@
|
|||
#include "pico/stdlib.h"
|
||||
|
||||
#include "breakout_mics6814.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
BreakoutMICS6814 ioe;
|
||||
|
||||
int main() {
|
||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||
|
||||
ioe.init();
|
||||
|
||||
while(true) {
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, true);
|
||||
sleep_ms(1000);
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, false);
|
||||
sleep_ms(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
set(OUTPUT_NAME potentiometer_demo)
|
||||
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
demo.cpp
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib breakout_potentiometer)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,23 @@
|
|||
#include "pico/stdlib.h"
|
||||
|
||||
#include "breakout_potentiometer.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
BreakoutPotentiometer pot;
|
||||
|
||||
int main() {
|
||||
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||
gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT);
|
||||
|
||||
pot.init();
|
||||
|
||||
while(true) {
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, true);
|
||||
sleep_ms(1000);
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, false);
|
||||
sleep_ms(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -8,4 +8,4 @@ target_sources(${LIB_NAME} INTERFACE
|
|||
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib nuvoton)
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib ioexpander)
|
||||
|
|
|
@ -1,5 +1,86 @@
|
|||
#include "breakout_encoder.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
void BreakoutEncoder::set_addr(uint8_t i2c_addr) {
|
||||
ioe.set_addr(i2c_addr);
|
||||
}
|
||||
|
||||
bool BreakoutEncoder::get_direction(void) {
|
||||
return direction_cw;
|
||||
}
|
||||
|
||||
void BreakoutEncoder::set_direction(bool clockwise) {
|
||||
direction_cw = clockwise;
|
||||
}
|
||||
|
||||
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);
|
||||
if(!direction_cw)
|
||||
count = 0 - count;
|
||||
|
||||
ioe.clear_interrupt_flag();
|
||||
return count;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,93 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../drivers/nuvoton/nuvoton.hpp"
|
||||
#include "../../drivers/ioexpander/ioexpander.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
typedef Nuvoton BreakoutEncoder;
|
||||
}
|
||||
class BreakoutEncoder {
|
||||
//--------------------------------------------------
|
||||
// Enums
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
enum Direction : bool {
|
||||
DIRECTION_CW = true,
|
||||
DIRECTION_CCW = false
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constants
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
static const uint8_t DEFAULT_I2C_ADDRESS = 0x0F;
|
||||
static constexpr float DEFAULT_BRIGHTNESS = 1.0f; //Effectively the maximum fraction of the period that the LED will be on
|
||||
static const bool DEFAULT_DIRECTION = DIRECTION_CW;
|
||||
static const uint8_t PIN_UNUSED = UINT8_MAX;
|
||||
static const uint32_t DEFAULT_TIMEOUT = 1;
|
||||
|
||||
private:
|
||||
static const uint8_t LED_R = 1;
|
||||
static const uint8_t LED_G = 7;
|
||||
static const uint8_t LED_B = 2;
|
||||
|
||||
static const uint8_t ENC_TERM_A = 12;
|
||||
static const uint8_t ENC_TERM_B = 3;
|
||||
static const uint8_t ENC_TERM_C = 11;
|
||||
|
||||
static const uint8_t ENC_CHANNEL = 1;
|
||||
|
||||
static const bool INVERT_OUTPUT = true; //true for common cathode, false for common anode
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
IOExpander ioe;
|
||||
bool direction_cw = DEFAULT_DIRECTION;
|
||||
float brightness = DEFAULT_BRIGHTNESS;
|
||||
uint8_t interrupt_pin = PIN_UNUSED; // A local copy of the value passed to the IOExpander, used in initialisation
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constructors/Destructor
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
BreakoutEncoder() :
|
||||
ioe(DEFAULT_I2C_ADDRESS) {}
|
||||
|
||||
BreakoutEncoder(uint8_t address) :
|
||||
ioe(address) {}
|
||||
|
||||
BreakoutEncoder(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) :
|
||||
ioe(i2c, address, sda, scl, interrupt, timeout),
|
||||
interrupt_pin(interrupt) {}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
bool init(bool skip_chip_id_check = false);
|
||||
|
||||
// For print access in micropython
|
||||
i2c_inst_t* get_i2c() const;
|
||||
int get_sda() const;
|
||||
int get_scl() const;
|
||||
int get_int() const;
|
||||
|
||||
// Calls through to IOExpander class
|
||||
void set_addr(uint8_t i2c_addr);
|
||||
|
||||
// Encoder breakout specific
|
||||
bool get_direction();
|
||||
void set_direction(bool clockwise);
|
||||
|
||||
void set_brightness(float brightness);
|
||||
void set_led(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
bool available();
|
||||
int16_t read();
|
||||
};
|
||||
|
||||
}
|
|
@ -8,4 +8,4 @@ target_sources(${LIB_NAME} INTERFACE
|
|||
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib nuvoton)
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib ioexpander)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../drivers/nuvoton/nuvoton.hpp"
|
||||
#include "../../drivers/ioexpander/ioexpander.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
typedef Nuvoton BreakoutIOExpander;
|
||||
typedef IOExpander BreakoutIOExpander;
|
||||
}
|
||||
|
|
|
@ -8,4 +8,4 @@ target_sources(${LIB_NAME} INTERFACE
|
|||
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib nuvoton)
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib ioexpander)
|
||||
|
|
|
@ -1,5 +1,154 @@
|
|||
#include "breakout_mics6814.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
}
|
||||
bool BreakoutMICS6814::init(bool skip_chip_id_check) {
|
||||
bool success = false;
|
||||
if(ioe.init(skip_chip_id_check)) {
|
||||
|
||||
ioe.set_mode(MICS_VREF, IOExpander::PIN_ADC);
|
||||
ioe.set_mode(MICS_RED, IOExpander::PIN_ADC);
|
||||
ioe.set_mode(MICS_NH3, IOExpander::PIN_ADC);
|
||||
ioe.set_mode(MICS_OX, IOExpander::PIN_ADC);
|
||||
|
||||
ioe.set_mode(MICS_HEATER_EN, IOExpander::PIN_OUT);
|
||||
ioe.output(MICS_HEATER_EN, 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* BreakoutMICS6814::get_i2c() const {
|
||||
return ioe.get_i2c();
|
||||
}
|
||||
|
||||
int BreakoutMICS6814::get_sda() const {
|
||||
return ioe.get_sda();
|
||||
}
|
||||
|
||||
int BreakoutMICS6814::get_scl() const {
|
||||
return ioe.get_scl();
|
||||
}
|
||||
|
||||
int BreakoutMICS6814::get_int() const {
|
||||
return ioe.get_int();
|
||||
}
|
||||
|
||||
void BreakoutMICS6814::set_addr(uint8_t i2c_addr) {
|
||||
ioe.set_addr(i2c_addr);
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::get_adc_vref(void) {
|
||||
return ioe.get_adc_vref();
|
||||
}
|
||||
|
||||
void BreakoutMICS6814::set_adc_vref(float vref) {
|
||||
ioe.set_adc_vref(vref);
|
||||
}
|
||||
|
||||
void BreakoutMICS6814::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 BreakoutMICS6814::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
|
||||
}
|
||||
|
||||
void BreakoutMICS6814::set_heater(bool on) {
|
||||
ioe.output(MICS_HEATER_EN, on ? IOExpander::LOW : IOExpander::HIGH);
|
||||
}
|
||||
|
||||
void BreakoutMICS6814::disable_heater() {
|
||||
ioe.output(MICS_HEATER_EN, IOExpander::HIGH);
|
||||
ioe.set_mode(MICS_HEATER_EN, IOExpander::PIN_IN);
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::get_raw_ref(uint32_t adc_timeout) {
|
||||
return ioe.input_as_voltage(MICS_VREF, adc_timeout);
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::get_raw_red(uint32_t adc_timeout) {
|
||||
return ioe.input_as_voltage(MICS_RED, adc_timeout);
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::get_raw_nh3(uint32_t adc_timeout) {
|
||||
return ioe.input_as_voltage(MICS_NH3, adc_timeout);
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::get_raw_oxd(uint32_t adc_timeout) {
|
||||
return ioe.input_as_voltage(MICS_OX, adc_timeout);
|
||||
}
|
||||
|
||||
BreakoutMICS6814::Reading BreakoutMICS6814::read_all(uint32_t adc_timeout) {
|
||||
BreakoutMICS6814::Reading reading;
|
||||
reading.reducing = read_reducing(adc_timeout);
|
||||
reading.nh3 = read_nh3(adc_timeout);
|
||||
reading.oxidising = read_oxidising(adc_timeout);
|
||||
reading.ref = read_ref(adc_timeout);
|
||||
return reading;
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::read_ref(uint32_t adc_timeout) {
|
||||
float ref = get_raw_ref(adc_timeout);
|
||||
if(ref == -1)
|
||||
ref = 0;
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::read_reducing(uint32_t adc_timeout) {
|
||||
float vref = ioe.get_adc_vref();
|
||||
|
||||
float red = get_raw_red(adc_timeout);
|
||||
if((red != -1) && (vref != red))
|
||||
red = (red * 56000.0f) / (vref - red);
|
||||
else
|
||||
red = 0;
|
||||
|
||||
return red;
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::read_nh3(uint32_t adc_timeout) {
|
||||
float vref = ioe.get_adc_vref();
|
||||
|
||||
float nh3 = get_raw_red(adc_timeout);
|
||||
if((nh3 != -1) && (vref != nh3))
|
||||
nh3 = (nh3 * 56000.0f) / (vref - nh3);
|
||||
else
|
||||
nh3 = 0;
|
||||
|
||||
return nh3;
|
||||
}
|
||||
|
||||
float BreakoutMICS6814::read_oxidising(uint32_t adc_timeout) {
|
||||
float vref = ioe.get_adc_vref();
|
||||
|
||||
float oxd = get_raw_red(adc_timeout);
|
||||
if((oxd != -1) && (vref != oxd))
|
||||
oxd = (oxd * 56000.0f) / (vref - oxd);
|
||||
else
|
||||
oxd = 0;
|
||||
|
||||
return oxd;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,103 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../drivers/nuvoton/nuvoton.hpp"
|
||||
#include "../../drivers/ioexpander/ioexpander.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
typedef Nuvoton BreakoutMICS6814;
|
||||
}
|
||||
class BreakoutMICS6814 {
|
||||
//--------------------------------------------------
|
||||
// Constants
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
static const uint8_t DEFAULT_I2C_ADDRESS = 0x19;
|
||||
static constexpr float DEFAULT_BRIGHTNESS = 1.0f; //Effectively the maximum fraction of the period that the LED will be on
|
||||
static const uint8_t PIN_UNUSED = UINT8_MAX;
|
||||
static const uint32_t DEFAULT_TIMEOUT = 1;
|
||||
static const uint32_t DEFAULT_ADC_TIMEOUT = 1;
|
||||
|
||||
private:
|
||||
static const uint8_t LED_R = 3;
|
||||
static const uint8_t LED_G = 7;
|
||||
static const uint8_t LED_B = 2;
|
||||
|
||||
static const uint8_t MICS_VREF = 14;
|
||||
static const uint8_t MICS_RED = 12;
|
||||
static const uint8_t MICS_NH3 = 11;
|
||||
static const uint8_t MICS_OX = 13;
|
||||
static const uint8_t MICS_HEATER_EN = 1;
|
||||
|
||||
static const bool INVERT_OUTPUT = true; //true for common cathode, false for common anode
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Substructures
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
struct Reading {
|
||||
float ref;
|
||||
float reducing;
|
||||
float nh3;
|
||||
float oxidising;
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
IOExpander ioe;
|
||||
float brightness = DEFAULT_BRIGHTNESS;
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constructors/Destructor
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
BreakoutMICS6814() :
|
||||
ioe(DEFAULT_I2C_ADDRESS) {}
|
||||
|
||||
BreakoutMICS6814(uint8_t address) :
|
||||
ioe(address) {}
|
||||
|
||||
BreakoutMICS6814(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) :
|
||||
ioe(i2c, address, sda, scl, interrupt, timeout) {}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
bool init(bool skip_chip_id_check = false);
|
||||
|
||||
// For print access in micropython
|
||||
i2c_inst_t* get_i2c() const;
|
||||
int get_sda() const;
|
||||
int get_scl() const;
|
||||
int get_int() const;
|
||||
|
||||
// Calls through to IOExpander class
|
||||
void set_addr(uint8_t i2c_addr);
|
||||
|
||||
float get_adc_vref();
|
||||
void set_adc_vref(float vref);
|
||||
|
||||
// MICS breakout specific
|
||||
void set_brightness(float brightness);
|
||||
void set_led(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
void set_heater(bool on);
|
||||
void disable_heater();
|
||||
|
||||
float get_raw_ref(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float get_raw_red(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float get_raw_nh3(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float get_raw_oxd(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
|
||||
Reading read_all(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float read_ref(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float read_reducing(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float read_nh3(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float read_oxidising(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
};
|
||||
|
||||
}
|
|
@ -8,4 +8,4 @@ target_sources(${LIB_NAME} INTERFACE
|
|||
target_include_directories(${LIB_NAME} INTERFACE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib nuvoton)
|
||||
target_link_libraries(${LIB_NAME} INTERFACE pico_stdlib ioexpander)
|
||||
|
|
|
@ -1,5 +1,109 @@
|
|||
#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_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_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_addr(uint8_t i2c_addr) {
|
||||
ioe.set_addr(i2c_addr);
|
||||
}
|
||||
|
||||
float BreakoutPotentiometer::get_adc_vref(void) {
|
||||
return ioe.get_adc_vref();
|
||||
}
|
||||
|
||||
void BreakoutPotentiometer::set_adc_vref(float vref) {
|
||||
ioe.set_adc_vref(vref);
|
||||
}
|
||||
|
||||
bool BreakoutPotentiometer::get_direction(void) {
|
||||
return direction_cw;
|
||||
}
|
||||
|
||||
void BreakoutPotentiometer::set_direction(bool clockwise) {
|
||||
if(clockwise) {
|
||||
// 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);
|
||||
}
|
||||
direction_cw = clockwise;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
int16_t BreakoutPotentiometer::read(uint32_t adc_timeout) {
|
||||
return ioe.input(POT_INPUT, adc_timeout);
|
||||
}
|
||||
|
||||
float BreakoutPotentiometer::read_as_percent(uint32_t adc_timeout) {
|
||||
return (ioe.input_as_voltage(POT_INPUT, adc_timeout) / ioe.get_adc_vref());
|
||||
}
|
||||
}
|
|
@ -1,8 +1,93 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../drivers/nuvoton/nuvoton.hpp"
|
||||
#include "../../drivers/ioexpander/ioexpander.hpp"
|
||||
|
||||
namespace pimoroni {
|
||||
|
||||
typedef Nuvoton BreakoutPotentiometer;
|
||||
}
|
||||
class BreakoutPotentiometer {
|
||||
//--------------------------------------------------
|
||||
// Enums
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
enum Direction : bool {
|
||||
DIRECTION_CW = true,
|
||||
DIRECTION_CCW = false
|
||||
};
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constants
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
static const uint8_t DEFAULT_I2C_ADDRESS = 0x0E;
|
||||
static constexpr float DEFAULT_BRIGHTNESS = 1.0f; //Effectively the maximum fraction of the period that the LED will be on
|
||||
static const bool DEFAULT_DIRECTION = DIRECTION_CW;
|
||||
static const uint8_t PIN_UNUSED = UINT8_MAX;
|
||||
static const uint32_t DEFAULT_TIMEOUT = 1;
|
||||
static const uint32_t DEFAULT_ADC_TIMEOUT = 1;
|
||||
|
||||
private:
|
||||
static const uint8_t LED_R = 1;
|
||||
static const uint8_t LED_G = 7;
|
||||
static const uint8_t LED_B = 2;
|
||||
|
||||
static const uint8_t POT_TERM_A = 12;
|
||||
static const uint8_t POT_TERM_B = 3;
|
||||
static const uint8_t POT_INPUT = 11;
|
||||
|
||||
static const bool INVERT_OUTPUT = true; //true for common cathode, false for common anode
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Variables
|
||||
//--------------------------------------------------
|
||||
private:
|
||||
IOExpander ioe;
|
||||
bool direction_cw = DEFAULT_DIRECTION;
|
||||
float brightness = DEFAULT_BRIGHTNESS;
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Constructors/Destructor
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
BreakoutPotentiometer() :
|
||||
ioe(DEFAULT_I2C_ADDRESS) {}
|
||||
|
||||
BreakoutPotentiometer(uint8_t address) :
|
||||
ioe(address) {}
|
||||
|
||||
BreakoutPotentiometer(i2c_inst_t *i2c, uint8_t address, uint8_t sda, uint8_t scl, uint8_t interrupt = PIN_UNUSED, uint32_t timeout = DEFAULT_TIMEOUT) :
|
||||
ioe(i2c, address, sda, scl, interrupt, timeout) {}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Methods
|
||||
//--------------------------------------------------
|
||||
public:
|
||||
bool init(bool skip_chip_id_check = false);
|
||||
|
||||
// For print access in micropython
|
||||
i2c_inst_t* get_i2c() const;
|
||||
int get_sda() const;
|
||||
int get_scl() const;
|
||||
int get_int() const;
|
||||
|
||||
// Calls through to IOExpander class
|
||||
void set_addr(uint8_t i2c_addr);
|
||||
|
||||
float get_adc_vref();
|
||||
void set_adc_vref(float vref);
|
||||
|
||||
// Potentiometer breakout specific
|
||||
bool get_direction();
|
||||
void set_direction(bool clockwise);
|
||||
|
||||
void set_brightness(float brightness);
|
||||
void set_led(uint8_t r, uint8_t g, uint8_t b);
|
||||
|
||||
int16_t read(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
float read_as_percent(uint32_t adc_timeout = DEFAULT_ADC_TIMEOUT);
|
||||
};
|
||||
|
||||
}
|
Ładowanie…
Reference in New Issue