Skip to content

Commit

Permalink
Merge pull request #5 from openvehicles/master
Browse files Browse the repository at this point in the history
3.1.011 to my fork
  • Loading branch information
KommyKT committed Nov 11, 2018
2 parents 61bbe09 + 5795056 commit 1951518
Show file tree
Hide file tree
Showing 23 changed files with 1,459 additions and 30 deletions.
Binary file not shown.
17 changes: 17 additions & 0 deletions vehicle/OVMS.V3/changes.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
Open Vehicle Monitor System v3 - Change log

????-??-?? ??? ??????? OTA release
- Twizy: SEVCON monitoring & recording
New commands:
xrt mon start [<filename>]
xrt mon stop
xrt mon reset
New metrics:
xrt.i.* = operational inverter data
xrt.s.* = power & torque by speed (virtual dyno)
- Twizy: experimental powermap calculation including region 3 / breakdown torque
New config:
xrt [motor_trq_breakdown] = 0 Breakdown torque in Nm, e.g. 210.375
xrt [motor_rpm_rated] = 0 Rated speed in rpm, e.g. 2100
See docs/Renault-Twizy/Twizy-Powermap-Calculator-Tbrk.ods for details.
- Add inactivity watchdog timers to CAN buses

2018-10-24 MWJ 3.1.011 OTA release
- Config backup & restore using encrypted ZIP archives
(AES 256 bit encryption, supported by e.g. 7z)
New commands:
config backup <path> [password=module password]
config restore <path> [password=module password]
- Support custom MAC address (config network mac ...)

2018-08-26 MWJ 3.1.010 OTA release
- TeslaRoadster: Fix for digital speedo bug
Expand Down
43 changes: 41 additions & 2 deletions vehicle/OVMS.V3/components/can/src/can.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static const char *TAG = "can";
#include <ctype.h>
#include <string.h>
#include "ovms_command.h"
#include "metrics_standard.h"

can MyCan __attribute__ ((init_priority (4500)));

Expand Down Expand Up @@ -326,6 +327,11 @@ void can_status(int verbosity, OvmsWriter* writer, OvmsCommand* cmd, int argc, c
writer->printf("Tx delays: %20d\n",sbus->m_status.txbuf_delay);
writer->printf("Tx err: %20d\n",sbus->m_status.errors_tx);
writer->printf("Tx ovrflw: %20d\n",sbus->m_status.txbuf_overflow);
writer->printf("Wdg Resets:%20d\n",sbus->m_status.watchdog_resets);
if (sbus->m_watchdog_timer>0)
{
writer->printf("Wdg Timer: %20d sec(s)\n",monotonictime-sbus->m_watchdog_timer);
}
writer->printf("Err flags: 0x%08x\n",sbus->m_status.error_flags);
}

Expand Down Expand Up @@ -432,7 +438,7 @@ can::~can()
void can::IncomingFrame(CAN_frame_t* p_frame)
{
p_frame->origin->m_status.packets_rx++;

p_frame->origin->m_watchdog_timer = monotonictime;
p_frame->origin->LogFrame(CAN_LogFrame_RX, p_frame);

ExecuteCallbacks(p_frame, false);
Expand Down Expand Up @@ -495,6 +501,10 @@ canbus::canbus(const char* name)
m_mode = CAN_MODE_OFF;
m_speed = CAN_SPEED_1000KBPS;
ClearStatus();

using std::placeholders::_1;
using std::placeholders::_2;
MyEvents.RegisterEvent(TAG, "ticker.10", std::bind(&canbus::BusTicker10, this, _1, _2));
}

canbus::~canbus()
Expand All @@ -517,6 +527,34 @@ void canbus::ClearStatus()
{
memset(&m_status, 0, sizeof(m_status));
m_status_chksum = 0;
m_watchdog_timer = monotonictime;
}

void canbus::BusTicker10(std::string event, void* data)
{
if ((m_powermode==On)&&(StandardMetrics.ms_v_env_on->AsBool()))
{
// Bus is powered on, and vehicle is ON
if ((monotonictime-m_watchdog_timer) > 60)
{
// We have a watchdog timeout
// We need to reset the CAN bus...
m_status.watchdog_resets++;
CAN_mode_t m = m_mode;
CAN_speed_t s = m_speed;
CAN_status_t t; memcpy(&t,&m_status,sizeof(CAN_status_t));
ESP_LOGE(TAG, "%s watchdog inactivity timeout - resetting bus",m_name);
Stop();
Start(m, s);
memcpy(&m_status,&t,sizeof(CAN_status_t));
m_watchdog_timer = monotonictime;
}
}
else
{
// Vehicle is OFF, so just tickle the watchdog timer
m_watchdog_timer = monotonictime;
}
}

