Modify & transmit params via CAN
This commit is contained in:
parent
a5f10be4fd
commit
253b10ba15
|
@ -5,8 +5,14 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
CountedEnum(ParamType, size_t, PF_BBAL, PF_TC1, PF_TC2, PF_TORQUEMAP, PF_TEST1,
|
||||||
|
PF_TEST2, PF_TEST3, PF_TEST4);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float bbal;
|
float bbal;
|
||||||
unsigned tc1;
|
unsigned tc1;
|
||||||
|
@ -17,6 +23,11 @@ typedef struct {
|
||||||
|
|
||||||
extern Params params;
|
extern Params params;
|
||||||
|
|
||||||
|
void params_init();
|
||||||
|
void params_inc(ParamType param);
|
||||||
|
void params_dec(ParamType param);
|
||||||
|
void params_broadcast(ParamType param);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef INC_UTIL_H
|
||||||
|
#define INC_UTIL_H
|
||||||
|
|
||||||
|
// This is wacky preprocessor magic that allows us to count the number of
|
||||||
|
// members of an enum. Unfortunately, it doesn't work with enum classes, so we
|
||||||
|
// have to use C-style enums.
|
||||||
|
#define CountedEnum(NAME, TYPE, ...) \
|
||||||
|
typedef enum { __VA_ARGS__ } NAME; \
|
||||||
|
static const size_t NAME##_COUNT = sizeof((int[]){__VA_ARGS__}) / sizeof(int);
|
||||||
|
|
||||||
|
#endif // INC_UTIL_H
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __INC_VEHICLE_H
|
#ifndef __INC_VEHICLE_H
|
||||||
#define __INC_VEHICLE_H
|
#define __INC_VEHICLE_H
|
||||||
|
|
||||||
|
#include "params.h"
|
||||||
#include "stw_defines.h"
|
#include "stw_defines.h"
|
||||||
#include "tx_port.h"
|
#include "tx_port.h"
|
||||||
|
|
||||||
|
@ -106,6 +107,8 @@ void vehicle_thread_entry(ULONG hfdcan_addr);
|
||||||
|
|
||||||
void vehicle_select_mission(Mission mission);
|
void vehicle_select_mission(Mission mission);
|
||||||
|
|
||||||
|
void vehicle_broadcast_param(ParamType param, int32_t value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "ft_logo_rainbow_rgb565.h"
|
#include "ft_logo_rainbow_rgb565.h"
|
||||||
#include "hx8357d.h"
|
#include "hx8357d.h"
|
||||||
#include "leds.h"
|
#include "leds.h"
|
||||||
|
#include "params.h"
|
||||||
#include "shorttimer.h"
|
#include "shorttimer.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -144,6 +145,7 @@ int main(void) {
|
||||||
if (HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4) != HAL_OK) {
|
if (HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4) != HAL_OK) {
|
||||||
Error_Handler();
|
Error_Handler();
|
||||||
}
|
}
|
||||||
|
params_init();
|
||||||
shorttimer_init(htim_us);
|
shorttimer_init(htim_us);
|
||||||
led_init(&hspi3, &htim1);
|
led_init(&hspi3, &htim1);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,118 @@
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
|
#include "can-halal.h"
|
||||||
|
#include "vehicle.h"
|
||||||
|
|
||||||
Params params = {0};
|
Params params = {0};
|
||||||
|
|
||||||
|
void params_init() { params.bbal = 50; }
|
||||||
|
|
||||||
|
void params_inc(ParamType param) {
|
||||||
|
switch (param) {
|
||||||
|
case PF_BBAL:
|
||||||
|
params.bbal += 0.5f;
|
||||||
|
if (params.bbal > 100.0f) {
|
||||||
|
params.bbal = 100.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TC1:
|
||||||
|
params.tc1++;
|
||||||
|
break;
|
||||||
|
case PF_TC2:
|
||||||
|
params.tc2++;
|
||||||
|
break;
|
||||||
|
case PF_TORQUEMAP:
|
||||||
|
params.torque_map++;
|
||||||
|
break;
|
||||||
|
case PF_TEST1:
|
||||||
|
params.test[0]++;
|
||||||
|
break;
|
||||||
|
case PF_TEST2:
|
||||||
|
params.test[1]++;
|
||||||
|
break;
|
||||||
|
case PF_TEST3:
|
||||||
|
params.test[2]++;
|
||||||
|
break;
|
||||||
|
case PF_TEST4:
|
||||||
|
params.test[3]++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void params_dec(ParamType param) {
|
||||||
|
switch (param) {
|
||||||
|
case PF_BBAL:
|
||||||
|
params.bbal -= 0.5f;
|
||||||
|
if (params.bbal < 0.0f) {
|
||||||
|
params.bbal = 0.0f;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TC1:
|
||||||
|
if (params.tc1 > 0) {
|
||||||
|
params.tc1--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TC2:
|
||||||
|
if (params.tc2 > 0) {
|
||||||
|
params.tc2--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TORQUEMAP:
|
||||||
|
if (params.torque_map > 0) {
|
||||||
|
params.torque_map--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TEST1:
|
||||||
|
if (params.test[0] > 0) {
|
||||||
|
params.test[0]--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TEST2:
|
||||||
|
if (params.test[1] > 0) {
|
||||||
|
params.test[1]--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TEST3:
|
||||||
|
if (params.test[2] > 0) {
|
||||||
|
params.test[2]--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PF_TEST4:
|
||||||
|
if (params.test[3] > 0) {
|
||||||
|
params.test[3]--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void params_broadcast(ParamType param) {
|
||||||
|
int32_t value;
|
||||||
|
switch (param) {
|
||||||
|
case PF_BBAL:
|
||||||
|
value = params.bbal * 10;
|
||||||
|
break;
|
||||||
|
case PF_TC1:
|
||||||
|
value = params.tc1;
|
||||||
|
break;
|
||||||
|
case PF_TC2:
|
||||||
|
value = params.tc2;
|
||||||
|
break;
|
||||||
|
case PF_TORQUEMAP:
|
||||||
|
value = params.torque_map;
|
||||||
|
break;
|
||||||
|
case PF_TEST1:
|
||||||
|
value = params.test[0];
|
||||||
|
break;
|
||||||
|
case PF_TEST2:
|
||||||
|
value = params.test[1];
|
||||||
|
break;
|
||||||
|
case PF_TEST3:
|
||||||
|
value = params.test[2];
|
||||||
|
break;
|
||||||
|
case PF_TEST4:
|
||||||
|
value = params.test[3];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
vehicle_broadcast_param(param, value);
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#define CAN_ID_AMS_STATUS 0xA
|
#define CAN_ID_AMS_STATUS 0xA
|
||||||
#define CAN_ID_MISSION_SELECTED 0x400
|
#define CAN_ID_MISSION_SELECTED 0x400
|
||||||
|
#define CAN_ID_STW_PARAM_SET 0x402
|
||||||
#define CAN_ID_AS_MISSION_FB 0x410
|
#define CAN_ID_AS_MISSION_FB 0x410
|
||||||
#define CAN_ID_STW_STATUS 0x412
|
#define CAN_ID_STW_STATUS 0x412
|
||||||
#define CAN_ID_SHUNT_CURRENT 0x521
|
#define CAN_ID_SHUNT_CURRENT 0x521
|
||||||
|
@ -33,8 +34,6 @@ void vehicle_thread_entry(ULONG hfdcan_addr) {
|
||||||
ftcan_add_filter(CAN_ID_SHUNT_VOLTAGE3, 0x7FF);
|
ftcan_add_filter(CAN_ID_SHUNT_VOLTAGE3, 0x7FF);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
uint8_t data[] = {0xFF, 0xEE};
|
|
||||||
ftcan_transmit(0x456, data, 2);
|
|
||||||
tx_thread_sleep(10);
|
tx_thread_sleep(10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +43,14 @@ void vehicle_select_mission(Mission mission) {
|
||||||
ftcan_transmit(CAN_ID_MISSION_SELECTED, &mission_int, 1);
|
ftcan_transmit(CAN_ID_MISSION_SELECTED, &mission_int, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vehicle_broadcast_param(ParamType param, int32_t value) {
|
||||||
|
uint8_t data[5];
|
||||||
|
uint8_t *ptr = data;
|
||||||
|
ptr = ftcan_marshal_unsigned(ptr, param, 1);
|
||||||
|
ptr = ftcan_marshal_signed(ptr, value, 4);
|
||||||
|
ftcan_transmit(CAN_ID_STW_PARAM_SET, data, 5);
|
||||||
|
}
|
||||||
|
|
||||||
void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data) {
|
void ftcan_msg_received_cb(uint16_t id, size_t datalen, const uint8_t *data) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case CAN_ID_AMS_STATUS:
|
case CAN_ID_AMS_STATUS:
|
||||||
|
|
|
@ -6,13 +6,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// We want to automatically count the number of data field types for the
|
#include "util.h"
|
||||||
// description array. This is wacky preprocessor magic that allows us to do just
|
|
||||||
// that. Unfortunately, it doesn't work with enum classes, so we have to use
|
|
||||||
// C-style enums.
|
|
||||||
#define CountedEnum(NAME, TYPE, ...) \
|
|
||||||
enum NAME : TYPE { __VA_ARGS__ }; \
|
|
||||||
constexpr size_t NAME##_COUNT = sizeof((int[]){__VA_ARGS__}) / sizeof(int);
|
|
||||||
|
|
||||||
CountedEnum(DataFieldType, size_t, DF_TSState, DF_ASState, DF_ActiveMission,
|
CountedEnum(DataFieldType, size_t, DF_TSState, DF_ASState, DF_ActiveMission,
|
||||||
DF_R2DProgress, DF_INVLReady, DF_INVRReady, DF_SDC, DF_ERR,
|
DF_R2DProgress, DF_INVLReady, DF_INVRReady, DF_SDC, DF_ERR,
|
||||||
|
@ -20,8 +14,6 @@ CountedEnum(DataFieldType, size_t, DF_TSState, DF_ASState, DF_ActiveMission,
|
||||||
DF_TireTempRL, DF_TireTempRR, DF_MinCellVolt, DF_MaxCellTemp,
|
DF_TireTempRL, DF_TireTempRR, DF_MinCellVolt, DF_MaxCellTemp,
|
||||||
DF_TSSoC, DF_LVSoC, DF_TSCurrent, DF_TSVoltageBat, DF_TSVoltageVeh,
|
DF_TSSoC, DF_LVSoC, DF_TSCurrent, DF_TSVoltageBat, DF_TSVoltageVeh,
|
||||||
DF_Speed, DF_BBal);
|
DF_Speed, DF_BBal);
|
||||||
CountedEnum(ParamFieldType, size_t, PF_BBAL, PF_TC1, PF_TC2, PF_TORQUEMAP,
|
|
||||||
PF_TEST1, PF_TEST2, PF_TEST3, PF_TEST4);
|
|
||||||
|
|
||||||
enum class NamedFieldKind { Float, Bool, Text, Int };
|
enum class NamedFieldKind { Float, Bool, Text, Int };
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
#include "gui/common/NamedField.hpp"
|
#include "gui/common/NamedField.hpp"
|
||||||
#include <gui_generated/containers/ConfigItemBase.hpp>
|
#include <gui_generated/containers/ConfigItemBase.hpp>
|
||||||
|
|
||||||
class ConfigItem : public ConfigItemBase, public NamedField<ParamFieldType> {
|
#include "params.h"
|
||||||
|
|
||||||
|
class ConfigItem : public ConfigItemBase, public NamedField<ParamType> {
|
||||||
public:
|
public:
|
||||||
ConfigItem();
|
ConfigItem();
|
||||||
virtual ~ConfigItem() {}
|
virtual ~ConfigItem() {}
|
||||||
|
|
|
@ -278,6 +278,35 @@ static_assert(sizeof(dataFieldDescs) / sizeof(dataFieldDescs[0]) ==
|
||||||
|
|
||||||
#define PARAM_FIELD(FIELD) []() { return (void *)¶ms.FIELD; }
|
#define PARAM_FIELD(FIELD) []() { return (void *)¶ms.FIELD; }
|
||||||
|
|
||||||
|
void inc_bbal(void *valPtr) {
|
||||||
|
// float *val = (float *)valPtr;
|
||||||
|
// *val += 0.1f;
|
||||||
|
// if (*val > 100.0f) {
|
||||||
|
// *val = 100.0f;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void dec_bbal(void *valPtr) {
|
||||||
|
// float *val = (float *)valPtr;
|
||||||
|
// *val -= 0.1f;
|
||||||
|
// if (*val < 0.0f) {
|
||||||
|
// *val = 0.0f;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
void inc_int(void *valPtr) {
|
||||||
|
// int *val = (int *)valPtr;
|
||||||
|
// *val += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dec_int(void *valPtr) {
|
||||||
|
// int *val = (int *)valPtr;
|
||||||
|
// *val -= 1;
|
||||||
|
// if (*val < 0) {
|
||||||
|
// *val = 0;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
NamedFieldDescription paramFieldDescs[] = {
|
NamedFieldDescription paramFieldDescs[] = {
|
||||||
[PF_BBAL] = {NamedFieldKind::Float, "BBAL", 2, 1, PARAM_FIELD(bbal)},
|
[PF_BBAL] = {NamedFieldKind::Float, "BBAL", 2, 1, PARAM_FIELD(bbal)},
|
||||||
[PF_TC1] = {NamedFieldKind::Int, "TC1", 2, 0, PARAM_FIELD(tc1)},
|
[PF_TC1] = {NamedFieldKind::Int, "TC1", 2, 0, PARAM_FIELD(tc1)},
|
||||||
|
@ -291,7 +320,7 @@ NamedFieldDescription paramFieldDescs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert(sizeof(paramFieldDescs) / sizeof(paramFieldDescs[0]) ==
|
static_assert(sizeof(paramFieldDescs) / sizeof(paramFieldDescs[0]) ==
|
||||||
ParamFieldType_COUNT,
|
ParamType_COUNT,
|
||||||
"Incorrect number of param field descriptions");
|
"Incorrect number of param field descriptions");
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -383,4 +412,4 @@ template <class T> void NamedField<T>::updateValueBuffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template class NamedField<DataFieldType>;
|
template class NamedField<DataFieldType>;
|
||||||
template class NamedField<ParamFieldType>;
|
template class NamedField<ParamType>;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "gui/common/NamedField.hpp"
|
#include "gui/common/NamedField.hpp"
|
||||||
#include "gui/containers/ConfigItem.hpp"
|
#include "gui/containers/ConfigItem.hpp"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "params.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <gui/vehicleconfig_screen/VehicleConfigView.hpp>
|
#include <gui/vehicleconfig_screen/VehicleConfigView.hpp>
|
||||||
|
|
||||||
|
@ -8,7 +9,7 @@ VehicleConfigView::VehicleConfigView() : selectedParam{0} {}
|
||||||
|
|
||||||
void VehicleConfigView::setupScreen() {
|
void VehicleConfigView::setupScreen() {
|
||||||
VehicleConfigViewBase::setupScreen();
|
VehicleConfigViewBase::setupScreen();
|
||||||
params.setNumberOfItems(ParamFieldType_COUNT);
|
params.setNumberOfItems(ParamType_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleConfigView::tearDownScreen() {
|
void VehicleConfigView::tearDownScreen() {
|
||||||
|
@ -16,31 +17,33 @@ void VehicleConfigView::tearDownScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleConfigView::paramsUpdateItem(ConfigItem &item, int16_t itemIndex) {
|
void VehicleConfigView::paramsUpdateItem(ConfigItem &item, int16_t itemIndex) {
|
||||||
item.setType(static_cast<ParamFieldType>(itemIndex));
|
item.setType(static_cast<ParamType>(itemIndex));
|
||||||
item.setSelected(itemIndex == selectedParam);
|
item.setSelected(itemIndex == selectedParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleConfigView::selectPrevParam() {
|
void VehicleConfigView::selectPrevParam() {
|
||||||
if (selectedParam == 0) {
|
if (selectedParam == 0) {
|
||||||
updateSelectedParam(ParamFieldType_COUNT - 1);
|
updateSelectedParam(ParamType_COUNT - 1);
|
||||||
} else {
|
} else {
|
||||||
updateSelectedParam(selectedParam - 1);
|
updateSelectedParam(selectedParam - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleConfigView::selectNextParam() {
|
void VehicleConfigView::selectNextParam() {
|
||||||
updateSelectedParam((selectedParam + 1) % ParamFieldType_COUNT);
|
updateSelectedParam((selectedParam + 1) % ParamType_COUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleConfigView::decParam() {
|
void VehicleConfigView::decParam() {
|
||||||
// TODO: How to handle this for different parameter types?
|
params_dec(static_cast<ParamType>(selectedParam));
|
||||||
|
params.itemChanged(selectedParam);
|
||||||
}
|
}
|
||||||
void VehicleConfigView::incParam() {
|
void VehicleConfigView::incParam() {
|
||||||
// TODO: How to handle this for different parameter types?
|
params_inc(static_cast<ParamType>(selectedParam));
|
||||||
|
params.itemChanged(selectedParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleConfigView::confirmParam() {
|
void VehicleConfigView::confirmParam() {
|
||||||
// TODO: How to handle this for different parameter types?
|
params_broadcast(static_cast<ParamType>(selectedParam));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VehicleConfigView::updateSelectedParam(int select) {
|
void VehicleConfigView::updateSelectedParam(int select) {
|
||||||
|
@ -81,7 +84,7 @@ void VehicleConfigView::updateSelectedParam(int select) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t firstWanted;
|
int16_t firstWanted;
|
||||||
if (selectedParam == 0 && previousSelected == ParamFieldType_COUNT - 1) {
|
if (selectedParam == 0 && previousSelected == ParamType_COUNT - 1) {
|
||||||
firstWanted = 0;
|
firstWanted = 0;
|
||||||
} else if (selectedParam > previousSelected) {
|
} else if (selectedParam > previousSelected) {
|
||||||
firstWanted = selectedParam - numVisible + 1;
|
firstWanted = selectedParam - numVisible + 1;
|
||||||
|
@ -90,8 +93,8 @@ void VehicleConfigView::updateSelectedParam(int select) {
|
||||||
}
|
}
|
||||||
if (firstWanted < 0) {
|
if (firstWanted < 0) {
|
||||||
firstWanted = 0;
|
firstWanted = 0;
|
||||||
} else if (firstWanted > ParamFieldType_COUNT - 1) {
|
} else if (firstWanted > ParamType_COUNT - 1) {
|
||||||
firstWanted = ParamFieldType_COUNT - 1;
|
firstWanted = ParamType_COUNT - 1;
|
||||||
}
|
}
|
||||||
params.animateToItem(firstWanted, 0);
|
params.animateToItem(firstWanted, 0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue