More MISRA-C changes
This commit is contained in:
parent
44ef6237c4
commit
b04c67eed5
Binary file not shown.
|
@ -6,7 +6,7 @@
|
|||
#include "gearbox.h"
|
||||
#include "nvs/eeprom_config.h"
|
||||
#include "common_structs.h"
|
||||
#include "endpoint.h"
|
||||
#include "endpoints/endpoint.h"
|
||||
#include <esp_app_format.h>
|
||||
|
||||
// Needed extra bytes for response, SID, RLI, Shift ID
|
||||
|
|
|
@ -1,211 +0,0 @@
|
|||
#ifndef DIAG_ENDPOINT_H
|
||||
#define DIAG_ENDPOINT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <driver/uart.h>
|
||||
#include "esp_log.h"
|
||||
#include "string.h"
|
||||
#include "canbus/can_hal.h"
|
||||
#include "esp_core_dump.h"
|
||||
#include "tcu_maths.h"
|
||||
#include "driver/twai.h"
|
||||
|
||||
// #define DIAG_CAN_MAX_SIZE 4095 // ISO-TP Maximum
|
||||
static const uint16_t DIAG_CAN_MAX_SIZE = 4095u; // ISO-TP Maximum
|
||||
|
||||
struct DiagMessage
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t data_size;
|
||||
uint8_t data[DIAG_CAN_MAX_SIZE]; // 512B messages max (EGS52/3 is always max 256 bytes)
|
||||
};
|
||||
|
||||
struct CanEndpointMsg
|
||||
{
|
||||
uint8_t data[DIAG_CAN_MAX_SIZE];
|
||||
uint16_t curr_pos;
|
||||
uint16_t max_pos;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Abstract endpoint
|
||||
*
|
||||
*/
|
||||
class AbstractEndpoint
|
||||
{
|
||||
public:
|
||||
AbstractEndpoint(void){};
|
||||
virtual void send_data(DiagMessage *msg); // Blocking operation
|
||||
virtual bool read_data(DiagMessage *dest);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Endpoint for USB communication with ultimate-nag52 custom USB util
|
||||
*
|
||||
*/
|
||||
#define UART_NUM
|
||||
|
||||
const static size_t UART_MSG_SIZE = 6 + (2 * DIAG_CAN_MAX_SIZE);
|
||||
|
||||
class UsbEndpoint : public AbstractEndpoint
|
||||
{
|
||||
public:
|
||||
const char HEX_DEF[17] = "0123456789ABCDEF";
|
||||
explicit UsbEndpoint(bool can_use_spiram) : AbstractEndpoint()
|
||||
{
|
||||
data_size = 0;
|
||||
line_idx = 0;
|
||||
max_bytes_left = 0;
|
||||
to_read = 0;
|
||||
length = 0;
|
||||
esp_err_t e;
|
||||
this->allocation_psram = can_use_spiram;
|
||||
e = uart_driver_install(0, UART_MSG_SIZE / 2u, UART_MSG_SIZE / 2u, 0, nullptr, 0);
|
||||
if (e == ESP_OK)
|
||||
{
|
||||
if (this->allocation_psram)
|
||||
{
|
||||
this->read_buffer = static_cast<char *>(heap_caps_malloc(UART_MSG_SIZE, MALLOC_CAP_SPIRAM));
|
||||
this->write_buffer = static_cast<char *>(heap_caps_malloc(UART_MSG_SIZE, MALLOC_CAP_SPIRAM));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: can_use_spiram is always true, since UsbEndpoint is only called with "true"; it should thus be considered to remove the parameter; MISRA-C proposes not to use malloc()
|
||||
this->read_buffer = static_cast<char *>(malloc(UART_MSG_SIZE));
|
||||
this->write_buffer = static_cast<char *>(malloc(UART_MSG_SIZE));
|
||||
}
|
||||
if (nullptr != this->read_buffer)
|
||||
{
|
||||
uart_flush(0);
|
||||
this->read_pos = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ESP_LOG_LEVEL(ESP_LOG_ERROR, "USBEndpoint", "Error installing UART driver: %s", esp_err_to_name(e));
|
||||
}
|
||||
}
|
||||
|
||||
void send_data(DiagMessage *msg) override
|
||||
{
|
||||
this->write_buffer[0] = '#';
|
||||
this->write_buffer[1] = HEX_DEF[(msg->id >> 12) & 0x0F];
|
||||
this->write_buffer[2] = HEX_DEF[(msg->id >> 8) & 0x0F];
|
||||
this->write_buffer[3] = HEX_DEF[(msg->id >> 4) & 0x0F];
|
||||
this->write_buffer[4] = HEX_DEF[msg->id & 0x0F];
|
||||
for (uint16_t i = 0; i < msg->data_size; i++)
|
||||
{
|
||||
this->write_buffer[5 + (i * 2)] = HEX_DEF[(msg->data[i] >> 4) & 0x0F];
|
||||
this->write_buffer[6 + (i * 2)] = HEX_DEF[msg->data[i] & 0x0F];
|
||||
}
|
||||
this->write_buffer[(msg->data_size * 2) + 5] = '\n';
|
||||
uart_write_bytes(0, &this->write_buffer[0], (msg->data_size * 2) + 6);
|
||||
}
|
||||
|
||||
bool read_data(DiagMessage *dest) override
|
||||
{
|
||||
this->length = 0;
|
||||
uart_get_buffered_data_len(0, &length);
|
||||
if (length != 0)
|
||||
{
|
||||
max_bytes_left = UART_MSG_SIZE - this->read_pos;
|
||||
to_read = MIN(length, max_bytes_left);
|
||||
uart_read_bytes(0, &this->read_buffer[this->read_pos], to_read, 0);
|
||||
this->read_pos += length;
|
||||
return false;
|
||||
}
|
||||
else if (this->read_pos != 0)
|
||||
{
|
||||
if (this->read_pos < 5)
|
||||
{
|
||||
ESP_LOG_LEVEL(ESP_LOG_ERROR, "USBEndpoint", "Corrupt incoming msg. Less than 5 bytes");
|
||||
this->read_pos = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t read_size = (this->read_buffer[0] << 8) | this->read_buffer[1];
|
||||
if (read_size != this->read_pos - 2)
|
||||
{
|
||||
ESP_LOG_LEVEL(ESP_LOG_ERROR, "USBEndpoint", "Corrupt incoming msg. Msg size is %d bytes, buffer has %d bytes", read_size, this->read_pos - 2);
|
||||
this->read_pos = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Valid msg!
|
||||
dest->id = (this->read_buffer[2] << 8) | this->read_buffer[3];
|
||||
dest->data_size = read_size - 2;
|
||||
memcpy(dest->data, &this->read_buffer[4], dest->data_size);
|
||||
this->read_pos = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
// NOTE TO SELF
|
||||
// Every USB MSG:
|
||||
// {ID: 0x07E0, Data: [0x00, 0x11, 0x22, 0x33]} = '#07E100112233\n'
|
||||
// Read msg size: 6 bytes: USB message size: 14 = (Read size *2) + 2
|
||||
char *read_buffer;
|
||||
char *write_buffer;
|
||||
uint16_t read_pos;
|
||||
bool clear_to_send = false;
|
||||
bool allocation_psram = false;
|
||||
int data_size;
|
||||
int line_idx;
|
||||
int max_bytes_left;
|
||||
int to_read;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Endpoint for ISO-TP communication with OBD readers
|
||||
*
|
||||
*/
|
||||
class CanEndpoint : public AbstractEndpoint
|
||||
{
|
||||
public:
|
||||
explicit CanEndpoint(EgsBaseCan *can_layer);
|
||||
void send_data(DiagMessage *msg) override;
|
||||
bool read_data(DiagMessage *dest) override;
|
||||
static void start_iso_tp(void *_this)
|
||||
{
|
||||
static_cast<CanEndpoint *>(_this)->iso_tp_server_loop();
|
||||
}
|
||||
|
||||
private:
|
||||
void process_single_frame(DiagCanMessage msg);
|
||||
void process_start_frame(DiagCanMessage msg);
|
||||
void process_multi_frame(DiagCanMessage msg);
|
||||
void process_flow_control(DiagCanMessage msg);
|
||||
|
||||
[[noreturn]] void iso_tp_server_loop();
|
||||
EgsBaseCan *can;
|
||||
QueueHandle_t rx_queue;
|
||||
// QueueHandle_t tx_queue;
|
||||
CanEndpointMsg tx_msg;
|
||||
CanEndpointMsg rx_msg;
|
||||
QueueHandle_t read_msg_queue;
|
||||
QueueHandle_t send_msg_queue;
|
||||
CanEndpointMsg tmp;
|
||||
bool is_sending;
|
||||
bool clear_to_send;
|
||||
bool is_receiving;
|
||||
uint8_t rx_bs;
|
||||
uint8_t tx_pci = 0x20;
|
||||
uint64_t last_rx_time;
|
||||
uint64_t last_tx_time;
|
||||
uint8_t tx_bs = 8;
|
||||
uint8_t tx_stmin = 20;
|
||||
uint8_t frames_received = 0;
|
||||
twai_message_t tx_can;
|
||||
uint8_t tx_count = 0;
|
||||
|
||||
bool send_to_twai(DiagCanMessage msg);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
#include "endpoint.h"
|
||||
#include "kwp2000_defines.h"
|
||||
#include "../kwp2000_defines.h"
|
||||
#include "driver/twai.h"
|
||||
|
||||
const DiagCanMessage FLOW_CONTROL = {0x30, KWP_CAN_BS, KWP_CAN_ST_MIN, 0, 0, 0, 0, 0};
|
||||
|
@ -23,6 +23,11 @@ CanEndpoint::CanEndpoint(EgsBaseCan* can_layer) {
|
|||
this->last_rx_time = 0;
|
||||
this->last_tx_time = 0;
|
||||
can_layer->register_diag_queue(&this->rx_queue, KWP_ECU_RX_ID);
|
||||
this->status = ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t CanEndpoint::init_state() {
|
||||
return this->status;
|
||||
}
|
||||
|
||||
bool CanEndpoint::send_to_twai(DiagCanMessage msg) {
|
|
@ -0,0 +1,121 @@
|
|||
#ifndef DIAG_ENDPOINT_H
|
||||
#define DIAG_ENDPOINT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <driver/uart.h>
|
||||
#include "esp_log.h"
|
||||
#include "string.h"
|
||||
#include "canbus/can_hal.h"
|
||||
#include "esp_core_dump.h"
|
||||
#include "tcu_maths.h"
|
||||
#include "driver/twai.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
// #define DIAG_CAN_MAX_SIZE 4095 // ISO-TP Maximum
|
||||
static const uint16_t DIAG_CAN_MAX_SIZE = 4095u; // ISO-TP Maximum
|
||||
|
||||
struct DiagMessage
|
||||
{
|
||||
uint16_t id;
|
||||
uint16_t data_size;
|
||||
uint8_t data[DIAG_CAN_MAX_SIZE]; // 512B messages max (EGS52/3 is always max 256 bytes)
|
||||
};
|
||||
|
||||
struct CanEndpointMsg
|
||||
{
|
||||
uint8_t data[DIAG_CAN_MAX_SIZE];
|
||||
uint16_t curr_pos;
|
||||
uint16_t max_pos;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Abstract endpoint
|
||||
*
|
||||
*/
|
||||
class AbstractEndpoint
|
||||
{
|
||||
public:
|
||||
AbstractEndpoint(void){};
|
||||
virtual void send_data(DiagMessage *msg); // Blocking operation
|
||||
virtual bool read_data(DiagMessage *dest);
|
||||
virtual esp_err_t init_state();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Endpoint for USB communication with ultimate-nag52 custom USB util
|
||||
*
|
||||
*/
|
||||
class UsbEndpoint : public AbstractEndpoint
|
||||
{
|
||||
public:
|
||||
explicit UsbEndpoint();
|
||||
void send_data(DiagMessage *msg) override;
|
||||
bool read_data(DiagMessage *dest) override;
|
||||
esp_err_t init_state() override;
|
||||
|
||||
private:
|
||||
// NOTE TO SELF
|
||||
// Every USB MSG:
|
||||
// {ID: 0x07E0, Data: [0x00, 0x11, 0x22, 0x33]} = '#07E100112233\n'
|
||||
// Read msg size: 6 bytes: USB message size: 14 = (Read size *2) + 2
|
||||
char *read_buffer;
|
||||
char *write_buffer;
|
||||
uint16_t read_pos;
|
||||
bool clear_to_send = false;
|
||||
int data_size;
|
||||
int line_idx;
|
||||
int max_bytes_left;
|
||||
int to_read;
|
||||
size_t length;
|
||||
esp_err_t status;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Endpoint for ISO-TP communication with OBD readers
|
||||
*
|
||||
*/
|
||||
class CanEndpoint : public AbstractEndpoint
|
||||
{
|
||||
public:
|
||||
explicit CanEndpoint(EgsBaseCan *can_layer);
|
||||
void send_data(DiagMessage *msg) override;
|
||||
bool read_data(DiagMessage *dest) override;
|
||||
esp_err_t init_state() override;
|
||||
static void start_iso_tp(void *_this)
|
||||
{
|
||||
static_cast<CanEndpoint *>(_this)->iso_tp_server_loop();
|
||||
}
|
||||
|
||||
private:
|
||||
void process_single_frame(DiagCanMessage msg);
|
||||
void process_start_frame(DiagCanMessage msg);
|
||||
void process_multi_frame(DiagCanMessage msg);
|
||||
void process_flow_control(DiagCanMessage msg);
|
||||
|
||||
[[noreturn]] void iso_tp_server_loop();
|
||||
EgsBaseCan *can;
|
||||
QueueHandle_t rx_queue;
|
||||
// QueueHandle_t tx_queue;
|
||||
CanEndpointMsg tx_msg;
|
||||
CanEndpointMsg rx_msg;
|
||||
QueueHandle_t read_msg_queue;
|
||||
QueueHandle_t send_msg_queue;
|
||||
CanEndpointMsg tmp;
|
||||
bool is_sending;
|
||||
bool clear_to_send;
|
||||
bool is_receiving;
|
||||
uint8_t rx_bs;
|
||||
uint8_t tx_pci = 0x20;
|
||||
uint64_t last_rx_time;
|
||||
uint64_t last_tx_time;
|
||||
uint8_t tx_bs = 8;
|
||||
uint8_t tx_stmin = 20;
|
||||
uint8_t frames_received = 0;
|
||||
twai_message_t tx_can;
|
||||
uint8_t tx_count = 0;
|
||||
esp_err_t status;
|
||||
|
||||
bool send_to_twai(DiagCanMessage msg);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,90 @@
|
|||
#include "endpoint.h"
|
||||
|
||||
|
||||
const static char HEX_DEF[17] = "0123456789ABCDEF";
|
||||
const static size_t UART_MSG_SIZE = 6 + (2 * DIAG_CAN_MAX_SIZE);
|
||||
|
||||
UsbEndpoint::UsbEndpoint() : AbstractEndpoint()
|
||||
{
|
||||
data_size = 0;
|
||||
line_idx = 0;
|
||||
max_bytes_left = 0;
|
||||
to_read = 0;
|
||||
length = 0;
|
||||
this->status = uart_driver_install(0, UART_MSG_SIZE / 2u, UART_MSG_SIZE / 2u, 0, nullptr, 0);
|
||||
if (this->status == ESP_OK)
|
||||
{
|
||||
this->read_buffer = static_cast<char *>(heap_caps_malloc(UART_MSG_SIZE, MALLOC_CAP_SPIRAM));
|
||||
this->write_buffer = static_cast<char *>(heap_caps_malloc(UART_MSG_SIZE, MALLOC_CAP_SPIRAM));
|
||||
if (nullptr != this->read_buffer && nullptr != this->write_buffer)
|
||||
{
|
||||
uart_flush(0);
|
||||
this->read_pos = 0;
|
||||
} else {
|
||||
this->status = ESP_ERR_NO_MEM;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t UsbEndpoint::init_state() {
|
||||
return this->status;
|
||||
}
|
||||
|
||||
void UsbEndpoint::send_data(DiagMessage *msg)
|
||||
{
|
||||
this->write_buffer[0] = '#';
|
||||
this->write_buffer[1] = HEX_DEF[(msg->id >> 12) & 0x0F];
|
||||
this->write_buffer[2] = HEX_DEF[(msg->id >> 8) & 0x0F];
|
||||
this->write_buffer[3] = HEX_DEF[(msg->id >> 4) & 0x0F];
|
||||
this->write_buffer[4] = HEX_DEF[msg->id & 0x0F];
|
||||
for (uint16_t i = 0; i < msg->data_size; i++)
|
||||
{
|
||||
this->write_buffer[5 + (i * 2)] = HEX_DEF[(msg->data[i] >> 4) & 0x0F];
|
||||
this->write_buffer[6 + (i * 2)] = HEX_DEF[msg->data[i] & 0x0F];
|
||||
}
|
||||
this->write_buffer[(msg->data_size * 2) + 5] = '\n';
|
||||
uart_write_bytes(0, &this->write_buffer[0], (msg->data_size * 2) + 6);
|
||||
}
|
||||
|
||||
bool UsbEndpoint::read_data(DiagMessage *dest)
|
||||
{
|
||||
this->length = 0;
|
||||
uart_get_buffered_data_len(0, &length);
|
||||
if (length != 0)
|
||||
{
|
||||
max_bytes_left = UART_MSG_SIZE - this->read_pos;
|
||||
to_read = MIN(length, max_bytes_left);
|
||||
uart_read_bytes(0, &this->read_buffer[this->read_pos], to_read, 0);
|
||||
this->read_pos += length;
|
||||
return false;
|
||||
}
|
||||
else if (this->read_pos != 0)
|
||||
{
|
||||
if (this->read_pos < 5)
|
||||
{
|
||||
ESP_LOG_LEVEL(ESP_LOG_ERROR, "USBEndpoint", "Corrupt incoming msg. Less than 5 bytes");
|
||||
this->read_pos = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t read_size = (this->read_buffer[0] << 8) | this->read_buffer[1];
|
||||
if (read_size != this->read_pos - 2)
|
||||
{
|
||||
ESP_LOG_LEVEL(ESP_LOG_ERROR, "USBEndpoint", "Corrupt incoming msg. Msg size is %d bytes, buffer has %d bytes", read_size, this->read_pos - 2);
|
||||
this->read_pos = 0;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Valid msg!
|
||||
dest->id = (this->read_buffer[2] << 8) | this->read_buffer[3];
|
||||
dest->data_size = read_size - 2;
|
||||
memcpy(dest->data, &this->read_buffer[4], dest->data_size);
|
||||
this->read_pos = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
|
@ -146,19 +146,15 @@ Kwp2000_server::Kwp2000_server(EgsBaseCan* can_layer, Gearbox* gearbox) {
|
|||
// Init SPIRAM (We will need this!)
|
||||
this->next_tp_time = 0;
|
||||
this->session_mode = SESSION_DEFAULT;
|
||||
this->usb_diag_endpoint = new UsbEndpoint(true);
|
||||
this->usb_diag_endpoint = new UsbEndpoint();
|
||||
this->reboot_pending = false;
|
||||
this->can_layer = can_layer;
|
||||
this->gearbox_ptr = gearbox;
|
||||
if (can_layer != nullptr) {
|
||||
this->can_endpoint = new CanEndpoint(can_layer);
|
||||
this->can_endpoint = new CanEndpoint(can_layer);
|
||||
if (this->can_endpoint->init_state() == ESP_OK) {
|
||||
// Start ISO-TP endpoint
|
||||
xTaskCreatePinnedToCore(can_endpoint->start_iso_tp, "ISO_TP_DIAG", 8192, this->can_endpoint, 5, nullptr, 0);
|
||||
} else {
|
||||
this->can_endpoint = nullptr;
|
||||
this->can_layer = nullptr;
|
||||
}
|
||||
|
||||
this->supplier_id = 0x08;
|
||||
if (can_layer == nullptr || gearbox == nullptr) {
|
||||
this->diag_var_code = 0x0000;
|
||||
|
@ -168,7 +164,7 @@ Kwp2000_server::Kwp2000_server(EgsBaseCan* can_layer, Gearbox* gearbox) {
|
|||
this->diag_var_code = 0x0251;
|
||||
break;
|
||||
case 2:
|
||||
this->diag_var_code = 0x0251;
|
||||
this->diag_var_code = 0x0252;
|
||||
break;
|
||||
case 3:
|
||||
this->diag_var_code = 0x0353;
|
||||
|
@ -217,16 +213,15 @@ void Kwp2000_server::server_loop() {
|
|||
uint64_t timestamp = esp_timer_get_time()/1000;
|
||||
bool read_msg = false;
|
||||
bool endpoint_was_usb = false;
|
||||
if (this->usb_diag_endpoint->read_data(&this->rx_msg)) {
|
||||
if (this->usb_diag_endpoint->init_state() == ESP_OK && this->usb_diag_endpoint->read_data(&this->rx_msg)) {
|
||||
endpoint_was_usb = true;
|
||||
read_msg = true;
|
||||
} else if (this->can_endpoint != nullptr && this->can_endpoint->read_data(&this->rx_msg)) {
|
||||
} else if (this->can_endpoint->init_state() == ESP_OK && this->can_endpoint->read_data(&this->rx_msg)) {
|
||||
endpoint_was_usb = false;
|
||||
read_msg = true;
|
||||
}
|
||||
if (read_msg) {
|
||||
this->next_tp_time = timestamp+KWP_TP_TIMEOUT_MS;
|
||||
//ESP_LOG_BUFFER_HEX_LEVEL("KWP_READ_MSG", this->rx_msg.data, this->rx_msg.data_size, esp_log_level_t::ESP_LOG_INFO);
|
||||
if (this->rx_msg.data_size == 0) {
|
||||
continue; // Huh?
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#ifndef _KWP_H__
|
||||
#define _KWP_H__
|
||||
|
||||
#include "endpoint.h"
|
||||
#include "endpoints/endpoint.h"
|
||||
#include <stdint.h>
|
||||
#include "kwp2000_defines.h"
|
||||
#include "gearbox.h"
|
||||
|
|
|
@ -42,5 +42,5 @@ bool is_engine_off(EgsBaseCan* can) {
|
|||
bool is_shifter_passive(EgsBaseCan* can) {
|
||||
// Shifter must be Offline (SNV) or P or N
|
||||
ShifterPosition pos = can->get_shifter_position_ewm(esp_timer_get_time()/1000, 250);
|
||||
return (pos == ShifterPosition::N || pos == ShifterPosition::D || pos == ShifterPosition::SignalNotAvailable);
|
||||
return (pos == ShifterPosition::N || pos == ShifterPosition::P || pos == ShifterPosition::SignalNotAvailable);
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#ifndef __KWP_UTILS_H__
|
||||
#define __KWP_UTILS_H__
|
||||
|
||||
#include "endpoint.h"
|
||||
#include "endpoints/endpoint.h"
|
||||
#include "stdint.h"
|
||||
|
||||
// Couple of helpful functions
|
||||
|
|
|
@ -55,23 +55,23 @@ static void IRAM_ATTR cpu_load_interrupt(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
const static timer_config_t PERFORM_T_CONFIG = {
|
||||
.alarm_en = timer_alarm_t::TIMER_ALARM_EN,
|
||||
.counter_en = timer_start_t::TIMER_START,
|
||||
.intr_type = TIMER_INTR_LEVEL,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.auto_reload = timer_autoreload_t::TIMER_AUTORELOAD_EN,
|
||||
.divider = 80 /* 1 us per tick */
|
||||
};
|
||||
|
||||
esp_err_t init_perfmon(void)
|
||||
{
|
||||
if (!perfmon_running)
|
||||
{
|
||||
timer_config_t config = {
|
||||
.alarm_en = timer_alarm_t::TIMER_ALARM_EN,
|
||||
.counter_en = timer_start_t::TIMER_START,
|
||||
.intr_type = TIMER_INTR_LEVEL,
|
||||
.counter_dir = TIMER_COUNT_UP,
|
||||
.auto_reload = timer_autoreload_t::TIMER_AUTORELOAD_EN,
|
||||
.divider = 80 /* 1 us per tick */
|
||||
};
|
||||
|
||||
dest.load_core_1 = 0;
|
||||
dest.load_core_2 = 0;
|
||||
|
||||
ESP_RETURN_ON_ERROR(timer_init(TIMER_GROUP_0, TIMER_1, &config), "PERFMON", "Timer init failed");
|
||||
ESP_RETURN_ON_ERROR(timer_init(TIMER_GROUP_0, TIMER_1, &PERFORM_T_CONFIG), "PERFMON", "Timer init failed");
|
||||
ESP_RETURN_ON_ERROR(timer_set_counter_value(TIMER_GROUP_0, TIMER_1, 0), "PERFMON", "Set counter value failed");
|
||||
ESP_RETURN_ON_ERROR(timer_set_alarm_value(TIMER_GROUP_0, TIMER_1, LOAD_FETCH_INTERVAL_MS * 1000), "PERFMON", "Set alarm value failed");
|
||||
ESP_RETURN_ON_ERROR(timer_enable_intr(TIMER_GROUP_0, TIMER_1), "PERFMON", "Enable intr failed");
|
||||
|
|
|
@ -136,32 +136,14 @@ esp_err_t Gearbox::start_controller()
|
|||
|
||||
GearboxGear gear_from_idx(uint8_t idx)
|
||||
{
|
||||
// Only for drivable gears. P/R/SNV is never used
|
||||
GearboxGear ret = GearboxGear::SignalNotAvailable;
|
||||
switch (idx)
|
||||
{
|
||||
case 1:
|
||||
ret = GearboxGear::First;
|
||||
break;
|
||||
case 2:
|
||||
ret = GearboxGear::Second;
|
||||
break;
|
||||
case 3:
|
||||
ret = GearboxGear::Third;
|
||||
break;
|
||||
case 4:
|
||||
ret = GearboxGear::Fourth;
|
||||
break;
|
||||
case 5:
|
||||
ret = GearboxGear::Fifth;
|
||||
break;
|
||||
case 6:
|
||||
if (likely(idx >= 1 && idx <= 5)) {
|
||||
ret = (GearboxGear)(idx); // Direct cast for gears 1-5
|
||||
} else if (idx == 6) {
|
||||
ret = GearboxGear::Reverse_First;
|
||||
break;
|
||||
case 7:
|
||||
} else if (idx == 7) {
|
||||
ret = GearboxGear::Reverse_Second;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -227,47 +209,22 @@ void Gearbox::dec_gear_request()
|
|||
|
||||
GearboxGear next_gear(GearboxGear g)
|
||||
{
|
||||
switch (g)
|
||||
{
|
||||
case GearboxGear::First:
|
||||
return GearboxGear::Second;
|
||||
case GearboxGear::Second:
|
||||
return GearboxGear::Third;
|
||||
case GearboxGear::Third:
|
||||
return GearboxGear::Fourth;
|
||||
case GearboxGear::Fourth:
|
||||
return GearboxGear::Fifth;
|
||||
case GearboxGear::Park:
|
||||
case GearboxGear::SignalNotAvailable:
|
||||
case GearboxGear::Neutral:
|
||||
case GearboxGear::Reverse_First:
|
||||
case GearboxGear::Reverse_Second:
|
||||
default:
|
||||
return g;
|
||||
GearboxGear next = g;
|
||||
uint8_t idx = (uint8_t)g;
|
||||
if (idx < 5) { // 1-4
|
||||
next = (GearboxGear)(idx+1);
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
GearboxGear prev_gear(GearboxGear g)
|
||||
{
|
||||
switch (g)
|
||||
{
|
||||
case GearboxGear::Second:
|
||||
return GearboxGear::First;
|
||||
case GearboxGear::Third:
|
||||
return GearboxGear::Second;
|
||||
case GearboxGear::Fourth:
|
||||
return GearboxGear::Third;
|
||||
case GearboxGear::Fifth:
|
||||
return GearboxGear::Fourth;
|
||||
case GearboxGear::First:
|
||||
case GearboxGear::Park:
|
||||
case GearboxGear::SignalNotAvailable:
|
||||
case GearboxGear::Neutral:
|
||||
case GearboxGear::Reverse_First:
|
||||
case GearboxGear::Reverse_Second:
|
||||
default:
|
||||
return g;
|
||||
GearboxGear prev = g;
|
||||
uint8_t idx = (uint8_t)g;
|
||||
if (idx > 1 && idx <= 5) { // 2-5
|
||||
prev = (GearboxGear)(idx-1);
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
// int find_target_ratio(int targ_gear, FwdRatios ratios) {
|
||||
|
|
|
@ -173,17 +173,7 @@ uint16_t PressureManager::find_working_mpc_pressure(GearboxGear curr_g) {
|
|||
}
|
||||
|
||||
float PressureManager::get_tcc_temp_multiplier(int atf_temp) {
|
||||
if (atf_temp < 40) {
|
||||
return 1.0;
|
||||
} else if (atf_temp < 60) {
|
||||
return 1.2;
|
||||
} else if (atf_temp < 80) {
|
||||
return 1.4;
|
||||
} else if (atf_temp < 100) {
|
||||
return 1.6;
|
||||
} else {
|
||||
return 1.8;
|
||||
}
|
||||
return (float)scale_number(sensor_data->atf_temp, 100, 200, 40, 100) / 100.0;
|
||||
}
|
||||
|
||||
ShiftData PressureManager::get_shift_data(ProfileGearChange shift_request, ShiftCharacteristics chars, uint16_t curr_mpc) {
|
||||
|
@ -249,14 +239,16 @@ void PressureManager::make_fill_data(ShiftPhase* dest, ShiftCharacteristics char
|
|||
if (this->hold2_time_map == nullptr) {
|
||||
dest->hold_time = 500;
|
||||
dest->spc_pressure = 1500;
|
||||
dest->mpc_pressure = 750 + curr_mpc;
|
||||
} else {
|
||||
Clutch to_change = get_clutch_to_apply(change);
|
||||
Clutch to_release = get_clutch_to_release(change);
|
||||
dest->hold_time = hold2_time_map->get_value(this->sensor_data->atf_temp, (uint8_t)to_change);
|
||||
dest->spc_pressure = hold2_pressure_map->get_value(1, (uint8_t)to_change);
|
||||
dest->mpc_pressure = hold2_pressure_map->get_value(1, (uint8_t)to_release) + curr_mpc/2;
|
||||
}
|
||||
dest->ramp_time = 100;
|
||||
const AdaptationCell* cell = this->adapt_map->get_adapt_cell(sensor_data, change, this->gb_max_torque);
|
||||
dest->mpc_pressure = curr_mpc + dest->spc_pressure/2;
|
||||
//const AdaptationCell* cell = this->adapt_map->get_adapt_cell(sensor_data, change, this->gb_max_torque);
|
||||
}
|
||||
|
||||
void PressureManager::make_torque_and_overlap_data(ShiftPhase* dest_torque, ShiftPhase* dest_overlap, ShiftPhase* prev, ShiftCharacteristics chars, ProfileGearChange change, uint16_t curr_mpc) {
|
||||
|
@ -270,13 +262,13 @@ void PressureManager::make_torque_and_overlap_data(ShiftPhase* dest_torque, Shif
|
|||
dest_torque->ramp_time = (float)chars.target_shift_time*torque_ratio;
|
||||
dest_overlap->ramp_time = (float)chars.target_shift_time*overlap_ratio;
|
||||
|
||||
dest_torque->mpc_pressure = prev->mpc_pressure; // Torque phase mpc pressure drop to 500 to initiate the release
|
||||
dest_overlap->mpc_pressure = prev->mpc_pressure; //hold2_pressure_map->get_value(1, (uint8_t)get_clutch_to_release(change)); // Ramp up MPC in overlap to control the release
|
||||
dest_torque->mpc_pressure = prev->mpc_pressure; // Torque MPC stays same
|
||||
dest_overlap->mpc_pressure = hold2_pressure_map->get_value(1, (uint8_t)get_clutch_to_release(change)); // Reduce MPC to just apply pressure
|
||||
|
||||
uint16_t spc_addr = MAX(100, abs(sensor_data->static_torque)*2.5); // 2.5mBar per Nm
|
||||
uint16_t spc_addr = MAX(50, abs(sensor_data->static_torque)*2); // 2mBar per Nm
|
||||
|
||||
dest_torque->spc_pressure = prev->mpc_pressure+spc_addr;
|
||||
dest_overlap->spc_pressure = dest_torque->spc_pressure + spc_addr*2;
|
||||
dest_torque->spc_pressure = prev->mpc_pressure; // Same as MPC (Begin torque transfer)
|
||||
dest_overlap->spc_pressure = dest_torque->spc_pressure + spc_addr; // SPC lock into place clutch for overlap phase
|
||||
}
|
||||
|
||||
void PressureManager::make_max_p_data(ShiftPhase* dest, ShiftPhase* prev, ShiftCharacteristics chars, ProfileGearChange change, uint16_t curr_mpc) {
|
||||
|
|
|
@ -41,42 +41,40 @@ bool output_rpm_ok = false;
|
|||
static void IRAM_ATTR on_pcnt_overflow_n2(void *args)
|
||||
{
|
||||
t_n2 = esp_timer_get_time();
|
||||
if (t_n2 - n2_intr_times[1] < 10)
|
||||
if (t_n2 - n2_intr_times[1] > 10)
|
||||
{
|
||||
return;
|
||||
portENTER_CRITICAL_ISR(&n2_mux);
|
||||
n2_intr_times[0] = n2_intr_times[1];
|
||||
n2_intr_times[1] = t_n2;
|
||||
portEXIT_CRITICAL_ISR(&n2_mux);
|
||||
}
|
||||
portENTER_CRITICAL_ISR(&n2_mux);
|
||||
n2_intr_times[0] = n2_intr_times[1];
|
||||
n2_intr_times[1] = t_n2;
|
||||
portEXIT_CRITICAL_ISR(&n2_mux);
|
||||
|
||||
}
|
||||
|
||||
static void IRAM_ATTR on_pcnt_overflow_n3(void *args)
|
||||
{
|
||||
t_n3 = esp_timer_get_time();
|
||||
if (t_n3 - n3_intr_times[1] < 10)
|
||||
if (t_n3 - n3_intr_times[1] > 10)
|
||||
{
|
||||
return;
|
||||
portENTER_CRITICAL_ISR(&n3_mux);
|
||||
n3_intr_times[0] = n3_intr_times[1];
|
||||
n3_intr_times[1] = t_n3;
|
||||
portEXIT_CRITICAL_ISR(&n3_mux);
|
||||
}
|
||||
portENTER_CRITICAL_ISR(&n3_mux);
|
||||
n3_intr_times[0] = n3_intr_times[1];
|
||||
n3_intr_times[1] = t_n3;
|
||||
portEXIT_CRITICAL_ISR(&n3_mux);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR on_pcnt_overflow_output(void* args) {
|
||||
t_output = esp_timer_get_time();
|
||||
if (t_output - output_intr_times[1] < 10) {
|
||||
return;
|
||||
if (t_output - output_intr_times[1] > 10) {
|
||||
portENTER_CRITICAL_ISR(&output_mux);
|
||||
output_intr_times[0] = output_intr_times[1];
|
||||
output_intr_times[1] = t_output;
|
||||
portEXIT_CRITICAL_ISR(&output_mux);
|
||||
}
|
||||
portENTER_CRITICAL_ISR(&output_mux);
|
||||
output_intr_times[0] = output_intr_times[1];
|
||||
output_intr_times[1] = t_output;
|
||||
portEXIT_CRITICAL_ISR(&output_mux);
|
||||
}
|
||||
|
||||
esp_err_t Sensors::init_sensors(){
|
||||
pcnt_config_t pcnt_cfg_n2{
|
||||
const pcnt_config_t pcnt_cfg_n2{
|
||||
.pulse_gpio_num = pcb_gpio_matrix->n2_pin,
|
||||
.ctrl_gpio_num = PCNT_PIN_NOT_USED,
|
||||
.lctrl_mode = PCNT_MODE_KEEP,
|
||||
|
@ -88,7 +86,7 @@ esp_err_t Sensors::init_sensors(){
|
|||
.unit = PCNT_N2_RPM,
|
||||
.channel = PCNT_CHANNEL_0};
|
||||
|
||||
pcnt_config_t pcnt_cfg_n3{
|
||||
const pcnt_config_t pcnt_cfg_n3{
|
||||
.pulse_gpio_num = pcb_gpio_matrix->n3_pin,
|
||||
.ctrl_gpio_num = PCNT_PIN_NOT_USED,
|
||||
.lctrl_mode = PCNT_MODE_KEEP,
|
||||
|
|
|
@ -153,7 +153,7 @@ int16_t *StoredTcuMap::get_current_eeprom_map_data(void)
|
|||
if (nullptr != dest)
|
||||
{
|
||||
succesful_allocation = true;
|
||||
if (!EEPROM::read_nvs_map_data(this->map_name, dest, this->default_map, this->map_element_count))
|
||||
if (EEPROM::read_nvs_map_data(this->map_name, dest, this->default_map, this->map_element_count) != ESP_OK)
|
||||
{
|
||||
heap_caps_free(dest);
|
||||
succesful_allocation = false;
|
||||
|
|
Loading…
Reference in New Issue