bool canbus::RxCallback(CAN_frame_t* frame)
Expand Down Expand Up @@ -671,7 +709,8 @@ bool canbus::StatusChanged()
{
// simple checksum to prevent log flooding:
uint32_t chksum = m_status.packets_rx + m_status.packets_tx + m_status.errors_rx + m_status.errors_tx
+ m_status.rxbuf_overflow + m_status.txbuf_overflow + m_status.error_flags + m_status.txbuf_delay;
+ m_status.rxbuf_overflow + m_status.txbuf_overflow + m_status.error_flags + m_status.txbuf_delay
+ m_status.watchdog_resets;
if (chksum != m_status_chksum)
{
m_status_chksum = chksum;
Expand Down
4 changes: 4 additions & 0 deletions vehicle/OVMS.V3/components/can/src/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include <list>
#include "pcp.h"
#include <esp_err.h>
#include "ovms_events.h"

#ifndef ESP_QUEUED
#define ESP_QUEUED 1 // frame has been queued for later processing
Expand Down Expand Up @@ -188,6 +189,7 @@ typedef struct
uint32_t error_flags; // driver specific bitset
uint16_t errors_rx; // RX error counter
uint16_t errors_tx; // TX error counter
uint16_t watchdog_resets; // Watchdog reset counter
} CAN_status_t;

// Log entry types:
Expand Down Expand Up @@ -240,6 +242,7 @@ class canbus : public pcp, public InternalRamAllocated

protected:
virtual esp_err_t QueueWrite(const CAN_frame_t* p_frame, TickType_t maxqueuewait=0);
void BusTicker10(std::string event, void* data);

public:
void LogFrame(CAN_LogEntry_t type, const CAN_frame_t* p_frame);
Expand All @@ -252,6 +255,7 @@ class canbus : public pcp, public InternalRamAllocated
CAN_mode_t m_mode;
CAN_status_t m_status;
uint32_t m_status_chksum;
uint32_t m_watchdog_timer;
QueueHandle_t m_txqueue;
};

Expand Down
12 changes: 6 additions & 6 deletions vehicle/OVMS.V3/components/can/src/canlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,25 +346,25 @@ void canlog_trace::OutputMsg(CAN_LogMsg_t& msg)

case CAN_LogStatus_Error:
esp_log_write(ESP_LOG_ERROR, TAG,
LOG_FORMAT(E, "%s %s intr=%d rxpkt=%d txpkt=%d errflags=%#x rxerr=%d txerr=%d rxovr=%d txovr=%d txdelay=%d"),
LOG_FORMAT(E, "%s %s intr=%d rxpkt=%d txpkt=%d errflags=%#x rxerr=%d txerr=%d rxovr=%d txovr=%d txdelay=%d wdgreset=%d"),
msg.timestamp, TAG,
GetLogEntryTypeName(msg.type), msg.bus->GetName(),
msg.status.interrupts,
msg.status.packets_rx, msg.status.packets_tx,
msg.status.error_flags, msg.status.errors_rx, msg.status.errors_tx,
msg.status.rxbuf_overflow, msg.status.txbuf_overflow,
msg.status.txbuf_delay);
msg.status.txbuf_delay, msg.status.watchdog_resets);
break;
case CAN_LogStatus_Statistics:
esp_log_write(ESP_LOG_DEBUG, TAG,
LOG_FORMAT(D, "%s %s intr=%d rxpkt=%d txpkt=%d errflags=%#x rxerr=%d txerr=%d rxovr=%d txovr=%d txdelay=%d"),
LOG_FORMAT(D, "%s %s intr=%d rxpkt=%d txpkt=%d errflags=%#x rxerr=%d txerr=%d rxovr=%d txovr=%d txdelay=%d wdgreset=%d"),
msg.timestamp, TAG,
GetLogEntryTypeName(msg.type), msg.bus->GetName(),
msg.status.interrupts,
msg.status.packets_rx, msg.status.packets_tx,
msg.status.error_flags, msg.status.errors_rx, msg.status.errors_tx,
msg.status.rxbuf_overflow, msg.status.txbuf_overflow,
msg.status.txbuf_delay);
msg.status.txbuf_delay, msg.status.watchdog_resets);
break;

