Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 23 additions & 7 deletions src/utility/IOExpander_Base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,34 @@ namespace m5
, pull_down = 2
};

/// Mutating methods report their result: the written value is not read
/// back, and read-modify-write accesses are not atomic against
/// concurrent access to the same register.

IOExpander_Base(std::uint8_t i2c_addr, std::uint32_t freq = 400000, m5::I2C_Class* i2c = &m5::In_I2C)
: I2C_Device(i2c_addr, freq, i2c)
{}
IOExpander_Base(const IOExpander_Base&) = delete;

// false input, true output
virtual void setDirection(uint8_t pin, bool direction) = 0;
/// @return true when every required register access was acknowledged;
/// false for an invalid pin or I2C failure.
virtual bool setDirection(uint8_t pin, bool direction) = 0;

/// Set the GPIO pull resistor state.
/// @return true only when the requested state was completely established;
/// @return true when every required register access was acknowledged;
/// false for an invalid pin, mode, or I2C failure.
virtual bool setPullMode(uint8_t pin, gpio_pull_t mode) = 0;

virtual void setHighImpedance(uint8_t pin, bool enable) = 0;
/// @return true when every required register access was acknowledged;
/// false for an invalid pin or I2C failure.
virtual bool setHighImpedance(uint8_t pin, bool enable) = 0;

virtual bool getWriteValue(uint8_t pin) = 0;

virtual void digitalWrite(uint8_t pin, bool level) = 0;
/// @return true when every required register access was acknowledged;
/// false for an invalid pin or I2C failure.
virtual bool digitalWrite(uint8_t pin, bool level) = 0;

virtual bool digitalRead(uint8_t pin) = 0;

Expand All @@ -48,11 +58,17 @@ namespace m5
return false;
}

virtual void resetIrq() = 0;
/// @return true when every required register access was acknowledged;
/// false on I2C failure.
virtual bool resetIrq() = 0;

virtual void disableIrq() = 0;
/// @return true when every required register access was acknowledged;
/// false on I2C failure.
virtual bool disableIrq() = 0;

virtual void enableIrq() = 0;
/// @return true when every required register access was acknowledged;
/// false on I2C failure.
virtual bool enableIrq() = 0;
};
}

Expand Down
30 changes: 15 additions & 15 deletions src/utility/M5IOE1_Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ namespace m5
return _init;
}

void M5IOE1_Class::setDirection(uint8_t pin, bool direction)
bool M5IOE1_Class::setDirection(uint8_t pin, bool direction)
{
if (!_isValidPin(pin)) { return; }
if (!_isValidPin(pin)) { return false; }
// false=input, true=output. MODE bit set means output.
const auto reg = _regForPin(M5IOE1_REG_GPIO_MODE_L, pin);
const auto bit = _bitForPin(pin);
direction ? bitOn(reg, bit) : bitOff(reg, bit);
return direction ? bitOn(reg, bit) : bitOff(reg, bit);
}

bool M5IOE1_Class::setPullMode(uint8_t pin, gpio_pull_t mode)
Expand All @@ -71,13 +71,13 @@ namespace m5
}
}

void M5IOE1_Class::setHighImpedance(uint8_t pin, bool enable)
bool M5IOE1_Class::setHighImpedance(uint8_t pin, bool enable)
{
if (!_isValidPin(pin)) { return; }
if (!_isValidPin(pin)) { return false; }
// M5IOE1 exposes drive mode here: 0=push-pull, 1=open-drain.
const auto reg = _regForPin(M5IOE1_REG_GPIO_DRV_L, pin);
const auto bit = _bitForPin(pin);
enable ? bitOn(reg, bit) : bitOff(reg, bit);
return enable ? bitOn(reg, bit) : bitOff(reg, bit);
}

bool M5IOE1_Class::getWriteValue(uint8_t pin)
Expand All @@ -86,12 +86,12 @@ namespace m5
return (readRegister8(_regForPin(M5IOE1_REG_GPIO_OUT_L, pin)) & _bitForPin(pin)) != 0;
}

void M5IOE1_Class::digitalWrite(uint8_t pin, bool level)
bool M5IOE1_Class::digitalWrite(uint8_t pin, bool level)
{
if (!_isValidPin(pin)) { return; }
if (!_isValidPin(pin)) { return false; }
const auto reg = _regForPin(M5IOE1_REG_GPIO_OUT_L, pin);
const auto bit = _bitForPin(pin);
level ? bitOn(reg, bit) : bitOff(reg, bit);
return level ? bitOn(reg, bit) : bitOff(reg, bit);
}

bool M5IOE1_Class::digitalRead(uint8_t pin)
Expand Down Expand Up @@ -135,21 +135,21 @@ namespace m5
return writeRegister(reg, data, sizeof(data));
}

void M5IOE1_Class::resetIrq()
bool M5IOE1_Class::resetIrq()
{
std::uint8_t data[2] = { 0x00, 0x00 };
writeRegister(M5IOE1_REG_GPIO_IS_L, data, sizeof(data));
return writeRegister(M5IOE1_REG_GPIO_IS_L, data, sizeof(data));
}

void M5IOE1_Class::disableIrq()
bool M5IOE1_Class::disableIrq()
{
std::uint8_t data[2] = { 0x00, 0x00 };
writeRegister(M5IOE1_REG_GPIO_IE_L, data, sizeof(data));
return writeRegister(M5IOE1_REG_GPIO_IE_L, data, sizeof(data));
}

