1
1
#include " BmsThread.h"
2
2
3
- BMSThread::BMSThread (LTC6811Bus* bus, unsigned int frequency, std::vector<Queue<BmsEvent, mailboxSize>*> mailboxes) : m_bus(bus), mailboxes(mailboxes) {
3
+ #include " LTC681xBus.h"
4
+ #include " LTC681xCommand.h"
5
+ #include " ThisThread.h"
6
+
7
+ BMSThread::BMSThread (LTC681xBus& bus, unsigned int frequency, std::vector<Queue<BmsEvent, mailboxSize>*> mailboxes) : m_bus(bus), mailboxes(mailboxes) {
4
8
m_delay = 1000 / frequency;
5
9
for (int i = 0 ; i < BMS_BANK_COUNT; i++) {
6
- m_chips.push_back (LTC6811 (* bus, i));
10
+ m_chips.push_back (LTC6811 (bus, i));
7
11
}
8
12
for (int i = 0 ; i < BMS_BANK_COUNT; i++) {
9
13
// m_chips[i].getConfig().gpio5 = LTC6811::GPIOOutputState::kLow;
@@ -14,79 +18,125 @@ BMSThread::BMSThread(LTC6811Bus* bus, unsigned int frequency, std::vector<Queue<
14
18
}
15
19
16
20
void BMSThread::threadWorker () {
17
- std::array<uint16_t , BMS_BANK_COUNT * BMS_BANK_CELL_COUNT> allVoltages;
18
- std::array<std::optional<int8_t >, BMS_BANK_COUNT * BMS_BANK_TEMP_COUNT> allTemps;
21
+ // Perform self tests
19
22
20
- while (true ) {
21
- // Measure from all BMS banks
22
- for (int i = 0 ; i < BMS_BANK_COUNT; i++) {
23
- LTC6811::Configuration& conf = m_chips[i].getConfig ();
23
+ // Cell Voltage self test
24
+ m_bus.WakeupBus ();
25
+ m_bus.SendCommand (LTC681xBus::BuildBroadcastBusCommand (StartSelfTestCellVoltage (AdcMode::k7k, SelfTestMode::kSelfTest1 )));
26
+ ThisThread::sleep_for (4 );
27
+ m_bus.WakeupBus ();
28
+ for (int i = 0 ; i < BMS_BANK_COUNT; i++) {
29
+ uint16_t rawVoltages[12 ];
30
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupA (), i), (uint8_t *)rawVoltages) != LTC681xBus::LTC681xBusStatus::Ok) {
31
+ printf (" Things are not okay. SelfTestVoltageA\n " );
32
+ }
33
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupB (), i), (uint8_t *)rawVoltages + 6 ) != LTC681xBus::LTC681xBusStatus::Ok) {
34
+ printf (" Things are not okay. SelfTestVoltageB\n " );
35
+ }
36
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupC (), i), (uint8_t *)rawVoltages + 12 ) != LTC681xBus::LTC681xBusStatus::Ok) {
37
+ printf (" Things are not okay. SelfTestVoltageC\n " );
38
+ }
39
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupD (), i), (uint8_t *)rawVoltages + 18 ) != LTC681xBus::LTC681xBusStatus::Ok) {
40
+ printf (" Things are not okay. SelfTestVoltageD\n " );
41
+ }
24
42
25
- // Turn on status LED
26
- conf.gpio5 = LTC6811::GPIOOutputState::kLow ;
27
- m_chips[i].updateConfig ();
43
+ for (int j = 0 ; j < 12 ; j++) {
44
+ printf (" AXST %2d: %4x\n " , j, rawVoltages[i]);
45
+ }
46
+ }
28
47
29
- uint16_t * voltages = m_chips[i].getVoltages ();
48
+ // Cell GPIO self test
49
+ m_bus.WakeupBus ();
50
+ m_bus.SendCommand (LTC681xBus::BuildBroadcastBusCommand (StartSelfTestGpio (AdcMode::k7k, SelfTestMode::kSelfTest1 )));
51
+ ThisThread::sleep_for (4 );
52
+ m_bus.WakeupBus ();
53
+ for (int i = 0 ; i < BMS_BANK_COUNT; i++) {
54
+ uint16_t rawVoltages[12 ];
55
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupA (), i), (uint8_t *)rawVoltages) != LTC681xBus::LTC681xBusStatus::Ok) {
56
+ printf (" Things are not okay. SelfTestVoltageA\n " );
57
+ }
58
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupB (), i), (uint8_t *)rawVoltages + 6 ) != LTC681xBus::LTC681xBusStatus::Ok) {
59
+ printf (" Things are not okay. SelfTestVoltageB\n " );
60
+ }
30
61
31
- // Measure all temperature sensors on the current bank
32
- uint16_t temperatures[BMS_BANK_TEMP_COUNT];
33
- for (unsigned int j = 0 ; j < BMS_BANK_TEMP_COUNT; j++) {
34
- conf.gpio1 = (j & 0x01 ) ? LTC6811::GPIOOutputState::kHigh
35
- : LTC6811::GPIOOutputState::kLow ;
36
- conf.gpio2 = (j & 0x02 ) ? LTC6811::GPIOOutputState::kHigh
37
- : LTC6811::GPIOOutputState::kLow ;
38
- conf.gpio3 = (j & 0x04 ) ? LTC6811::GPIOOutputState::kHigh
39
- : LTC6811::GPIOOutputState::kLow ;
40
- conf.gpio4 = LTC6811::GPIOOutputState::kPassive ;
41
- m_chips[i].updateConfig ();
62
+ for (int j = 0 ; j < 12 ; j++) {
63
+ printf (" CVST %2d: %4x\n " , j, rawVoltages[i]);
64
+ }
65
+ }
42
66
43
- // Wait for config changes to take effect
44
- ThisThread::sleep_for (3 );
67
+ printf (" SELF TEST DONE \n " );
45
68
46
- uint16_t * temps = m_chips[i].getGpioPin (GpioSelection::k4);
47
- temperatures[j] = temps[j] / 10 ;
69
+ std::array<uint16_t , BMS_BANK_COUNT * BMS_BANK_CELL_COUNT> allVoltages;
70
+ std::array<std::optional<int8_t >, BMS_BANK_COUNT * BMS_BANK_TEMP_COUNT> allTemps;
71
+ while (true ) {
72
+ m_bus.WakeupBus ();
73
+
74
+ // Set all status lights high
75
+ // TODO: This should be in some sort of config class
76
+ uint8_t statusOn[6 ] = { 0x78 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 };
77
+ uint8_t statusOff[6 ] = { 0xf8 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 };
78
+ auto ledCmd = LTC681xBus::BuildBroadcastBusCommand (WriteConfigurationGroupA ());
79
+ m_bus.SendDataCommand (ledCmd, statusOn);
80
+
81
+ // Start ADC on all chips
82
+ auto startAdcCmd = StartCellVoltageADC (AdcMode::k7k, false , CellSelection::kAll );
83
+ if (m_bus.SendCommand (LTC681xBus::BuildBroadcastBusCommand (startAdcCmd)) != LTC681xBus::LTC681xBusStatus::Ok) {
84
+ printf (" Things are not okay. StartADC\n " );
85
+ }
48
86
49
- delete temps;
87
+ // Read back values from all chips
88
+ for (int i = 0 ; i < BMS_BANK_COUNT; i++) {
89
+ if (m_bus.PollAdcCompletion (LTC681xBus::BuildAddressedBusCommand (PollADCStatus (), 0 )) == LTC681xBus::LTC681xBusStatus::PollTimeout) {
90
+ printf (" Poll timeout.\n " );
91
+ } else {
92
+ printf (" Poll OK.\n " );
50
93
}
51
94
52
- // Turn off status LED
53
- conf.gpio5 = LTC6811::GPIOOutputState::kHigh ;
54
- m_chips[i].updateConfig ();
95
+ uint16_t rawVoltages[12 ];
96
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupA (), i), (uint8_t *)rawVoltages) != LTC681xBus::LTC681xBusStatus::Ok) {
97
+ printf (" Things are not okay. VoltageA\n " );
98
+ }
99
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupB (), i), (uint8_t *)rawVoltages + 6 ) != LTC681xBus::LTC681xBusStatus::Ok) {
100
+ printf (" Things are not okay. VoltageB\n " );
101
+ }
102
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupC (), i), (uint8_t *)rawVoltages + 12 ) != LTC681xBus::LTC681xBusStatus::Ok) {
103
+ printf (" Things are not okay. VoltageC\n " );
104
+ }
105
+ if (m_bus.SendReadCommand (LTC681xBus::BuildAddressedBusCommand (ReadCellVoltageGroupD (), i), (uint8_t *)rawVoltages + 18 ) != LTC681xBus::LTC681xBusStatus::Ok) {
106
+ printf (" Things are not okay. VoltageD\n " );
107
+ }
55
108
56
- //
57
- // Process values
58
- //
59
109
for (int j = 0 ; j < 12 ; j++) {
60
- uint16_t voltage = voltages[j] / 10 ;
110
+ // Endianness of the protocol allows a simple cast :-)
111
+ uint16_t voltage = rawVoltages[j] / 10 ;
61
112
62
113
int index = BMS_CELL_MAP[j];
63
114
if (index != -1 ) {
64
115
allVoltages[(BMS_BANK_CELL_COUNT * i) + index] = voltage;
65
116
}
66
117
}
67
-
68
- for (unsigned int j = 0 ; j < BMS_BANK_TEMP_COUNT; j++) {
69
- auto temp = convertTemp (temperatures[j]);
70
- allTemps[(BMS_BANK_TEMP_COUNT * i) + j] = temp;
71
- }
72
-
73
- delete voltages;
74
118
}
75
119
120
+ m_bus.SendDataCommand (ledCmd, statusOff);
121
+
76
122
for (auto mailbox : mailboxes) {
77
123
if (!mailbox->full ()) {
78
124
{
79
125
auto msg = new VoltageMeasurement ();
80
126
msg->voltageValues = allVoltages;
81
127
mailbox->put ((BmsEvent*) msg);
82
128
}
129
+ /*
83
130
{
84
131
auto msg = new TemperatureMeasurement();
85
132
msg->temperatureValues = allTemps;
86
133
mailbox->put((BmsEvent*) msg);
87
134
}
135
+ */
88
136
}
89
137
}
138
+
139
+ ThisThread::sleep_for (100 );
90
140
}
91
141
}
92
142
0 commit comments