case CAN_LogInfo_Comment:
Expand Down Expand Up @@ -434,13 +434,13 @@ void canlog_crtd::OutputMsg(CAN_LogMsg_t& msg)

case CAN_LogStatus_Error:
case CAN_LogStatus_Statistics:
fprintf(m_file, "%d.%03d %s%s %s intr=%d rxpkt=%d txpkt=%d errflags=%#x rxerr=%d txerr=%d rxovr=%d txovr=%d txdelay=%d\n",
fprintf(m_file, "%d.%03d %s%s %s intr=%d rxpkt=%d txpkt=%d errflags=%#x rxerr=%d txerr=%d rxovr=%d txovr=%d txdelay=%d wdgreset=%d\n",
msg.timestamp / 1000, msg.timestamp % 1000, msg.bus->GetName()+3,
(msg.type == CAN_LogStatus_Error) ? "CEV" : "CXX",
GetLogEntryTypeName(msg.type), msg.status.interrupts,
msg.status.packets_rx, msg.status.packets_tx, msg.status.error_flags,
msg.status.errors_rx, msg.status.errors_tx, msg.status.rxbuf_overflow, msg.status.txbuf_overflow,
msg.status.txbuf_delay);
msg.status.txbuf_delay, msg.status.watchdog_resets);
break;
break;

Expand Down
4 changes: 4 additions & 0 deletions vehicle/OVMS.V3/components/ovms_webserver/assets/ovms.css
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,10 @@ pre {
.panel-single .panel-footer {
padding: 10px;
}
.panel-single .form-horizontal .form-group {
margin-right: -10px;
margin-left: -10px;
}
}

@media (min-width: 992px) {
Expand Down
Binary file modified vehicle/OVMS.V3/components/ovms_webserver/assets/style.css.gz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,15 @@ void OvmsVehicleRenaultTwizy::IncomingFrameCan1(CAN_frame_t* p_frame)
break;


case 0x629:
// --------------------------------------------------------------------------
// *** SEVCON status ***
// sent every 100 ms (10 per second) while SEVCON is running
if (m_sevcon)
m_sevcon->QueryMonitoringData();
break;


case 0x69F:
// --------------------------------------------------------------------------
// *** VIN ***
Expand Down
77 changes: 69 additions & 8 deletions vehicle/OVMS.V3/components/vehicle_renaulttwizy/src/rt_sevcon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ using namespace std;
*/

SevconClient::SevconClient(OvmsVehicleRenaultTwizy* twizy)
: m_sync(twizy->m_can1), m_async(twizy->m_can1)
: m_sync(twizy->m_can1), m_async(twizy->m_can1, 50)
{
ESP_LOGI(TAG, "sevcon subsystem init");

Expand All @@ -60,6 +60,9 @@ SevconClient::SevconClient(OvmsVehicleRenaultTwizy* twizy)

m_cfgmode_request = false;

InitMonitoring();
xTaskCreatePinnedToCore(SevconAsyncTaskEntry, "OVMS SevconAsync", 4*1024, (void*)this, 10, &m_asynctask, 1);

// register shell commands:

OvmsCommand *cmd_cfg = m_twizy->cmd_xrt->RegisterCommand("cfg", "SEVCON tuning", NULL, "", 0, 0, true);
Expand Down Expand Up @@ -101,6 +104,13 @@ SevconClient::SevconClient(OvmsVehicleRenaultTwizy* twizy)
cmd_cfg->RegisterCommand("querylogs", "Send SEVCON diag logs to server", shell_cfg_querylogs, "[which=1] [start=0]", 0, 2, true);
cmd_cfg->RegisterCommand("clearlogs", "Clear SEVCON diag logs", shell_cfg_clearlogs, "[which=99]", 0, 1, true);

OvmsCommand *cmd_mon = m_twizy->cmd_xrt->RegisterCommand("mon", "SEVCON monitoring", NULL, "", 0, 0, true);

cmd_mon->RegisterCommand("start", "Start monitoring", shell_mon_start, "[<filename>]", 0, 1, true);
cmd_mon->RegisterCommand("stop", "Stop monitoring", shell_mon_stop, "", 0, 0, true);
cmd_mon->RegisterCommand("reset", "Reset monitoring", shell_mon_reset, "", 0, 0, true);


// TODO:
// lock, unlock, valet, unvalet
// LATER:
Expand All @@ -113,6 +123,7 @@ SevconClient::SevconClient(OvmsVehicleRenaultTwizy* twizy)
using std::placeholders::_1;
using std::placeholders::_2;
MyEvents.RegisterEvent(TAG, "canopen.node.emcy", std::bind(&SevconClient::EmcyListener, this, _1, _2));
MyEvents.RegisterEvent(TAG, "sd.unmounting", std::bind(&SevconClient::UnmountListener, this, _1, _2));

m_kickdown_timer = xTimerCreate("RT kickdown", pdMS_TO_TICKS(100), pdTRUE, NULL, KickdownTimer);
}
Expand All @@ -123,6 +134,8 @@ SevconClient::~SevconClient()
xTimerDelete(m_kickdown_timer, 0);
if (m_faultqueue)
vQueueDelete(m_faultqueue);
if (m_asynctask)
vTaskDelete(m_asynctask);
}

