Implement I2C communication with STM
This commit is contained in:
25
src/App.cpp
25
src/App.cpp
@ -1,5 +1,6 @@
|
||||
#include "App.h"
|
||||
|
||||
#include "AppState.h"
|
||||
#include "MissionSelect.h"
|
||||
#include "events.h"
|
||||
|
||||
@ -13,10 +14,14 @@
|
||||
#include <fmt/format.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <stdexcept>
|
||||
|
||||
App::App() : view{AppView::MISSION_SELECT} { init_sdl(); }
|
||||
App::App() {
|
||||
init_sdl();
|
||||
init_state();
|
||||
}
|
||||
|
||||
App::~App() {
|
||||
// Destroy window
|
||||
@ -43,6 +48,14 @@ void App::init_sdl() {
|
||||
}
|
||||
}
|
||||
|
||||
void App::init_state() {
|
||||
try {
|
||||
state = std::make_unique<AppState>("/dev/i2c-3");
|
||||
} catch (const std::runtime_error& e) {
|
||||
spdlog::error("Couldn't create AppState: {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
int App::run() {
|
||||
mission_select = std::make_unique<MissionSelect>(renderer);
|
||||
|
||||
@ -58,6 +71,10 @@ int App::run() {
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
if (state != nullptr) {
|
||||
state->poll();
|
||||
}
|
||||
|
||||
handle_events();
|
||||
render();
|
||||
|
||||
@ -93,22 +110,24 @@ void App::handle_events() {
|
||||
}
|
||||
}
|
||||
|
||||
AppView view = state->get_view();
|
||||
switch (view) {
|
||||
case AppView::MISSION_SELECT:
|
||||
mission_select->handle_events(events);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(fmt::format("Unknown view: {}", (int)view));
|
||||
throw std::runtime_error(fmt::format("Unknown view: {}", view));
|
||||
}
|
||||
}
|
||||
|
||||
void App::render() {
|
||||
AppView view = state->get_view();
|
||||
switch (view) {
|
||||
case AppView::MISSION_SELECT:
|
||||
mission_select->draw();
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(fmt::format("Unknown view: {}", (int)view));
|
||||
throw std::runtime_error(fmt::format("Unknown view: {}", view));
|
||||
}
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
69
src/AppState.cpp
Normal file
69
src/AppState.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
#include "AppState.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <optional>
|
||||
extern "C" {
|
||||
#include <i2c/smbus.h>
|
||||
}
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
#include <unistd.h>
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, AppView view) {
|
||||
switch (view) {
|
||||
case AppView::MISSION_SELECT:
|
||||
return os << "MISSION_SELECT";
|
||||
case AppView::AMI:
|
||||
return os << "AMI";
|
||||
case AppView::DRIVER:
|
||||
return os << "DRIVER";
|
||||
case AppView::TESTING:
|
||||
return os << "TESTING";
|
||||
default:
|
||||
return os << "UNKNOWN_VIEW[" << static_cast<int>(view) << "]";
|
||||
}
|
||||
}
|
||||
|
||||
AppState::AppState(const std::string& i2c_dev_path)
|
||||
: view{AppView::MISSION_SELECT} {
|
||||
i2c_dev_file = open(i2c_dev_path.c_str(), O_RDWR);
|
||||
if (i2c_dev_file < 0) {
|
||||
spdlog::error("Couldn't open I2C device: {}", errno);
|
||||
i2c_dev_file = std::nullopt;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ioctl(*i2c_dev_file, I2C_SLAVE, I2C_SLAVE_ADDR) < 0) {
|
||||
spdlog::error("Couldn't set I2C slave address: {}", errno);
|
||||
close(*i2c_dev_file);
|
||||
i2c_dev_file = std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
AppState::~AppState() {
|
||||
if (i2c_dev_file) {
|
||||
close(*i2c_dev_file);
|
||||
}
|
||||
}
|
||||
|
||||
void AppState::poll() {
|
||||
if (!i2c_dev_file) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t data[32];
|
||||
int count = i2c_smbus_read_block_data(*i2c_dev_file, I2C_POLL_COMMAND, data);
|
||||
if (count < 0) {
|
||||
throw std::runtime_error(fmt::format("Couldn't poll I2C slave: {}", errno));
|
||||
}
|
||||
view = static_cast<AppView>(data[0]);
|
||||
spdlog::info("View after poll: {}", view);
|
||||
}
|
||||
|
||||
AppView AppState::get_view() { return view; }
|
||||
Reference in New Issue
Block a user