Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uMWC: adapt driver to new firmware #723

Merged
merged 3 commits into from
Jun 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 10 additions & 8 deletions modules/MicroMegaWattBSP/MicroMegaWattBSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,35 @@ void MicroMegaWattBSP::init() {
return;
}

invoke_init(*p_powermeter);
SebaLukas marked this conversation as resolved.
Show resolved Hide resolved
invoke_init(*p_board_support);
invoke_init(*p_dc_supply);
invoke_init(*p_powermeter);
}

void MicroMegaWattBSP::ready() {
serial.run();

if (!serial.reset(config.reset_gpio)) {
EVLOG_error << "uMWC reset not successful.";
if (not config.reset_gpio_chip.empty()) {
EVLOG_info << "Perform HW reset with gpio chip " << config.reset_gpio_chip << " line " << config.reset_gpio;
if (!serial.reset(config.reset_gpio_chip, config.reset_gpio)) {
EVLOG_error << "uMWC reset not successful.";
}
}

serial.signalSpuriousReset.connect([this]() { EVLOG_error << "uMWC uC spurious reset!"; });
serial.signalConnectionTimeout.connect([this]() { EVLOG_error << "uMWC UART timeout!"; });
serial.signalSpuriousReset.connect([this]() { EVLOG_warning << "uMWC uC spurious reset!"; });
serial.signalConnectionTimeout.connect([this]() { EVLOG_warning << "uMWC UART timeout!"; });

serial.signalTelemetry.connect([this](Telemetry t) {
mqtt.publish("everest_external/umwc/cp_hi", t.cp_hi);
mqtt.publish("everest_external/umwc/cp_lo", t.cp_lo);
mqtt.publish("everest_external/umwc/pwm_dc", t.pwm_dc);
mqtt.publish("everest_external/umwc/relais_on", t.relais_on);
mqtt.publish("everest_external/umwc/output_voltage", t.voltage);
});
serial.signalPowerMeter.connect(
[this](PowerMeter p) { mqtt.publish("everest_external/umwc/output_voltage", p.voltage); });

invoke_ready(*p_powermeter);
SebaLukas marked this conversation as resolved.
Show resolved Hide resolved
invoke_ready(*p_board_support);
invoke_ready(*p_dc_supply);
invoke_ready(*p_powermeter);

if (not serial.is_open()) {
auto err = p_board_support->error_factory->create_error("evse_board_support/CommunicationFault", "",
Expand Down
1 change: 1 addition & 0 deletions modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
struct Conf {
std::string serial_port;
int baud_rate;
std::string reset_gpio_chip;

Check notice on line 28 in modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/MicroMegaWattBSP/MicroMegaWattBSP.hpp#L28

struct member 'Conf::reset_gpio_chip' is never used.
int reset_gpio;
int dc_max_voltage;
};
Expand Down
106 changes: 57 additions & 49 deletions modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,73 +5,81 @@

namespace module {
namespace board_support {

/*


static types::board_support::Event cast_event_type(const Event& e) {
switch (e.type) {
case Event_InterfaceEvent_CAR_PLUGGED_IN:
return types::board_support::Event::CarPluggedIn;
case Event_InterfaceEvent_CAR_REQUESTED_POWER:
return types::board_support::Event::CarRequestedPower;
case Event_InterfaceEvent_POWER_ON:
return types::board_support::Event::PowerOn;
case Event_InterfaceEvent_POWER_OFF:
return types::board_support::Event::PowerOff;
case Event_InterfaceEvent_CAR_REQUESTED_STOP_POWER:
return types::board_support::Event::CarRequestedStopPower;
case Event_InterfaceEvent_CAR_UNPLUGGED:
return types::board_support::Event::CarUnplugged;
case Event_InterfaceEvent_ERROR_E:
return types::board_support::Event::ErrorE;
case Event_InterfaceEvent_ERROR_DF:
return types::board_support::Event::ErrorDF;
case Event_InterfaceEvent_ERROR_RELAIS:
return types::board_support::Event::ErrorRelais;
case Event_InterfaceEvent_ERROR_RCD:
return types::board_support::Event::ErrorRCD;
case Event_InterfaceEvent_ERROR_VENTILATION_NOT_AVAILABLE:
return types::board_support::Event::ErrorVentilationNotAvailable;
case Event_InterfaceEvent_ERROR_OVER_CURRENT:
return types::board_support::Event::ErrorOverCurrent;
case Event_InterfaceEvent_ENTER_BCD:
return types::board_support::Event::EFtoBCD;
case Event_InterfaceEvent_LEAVE_BCD:
return types::board_support::Event::BCDtoEF;
case Event_InterfaceEvent_PERMANENT_FAULT:
return types::board_support::Event::PermanentFault;
case Event_InterfaceEvent_EVSE_REPLUG_STARTED:
return types::board_support::Event::EvseReplugStarted;
case Event_InterfaceEvent_EVSE_REPLUG_FINISHED:
return types::board_support::Event::EvseReplugFinished;
static types::board_support_common::BspEvent cast_event_type(CpState cp_state) {
types::board_support_common::BspEvent event;
switch (cp_state) {
case CpState_STATE_A:
event.event = types::board_support_common::Event::A;
break;
case CpState_STATE_B:
event.event = types::board_support_common::Event::B;
break;
case CpState_STATE_C:
event.event = types::board_support_common::Event::C;
break;
case CpState_STATE_D:
event.event = types::board_support_common::Event::D;
break;
case CpState_STATE_E:
event.event = types::board_support_common::Event::E;
break;
case CpState_STATE_F:
event.event = types::board_support_common::Event::F;
break;
}
return event;
}

EVLOG_error << "Received an unknown interface event from uMWC: " << (int)e.type;
return types::board_support::Event::ErrorVentilationNotAvailable;
static types::board_support_common::BspEvent cast_event_type(bool relais_state) {
types::board_support_common::BspEvent event;
if (relais_state) {
event.event = types::board_support_common::Event::PowerOn;
} else {
event.event = types::board_support_common::Event::PowerOff;
}
return event;
}
*/

void evse_board_supportImpl::init() {
{
std::lock_guard<std::mutex> lock(capsMutex);

caps.min_current_A_import = 0;
caps.max_current_A_import = 6;
caps.max_current_A_import = 100;
caps.min_phase_count_import = 1;
caps.max_phase_count_import = 3;
caps.supports_changing_phases_during_charging = false;
caps.connector_type = types::evse_board_support::Connector_type::IEC62196Type2Cable;

caps.min_current_A_export = 0;
caps.max_current_A_export = 6;
caps.max_current_A_export = 100;
caps.min_phase_count_export = 1;
caps.max_phase_count_export = 3;
}

/* mod->serial.signalEvent.connect([this](Event e) {
EVLOG_info << "CP EVENT: " << types::board_support::event_to_string(cast_event_type(e));
publish_event(cast_event_type(e));
});*/
mod->serial.signalKeepAliveLo.connect([this](KeepAliveLo l) {
if (not keep_alive_printed) {
EVLOG_info << "uMWC Controller Configuration:";
EVLOG_info << " Hardware revision: " << l.hw_revision;
EVLOG_info << " Firmware version: " << l.sw_version_string;
}
keep_alive_printed = true;
});

mod->serial.signalCPState.connect([this](CpState cp_state) {
if (cp_state not_eq last_cp_state) {
auto event_cp_state = cast_event_type(cp_state);
EVLOG_info << "CP state changed: " << types::board_support_common::event_to_string(event_cp_state.event);
publish_event(event_cp_state);
last_cp_state = cp_state;
}
});
mod->serial.signalRelaisState.connect([this](bool relais_state) {
if (last_relais_state not_eq relais_state) {
publish_event(cast_event_type(relais_state));
last_relais_state = relais_state;
}
});
}

void evse_board_supportImpl::ready() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@
// insert your private definitions here
types::evse_board_support::HardwareCapabilities caps;
std::mutex capsMutex;
std::atomic_bool keep_alive_printed{false};
CpState last_cp_state{CpState::CpState_STATE_E};
bool last_relais_state{false};

Check notice on line 66 in modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/MicroMegaWattBSP/board_support/evse_board_supportImpl.hpp#L66

class member 'evse_board_supportImpl::last_relais_state' is never used.
// ev@3370e4dd-95f4-47a9-aaec-ea76f34a66c9:v1
};

Expand Down
18 changes: 14 additions & 4 deletions modules/MicroMegaWattBSP/dc_supply/power_supply_DCImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,22 @@ namespace module {
namespace dc_supply {

void power_supply_DCImpl::init() {

mod->serial.signalPowerMeter.connect([this](const PowerMeter& p) {
mod->serial.signalTelemetry.connect([this](Telemetry t) {
types::power_supply_DC::VoltageCurrent vc;
vc.voltage_V = p.voltage;
vc.current_A = 0.;
vc.current_A = 0;
vc.voltage_V = t.voltage;
publish_voltage_current(vc);

types::powermeter::Powermeter p;
p.timestamp = Everest::Date::to_rfc3339(date::utc_clock::now());
p.meter_id = "UMWC";
types::units::Energy e;
e.total = 0.;
p.energy_Wh_import = e;
types::units::Voltage v;
v.DC = t.voltage;
p.voltage_V = v;
mod->p_powermeter->publish_powermeter(p);
});
}

Expand Down
17 changes: 10 additions & 7 deletions modules/MicroMegaWattBSP/manifest.yaml
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
description: Driver module for the Micro Mega Watt DC Charging Tester v1.0
config:
serial_port:
description: Serial port the Yeti hardware is connected to
description: Serial port the uMWC hardware is connected to
type: string
default: /dev/ttyUSB0
baud_rate:
description: Serial baud rate to use when communicating with Yeti hardware
description: Serial baud rate to use when communicating with uMWC hardware
type: integer
minimum: 9600
maximum: 230400
default: 115200
reset_gpio_chip:
description: >-
Reset GPIO chip to use to HW reset uMWC. If set to empty string, it is disabled.
type: string
default: 'gpiochip0'
reset_gpio:
description: Reset GPIO number to use to HW reset uMWC. If set <0 it is disabled.
description: GPIO line to use to reset uMWC
type: integer
minimum: -1
maximum: 1000
default: -1
default: 27
dc_max_voltage:
description: Maximum voltage to support
type: integer
Expand All @@ -28,7 +31,7 @@ provides:
description: Interface for the DC/DC output supply
powermeter:
interface: powermeter
description: provides the Yeti Internal Power Meter
description: Interface for the powermeter
board_support:
interface: evse_board_support
description: provides the board support Interface to low level control control pilot, relais, rcd, motor lock
Expand Down
37 changes: 7 additions & 30 deletions modules/MicroMegaWattBSP/powermeter/powermeterImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,24 @@
namespace module {
namespace powermeter {

static types::powermeter::Powermeter umwc_to_everest(const PowerMeter& p) {
types::powermeter::Powermeter j;

j.timestamp = Everest::Date::to_rfc3339(date::utc_clock::now());
j.meter_id = "UMWC_POWERMETER";

j.energy_Wh_import.total = 0;

types::units::Power pwr;
pwr.total = 0;
j.power_W = pwr;

types::units::Voltage volt;
volt.DC = p.voltage;
j.voltage_V = volt;

types::units::Current amp;
amp.DC = 0;
j.current_A = amp;

return j;
}

void powermeterImpl::init() {
mod->serial.signalPowerMeter.connect([this](const PowerMeter& p) { publish_powermeter(umwc_to_everest(p)); });
}

void powermeterImpl::ready() {
}

types::powermeter::TransactionStartResponse
powermeterImpl::handle_start_transaction(types::powermeter::TransactionReq& value) {
// your code for cmd start_transaction goes here
return {types::powermeter::TransactionRequestStatus::NOT_SUPPORTED,
"MicroMegaWattBSP powermeter does not support the start_transaction command"};
}

types::powermeter::TransactionStopResponse powermeterImpl::handle_stop_transaction(std::string& transaction_id) {
return {types::powermeter::TransactionRequestStatus::NOT_SUPPORTED,
{},
{},
"MicroMegaWattBSP powermeter does not support the stop_transaction command"};
};

types::powermeter::TransactionStartResponse
powermeterImpl::handle_start_transaction(types::powermeter::TransactionReq& value) {
return {types::powermeter::TransactionRequestStatus::NOT_SUPPORTED,
"MicroMegaWattBSP powermeter does not support the start_transaction command"};
}

} // namespace powermeter
Expand Down
1 change: 1 addition & 0 deletions modules/MicroMegaWattBSP/umwc_comms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ target_link_libraries(umwc_comms
PRIVATE
Pal::Sigslot
everest::framework
everest::gpio
)
30 changes: 12 additions & 18 deletions modules/MicroMegaWattBSP/umwc_comms/evSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include <everest/3rd_party/nanopb/pb_decode.h>
#include <everest/3rd_party/nanopb/pb_encode.h>

#include <gpio.hpp>

#include "umwc.pb.h"

evSerial::evSerial() {
Expand Down Expand Up @@ -151,10 +153,6 @@ void evSerial::handlePacket(uint8_t* buf, int len) {
// detect connection timeout if keep_alive packets stop coming...
last_keep_alive_lo_timestamp = date::utc_clock::now();
break;
case McuToEverest_power_meter_tag:
// printf("Received power_meter %i\n", (int)(msg_in.payload.power_meter.voltage));
signalPowerMeter(msg_in.payload.power_meter);
break;
case McuToEverest_telemetry_tag:
/*printf("Received telemetry cp_hi %f cp_lo %f relais_on %i pwm_dc %f\n", msg_in.payload.telemetry.cp_hi,
msg_in.payload.telemetry.cp_lo, (int)msg_in.payload.telemetry.relais_on,
Expand All @@ -164,9 +162,6 @@ void evSerial::handlePacket(uint8_t* buf, int len) {
case McuToEverest_cp_state_tag:
signalCPState(msg_in.payload.cp_state);
break;
case McuToEverest_pp_state_tag:
signalPPState(msg_in.payload.pp_state);
break;
case McuToEverest_relais_state_tag:
signalRelaisState(msg_in.payload.relais_state);
break;
Expand Down Expand Up @@ -362,22 +357,21 @@ void evSerial::setOutputVoltageCurrent(float v, float c) {
linkWrite(&msg_out);
}

bool evSerial::reset(const int reset_pin) {
bool evSerial::reset(const std::string& reset_chip, const int reset_line) {

reset_done_flag = false;
forced_reset = true;

if (reset_pin > 0) {
if (not reset_chip.empty()) {
// Try to hardware reset Yeti controller to be in a known state
char cmd[100];
sprintf(cmd, "echo %i >/sys/class/gpio/export", reset_pin);
system(cmd);
sprintf(cmd, "echo out > /sys/class/gpio/gpio%i/direction", reset_pin);
system(cmd);
sprintf(cmd, "echo 0 > /sys/class/gpio/gpio%i/value", reset_pin);
system(cmd);
sprintf(cmd, "echo 1 > /sys/class/gpio/gpio%i/value", reset_pin);
system(cmd);
Everest::Gpio reset_gpio;
reset_gpio.open(reset_chip, reset_line);
reset_gpio.set_output(true);
reset_gpio.set(true);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
reset_gpio.set(false);
std::this_thread::sleep_for(std::chrono::milliseconds(10));
reset_gpio.set(true);
} else {
// Try to soft reset Yeti controller to be in a known state
EverestToMcu msg_out = EverestToMcu_init_default;
Expand Down
Loading
Loading