SevconClient* SevconClient::GetInstance(OvmsWriter* writer /*=NULL*/)
Expand All @@ -135,6 +148,17 @@ SevconClient* SevconClient::GetInstance(OvmsWriter* writer /*=NULL*/)
}


void SevconClient::UnmountListener(string event, void* data)
{
// close monitor recording file:
if (m_mon_file) {
OvmsMutexLock lock(&m_mon_mutex);
fclose((FILE*)m_mon_file);
m_mon_file = NULL;
}
}


SevconJob::SevconJob(SevconClient* client)
{
m_client = client;
Expand Down Expand Up @@ -224,6 +248,38 @@ CANopenResult_t SevconClient::GetHeartbeat(CANopenJob& job, CANopenNMTState_t& v
return res;
}

CANopenResult_t SevconClient::SendRead(uint16_t index, uint8_t subindex, uint32_t* value)
{
CANopenResult_t res = CheckBus();
if (res != COR_OK)
return res;
return m_async.ReadSDO(m_nodeid, index, subindex, (uint8_t*)value, sizeof(uint32_t));
}

CANopenResult_t SevconClient::SendRead(uint16_t index, uint8_t subindex, int32_t* value)
{
CANopenResult_t res = CheckBus();
if (res != COR_OK)
return res;
return m_async.ReadSDO(m_nodeid, index, subindex, (uint8_t*)value, sizeof(int32_t));
}

CANopenResult_t SevconClient::SendRead(uint16_t index, uint8_t subindex, uint16_t* value)
{
CANopenResult_t res = CheckBus();
if (res != COR_OK)
return res;
return m_async.ReadSDO(m_nodeid, index, subindex, (uint8_t*)value, sizeof(uint16_t));
}

CANopenResult_t SevconClient::SendRead(uint16_t index, uint8_t subindex, int16_t* value)
{
CANopenResult_t res = CheckBus();
if (res != COR_OK)
return res;
return m_async.ReadSDO(m_nodeid, index, subindex, (uint8_t*)value, sizeof(int16_t));
}

CANopenResult_t SevconClient::SendWrite(uint16_t index, uint8_t subindex, uint32_t* value)
{
CANopenResult_t res = CheckBus();
Expand All @@ -241,12 +297,20 @@ CANopenResult_t SevconClient::SendRequestState(CANopenNMTCommand_t command)
}


void SevconClient::ProcessAsyncResults()
void SevconClient::SevconAsyncTaskEntry(void *pvParameters)
{
SevconClient *me = (SevconClient*)pvParameters;
me->SevconAsyncTask();
}

void SevconClient::SevconAsyncTask()
{
CANopenJob job;
while (m_async.ReceiveDone(job, 0) != COR_ERR_QueueEmpty) {
ESP_LOGD(TAG, "Sevcon async result for %s: %s",
CANopen::GetJobName(job).c_str(), GetResultString(job).c_str());
while (true) {
if (m_async.ReceiveDone(job, portMAX_DELAY) != COR_ERR_QueueEmpty) {
// ESP_LOGD(TAG, "Sevcon async result for %s: %s", CANopen::GetJobName(job).c_str(), GetResultString(job).c_str());
ProcessMonitoringData(job);
}
}
}

Expand Down Expand Up @@ -394,9 +458,6 @@ void SevconClient::Ticker1(uint32_t ticker)
// update metrics:
StdMetrics.ms_v_env_drivemode->SetValue((long) m_drivemode.u32);

// cleanup CANopen job result queue:
ProcessAsyncResults();

// Send fault alerts:
uint16_t faultcode;
while (xQueueReceive(m_faultqueue, &faultcode, 0) == pdTRUE) {
Expand Down
Loading

0 comments on commit 1951518

Please sign in to comment.