void M5IOE1_Class::enableIrq()
bool M5IOE1_Class::enableIrq()
{
std::uint8_t data[2] = { 0xFF, 0x3F };
writeRegister(M5IOE1_REG_GPIO_IE_L, data, sizeof(data));
return writeRegister(M5IOE1_REG_GPIO_IE_L, data, sizeof(data));
}
}
14 changes: 8 additions & 6 deletions src/utility/M5IOE1_Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,17 @@ namespace m5

bool begin();

void setDirection(uint8_t pin, bool direction) override;
bool setDirection(uint8_t pin, bool direction) override;

bool setPullMode(uint8_t pin, gpio_pull_t mode) override;

void setHighImpedance(uint8_t pin, bool enable) override;
/// On the M5IOE1 this selects the drive mode (open-drain), which keeps
/// sinking the pin while the output latch is low; it is not a disconnect.
bool setHighImpedance(uint8_t pin, bool enable) override;

bool getWriteValue(uint8_t pin) override;

void digitalWrite(uint8_t pin, bool level) override;
bool digitalWrite(uint8_t pin, bool level) override;

bool digitalRead(uint8_t pin) override;
bool getInputLevel(uint8_t pin, bool* level) override;
Expand All @@ -79,11 +81,11 @@ namespace m5
bool setPwmDuty12bit(pwm_channel_t channel, std::uint32_t duty12,
pwm_polarity_t polarity = pwm_polarity_t::normal, bool enable = true);

void resetIrq() override;
bool resetIrq() override;

void disableIrq() override;
bool disableIrq() override;

void enableIrq() override;
bool enableIrq() override;

private:
static bool _isValidPin(uint8_t pin) { return pin < 14; }
Expand Down
34 changes: 19 additions & 15 deletions src/utility/PI4IOE5V6408_Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ bool PI4IOE5V6408_Class::begin()
}

// false input, true output
void PI4IOE5V6408_Class::setDirection(uint8_t pin, bool direction)
bool PI4IOE5V6408_Class::setDirection(uint8_t pin, bool direction)
{
if (pin >= 8) { return false; }
if (direction) {
bitOn(0x03, 1 << pin); // Output, set 1
return bitOn(0x03, 1 << pin); // Output, set 1
} else {
bitOff(0x03, 1 << pin); // Input, set 0
return bitOff(0x03, 1 << pin); // Input, set 0
}
}

Expand All @@ -47,12 +48,13 @@ bool PI4IOE5V6408_Class::setPullMode(uint8_t pin, gpio_pull_t mode)
}
}

void PI4IOE5V6408_Class::setHighImpedance(uint8_t pin, bool enable)
bool PI4IOE5V6408_Class::setHighImpedance(uint8_t pin, bool enable)
{
if (pin >= 8) { return false; }
if (enable) {
bitOn(0x07, 1 << pin);
return bitOn(0x07, 1 << pin);
} else {
bitOff(0x07, 1 << pin);
return bitOff(0x07, 1 << pin);
}
}

Expand All @@ -62,12 +64,13 @@ bool PI4IOE5V6408_Class::getWriteValue(uint8_t pin)
return (data & (1 << pin)) != 0;
}

void PI4IOE5V6408_Class::digitalWrite(uint8_t pin, bool level)
bool PI4IOE5V6408_Class::digitalWrite(uint8_t pin, bool level)
{
if (pin >= 8) { return false; }
if (level) {
bitOn(0x05, 1 << pin);
return bitOn(0x05, 1 << pin);
} else {
bitOff(0x05, 1 << pin);
return bitOff(0x05, 1 << pin);
}
}

Expand All @@ -77,18 +80,19 @@ bool PI4IOE5V6408_Class::digitalRead(uint8_t pin)
return (data & (1 << pin)) != 0;
}

void PI4IOE5V6408_Class::resetIrq()
bool PI4IOE5V6408_Class::resetIrq()
{
readRegister8(0x13);
uint8_t value;
return readRegister(0x13, &value, 1);
}

void PI4IOE5V6408_Class::disableIrq()
bool PI4IOE5V6408_Class::disableIrq()
{
writeRegister8(0x11, 0B11111111);
return writeRegister8(0x11, 0B11111111);
}

void PI4IOE5V6408_Class::enableIrq()
bool PI4IOE5V6408_Class::enableIrq()
{
writeRegister8(0x11, 0x0);
return writeRegister8(0x11, 0x0);
}
}
12 changes: 6 additions & 6 deletions src/utility/PI4IOE5V6408_Class.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,23 @@ namespace m5
bool begin();

// false input, true output
void setDirection(uint8_t pin, bool direction) override;
bool setDirection(uint8_t pin, bool direction) override;

bool setPullMode(uint8_t pin, gpio_pull_t mode) override;

void setHighImpedance(uint8_t pin, bool enable) override;
bool setHighImpedance(uint8_t pin, bool enable) override;

bool getWriteValue(uint8_t pin) override;

void digitalWrite(uint8_t pin, bool level) override;
bool digitalWrite(uint8_t pin, bool level) override;

bool digitalRead(uint8_t pin) override;

void resetIrq() override;
bool resetIrq() override;

void disableIrq() override;
bool disableIrq() override;

void enableIrq() override;
bool enableIrq() override;
};
}

Expand Down
Loading