big refactoring: J1939, log output, state machine bug fixes

This commit is contained in:
2026-05-07 22:12:13 +03:00
parent 137c9d3c8d
commit 7a74ef1367
49 changed files with 2574 additions and 684 deletions
Executable → Regular
+155 -199
View File
@@ -1,226 +1,182 @@
/*
* debug.c
*
* Created on: Apr 16, 2024
* Author: colorbass
*/
#include "main.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include "debug.h"
#include "board.h"
#include "charger_gbt.h"
#include "serial_control.h"
#include "usart.h"
#include <time.h>
#include <connector.h>
#define DEBUG_BUFFER_SIZE 1024
#define DEBUG_BUFFER_MAX_COUNT 128
#define LOG_BUFFER_SIZE 128
uint8_t debug_rx_buffer[256];
uint8_t debug_cmd_received;
uint8_t debug_rx_buffer_size = 0;
typedef struct {
uint8_t buffer[DEBUG_BUFFER_SIZE];
volatile uint16_t write_index;
volatile uint16_t read_index;
volatile uint16_t count;
} DebugBuffer_t;
extern UART_HandleTypeDef huart2;
static DebugBuffer_t debug_buffer = {
.buffer = {0},
.write_index = 0,
.read_index = 0,
.count = 0
};
static uint8_t log_buffer[LOG_BUFFER_SIZE];
static void debug_uart1_write(const uint8_t *data, uint16_t len)
{
/* Best-effort debug mirror to USART1 (PA9/PA10), safe for IRQ context. */
for (uint16_t i = 0; i < len; i++) {
uint32_t timeout = 10000U;
while (((USART1->SR & USART_SR_TXE) == 0U) && (timeout > 0U)) {
timeout--;
}
if (timeout == 0U) {
return;
}
USART1->DR = data[i];
}
}
#if defined(__GNUC__)
int _write(int fd, char * ptr, int len)
{
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, 1);
HAL_UART_Transmit(&huart2, (uint8_t *) ptr, len, HAL_MAX_DELAY);
HAL_GPIO_WritePin(USART2_DIR_GPIO_Port, USART2_DIR_Pin, 0);
(void)fd;
debug_buffer_add((const uint8_t*)ptr, (uint16_t)len);
return len;
}
#endif
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size){
// if(huart->Instance == USART1){
// mm_rx_interrupt(huart, Size);
// }
if(huart->Instance == USART2){
debug_rx_interrupt(huart, Size);
void debug_buffer_add(const uint8_t* data, uint16_t len)
{
debug_uart1_write(data, len);
__disable_irq();
for (uint16_t i = 0; i < len; i++) {
if (debug_buffer.count >= DEBUG_BUFFER_SIZE) {
debug_buffer.read_index = (debug_buffer.read_index + 1U) % DEBUG_BUFFER_SIZE;
debug_buffer.count--;
}
debug_buffer.buffer[debug_buffer.write_index] = data[i];
debug_buffer.write_index = (debug_buffer.write_index + 1U) % DEBUG_BUFFER_SIZE;
debug_buffer.count++;
}
__enable_irq();
}
void debug_rx_interrupt(UART_HandleTypeDef *huart, uint16_t Size){
debug_rx_buffer[Size] = '\0';
debug_rx_buffer_size = Size;
debug_cmd_received = 1;
uint16_t debug_buffer_available(void)
{
__disable_irq();
uint16_t count = debug_buffer.count;
__enable_irq();
return count;
}
void debug_init(){
HAL_UARTEx_ReceiveToIdle_IT(&huart2,debug_rx_buffer,255);
//mm_schedule_write(0x01, 0x0000, 0x0800);
// mm_schedule_write(0x02, 0x00FF, 0xFFFF);
//for (int i=0;i<60;i++)
// mm_schedule_write(0x02, 0x0000, 0xFF00);
// mm_schedule_write(0x01, 0x0000, 0x0100);
// mm_schedule_write(0x01, 0x0000, 0x0100);
}
void parse_command(uint8_t* buffer, size_t length) {
// ignore \r \n symbols
size_t i = 0;
for (i = 0; i < length; i++) {
if (buffer[i] == '\r' || buffer[i] == '\n') {
buffer[i] = '\0';
length = i;
break;
}
}
if (buffer[0] == 0) return;
if (strncmp((const char*)buffer, "reset", length) == 0) {
printf("Resetting...\n");
NVIC_SystemReset();
} else if (strncmp((const char*)buffer, "relayaux", length) == 0) {
printf("Relaying...\n");
RELAY_Write(RELAY_1, 1);
HAL_Delay(200);
RELAY_Write(RELAY_1, 0);
} else if (strncmp((const char*)buffer, "relaycc", length) == 0) {
printf("Relaying...\n");
RELAY_Write(RELAY_CC, 1);
HAL_Delay(200);
RELAY_Write(RELAY_CC, 0);
// } else if (strncmp((const char*)buffer, "voltage", length) == 0) {
// printf("Voltaging...\n");
// mm_schedule_read(0x02, 0x0001);
} else if (strncmp((const char*)buffer, "adc", length) == 0) {
printf("CC1=%.2f\n", CONN_CC_GetAdc());
// } else if (strncmp((const char*)buffer, "lock_state", length) == 0) {
// printf("AUX/Lock state=%d\n", GBT_LockGetState());
} else if (strncmp((const char*)buffer, "complete", length) == 0) {
CONN_SetState(Finished);
} else if (strncmp((const char*)buffer, "start", length) == 0) {
printf("Started\n");
GBT_SwitchState(GBT_EV_CONNECTING);
} else if (strncmp((const char*)buffer, "stop", length) == 0) {
printf("Stopped\n");
GBT_StopEVSE(GBT_CST_SUSPENDS_ARTIFICIALLY);
} else if (strncmp((const char*)buffer, "stop1", length) == 0) {
printf("Stopped\n");
GBT_ForceStop();
// } else if (strncmp((const char*)buffer, "force", length) == 0) {
// printf("Stopped\n");
// GBT_Lock(1);
// GBT_SwitchState(GBT_S2_LOCKED);
// GBT_Delay(500);
} else if (strncmp((const char*)buffer, "cc_state", length) == 0) {
switch(CONN_CC_GetState()){
case GBT_CC_UNKNOWN:
printf("GBT_CC_UNKNOWN\n");
break;
case GBT_CC_12V:
printf("GBT_CC_12V\n");
break;
case GBT_CC_6V:
printf("GBT_CC_6V\n");
break;
case GBT_CC_4V:
printf("GBT_CC_4V\n");
break;
case GBT_CC_2V:
printf("GBT_CC_2V\n");
break;
}
} else if (strncmp((const char*)buffer, "temp", length) == 0) {
printf("temp1 %d\n",GBT_ReadTemp(0));
printf("temp2 %d\n",GBT_ReadTemp(1));
} else if (strncmp((const char*)buffer, "info1", length) == 0) {
printf("Battery info:\n");
printf("maxCV %dV\n",GBT_BATStat.maxCellVoltage/100); // 0.01v/bit
printf("maxCC %dA\n",GBT_BATStat.maxChargingCurrent/10); // 0.1A/bit
printf("totE %dkWh\n",GBT_BATStat.totalEnergy/10); // 0.1kWh
printf("maxCV %dV\n",GBT_BATStat.maxChargingVoltage/10); // 0.1V/ bit
printf("maxT %dC\n",(int16_t)GBT_BATStat.maxTemp-50); // 1C/bit, -50C offset
printf("SOC %dp\n",GBT_BATStat.SOC/10); // 0.1%/bit , 0..100%
printf("Volt. %dV\n",GBT_BATStat.measVoltage/10); // 0.1V/bit
} else if (strncmp((const char*)buffer, "info2", length) == 0) {
printf("EV info:\n");
printf("GBT_ver V%d.%d%d\n",GBT_EVInfo.version[0],GBT_EVInfo.version[1],GBT_EVInfo.version[2]);
printf("Battery type: %d\n",GBT_EVInfo.batteryType);
printf("Battery capacity: %d\n", GBT_EVInfo.batteryCapacity); // 0.1Ah/bit
printf("Battery voltage: %d\n", GBT_EVInfo.batteryVoltage); // 0.1V/bit
printf("Battery vendor: %.4s\n", GBT_EVInfo.batteryVendor); // Battery vendor (ASCII string)
printf("Battery SN: %lu\n", GBT_EVInfo.batterySN); // int
printf("Battery manufacture date: %02d.%02d.%04d\n", GBT_EVInfo.batteryManuD, GBT_EVInfo.batteryManuM ,GBT_EVInfo.batteryManuY+1985); // year (offset 1985)
printf("Battery cycles: %d\n", GBT_EVInfo.batteryCycleCount); //uint24_t
printf("Own auto: %d\n", GBT_EVInfo.ownAuto); // 0 = lizing, 1 = own auto
printf("EVIN: %.17s\n", GBT_EVInfo.EVIN); //EVIN
printf("EV_SW_VER: %.8s\n", GBT_EVInfo.EV_SW_VER);
} else if (strncmp((const char*)buffer, "info3", length) == 0) {
printf("GBT_MaxLoad info:\n");
printf("Output max current: %d\n",GBT_MaxLoad.maxOutputCurrent);
printf("Output min current: %d\n",GBT_MaxLoad.minOutputCurrent);
printf("Output max voltage: %d\n",GBT_MaxLoad.maxOutputVoltage);
printf("Output min voltage: %d\n",GBT_MaxLoad.minOutputVoltage);
printf("\nGBT_ChargerInfo info:\n");
printf("BMS Recognized: %d\n",GBT_ChargerInfo.bmsIdentified);
printf("Charger location: %.3s\n",GBT_ChargerInfo.chargerLocation);
printf("Charger number: %lu\n",GBT_ChargerInfo.chargerNumber);
} else if (strncmp((const char*)buffer, "help", length) == 0) {
printf("Command list:\n");
printf("reset\n");
printf("help\n");
printf("cc_state\n");
printf("lock_state\n");
printf("adc\n");
printf("relay(cc,aux)\n");
printf("start\n");
printf("stop\n");
printf("stop1\n");
// printf("force\n");
printf("temp\n");
printf("info1\n");
printf("info2\n");
printf("info3\n");
printf("time\n");
printf("cantest\n");
//TODO: info commands
} else if (strncmp((const char*)buffer, "time", length) == 0) {
time_t unix_time = (time_t)get_Current_Time();
struct tm *parts = localtime(&unix_time);
printf("Year: %d\n", parts->tm_year + 1900);
printf("Month: %d\n", parts->tm_mon + 1);
printf("Day: %d\n", parts->tm_mday);
printf("Hour: %d\n", parts->tm_hour);
printf("Minute: %d\n", parts->tm_min);
printf("Second: %d\n", parts->tm_sec);
} else if (strncmp((const char*)buffer, "cantest", length) == 0) {
//GBT_SendCHM();
GBT_Error(0xFDF0C0FC); //BRM Timeout
printf("can test\n");
} else {
printf("Unknown command\n");
}
}
void debug_task(){
if(debug_cmd_received){
parse_command(debug_rx_buffer, debug_rx_buffer_size);
HAL_UARTEx_ReceiveToIdle_IT(&huart2,debug_rx_buffer,255);
debug_cmd_received = 0;
void debug_buffer_send(void)
{
__disable_irq();
if (debug_buffer.count == 0U) {
__enable_irq();
return;
}
uint16_t bytes_to_send = debug_buffer.count;
if (bytes_to_send > DEBUG_BUFFER_MAX_COUNT) {
bytes_to_send = DEBUG_BUFFER_MAX_COUNT;
}
uint16_t bytes_to_end = DEBUG_BUFFER_SIZE - debug_buffer.read_index;
if (bytes_to_send > bytes_to_end) {
bytes_to_send = bytes_to_end;
}
if (bytes_to_send == debug_buffer.count) {
SC_SendPacket(&debug_buffer.buffer[debug_buffer.read_index], bytes_to_send, CMD_GET_LOG);
} else {
SC_SendPacket(&debug_buffer.buffer[debug_buffer.read_index], bytes_to_send, CMD_GET_LOG_CONTINUE);
}
debug_buffer.read_index = (debug_buffer.read_index + bytes_to_send) % DEBUG_BUFFER_SIZE;
debug_buffer.count -= bytes_to_send;
__enable_irq();
}
int log_printf(int level, const char *format, ...)
{
va_list args;
int result;
const char *tag;
int written;
EDCAN_LogLevel_t current_level;
EDCAN_LogLevel_t msg_level;
if(level < LOG_EMERG || level > LOG_DEBUG){
return 0;
}
msg_level = (EDCAN_LogLevel_t)level;
current_level = EDCAN_GetLogLevel();
if(msg_level > current_level){
return 0;
}
switch(level){
case LOG_EMERG:
tag = "[EMR] ";
break;
case LOG_ALERT:
tag = "[ALT] ";
break;
case LOG_CRIT:
tag = "[CRT] ";
break;
case LOG_ERR:
tag = "[ERR] ";
break;
case LOG_WARN:
tag = "[WRN] ";
break;
case LOG_NOTICE:
tag = "[NTC] ";
break;
case LOG_INFO:
tag = "[INF] ";
break;
case LOG_DEBUG:
tag = "[DBG] ";
break;
default:
tag = "[LOG] ";
break;
}
log_buffer[0] = (uint8_t)level;
written = snprintf((char*)&log_buffer[1], LOG_BUFFER_SIZE - 2, "EV %s", tag);
if(written < 0){
return written;
}
if(written >= (LOG_BUFFER_SIZE - 2)){
written = LOG_BUFFER_SIZE - 2;
}
va_start(args, format);
result = vsnprintf((char*)&log_buffer[1 + written], LOG_BUFFER_SIZE - 2 - written, format, args);
va_end(args);
if (result < 0) {
return result;
}
if (result >= (LOG_BUFFER_SIZE - 2 - written)) {
result = LOG_BUFFER_SIZE - 2 - written;
}
log_buffer[1 + written + result] = '\0';
debug_buffer_add(log_buffer, (uint16_t)(2 + written + result));
return result + written;
}