Skip to content

Commit 32d791e

Browse files
authored
fix(pi4ioe5v): Fix component implementation to be correct (#533)
* fix(pi4ioe5v): Fix component implementation to be correct * fix inconsistency and remove unused reg def. * fix inconsistencies
1 parent f1d6c37 commit 32d791e

File tree

2 files changed

+459
-143
lines changed

2 files changed

+459
-143
lines changed

components/pi4ioe5v/example/main/pi4ioe5v_example.cpp

Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,65 +2,99 @@
22
#include <sdkconfig.h>
33

44
#include "i2c.hpp"
5+
#include "logger.hpp"
56
#include "pi4ioe5v.hpp"
67
#include "task.hpp"
78

89
using namespace std::chrono_literals;
910

1011
extern "C" void app_main(void) {
11-
fmt::print("Starting PI4IOE5V example...\n");
12+
13+
espp::Logger logger({.tag = "PI4IOE5V example", .level = espp::Logger::Verbosity::INFO});
14+
15+
logger.info("Starting PI4IOE5V example...");
1216

1317
//! [pi4ioe5v_example]
18+
// make the I2C that we'll use to communicate
1419
espp::I2c i2c({
1520
.port = I2C_NUM_1,
1621
.sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO,
1722
.scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO,
23+
.sda_pullup_en = GPIO_PULLUP_ENABLE,
24+
.scl_pullup_en = GPIO_PULLUP_ENABLE,
1825
});
1926

20-
// Configure PI4IOE5V: single 8-bit port as outputs
27+
// Configure PI4IOE5V: 8-bit port with mixed inputs/outputs
2128
espp::Pi4ioe5v exp({
2229
.device_address = espp::Pi4ioe5v::DEFAULT_ADDRESS,
23-
.direction_mask = 0x00, // all outputs
24-
.output_state = 0xFF, // initial state
25-
.probe = std::bind(&espp::I2c::probe_device, &i2c, std::placeholders::_1),
26-
.write = std::bind(&espp::I2c::write, &i2c, std::placeholders::_1, std::placeholders::_2,
27-
std::placeholders::_3),
28-
.read_register =
29-
std::bind(&espp::I2c::read_at_register, &i2c, std::placeholders::_1,
30-
std::placeholders::_2, std::placeholders::_3, std::placeholders::_4),
31-
.write_then_read =
32-
std::bind(&espp::I2c::write_read, &i2c, std::placeholders::_1, std::placeholders::_2,
33-
std::placeholders::_3, std::placeholders::_4, std::placeholders::_5),
34-
.log_level = espp::Logger::Verbosity::WARN,
30+
.direction_mask = 0xF0, // upper 4 bits as outputs, lower 4 bits as inputs
31+
.interrupt_mask = 0xFF, // all interrupts disabled for now
32+
.initial_output = 0xA0, // initial pattern for outputs
33+
.write = std::bind_front(&espp::I2c::write, &i2c),
34+
.write_then_read = std::bind_front(&espp::I2c::write_read, &i2c),
35+
.auto_init = false,
36+
.log_level = espp::Logger::Verbosity::INFO,
3537
});
3638

3739
std::error_code ec;
38-
exp.initialize(ec);
39-
if (ec) {
40-
fmt::print("PI4IOE5V init failed: {}\n", ec.message());
40+
// Initialize separately from the constructor since we set auto_init to false
41+
if (!exp.initialize(ec)) {
42+
logger.error("PI4IOE5V initialization failed: {}", ec.message());
4143
return;
4244
}
4345

46+
// Configure pull resistors for input pins (lower 4 bits)
47+
exp.set_pull_resistor_for_pin(0xF0, espp::Pi4ioe5v::PullResistor::PULL_UP, ec);
48+
if (ec) {
49+
logger.error("Failed to configure pull resistors: {}", ec.message());
50+
}
51+
52+
// Create task to periodically toggle outputs and read inputs
4453
auto task_fn = [&](std::mutex &m, std::condition_variable &cv) {
45-
static uint8_t value = 0xAA;
46-
value ^= 0xFF; // toggle pattern
47-
exp.write_outputs(value, ec);
48-
if (!ec) {
49-
uint8_t inputs = exp.read_inputs(ec);
50-
if (!ec) {
51-
fmt::print("OUT=0x{:02X} IN=0x{:02X}\n", value, inputs);
52-
}
54+
static auto start = std::chrono::high_resolution_clock::now();
55+
static uint8_t output_pattern = 0x50;
56+
57+
auto now = std::chrono::high_resolution_clock::now();
58+
auto seconds = std::chrono::duration<float>(now - start).count();
59+
60+
// Toggle output pattern on upper 4 bits
61+
output_pattern ^= 0xF0;
62+
exp.output(output_pattern, ec);
63+
if (ec) {
64+
logger.error("Failed to set outputs: {}", ec.message());
65+
return true; // stop the task
66+
}
67+
68+
// Read all pins
69+
auto pins = exp.get_pins(ec);
70+
if (ec) {
71+
logger.error("Failed to read pins: {}", ec.message());
72+
return true; // stop the task
5373
}
74+
75+
// Read current output state
76+
auto outputs = exp.get_output(ec);
77+
if (ec) {
78+
logger.error("Failed to read outputs: {}", ec.message());
79+
return true; // stop the task
80+
}
81+
82+
fmt::print("{:.3f}, inputs: {:#04x}, outputs: {:#04x}\n", seconds, pins, outputs);
83+
84+
// NOTE: sleeping in this way allows the sleep to exit early when the
85+
// task is being stopped / destroyed
5486
{
5587
std::unique_lock<std::mutex> lk(m);
5688
cv.wait_for(lk, 500ms);
5789
}
90+
// don't want to stop the task
5891
return false;
5992
};
6093

61-
espp::Task task({.callback = task_fn,
62-
.task_config = {.name = "PI4IOE5V Task", .stack_size_bytes = 4 * 1024},
63-
.log_level = espp::Logger::Verbosity::WARN});
94+
auto task = espp::Task({.callback = task_fn,
95+
.task_config = {.name = "PI4IOE5V Task", .stack_size_bytes = 4 * 1024},
96+
.log_level = espp::Logger::Verbosity::WARN});
97+
fmt::print("% time(s), inputs (lower 4 bits), outputs (upper 4 bits)\n");
6498
task.start();
6599
//! [pi4ioe5v_example]
66100

0 commit comments

Comments
 (0)