Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#include "PhyVersoBSP.hpp"
|
||||
#include <filesystem>
|
||||
|
||||
namespace module {
|
||||
|
||||
void PhyVersoBSP::init() {
|
||||
// transform everest config into evConfig accessible to evSerial
|
||||
everest_config_to_verso_config();
|
||||
|
||||
// initialize serial driver
|
||||
if (!serial.open_device(config.serial_port.c_str(), config.baud_rate)) {
|
||||
EVLOG_error << "Could not open serial port " << config.serial_port << " with baud rate " << config.baud_rate;
|
||||
return;
|
||||
}
|
||||
|
||||
// init user gpios
|
||||
if (not gpio.init_gpios()) {
|
||||
EVLOG_error << "Could not initialize user GPIOs. Terminating.";
|
||||
return;
|
||||
}
|
||||
|
||||
serial.flush_buffers();
|
||||
|
||||
serial.signal_config_request.connect([&]() {
|
||||
serial.send_config();
|
||||
EVLOG_info << "Sent config packet to MCU";
|
||||
});
|
||||
|
||||
serial.signal_connection_timeout.connect([this]() {
|
||||
auto err = p_connector_1->error_factory->create_error("evse_board_support/CommunicationFault", "McuToEverest",
|
||||
"Serial connection to MCU timed out");
|
||||
p_connector_1->raise_error(err);
|
||||
err = p_connector_2->error_factory->create_error("evse_board_support/CommunicationFault", "McuToEverest",
|
||||
"Serial connection to MCU timed out");
|
||||
p_connector_2->raise_error(err);
|
||||
});
|
||||
|
||||
serial.signal_error_flags.connect([this](int connector, ErrorFlags error_flags) {
|
||||
// heartbeat failure from Mcu side (not receiving packets) will be visible in both connector errors
|
||||
if (error_flags.heartbeat_timeout != last_heartbeat_error) {
|
||||
if (error_flags.heartbeat_timeout) {
|
||||
auto err = p_connector_1->error_factory->create_error(
|
||||
"evse_board_support/CommunicationFault", "EverestToMcu", "MCU did not receive Everest heartbeat");
|
||||
p_connector_1->raise_error(err);
|
||||
err = p_connector_2->error_factory->create_error(
|
||||
"evse_board_support/CommunicationFault", "EverestToMcu", "MCU did not receive Everest heartbeat");
|
||||
p_connector_2->raise_error(err);
|
||||
} else {
|
||||
p_connector_1->clear_error("evse_board_support/CommunicationFault", "EverestToMcu");
|
||||
p_connector_2->clear_error("evse_board_support/CommunicationFault", "EverestToMcu");
|
||||
}
|
||||
}
|
||||
last_heartbeat_error = error_flags.heartbeat_timeout;
|
||||
});
|
||||
|
||||
serial.signal_keep_alive.connect([this](KeepAlive d) {
|
||||
mcu_config_done = d.configuration_done;
|
||||
p_connector_1->clear_error("evse_board_support/CommunicationFault", "McuToEverest");
|
||||
p_connector_2->clear_error("evse_board_support/CommunicationFault", "McuToEverest");
|
||||
});
|
||||
|
||||
serial.reset(1);
|
||||
|
||||
serial.run();
|
||||
gpio.run();
|
||||
|
||||
// very sporadically multiple resets needed for MCU to respond -> retrying until we get MCU response in a
|
||||
// configured, ready and running state
|
||||
mcu_config_done = false;
|
||||
uint16_t n_tries = 0;
|
||||
while (!mcu_config_done) {
|
||||
serial.keep_alive();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
n_tries++;
|
||||
if (n_tries > 20) {
|
||||
EVLOG_info << "Trying reset again";
|
||||
serial.flush_buffers();
|
||||
serial.reset(1);
|
||||
n_tries = 0;
|
||||
}
|
||||
}
|
||||
|
||||
invoke_init(*p_connector_1);
|
||||
invoke_init(*p_connector_2);
|
||||
invoke_init(*p_rcd_1);
|
||||
invoke_init(*p_rcd_2);
|
||||
invoke_init(*p_connector_lock_1);
|
||||
invoke_init(*p_connector_lock_2);
|
||||
}
|
||||
|
||||
void PhyVersoBSP::ready() {
|
||||
invoke_ready(*p_connector_1);
|
||||
invoke_ready(*p_connector_2);
|
||||
invoke_ready(*p_rcd_1);
|
||||
invoke_ready(*p_rcd_2);
|
||||
invoke_ready(*p_connector_lock_1);
|
||||
invoke_ready(*p_connector_lock_2);
|
||||
|
||||
if (not serial.is_open()) {
|
||||
auto err = p_connector_1->error_factory->create_error("evse_board_support/CommunicationFault", "",
|
||||
"Could not open serial port.");
|
||||
p_connector_1->raise_error(err);
|
||||
err = p_connector_2->error_factory->create_error("evse_board_support/CommunicationFault", "",
|
||||
"Could not open serial port.");
|
||||
p_connector_2->raise_error(err);
|
||||
}
|
||||
}
|
||||
|
||||
// fills evConfig bridge with config values from manifest/everest config
|
||||
void PhyVersoBSP::everest_config_to_verso_config() {
|
||||
// if a port is configured to be AC and has a socket, a motor lock type specification/usage is mandatory
|
||||
if ((this->config.conn1_disable_port == false) && (this->config.conn1_dc == false) &&
|
||||
(this->config.conn1_has_socket == true) && (this->config.conn1_motor_lock_type < 1)) {
|
||||
EVLOG_critical << "Motor lock type for connector 1 has to be specified when using connector 1 as AC charging "
|
||||
"port with a socket/detachable charging cable!";
|
||||
throw std::runtime_error("Motor lock type for connector 1 has to be specified when using connector 1 as AC "
|
||||
"charging port with a socket/detachable charging cable!");
|
||||
}
|
||||
if ((this->config.conn2_disable_port == false) && (this->config.conn2_dc == false) &&
|
||||
(this->config.conn2_has_socket == true) && (this->config.conn2_motor_lock_type < 1)) {
|
||||
EVLOG_critical << "Motor lock type for connector 2 has to be specified when using connector 2 as AC charging "
|
||||
"port with a socket/detachable charging cable!";
|
||||
throw std::runtime_error("Motor lock type for connector 2 has to be specified when using connector 2 as AC "
|
||||
"charging port with a socket/detachable charging cable!");
|
||||
}
|
||||
|
||||
if ((this->config.conn1_feedback_pull < 0) || (this->config.conn1_feedback_pull > 2)) {
|
||||
EVLOG_error << "conn1_feedback_pull out of range! Falling back to default: 2";
|
||||
verso_config.conf.conn1_feedback_pull = 2;
|
||||
} else {
|
||||
verso_config.conf.conn1_feedback_pull = this->config.conn1_feedback_pull;
|
||||
}
|
||||
|
||||
if ((this->config.conn2_feedback_pull < 0) || (this->config.conn2_feedback_pull > 2)) {
|
||||
EVLOG_error << "conn2_feedback_pull out of range! Falling back to default: 2";
|
||||
verso_config.conf.conn2_feedback_pull = 2;
|
||||
} else {
|
||||
verso_config.conf.conn2_feedback_pull = this->config.conn2_feedback_pull;
|
||||
}
|
||||
|
||||
verso_config.conf.serial_port = this->config.serial_port;
|
||||
verso_config.conf.baud_rate = this->config.baud_rate;
|
||||
verso_config.conf.reset_gpio_bank = this->config.reset_gpio_bank;
|
||||
verso_config.conf.reset_gpio_pin = this->config.reset_gpio_pin;
|
||||
verso_config.conf.conn1_motor_lock_type = this->config.conn1_motor_lock_type;
|
||||
verso_config.conf.conn2_motor_lock_type = this->config.conn2_motor_lock_type;
|
||||
verso_config.conf.conn1_gpio_stop_button_enabled = this->config.conn1_gpio_stop_button_enabled;
|
||||
verso_config.conf.conn1_gpio_stop_button_bank = this->config.conn1_gpio_stop_button_bank;
|
||||
verso_config.conf.conn1_gpio_stop_button_pin = this->config.conn1_gpio_stop_button_pin;
|
||||
verso_config.conf.conn1_gpio_stop_button_invert = this->config.conn1_gpio_stop_button_invert;
|
||||
verso_config.conf.conn2_gpio_stop_button_enabled = this->config.conn2_gpio_stop_button_enabled;
|
||||
verso_config.conf.conn2_gpio_stop_button_bank = this->config.conn2_gpio_stop_button_bank;
|
||||
verso_config.conf.conn2_gpio_stop_button_pin = this->config.conn2_gpio_stop_button_pin;
|
||||
verso_config.conf.conn2_gpio_stop_button_invert = this->config.conn2_gpio_stop_button_invert;
|
||||
verso_config.conf.conn1_disable_port = this->config.conn1_disable_port;
|
||||
verso_config.conf.conn2_disable_port = this->config.conn2_disable_port;
|
||||
verso_config.conf.conn1_feedback_active_low = this->config.conn1_feedback_active_low;
|
||||
verso_config.conf.conn2_feedback_active_low = this->config.conn2_feedback_active_low;
|
||||
verso_config.conf.conn1_dc = this->config.conn1_dc;
|
||||
verso_config.conf.conn2_dc = this->config.conn2_dc;
|
||||
}
|
||||
|
||||
} // namespace module
|
||||
Reference in New Issue
Block a user