16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-19 02:09:17 +02:00

uart experiments

windows build fix

log uart write error

uart changes

uart changes

uart changes

uart changes

uart changes

uart works

uart changes

verbose uart log

uart changes

uart changes

uart logging

uart logging

uart changes

changes

uart changes
This commit is contained in:
milek7
2017-09-21 19:33:48 +02:00
parent 8fa81a1c12
commit f2a57dda63
18 changed files with 537 additions and 1189 deletions

173
uart.cpp Normal file
View File

@@ -0,0 +1,173 @@
#include "stdafx.h"
#include "uart.h"
#include "Globals.h"
#include "World.h"
#include "Train.h"
#include "Logs.h"
uart_input::uart_input()
{
conf = Global::uart_conf;
if (sp_get_port_by_name(conf.port.c_str(), &port) != SP_OK)
throw std::runtime_error("uart: cannot find specified port");
if (sp_open(port, SP_MODE_READ_WRITE) != SP_OK)
throw std::runtime_error("uart: cannot open port");
if (sp_set_baudrate(port, conf.baud) != SP_OK)
throw std::runtime_error("uart: cannot set baudrate");
if (sp_set_flowcontrol(port, SP_FLOWCONTROL_NONE) != SP_OK)
throw std::runtime_error("uart: cannot set flowcontrol");
if (sp_flush(port, SP_BUF_BOTH) != SP_OK)
throw std::runtime_error("uart: cannot flush");
old_packet.fill(0);
last_update = std::chrono::high_resolution_clock::now();
}
uart_input::~uart_input()
{
sp_close(port);
sp_free_port(port);
}
#define SPLIT_INT16(x) (uint8_t)x, (uint8_t)(x >> 8)
void uart_input::poll()
{
auto now = std::chrono::high_resolution_clock::now();
if (std::chrono::duration<float>(now - last_update).count() < conf.updatetime)
return;
last_update = now;
TTrain *t = Global::pWorld->train();
sp_return ret;
if (sp_input_waiting(port) >= 16)
{
std::array<uint8_t, 16> buffer;
ret = sp_blocking_read(port, (void*)buffer.data(), buffer.size(), 0);
if (ret < 0)
throw std::runtime_error("uart: failed to read from port");
sp_drain(port);
data_pending = false;
for (auto entry : input_bits)
{
input_type_t type = std::get<2>(entry);
size_t byte = std::get<0>(entry) / 8;
size_t bit = std::get<0>(entry) % 8;
bool state = (bool)(buffer[byte] & (1 << bit));
bool repeat = (type == impulse_r ||
type == impulse_r_off ||
type == impulse_r_on);
bool changed = (state != (bool)(old_packet[byte] & (1 << bit)));
if (!changed && !(repeat && state))
continue;
int action;
command_data::desired_state_t desired_state;
if (type == toggle)
{
action = GLFW_PRESS;
desired_state = state ? command_data::ON : command_data::OFF;
}
else if (type == impulse_r_on)
{
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
desired_state = command_data::ON;
}
else if (type == impulse_r_off)
{
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
desired_state = command_data::OFF;
}
else if (type == impulse || type == impulse_r)
{
action = state ? (changed ? GLFW_PRESS : GLFW_REPEAT) : GLFW_RELEASE;
desired_state = command_data::TOGGLE;
}
relay.post(std::get<1>(entry), 0, 0, action, 0, desired_state);
}
int mainctrl = buffer[6];
int scndctrl = buffer[7];
float trainbrake = (float)(((uint16_t)buffer[8] | ((uint16_t)buffer[9] << 8)) - conf.mainbrakemin) / (conf.mainbrakemax - conf.mainbrakemin);
float localbrake = (float)(((uint16_t)buffer[10] | ((uint16_t)buffer[11] << 8)) - conf.mainbrakemin) / (conf.localbrakemax - conf.localbrakemin);
t->set_mainctrl(mainctrl);
t->set_scndctrl(scndctrl);
t->set_trainbrake(trainbrake);
t->set_localbrake(localbrake);
old_packet = buffer;
}
if (!data_pending && sp_output_waiting(port) == 0)
{
// TODO: ugly! move it into structure like input_bits
uint8_t buzzer = (uint8_t)t->get_alarm();
uint8_t tacho = (uint8_t)t->get_tacho();
uint16_t tank_press = (uint16_t)std::min(conf.tankuart, t->get_tank_pressure() / conf.tankmax * conf.tankuart);
uint16_t pipe_press = (uint16_t)std::min(conf.pipeuart, t->get_pipe_pressure() / conf.pipemax * conf.pipeuart);
uint16_t brake_press = (uint16_t)std::min(conf.brakeuart, t->get_brake_pressure() / conf.brakemax * conf.brakeuart);
uint16_t hv_voltage = (uint16_t)std::min(conf.hvuart, t->get_hv_voltage() / conf.hvmax * conf.hvuart);
auto current = t->get_current();
uint16_t current1 = (uint16_t)std::min(conf.currentuart, current[0]) / conf.currentmax * conf.currentuart;
uint16_t current2 = (uint16_t)std::min(conf.currentuart, current[1]) / conf.currentmax * conf.currentuart;
uint16_t current3 = (uint16_t)std::min(conf.currentuart, current[2]) / conf.currentmax * conf.currentuart;
std::array<uint8_t, 31> buffer =
{
0, 0, //byte 0-1
tacho, //byte 2
0, 0, 0, 0, 0, 0, //byte 3-8
SPLIT_INT16(brake_press), //byte 9-10
SPLIT_INT16(pipe_press), //byte 11-12
SPLIT_INT16(tank_press), //byte 13-14
SPLIT_INT16(hv_voltage), //byte 15-16
SPLIT_INT16(current1), //byte 17-18
SPLIT_INT16(current2), //byte 19-20
SPLIT_INT16(current3), //byte 21-22
0, 0, 0, 0, 0, 0, 0, 0 //byte 23-30
};
buffer[4] |= t->btLampkaOpory.b() << 1;
buffer[4] |= t->btLampkaWysRozr.b() << 2;
buffer[6] |= t->btLampkaOgrzewanieSkladu.b() << 0;
buffer[6] |= t->btLampkaOpory.b() << 1;
buffer[6] |= t->btLampkaPoslizg.b() << 2;
buffer[6] |= t->btLampkaCzuwaka.b() << 6;
buffer[6] |= t->btLampkaSHP.b() << 7;
buffer[7] |= t->btLampkaStyczn.b() << 0;
buffer[7] |= t->btLampkaNadmPrzetw.b() << 2;
buffer[7] |= t->btLampkaNadmSil.b() << 4;
buffer[7] |= t->btLampkaWylSzybki.b() << 5;
buffer[7] |= t->btLampkaNadmSpr.b() << 6;
buffer[8] |= buzzer << 7;
sp_flush(port, SP_BUF_INPUT); // flush input buffer in preparation for reply packet
ret = sp_blocking_write(port, (void*)buffer.data(), buffer.size(), 0);
if (ret != buffer.size())
throw std::runtime_error("uart: failed to write to port");
data_pending = true;
}
}