kopia lustrzana https://github.com/pimoroni/pimoroni-pico
further module implementation
rodzic
30547952f2
commit
52a8246dee
|
@ -3,14 +3,14 @@
|
||||||
namespace pimoroni {
|
namespace pimoroni {
|
||||||
IO::IO(uint pin) :
|
IO::IO(uint pin) :
|
||||||
pin(pin) {
|
pin(pin) {
|
||||||
gpio_init(pin);
|
gpio_init(pin);
|
||||||
};
|
};
|
||||||
|
|
||||||
IO::IO(uint pin, bool out, bool pull_up, bool pull_down) :
|
IO::IO(uint pin, bool out, bool pull_up, bool pull_down) :
|
||||||
pin(pin) {
|
pin(pin) {
|
||||||
gpio_init(pin);
|
gpio_init(pin);
|
||||||
direction(out, pull_up, pull_down);
|
direction(out, pull_up, pull_down);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool IO::direction() {
|
bool IO::direction() {
|
||||||
return gpio_is_dir_out(pin);
|
return gpio_is_dir_out(pin);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "audio_amp.hpp"
|
#include "audio_amp.hpp"
|
||||||
#include "../../logging.hpp"
|
#include "../../logging.hpp"
|
||||||
#include "../../errors.hpp"
|
#include "../../errors.hpp"
|
||||||
|
#include "tas_regs.hpp"
|
||||||
|
|
||||||
namespace pimoroni {
|
namespace pimoroni {
|
||||||
|
|
||||||
|
@ -15,7 +16,10 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioAmpModule::AudioAmpModule() :
|
AudioAmpModule::AudioAmpModule() :
|
||||||
YukonModule() {
|
YukonModule(),
|
||||||
|
slow_sda(nullptr),
|
||||||
|
slow_scl(nullptr),
|
||||||
|
amp_en(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioAmpModule::~AudioAmpModule() {
|
AudioAmpModule::~AudioAmpModule() {
|
||||||
|
@ -26,6 +30,13 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioAmpModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
void AudioAmpModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
||||||
|
// Create the "I2C" pin objects
|
||||||
|
slow_sda = new TCA_IO(slot.SLOW1, accessor);
|
||||||
|
slow_scl = new TCA_IO(slot.SLOW2, accessor);
|
||||||
|
|
||||||
|
// Create the enable pin object
|
||||||
|
amp_en = new TCA_IO(slot.SLOW3, accessor);
|
||||||
|
|
||||||
// Configure strip and power pins
|
// Configure strip and power pins
|
||||||
configure();
|
configure();
|
||||||
|
|
||||||
|
@ -34,27 +45,99 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioAmpModule::configure() {
|
void AudioAmpModule::configure() {
|
||||||
|
slow_sda->to_output(true);
|
||||||
|
slow_scl->to_output(true);
|
||||||
|
amp_en->to_output(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioAmpModule::enable() {
|
void AudioAmpModule::enable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
amp_en->value(true);
|
||||||
|
|
||||||
|
// Pre-Reset Configuration
|
||||||
|
write_i2c_reg(PAGE, 0x01); // Page 1
|
||||||
|
write_i2c_reg(0x37, 0x3a); // Bypass
|
||||||
|
|
||||||
|
write_i2c_reg(PAGE, 0xFD); // Page FD
|
||||||
|
write_i2c_reg(0x0D, 0x0D); // Access page
|
||||||
|
write_i2c_reg(0x06, 0xC1); // Set Dmin
|
||||||
|
|
||||||
|
write_i2c_reg(PAGE, 0x01); // Page 1
|
||||||
|
write_i2c_reg(0x19, 0xC0); // Force modulation
|
||||||
|
write_i2c_reg(PAGE, 0xFD); // Page FD
|
||||||
|
write_i2c_reg(0x0D, 0x0D); // Access page
|
||||||
|
write_i2c_reg(0x06, 0xD5); // Set Dmin
|
||||||
|
|
||||||
|
// Software Reset
|
||||||
|
write_i2c_reg(PAGE, 0x00); // Page 0
|
||||||
|
write_i2c_reg(0x7F, 0x00); // Book 0
|
||||||
|
write_i2c_reg(0x01, 0x01); // Software Reset
|
||||||
|
|
||||||
|
// Post-Reset Configuration
|
||||||
|
write_i2c_reg(PAGE, 0x01); // Page 1
|
||||||
|
write_i2c_reg(0x37, 0x3a); // Bypass
|
||||||
|
|
||||||
|
write_i2c_reg(PAGE, 0xFD); // Page FD
|
||||||
|
write_i2c_reg(0x0D, 0x0D); // Access page
|
||||||
|
write_i2c_reg(0x06, 0xC1); // Set Dmin
|
||||||
|
write_i2c_reg(0x06, 0xD5); // Set Dmin
|
||||||
|
|
||||||
|
// Initial Device Configuration - PWR_MODE0
|
||||||
|
write_i2c_reg(PAGE, 0x00); // Page 0
|
||||||
|
write_i2c_reg(0x0E, 0x44); // TDM tx vsns transmit enable with slot 4
|
||||||
|
write_i2c_reg(0x0F, 0x40); // TDM tx isns transmit enable with slot 0
|
||||||
|
|
||||||
|
write_i2c_reg(PAGE, 0x01); // Page 1
|
||||||
|
write_i2c_reg(0x21, 0x00); // Disable Comparator Hysterisis
|
||||||
|
write_i2c_reg(0x17, 0xC8); // SARBurstMask=0
|
||||||
|
write_i2c_reg(0x19, 0x00); // LSR Mode
|
||||||
|
write_i2c_reg(0x35, 0x74); // Noise minimized
|
||||||
|
|
||||||
|
write_i2c_reg(PAGE, 0xFD); // Page FD
|
||||||
|
write_i2c_reg(0x0D, 0x0D); // Access page
|
||||||
|
write_i2c_reg(0x3E, 0x4A); // Optimal Dmin
|
||||||
|
write_i2c_reg(0x0D, 0x00); // Remove access
|
||||||
|
|
||||||
|
write_i2c_reg(PAGE, 0x00); // Page 0
|
||||||
|
write_i2c_reg(CHNL_0, 0xA8); // PWR_MODE0 selected
|
||||||
|
write_i2c_reg(PVDD_UVLO, 0x00); // PVDD UVLO set to 2.76V
|
||||||
|
// My addition
|
||||||
|
write_i2c_reg(DC_BLK0, 0xA1); // VBAT1S_MODE set to internally generated
|
||||||
|
write_i2c_reg(DVC, 0x68); // Go to a low default
|
||||||
|
write_i2c_reg(INT_CLK_CFG, 0x99 + 0b0100000); // CLK_PWR_UD_EN abled, with long time. This causes output to stay active without mute.
|
||||||
|
|
||||||
|
write_i2c_reg(INT_MASK0, 0xFF);
|
||||||
|
write_i2c_reg(INT_MASK1, 0xFF);
|
||||||
|
write_i2c_reg(INT_MASK2, 0xFF);
|
||||||
|
write_i2c_reg(INT_MASK3, 0xFF);
|
||||||
|
write_i2c_reg(INT_MASK4, 0xFF);
|
||||||
|
|
||||||
|
write_i2c_reg(MODE_CTRL, 0x80); // Play audio, power up with playback, IV enabled
|
||||||
|
// A second play command is required for some reason, to take it out of software shutdown
|
||||||
|
// Temp commented out self.write_i2c_reg(MODE_CTRL, 0x80) # Play audio, power up with playback, IV enabled
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioAmpModule::disable() {
|
void AudioAmpModule::disable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
amp_en->value(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioAmpModule::is_enabled() {
|
bool AudioAmpModule::is_enabled() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return amp_en->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioAmpModule::exit_soft_shutdown() {
|
void AudioAmpModule::exit_soft_shutdown() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
write_i2c_reg(MODE_CTRL, 0x80); // Calling this after a play seems to wake the amp up, but adds around 16ms
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioAmpModule::set_volume(float volume) {
|
void AudioAmpModule::set_volume(float volume) {
|
||||||
|
if(volume < 0.0f || volume > 1.0f) {
|
||||||
|
throw std::invalid_argument("Volume out of range. Expected 0.0 to 1.0\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
write_i2c_reg(DVC, (uint8_t)((1.0f - volume) * 0xC8));
|
||||||
}
|
}
|
||||||
|
|
||||||
float AudioAmpModule::read_temperature() {
|
float AudioAmpModule::read_temperature() {
|
||||||
|
|
|
@ -44,10 +44,9 @@ namespace pimoroni {
|
||||||
uint I2S_CLK;
|
uint I2S_CLK;
|
||||||
uint I2S_FS;
|
uint I2S_FS;
|
||||||
private:
|
private:
|
||||||
TCA slow_sda;
|
TCA_IO* slow_sda;
|
||||||
TCA slow_scl;
|
TCA_IO* slow_scl;
|
||||||
TCA amp_en;
|
TCA_IO* amp_en;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
namespace pimoroni {
|
||||||
|
|
||||||
|
enum TASRegs {
|
||||||
|
// PAGE 0 Regs
|
||||||
|
PAGE = 0x00, // Device Page Section 8.9.5
|
||||||
|
SW_RESET = 0x01, // Software Reset Section 8.9.6
|
||||||
|
MODE_CTRL = 0x02, // Device operational mode Section 8.9.7
|
||||||
|
CHNL_0 = 0x03, // Y Bridge and Channel settings Section 8.9.8
|
||||||
|
DC_BLK0 = 0x04, // SAR Filter and DC Path Blocker Section 8.9.9
|
||||||
|
DC_BLK1 = 0x05, // Record DC Blocker Section 8.9.10
|
||||||
|
MISC_CFG1 = 0x06, // Misc Configuration 1 Section 8.9.11
|
||||||
|
MISC_CFG2 = 0x07, // Misc Configuration 2 Section 8.9.12
|
||||||
|
TDM_CFG0 = 0x08, // TDM Configuration 0 Section 8.9.13
|
||||||
|
TDM_CFG1 = 0x09, // TDM Configuration 1 Section 8.9.14
|
||||||
|
TDM_CFG2 = 0x0A, // TDM Configuration 2 Section 8.9.15
|
||||||
|
LIM_MAX_ATTN = 0x0B, // Limiter Section 8.9.16
|
||||||
|
TDM_CFG3 = 0x0C, // TDM Configuration 3 Section 8.9.17
|
||||||
|
TDM_CFG4 = 0x0D, // TDM Configuration 4 Section 8.9.18
|
||||||
|
TDM_CFG5 = 0x0E, // TDM Configuration 5 Section 8.9.19
|
||||||
|
TDM_CFG6 = 0x0F, // TDM Configuration 6 Section 8.9.20
|
||||||
|
TDM_CFG7 = 0x10, // TDM Configuration 7 Section 8.9.21
|
||||||
|
TDM_CFG8 = 0x11, // TDM Configuration 8 Section 8.9.22
|
||||||
|
TDM_CFG9 = 0x12, // TDM Configuration 9 Section 8.9.23
|
||||||
|
TDM_CFG10 = 0x13, // TDM Configuration 10 Section 8.9.24
|
||||||
|
TDM_CFG11 = 0x14, // TDM Configuration 11 Section 8.9.25
|
||||||
|
ICC_CNFG2 = 0x15, // ICC Mode Section 8.9.26
|
||||||
|
TDM_CFG12 = 0x16, // TDM Configuration 12 Section 8.9.27
|
||||||
|
ICLA_CFG0 = 0x17, // Inter Chip Limiter Alignment 0 Section 8.9.28
|
||||||
|
ICLA_CFG1 = 0x18, // Inter Chip Gain Alignment 1 Section 8.9.29
|
||||||
|
DG_0 = 0x19, // Diagnostic Signal Section 8.9.30
|
||||||
|
DVC = 0x1A, // Digital Volume Control Section 8.9.31
|
||||||
|
LIM_CFG0 = 0x1B, // Limiter Configuration 0 Section 8.9.32
|
||||||
|
LIM_CFG1 = 0x1C, // Limiter Configuration 1 Section 8.9.33
|
||||||
|
BOP_CFG0 = 0x1D, // Brown Out Prevention 0 Section 8.9.34
|
||||||
|
BOP_CFG1 = 0x1E, // Brown Out Prevention 1 Section 8.9.35
|
||||||
|
BOP_CFG2 = 0x1F, // Brown Out Prevention 2 Section 8.9.36
|
||||||
|
BOP_CFG3 = 0x20, // Brown Out Prevention 3 Section 8.9.37
|
||||||
|
BOP_CFG4 = 0x21, // Brown Out Prevention 4 Section 8.9.38
|
||||||
|
BOP_CFG5 = 0x22, // BOP Configuration 5 Section 8.9.40
|
||||||
|
BOP_CFG6 = 0x23, // Brown Out Prevention 6 Section 8.9.41
|
||||||
|
BOP_CFG7 = 0x24, // Brown Out Prevention 7 Section 8.9.42
|
||||||
|
BOP_CFG8 = 0x25, // Brown Out Prevention 8 Section 8.9.43
|
||||||
|
BOP_CFG9 = 0x26, // Brown Out Prevention 9 Section 8.9.44
|
||||||
|
BOP_CFG10 = 0x27, // BOP Configuration 10 Section 8.9.45
|
||||||
|
BOP_CFG11 = 0x28, // Brown Out Prevention 11 Section 8.9.46
|
||||||
|
BOP_CFG12 = 0x29, // Brown Out Prevention 12 Section 8.9.47
|
||||||
|
BOP_CFG13 = 0x2A, // Brown Out Prevention 13 Section 8.9.48
|
||||||
|
BOP_CFG14 = 0x2B, // Brown Out Prevention 14 Section 8.9.49
|
||||||
|
BOP_CFG15 = 0x2C, // BOP Configuration 15 Section 8.9.50
|
||||||
|
BOP_CFG17 = 0x2D, // Brown Out Prevention 16 Section 8.9.51
|
||||||
|
BOP_CFG18 = 0x2E, // Brown Out Prevention 17 Section 8.9.52
|
||||||
|
BOP_CFG19 = 0x2F, // Brown Out Prevention 18 Section 8.9.53
|
||||||
|
BOP_CFG20 = 0x30, // Brown Out Prevention 19 Section 8.9.54
|
||||||
|
BOP_CFG21 = 0x31, // BOP Configuration 21 Section 8.9.55
|
||||||
|
BOP_CFG22 = 0x32, // Brown Out Prevention 22 Section 8.9.56
|
||||||
|
BOP_CFG23 = 0x33, // Lowest PVDD Measured Section 8.9.57
|
||||||
|
BOP_CFG24 = 0x34, // Lowest BOP Attack Rate Section 8.9.57
|
||||||
|
NG_CFG0 = 0x35, // Noise Gate 0 Section 8.9.60
|
||||||
|
NG_CFG1 = 0x36, // Noise Gate 1 Section 8.9.61
|
||||||
|
LVS_CFG0 = 0x37, // Low Voltage Signaling Section 8.9.62
|
||||||
|
DIN_PD = 0x38, // Digital Input Pin Pull Down Section 8.9.63
|
||||||
|
IO_DRV0 = 0x39, // Output Driver Strength Section 8.9.64
|
||||||
|
IO_DRV1 = 0x3A, // Output Driver Strength Section 8.9.65
|
||||||
|
INT_MASK0 = 0x3B, // Interrupt Mask 0 Section 8.9.66
|
||||||
|
INT_MASK1 = 0x3C, // Interrupt Mask 1 Section 8.9.67
|
||||||
|
INT_MASK4 = 0x3D, // Interrupt Mask 4 Section 8.9.68
|
||||||
|
INT_MASK2 = 0x40, // Interrupt Mask 2 Section 8.9.69
|
||||||
|
INT_MASK3 = 0x41, // Interrupt Mask 3 Section 8.9.70
|
||||||
|
INT_LIVE0 = 0x42, // Live Interrupt Read-back 0 Section 8.9.71
|
||||||
|
INT_LIVE1 = 0x43, // Live Interrupt Read-back 1 Section 8.9.72
|
||||||
|
INT_LIVE1_0 = 0x44, // Live Interrupt Read-back 1_0 Section 8.9.73
|
||||||
|
INT_LIVE2 = 0x47, // Live Interrupt Read-back 2 Section 8.9.74
|
||||||
|
INT_LIVE3 = 0x48, // Live Interrupt Read-back 3 Section 8.9.75
|
||||||
|
INT_LTCH0 = 0x49, // Latched Interrupt Read-back 0 Section 8.9.76
|
||||||
|
INT_LTCH1 = 0x4A, // Latched Interrupt Read-back 1 Section 8.9.77
|
||||||
|
INT_LTCH1_0 = 0x4B, // Latched Interrupt Read-back 1_0 Section 8.9.78
|
||||||
|
INT_LTCH2 = 0x4F, // Latched Interrupt Read-back 2 Section 8.9.79
|
||||||
|
INT_LTCH3 = 0x50, // Latched Interrupt Read-back 3 Section 8.9.80
|
||||||
|
INT_LTCH4 = 0x51, // Latched Interrupt Read-back 4 Section 8.9.81
|
||||||
|
VBAT_MSB = 0x52, // SAR VBAT1S 0 Section 8.9.82
|
||||||
|
VBAT_LSB = 0x53, // SAR VBAT1S 1 Section 8.9.83
|
||||||
|
PVDD_MSB = 0x54, // SAR PVDD 0 Section 8.9.84
|
||||||
|
PVDD_LSB = 0x55, // SAR PVDD 1 Section 8.9.85
|
||||||
|
TEMP = 0x56, // SAR ADC Conversion 2 Section 8.9.86
|
||||||
|
INT_CLK_CFG = 0x5C, // Clock Setting and IRQZ Section 8.9.87
|
||||||
|
MISC_CFG3 = 0x5D, // Misc Configuration 3 Section 8.9.88
|
||||||
|
CLOCK_CFG = 0x60, // Clock Configuration Section 8.9.89
|
||||||
|
IDLE_IND = 0x63, // Idle channel current optimization Section 8.9.90
|
||||||
|
MISC_CFG4 = 0x65, // Misc Configuration 4 Section 8.9.91
|
||||||
|
TG_CFG0 = 0x67, // Tone Generator Section 8.9.92
|
||||||
|
CLK_CFG = 0x68, // Detect Clock Ration and Sample Rate Section 8.9.93
|
||||||
|
LV_EN_CFG = 0x6A, // Class-D and LVS Delays Section 8.9.94
|
||||||
|
NG_CFG2 = 0x6B, // Noise Gate 2 Section 8.9.95
|
||||||
|
NG_CFG3 = 0x6C, // Noise Gate 3 Section 8.9.96
|
||||||
|
NG_CFG4 = 0x6D, // Noise Gate 4 Section 8.9.97
|
||||||
|
NG_CFG5 = 0x6E, // Noise Gate 5 Section 8.9.98
|
||||||
|
NG_CFG6 = 0x6F, // Noise Gate 6 Section 8.9.99
|
||||||
|
NG_CFG7 = 0x70, // Noise Gate 7 Section 8.9.100
|
||||||
|
PVDD_UVLO = 0x71, // UVLO Threshold Section 8.9.101
|
||||||
|
DMD = 0x73, // DAC Modulator Dither Section 8.9.102
|
||||||
|
I2C_CKSUM = 0x7E, // I2C Checksum Section 8.9.104
|
||||||
|
BOOK = 0x7F, // Device Book Section 8.9.105
|
||||||
|
|
||||||
|
// PAGE 1 Regs
|
||||||
|
LSR = 0x19, // Modulation Section 8.9.106
|
||||||
|
INT_LDO = 0x36, // Internal LDO Setting Section 8.9.107
|
||||||
|
SDOUT_HIZ_1 = 0x3D, // Slots Control Section 8.9.108
|
||||||
|
SDOUT_HIZ_2 = 0x3E, // Slots Control Section 8.9.109
|
||||||
|
SDOUT_HIZ_3 = 0x3F, // Slots Control Section 8.9.110
|
||||||
|
SDOUT_HIZ_4 = 0x40, // Slots Control Section 8.9.111
|
||||||
|
SDOUT_HIZ_5 = 0x41, // Slots Control Section 8.9.112
|
||||||
|
SDOUT_HIZ_6 = 0x42, // Slots Control Section 8.9.113
|
||||||
|
SDOUT_HIZ_7 = 0x43, // Slots Control Section 8.9.114
|
||||||
|
SDOUT_HIZ_8 = 0x44, // Slots Control Section 8.9.115
|
||||||
|
SDOUT_HIZ_9 = 0x45, // Slots Control Section 8.9.116
|
||||||
|
TG_EN = 0x47, // Thermal Detection Enable Section 8.9.117
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -34,6 +34,13 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BenchPowerModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
void BenchPowerModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
||||||
|
// Create the voltage pwm object
|
||||||
|
voltage_pwm = new PWMCluster(pio0, 0, slot.FAST2, 1, true);
|
||||||
|
|
||||||
|
// Create the power control pin objects
|
||||||
|
power_en = new IO(slot.FAST1);
|
||||||
|
power_good = new TCA_IO(slot.SLOW1, accessor);
|
||||||
|
|
||||||
// Configure strip and power pins
|
// Configure strip and power pins
|
||||||
configure();
|
configure();
|
||||||
|
|
||||||
|
@ -42,47 +49,87 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BenchPowerModule::configure() {
|
void BenchPowerModule::configure() {
|
||||||
|
// Calculate a suitable pwm wrap period for this frequency
|
||||||
|
uint32_t period; uint32_t div256;
|
||||||
|
if(pimoroni::PWMCluster::calculate_pwm_factors(250000, period, div256)) {
|
||||||
|
pwm_period = period;
|
||||||
|
|
||||||
|
// Update the pwm before setting the new wrap
|
||||||
|
voltage_pwm->set_chan_level(0, 0, false);
|
||||||
|
voltage_pwm->set_chan_offset(0, 0, false);
|
||||||
|
|
||||||
|
// Set the new wrap (should be 1 less than the period to get full 0 to 100%)
|
||||||
|
voltage_pwm->set_wrap(pwm_period, true); // NOTE Minus 1 not needed here. Maybe should change Wrap behaviour so it is needed, for consistency with hardware pwm?
|
||||||
|
|
||||||
|
// Apply the new divider
|
||||||
|
// This is done after loading new PWM values to avoid a lockup condition
|
||||||
|
uint8_t div = div256 >> 8;
|
||||||
|
uint8_t mod = div256 % 256;
|
||||||
|
voltage_pwm->set_clkdiv_int_frac(div, mod);
|
||||||
|
}
|
||||||
|
|
||||||
|
power_en->to_output(false);
|
||||||
|
power_good->to_input();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BenchPowerModule::enable() {
|
void BenchPowerModule::enable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
power_en->value(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BenchPowerModule::disable() {
|
void BenchPowerModule::disable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
power_en->value(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BenchPowerModule::is_enabled() {
|
bool BenchPowerModule::is_enabled() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return power_en->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BenchPowerModule::set_pwm(float percent) {
|
void BenchPowerModule::set_pwm(float percent) {
|
||||||
|
voltage_pwm->set_chan_level(0, (uint32_t)(percent * (float)pwm_period));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BenchPowerModule::set_target_voltage(float voltage) {
|
void BenchPowerModule::set_target_voltage(float voltage) {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
float percent;
|
||||||
|
if(voltage >= VOLTAGE_MID) {
|
||||||
|
percent = (voltage - VOLTAGE_MID) * 0.5f / (VOLTAGE_MAX - VOLTAGE_MID) + 0.5f;
|
||||||
|
percent = MIN(percent, 1.0f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
percent = (voltage - VOLTAGE_MIN) * 0.5f / (VOLTAGE_MID - VOLTAGE_MIN);
|
||||||
|
percent = MAX(percent, 0.0);
|
||||||
|
}
|
||||||
|
set_target(percent);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BenchPowerModule::set_target(float percent) {
|
void BenchPowerModule::set_target(float percent) {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
if(percent < 0.0f || percent > 1.0f) {
|
||||||
|
throw std::invalid_argument("percent out of range. Expected 0.0 to 1.0\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
set_pwm((percent * (PWM_MAX - PWM_MIN)) + PWM_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
float BenchPowerModule::read_voltage() {
|
float BenchPowerModule::read_voltage() {
|
||||||
// return (self.__shared_adc_voltage() * (100 + 22)) / 22
|
// return (self.__shared_adc_voltage() * (100 + 22)) / 22
|
||||||
float value = __read_adc1();
|
float value = __read_adc1();
|
||||||
|
float voltage;
|
||||||
if(value >= VOLTAGE_MID_MEASURE) {
|
if(value >= VOLTAGE_MID_MEASURE) {
|
||||||
return ((value - VOLTAGE_MID_MEASURE) * (VOLTAGE_MAX - VOLTAGE_MID)) / (VOLTAGE_MAX_MEASURE - VOLTAGE_MID_MEASURE) + VOLTAGE_MID;
|
voltage = ((value - VOLTAGE_MID_MEASURE) * (VOLTAGE_MAX - VOLTAGE_MID)) / (VOLTAGE_MAX_MEASURE - VOLTAGE_MID_MEASURE) + VOLTAGE_MID;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float voltage = ((value - VOLTAGE_MIN_MEASURE) * (VOLTAGE_MID - VOLTAGE_MIN)) / (VOLTAGE_MID_MEASURE - VOLTAGE_MIN_MEASURE) + VOLTAGE_MIN;
|
voltage = ((value - VOLTAGE_MIN_MEASURE) * (VOLTAGE_MID - VOLTAGE_MIN)) / (VOLTAGE_MID_MEASURE - VOLTAGE_MIN_MEASURE) + VOLTAGE_MIN;
|
||||||
return MAX(voltage, 0.0);
|
voltage = MAX(voltage, 0.0);
|
||||||
}
|
}
|
||||||
|
return voltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BenchPowerModule::read_power_good() {
|
bool BenchPowerModule::read_power_good() {
|
||||||
return 0; // TODO
|
return power_good->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
float BenchPowerModule::read_temperature() {
|
float BenchPowerModule::read_temperature() {
|
||||||
|
|
|
@ -47,12 +47,14 @@ namespace pimoroni {
|
||||||
float min_temperature;
|
float min_temperature;
|
||||||
float avg_temperature;
|
float avg_temperature;
|
||||||
float count_avg;
|
float count_avg;
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
private:
|
private:
|
||||||
PWMCluster* voltage_pwm;
|
PWMCluster* voltage_pwm;
|
||||||
IO* power_en;
|
IO* power_en;
|
||||||
IO* power_good;
|
TCA_IO* power_good;
|
||||||
|
uint32_t pwm_period;
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
|
@ -18,12 +18,16 @@ namespace pimoroni {
|
||||||
YukonModule(),
|
YukonModule(),
|
||||||
frequency(frequency),
|
frequency(frequency),
|
||||||
motor(nullptr),
|
motor(nullptr),
|
||||||
encoder(nullptr) {
|
encoder(nullptr),
|
||||||
|
motor_en(nullptr),
|
||||||
|
motor_nfault(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BigMotorModule::~BigMotorModule() {
|
BigMotorModule::~BigMotorModule() {
|
||||||
delete(motor);
|
delete(motor);
|
||||||
delete(encoder);
|
delete(encoder);
|
||||||
|
delete(motor_en);
|
||||||
|
delete(motor_nfault);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BigMotorModule::name() {
|
std::string BigMotorModule::name() {
|
||||||
|
@ -31,6 +35,13 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigMotorModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
void BigMotorModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
||||||
|
// Create motor object
|
||||||
|
motor = new MotorCluster(pio0, 0, slot.FAST3, NUM_MOTORS);
|
||||||
|
|
||||||
|
// Create motor control pin objects
|
||||||
|
motor_en = new TCA_IO(slot.SLOW3, accessor);
|
||||||
|
motor_nfault = new TCA_IO(slot.SLOW2, accessor);
|
||||||
|
|
||||||
// Configure strip and power pins
|
// Configure strip and power pins
|
||||||
configure();
|
configure();
|
||||||
|
|
||||||
|
@ -39,23 +50,31 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigMotorModule::configure() {
|
void BigMotorModule::configure() {
|
||||||
|
motor->disable_all();
|
||||||
|
motor->decay_mode(0, SLOW_DECAY);
|
||||||
|
|
||||||
|
motor_nfault ->to_input();
|
||||||
|
motor_en->to_output(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigMotorModule::enable() {
|
void BigMotorModule::enable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
motor_en->value(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BigMotorModule::disable() {
|
void BigMotorModule::disable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
motor_en->value(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BigMotorModule::is_enabled() {
|
bool BigMotorModule::is_enabled() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return motor_en->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BigMotorModule::read_fault() {
|
bool BigMotorModule::read_fault() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return !motor_nfault->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BigMotorModule::read_current() {
|
bool BigMotorModule::read_current() {
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace pimoroni {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public:
|
public:
|
||||||
static const std::string NAME;
|
static const std::string NAME;
|
||||||
|
static const uint NUM_MOTORS = 2;
|
||||||
static constexpr float DEFAULT_FREQUENCY = 25000.0f;
|
static constexpr float DEFAULT_FREQUENCY = 25000.0f;
|
||||||
static constexpr float TEMPERATURE_THRESHOLD = 50.0f;
|
static constexpr float TEMPERATURE_THRESHOLD = 50.0f;
|
||||||
static constexpr float CURRENT_THRESHOLD = 25.0f;
|
static constexpr float CURRENT_THRESHOLD = 25.0f;
|
||||||
|
@ -50,8 +51,8 @@ namespace pimoroni {
|
||||||
MotorCluster* motor;
|
MotorCluster* motor;
|
||||||
Encoder* encoder;
|
Encoder* encoder;
|
||||||
private:
|
private:
|
||||||
TCA motor_en;
|
TCA_IO* motor_en;
|
||||||
TCA motor_nfault;
|
TCA_IO* motor_nfault;
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include "common.hpp"
|
||||||
|
|
||||||
|
namespace pimoroni {
|
||||||
|
TCA_IO::TCA_IO(TCA pin, TCAAccessor& accessor) :
|
||||||
|
pin(pin),
|
||||||
|
accessor(accessor) {
|
||||||
|
to_input();
|
||||||
|
};
|
||||||
|
|
||||||
|
TCA_IO::TCA_IO(TCA pin, TCAAccessor& accessor, bool out) :
|
||||||
|
pin(pin),
|
||||||
|
accessor(accessor) {
|
||||||
|
direction(out);
|
||||||
|
};
|
||||||
|
|
||||||
|
//TCA_IO::~TCA_IO() {
|
||||||
|
// to_input();
|
||||||
|
//}
|
||||||
|
|
||||||
|
bool TCA_IO::direction() {
|
||||||
|
return accessor.get_slow_config(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCA_IO::direction(bool out) {
|
||||||
|
accessor.set_slow_config(pin, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCA_IO::to_output(bool val) {
|
||||||
|
value(val);
|
||||||
|
direction(GPIO_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCA_IO::to_input() {
|
||||||
|
direction(GPIO_IN);
|
||||||
|
value(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TCA_IO::value() {
|
||||||
|
if(direction()) {
|
||||||
|
return accessor.get_slow_output(pin);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return accessor.get_slow_input(pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCA_IO::value(bool val) {
|
||||||
|
accessor.set_slow_output(pin, val);
|
||||||
|
}
|
||||||
|
};
|
|
@ -8,6 +8,11 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
namespace pimoroni {
|
namespace pimoroni {
|
||||||
|
|
||||||
|
#define CHECK_INITIALISED \
|
||||||
|
if(!is_initialised()) { \
|
||||||
|
throw std::runtime_error("Module not initialised\n"); \
|
||||||
|
}
|
||||||
|
|
||||||
struct TCA {
|
struct TCA {
|
||||||
uint CHIP;
|
uint CHIP;
|
||||||
uint GPIO;
|
uint GPIO;
|
||||||
|
@ -43,7 +48,7 @@ namespace pimoroni {
|
||||||
HIGH = true
|
HIGH = true
|
||||||
};
|
};
|
||||||
|
|
||||||
class SlotAccessor {
|
class TCAAccessor {
|
||||||
public:
|
public:
|
||||||
virtual bool get_slow_input(TCA gpio) = 0;
|
virtual bool get_slow_input(TCA gpio) = 0;
|
||||||
virtual bool get_slow_output(TCA gpio) = 0;
|
virtual bool get_slow_output(TCA gpio) = 0;
|
||||||
|
@ -53,11 +58,30 @@ namespace pimoroni {
|
||||||
virtual void set_slow_output(TCA gpio, bool value) = 0;
|
virtual void set_slow_output(TCA gpio, bool value) = 0;
|
||||||
virtual void set_slow_config(TCA gpio, bool output) = 0;
|
virtual void set_slow_config(TCA gpio, bool output) = 0;
|
||||||
virtual void set_slow_polarity(TCA gpio, bool polarity) = 0;
|
virtual void set_slow_polarity(TCA gpio, bool polarity) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SlotAccessor : public TCAAccessor {
|
||||||
|
public:
|
||||||
virtual float read_slot_adc1(SLOT slot) = 0;
|
virtual float read_slot_adc1(SLOT slot) = 0;
|
||||||
virtual float read_slot_adc2(SLOT slot) = 0;
|
virtual float read_slot_adc2(SLOT slot) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TCA_IO {
|
||||||
|
public:
|
||||||
|
TCA_IO(TCA pin, TCAAccessor& accessor);
|
||||||
|
TCA_IO(TCA pin, TCAAccessor& accessor, bool out);
|
||||||
|
//~TCA_IO();
|
||||||
|
bool direction();
|
||||||
|
void direction(bool out);
|
||||||
|
void to_output(bool val);
|
||||||
|
void to_input();
|
||||||
|
bool value();
|
||||||
|
void value(bool val);
|
||||||
|
private:
|
||||||
|
TCA pin;
|
||||||
|
TCAAccessor& accessor;
|
||||||
|
};
|
||||||
|
|
||||||
class YukonModule {
|
class YukonModule {
|
||||||
public:
|
public:
|
||||||
static constexpr float ROOM_TEMP = 273.15f + 25.0f;
|
static constexpr float ROOM_TEMP = 273.15f + 25.0f;
|
||||||
|
@ -102,23 +126,17 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
float __read_adc1() {
|
float __read_adc1() {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
return __accessor->read_slot_adc1(slot);
|
return __accessor->read_slot_adc1(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
float __read_adc2() {
|
float __read_adc2() {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
return __accessor->read_slot_adc2(slot);
|
return __accessor->read_slot_adc2(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
float __read_adc2_as_temp() {
|
float __read_adc2_as_temp() {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
float sense = __accessor->read_slot_adc2(slot);
|
float sense = __accessor->read_slot_adc2(slot);
|
||||||
float r_thermistor = sense / ((3.3f - sense) / 5100.0f);
|
float r_thermistor = sense / ((3.3f - sense) / 5100.0f);
|
||||||
float t_kelvin = (BETA * ROOM_TEMP) / (BETA + (ROOM_TEMP * log(r_thermistor / RESISTOR_AT_ROOM_TEMP)));
|
float t_kelvin = (BETA * ROOM_TEMP) / (BETA + (ROOM_TEMP * log(r_thermistor / RESISTOR_AT_ROOM_TEMP)));
|
||||||
|
|
|
@ -18,11 +18,17 @@ namespace pimoroni {
|
||||||
YukonModule(),
|
YukonModule(),
|
||||||
motor_type(DUAL),
|
motor_type(DUAL),
|
||||||
frequency(frequency),
|
frequency(frequency),
|
||||||
motors(nullptr) {
|
motors(nullptr),
|
||||||
|
motors_decay(nullptr),
|
||||||
|
motors_toff(nullptr),
|
||||||
|
motors_en(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DualMotorModule::~DualMotorModule() {
|
DualMotorModule::~DualMotorModule() {
|
||||||
delete(motors);
|
delete(motors);
|
||||||
|
delete(motors_decay);
|
||||||
|
delete(motors_toff);
|
||||||
|
delete(motors_en);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DualMotorModule::name() {
|
std::string DualMotorModule::name() {
|
||||||
|
@ -30,7 +36,15 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualMotorModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
void DualMotorModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
||||||
// Configure strip and power pins
|
// Create motor objects
|
||||||
|
motors = new MotorCluster(pio0, 0, slot.FAST1, NUM_MOTORS);
|
||||||
|
|
||||||
|
// Create motor control pin objects
|
||||||
|
motors_decay = new TCA_IO(slot.SLOW1, accessor);
|
||||||
|
motors_toff = new TCA_IO(slot.SLOW2, accessor);
|
||||||
|
motors_en = new TCA_IO(slot.SLOW3, accessor);
|
||||||
|
|
||||||
|
// Configure motors
|
||||||
configure();
|
configure();
|
||||||
|
|
||||||
// Pass the slot and adc functions up to the parent now that module specific initialisation has finished
|
// Pass the slot and adc functions up to the parent now that module specific initialisation has finished
|
||||||
|
@ -38,35 +52,46 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualMotorModule::configure() {
|
void DualMotorModule::configure() {
|
||||||
|
motors->disable_all();
|
||||||
|
|
||||||
|
motors_decay->to_output(false);
|
||||||
|
motors_toff->to_output(false);
|
||||||
|
motors_en->to_output(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualMotorModule::enable() {
|
void DualMotorModule::enable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
motors_en->value(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualMotorModule::disable() {
|
void DualMotorModule::disable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
motors_en->value(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualMotorModule::is_enabled() {
|
bool DualMotorModule::is_enabled() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return motors_en->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualMotorModule::decay() {
|
bool DualMotorModule::decay() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return motors_decay->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualMotorModule::decay(bool val) {
|
void DualMotorModule::decay(bool val) {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
motors_decay->value(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualMotorModule::toff() {
|
bool DualMotorModule::toff() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return motors_toff->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualMotorModule::toff(bool val) {
|
void DualMotorModule::toff(bool val) {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
return motors_toff->value(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualMotorModule::read_fault() {
|
bool DualMotorModule::read_fault() {
|
||||||
|
|
|
@ -55,9 +55,9 @@ namespace pimoroni {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
private:
|
private:
|
||||||
MotorCluster* motors;
|
MotorCluster* motors;
|
||||||
TCA motors_decay;
|
TCA_IO* motors_decay;
|
||||||
TCA motors_toff;
|
TCA_IO* motors_toff;
|
||||||
TCA motors_en;
|
TCA_IO* motors_en;
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
|
@ -27,6 +27,8 @@ namespace pimoroni {
|
||||||
delete(sw_output[1]);
|
delete(sw_output[1]);
|
||||||
delete(sw_enable[0]);
|
delete(sw_enable[0]);
|
||||||
delete(sw_enable[1]);
|
delete(sw_enable[1]);
|
||||||
|
delete(power_good[0]);
|
||||||
|
delete(power_good[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DualSwitchedModule::name() {
|
std::string DualSwitchedModule::name() {
|
||||||
|
@ -39,8 +41,8 @@ namespace pimoroni {
|
||||||
sw_output[1] = new IO(slot.FAST3);
|
sw_output[1] = new IO(slot.FAST3);
|
||||||
sw_enable[0] = new IO(slot.FAST1);
|
sw_enable[0] = new IO(slot.FAST1);
|
||||||
sw_enable[1] = new IO(slot.FAST3);
|
sw_enable[1] = new IO(slot.FAST3);
|
||||||
power_good[0] = slot.SLOW1;
|
power_good[0] = new TCA_IO(slot.SLOW1, accessor);
|
||||||
power_good[1] = slot.SLOW3;
|
power_good[1] = new TCA_IO(slot.SLOW3, accessor);
|
||||||
|
|
||||||
// Configure switch and power pins
|
// Configure switch and power pins
|
||||||
configure();
|
configure();
|
||||||
|
@ -56,14 +58,12 @@ namespace pimoroni {
|
||||||
sw_enable[0]->to_output(false);
|
sw_enable[0]->to_output(false);
|
||||||
sw_enable[1]->to_output(false);
|
sw_enable[1]->to_output(false);
|
||||||
|
|
||||||
__accessor->set_slow_config(power_good[0], false);
|
power_good[0]->to_input();
|
||||||
__accessor->set_slow_config(power_good[1], false);
|
power_good[1]->to_input();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualSwitchedModule::enable(uint output) {
|
void DualSwitchedModule::enable(uint output) {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
if(output < 1 || output > NUM_SWITCHES) {
|
if(output < 1 || output > NUM_SWITCHES) {
|
||||||
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
||||||
}
|
}
|
||||||
|
@ -72,9 +72,7 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualSwitchedModule::disable(uint output) {
|
void DualSwitchedModule::disable(uint output) {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
if(output < 1 || output > NUM_SWITCHES) {
|
if(output < 1 || output > NUM_SWITCHES) {
|
||||||
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
||||||
}
|
}
|
||||||
|
@ -83,9 +81,7 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualSwitchedModule::is_enabled(uint output) {
|
bool DualSwitchedModule::is_enabled(uint output) {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
if(output < 1 || output > NUM_SWITCHES) {
|
if(output < 1 || output > NUM_SWITCHES) {
|
||||||
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
||||||
}
|
}
|
||||||
|
@ -94,9 +90,7 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DualSwitchedModule::output(uint output, bool val) {
|
void DualSwitchedModule::output(uint output, bool val) {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
if(output < 1 || output > NUM_SWITCHES) {
|
if(output < 1 || output > NUM_SWITCHES) {
|
||||||
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
||||||
}
|
}
|
||||||
|
@ -105,9 +99,7 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualSwitchedModule:: read_output(uint output) {
|
bool DualSwitchedModule:: read_output(uint output) {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
if(output < 1 || output > NUM_SWITCHES) {
|
if(output < 1 || output > NUM_SWITCHES) {
|
||||||
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
||||||
}
|
}
|
||||||
|
@ -116,14 +108,12 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DualSwitchedModule::read_power_good(uint output) {
|
bool DualSwitchedModule::read_power_good(uint output) {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
if(output < 1 || output > NUM_SWITCHES) {
|
if(output < 1 || output > NUM_SWITCHES) {
|
||||||
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
throw std::runtime_error("switch index out of range. Expected 1 to 2\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
return __accessor->get_slow_input(power_good[output - 1]);
|
return power_good[output - 1]->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
float DualSwitchedModule::read_temperature() {
|
float DualSwitchedModule::read_temperature() {
|
||||||
|
|
|
@ -43,7 +43,7 @@ namespace pimoroni {
|
||||||
private:
|
private:
|
||||||
IO* sw_output[2];
|
IO* sw_output[2];
|
||||||
IO* sw_enable[2];
|
IO* sw_enable[2];
|
||||||
TCA power_good[2];
|
TCA_IO* power_good[2];
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
|
@ -86,30 +86,22 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LEDStripModule::enable() {
|
void LEDStripModule::enable() {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
power_en->value(true);
|
power_en->value(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LEDStripModule::disable() {
|
void LEDStripModule::disable() {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
power_en->value(false);
|
power_en->value(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LEDStripModule::is_enabled() {
|
bool LEDStripModule::is_enabled() {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
return power_en->value();
|
return power_en->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LEDStripModule::read_power_good() {
|
bool LEDStripModule::read_power_good() {
|
||||||
if(!is_initialised()) {
|
CHECK_INITIALISED
|
||||||
throw std::runtime_error("Module not initialised\n");
|
|
||||||
}
|
|
||||||
return power_good->value();
|
return power_good->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,9 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadServoDirectModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
void QuadServoDirectModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
||||||
|
// Create servo cluster object
|
||||||
|
servos = new ServoCluster(pio0, 0, slot.FAST1, NUM_SERVOS);
|
||||||
|
|
||||||
// Configure strip and power pins
|
// Configure strip and power pins
|
||||||
configure();
|
configure();
|
||||||
|
|
||||||
|
@ -35,7 +38,7 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadServoDirectModule::configure() {
|
void QuadServoDirectModule::configure() {
|
||||||
|
servos->disable_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
float QuadServoDirectModule::read_adc1() {
|
float QuadServoDirectModule::read_adc1() {
|
||||||
|
|
|
@ -16,11 +16,15 @@ namespace pimoroni {
|
||||||
QuadServoRegModule::QuadServoRegModule(bool halt_on_not_pgood) :
|
QuadServoRegModule::QuadServoRegModule(bool halt_on_not_pgood) :
|
||||||
YukonModule(),
|
YukonModule(),
|
||||||
halt_on_not_pgood(halt_on_not_pgood),
|
halt_on_not_pgood(halt_on_not_pgood),
|
||||||
servos(nullptr) {
|
servos(nullptr),
|
||||||
|
power_en(nullptr),
|
||||||
|
power_good(nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
QuadServoRegModule::~QuadServoRegModule() {
|
QuadServoRegModule::~QuadServoRegModule() {
|
||||||
delete(servos);
|
delete(servos);
|
||||||
|
delete(power_en);
|
||||||
|
delete(power_good);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string QuadServoRegModule::name() {
|
std::string QuadServoRegModule::name() {
|
||||||
|
@ -28,6 +32,13 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadServoRegModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
void QuadServoRegModule::initialise(const SLOT& slot, SlotAccessor& accessor) {
|
||||||
|
// Create servo cluster object
|
||||||
|
servos = new ServoCluster(pio0, 0, slot.FAST1, NUM_SERVOS);
|
||||||
|
|
||||||
|
// Create the power control pin objects
|
||||||
|
power_en = new TCA_IO(slot.SLOW1, accessor);
|
||||||
|
power_good = new TCA_IO(slot.SLOW2, accessor);
|
||||||
|
|
||||||
// Configure strip and power pins
|
// Configure strip and power pins
|
||||||
configure();
|
configure();
|
||||||
|
|
||||||
|
@ -36,23 +47,30 @@ namespace pimoroni {
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadServoRegModule::configure() {
|
void QuadServoRegModule::configure() {
|
||||||
|
servos->disable_all();
|
||||||
|
|
||||||
|
power_en->to_output(false);
|
||||||
|
power_good->to_input();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadServoRegModule::enable() {
|
void QuadServoRegModule::enable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
power_en->value(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuadServoRegModule::disable() {
|
void QuadServoRegModule::disable() {
|
||||||
|
CHECK_INITIALISED
|
||||||
|
power_en->value(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QuadServoRegModule::is_enabled() {
|
bool QuadServoRegModule::is_enabled() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return power_en->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QuadServoRegModule::read_power_good() {
|
bool QuadServoRegModule::read_power_good() {
|
||||||
return 0; // TODO
|
CHECK_INITIALISED
|
||||||
|
return power_good->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
float QuadServoRegModule::read_temperature() {
|
float QuadServoRegModule::read_temperature() {
|
||||||
|
|
|
@ -44,8 +44,8 @@ public:
|
||||||
public:
|
public:
|
||||||
ServoCluster* servos;
|
ServoCluster* servos;
|
||||||
private:
|
private:
|
||||||
IO* power_en;
|
TCA_IO* power_en;
|
||||||
IO* power_good;
|
TCA_IO* power_good;
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
|
@ -2,6 +2,7 @@ add_library(yukon INTERFACE)
|
||||||
|
|
||||||
target_sources(yukon INTERFACE
|
target_sources(yukon INTERFACE
|
||||||
${CMAKE_CURRENT_LIST_DIR}/yukon.cpp
|
${CMAKE_CURRENT_LIST_DIR}/yukon.cpp
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/modules/common.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/logging.cpp
|
${CMAKE_CURRENT_LIST_DIR}/logging.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/modules/led_strip/led_strip.cpp
|
${CMAKE_CURRENT_LIST_DIR}/modules/led_strip/led_strip.cpp
|
||||||
${CMAKE_CURRENT_LIST_DIR}/modules/quad_servo/quad_servo_direct.cpp
|
${CMAKE_CURRENT_LIST_DIR}/modules/quad_servo/quad_servo_direct.cpp
|
||||||
|
|
Ładowanie…
Reference in New Issue