|
12 | 12 |
|
13 | 13 | #include "ftdi/ftdi.hh" |
14 | 14 | #include "ftdi/spi_host.hh" |
| 15 | +#include "ftdi/gpio.hh" |
15 | 16 | #include "flash/flash.hh" |
16 | 17 | #include "commands.hh" |
17 | 18 | #include "ftdi/log.hh" |
@@ -41,17 +42,22 @@ static std::vector<ftdi::DeviceInfo> scan() { |
41 | 42 | } |
42 | 43 |
|
43 | 44 | static std::unique_ptr<argparse::ArgumentParser> |
44 | | -new_flash_command(const std::string& name, const std::string& desc) { |
| 45 | +new_command(const std::string& name, const std::string& desc) { |
45 | 46 | auto cmd = std::make_unique<argparse::ArgumentParser>(name); |
46 | 47 | cmd->add_description(desc); |
47 | | - cmd->add_argument("--interface", "-i").help("One of [spi, i2c, gpio]"); |
48 | 48 | cmd->add_argument("--traces", "-t") |
49 | 49 | .help("Enable ftdi traces") |
50 | 50 | .default_value(false) |
51 | 51 | .implicit_value(true); |
52 | 52 | cmd->add_argument("--ftdi") |
53 | 53 | .default_value(std::string("FT4222")) |
54 | 54 | .help("Filter ftdi chips connected to USB"); |
| 55 | + return cmd; |
| 56 | +} |
| 57 | + |
| 58 | +static std::unique_ptr<argparse::ArgumentParser> |
| 59 | +new_flash_command(const std::string& name, const std::string& desc) { |
| 60 | + auto cmd = new_command(name, desc); |
55 | 61 | cmd->add_argument("--clock") |
56 | 62 | .default_value(std::size_t{15000000}) |
57 | 63 | .help("The spi clock speed in Hz.") |
@@ -79,6 +85,22 @@ handle_flash_command(std::unique_ptr<argparse::ArgumentParser>& cmd) { |
79 | 85 | exit(0); |
80 | 86 | } |
81 | 87 |
|
| 88 | +static std::optional<ftdi::Gpio> |
| 89 | +handle_gpio_command(std::unique_ptr<argparse::ArgumentParser>& cmd) { |
| 90 | + auto ftdi_filter = cmd->get<std::string>("--ftdi"); |
| 91 | + auto devices = scan(); |
| 92 | + auto filtered = ftdi::DeviceInfo::filter_by_description(devices, ftdi_filter); |
| 93 | + if (filtered.empty()) { |
| 94 | + std::print("No {} ftdi found.\n", ftdi_filter); |
| 95 | + exit(0); |
| 96 | + } |
| 97 | + if (auto opt = ftdi::Gpio::from_device_info(filtered[0])) { |
| 98 | + return opt; |
| 99 | + } |
| 100 | + std::println("Can't open GPIO."); |
| 101 | + exit(0); |
| 102 | +} |
| 103 | + |
82 | 104 | int main(int argc, char* argv[]) { |
83 | 105 | std::map<std::string, Action> commands; |
84 | 106 |
|
@@ -204,6 +226,19 @@ int main(int argc, char* argv[]) { |
204 | 226 | return 0; |
205 | 227 | }; |
206 | 228 |
|
| 229 | + auto gpio_write_cmd = new_command("gpio-write", "Write a value to an FTDI GPIO pin."); |
| 230 | + gpio_write_cmd->add_argument("pin").help("GPIO pin number (0-3)").required().scan<'d', int>(); |
| 231 | + gpio_write_cmd->add_argument("value").help("Value to write (0 or 1)").required().scan<'d', int>(); |
| 232 | + program.add_subparser(*gpio_write_cmd); |
| 233 | + commands["gpio-write"] = [&]() -> int { |
| 234 | + auto pin = static_cast<uint8_t>(gpio_write_cmd->get<int>("pin")); |
| 235 | + auto value = gpio_write_cmd->get<int>("value") != 0; |
| 236 | + auto gpio = handle_gpio_command(gpio_write_cmd); |
| 237 | + commands::GpioWrite(*gpio, pin, value).run(); |
| 238 | + gpio->close(); |
| 239 | + return 0; |
| 240 | + }; |
| 241 | + |
207 | 242 | if (argc == 1) { |
208 | 243 | std::cout << program; // This prints the auto-generated help |
209 | 244 | return 0; |
|
0 commit comments