Skip to content

Commit

Permalink
Add VESC example program
Browse files Browse the repository at this point in the history
Define example program `//examples:vesc_cmd` that sends a 1.0F current
reference to a motor controller connected to `/dev/ttyS0`. This program
is implicitly constrained to the Raspberry Pi via the dependencies of
`//third_party/vesc_uart`.

Change-Id: I8cbf7d674e1f47d2e0ebce7f795a1b5d353f918e
  • Loading branch information
oliverlee committed Jul 26, 2023
1 parent 28c2e70 commit bf1d8df
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 5 deletions.
7 changes: 7 additions & 0 deletions examples/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
load("@rules_cc//cc:defs.bzl", "cc_binary")

cc_binary(
name = "vesc_cmd",
srcs = ["vesc_cmd.cpp"],
deps = ["//third_party/vesc_uart"],
)
8 changes: 8 additions & 0 deletions examples/vesc_cmd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "third_party/vesc_uart/VescUart.h"

auto main() -> int
{
::VescUartSetCurrent(1.0f);

return 0;
}
7 changes: 4 additions & 3 deletions third_party/vesc_uart/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ cc_library(
"src/includes",
],
visibility = ["//:__subpackages__"],
deps = [
"//uart_abstraction:fake",
],
deps = select({
"//toolchain:linux_aarch64": ["//uart_abstraction:rpi"],
"//conditions:default": ["//uart_abstraction:fake"],
}),
)
2 changes: 1 addition & 1 deletion third_party/vesc_uart/src/compatability/WProgram.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ using boolean = bool;
#include <cassert>
#include <chrono>
#include <thread>
auto delay(int milliseconds) -> void
inline auto delay(int milliseconds) -> void
{
assert((milliseconds >= 0) && "A negative sleep duration requested");

Expand Down
10 changes: 10 additions & 0 deletions uart_abstraction/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ cc_library(
hdrs = ["HardwareSerial.hpp"],
visibility = ["//:__subpackages__"],
)

cc_library(
name = "rpi",
srcs = [
"rpi/HardwareSerial.cpp",
],
hdrs = ["HardwareSerial.hpp"],
visibility = ["//:__subpackages__"],
deps = ["@asio"],
)
2 changes: 2 additions & 0 deletions uart_abstraction/HardwareSerial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

struct HardwareSerial
{
HardwareSerial(const char* dev);

[[nodiscard]]
auto available() const -> bool;

Expand Down
4 changes: 3 additions & 1 deletion uart_abstraction/fake/HardwareSerial.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "uart_abstraction/HardwareSerial.hpp"

HardwareSerial::HardwareSerial(const char*) {}

// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
auto HardwareSerial::available() const -> bool
{
Expand All @@ -18,4 +20,4 @@ auto HardwareSerial::write(
{}

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
HardwareSerial Serial;
HardwareSerial Serial{""};
64 changes: 64 additions & 0 deletions uart_abstraction/rpi/HardwareSerial.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "uart_abstraction/HardwareSerial.hpp"

#include <asio.hpp>
#include <cassert>
#include <optional>
#include <stdexcept>
#include <sys/select.h>

namespace {
auto ctx = asio::io_context{};
auto underlying = std::optional<asio::serial_port>{};
} // namespace

// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
HardwareSerial Serial{"/dev/ttyS0"};

HardwareSerial::HardwareSerial(const char* device)
{
underlying.emplace(ctx, device);

using opt = asio::serial_port_base;

underlying->set_option(opt::baud_rate{115200});
underlying->set_option(opt::character_size{8});
underlying->set_option(opt::parity{opt::parity::none});
underlying->set_option(opt::stop_bits{opt::stop_bits::one});

assert(underlying->is_open() and "underlying device not open");
}

auto HardwareSerial::available() const -> bool
{
auto native = underlying->native_handle();

::fd_set rfds;
auto tv = ::timeval{{}, {}};

FD_ZERO(&rfds);
FD_SET(native, &rfds);

const auto retval = ::select(1, &rfds, NULL, NULL, &tv);
assert(retval >= 0 and "error in checking serial availability");

return retval > 0;
}

auto HardwareSerial::read() const -> std::uint8_t
{
char c;

for (auto n = std::size_t{}; n != 1;) {
n = underlying->read_some(asio::buffer(&c, 1));
assert(n <= 1 and "read more than 1 byte");
}

return static_cast<std::uint8_t>(c);
}

auto HardwareSerial::write(std::uint8_t* buffer, std::size_t size) const -> void
{
for (auto buf = asio::buffer(buffer, size); buf.size() != 0;) {
buf += underlying->write_some(buf);
}
}

0 comments on commit bf1d8df

Please sign in to comment.