11#pragma once
22
33#include < array>
4- #include < bitset>
4+
5+ #ifdef ENABLE_CROSS_ONLY_HEADERS
6+ // TODO(fps 7/12/2023): This is super hacky and I hate throwing #ifdefs
7+ // in our nicely host-independent code but for now we really just need
8+ // the vTaskDelay function and hopefully sometime in the near future I
9+ // can refactor this file with a nice templated sleep function.
10+ #include " FreeRTOS.h"
11+ // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
12+ #define HACKY_TASK_SLEEP (___timeout___ ) vTaskDelay(___timeout___)
13+
14+ #else
15+
16+ // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
17+ #define HACKY_TASK_SLEEP (___timeout___ ) (void )(___timeout___)
18+ #endif
519
620#include " can/core/can_writer_task.hpp"
721#include " can/core/ids.hpp"
1024#include " common/core/logging.h"
1125#include " common/core/message_queue.hpp"
1226#include " i2c/core/messages.hpp"
13- #include " ot_utils/core/filters/sma.hpp"
1427#include " sensors/core/fdc1004.hpp"
1528#include " sensors/core/sensor_hardware_interface.hpp"
1629#include " sensors/core/utils.hpp"
@@ -38,19 +51,23 @@ class FDC1004 {
3851 [[nodiscard]] auto initialized () const -> bool { return _initialized; }
3952
4053 auto initialize () -> void {
41- // FIXME we should grab device id and compare it to the static
42- // device id in code.
43-
44- // We should send a message that the sensor is in a ready state,
45- // not sure if we should have a separate can message to do that
46- // holding off for this PR.
47- if (shared_sensor) {
48- measure_mode = fdc1004::MeasureConfigMode::TWO;
54+ if (!_initialized) {
55+ // FIXME we should grab device id and compare it to the static
56+ // device id in code.
57+
58+ // We should send a message that the sensor is in a ready state,
59+ // not sure if we should have a separate can message to do that
60+ // holding off for this PR.
61+
62+ // Initial delay to avoid I2C bus traffic.
63+ HACKY_TASK_SLEEP (100 );
4964 update_capacitance_configuration ();
65+ // Second delay to ensure IC is ready to start
66+ // readings (and also to avoid I2C bus traffic).
67+ HACKY_TASK_SLEEP (100 );
68+ set_sample_rate ();
69+ _initialized = true ;
5070 }
51- measure_mode = fdc1004::MeasureConfigMode::ONE;
52- update_capacitance_configuration ();
53- _initialized = true ;
5471 }
5572
5673 auto register_map () -> fdc1004::FDC1004RegisterMap & { return _registers; }
@@ -70,7 +87,6 @@ class FDC1004 {
7087 }
7188 sensor_id = _id;
7289 update_capacitance_configuration ();
73- filter.reset_filter ();
7490 }
7591 }
7692
@@ -100,7 +116,6 @@ class FDC1004 {
100116 // mode.
101117 current_offset_pf = -1 ;
102118 set_offset (0 );
103- set_sample_rate ();
104119 }
105120
106121 void reset_limited () {
@@ -116,13 +131,10 @@ class FDC1004 {
116131 _registers.fdc_conf .measurement_rate =
117132 static_cast <uint8_t >(measurement_rate);
118133 _registers.fdc_conf .repeating_measurements = 1 ;
119- if (measure_mode == fdc1004::MeasureConfigMode::TWO) {
120- _registers.fdc_conf .measure_mode_1 = 0 ;
121- _registers.fdc_conf .measure_mode_2 = 1 ;
122- } else {
123- _registers.fdc_conf .measure_mode_1 = 1 ;
124- _registers.fdc_conf .measure_mode_2 = 0 ;
125- }
134+ // Enable both measurements no matter what. We check the Ready
135+ // bits anyways and the data doesn't overwrite, so there's no danger.
136+ _registers.fdc_conf .measure_mode_1 = 1 ;
137+ _registers.fdc_conf .measure_mode_2 = 1 ;
126138 _registers.fdc_conf .padding_0 = 0 ;
127139 _registers.fdc_conf .padding_1 = 0 ;
128140 set_register (_registers.fdc_conf );
@@ -164,66 +176,51 @@ class FDC1004 {
164176 auto poll_limited_capacitance (uint16_t number_reads, can::ids::SensorId _id,
165177 uint8_t tags) -> void {
166178 set_sensor_id (_id);
167- auto converted_msb_addr =
168- static_cast <uint8_t >(fdc1004::Registers::MEAS1_MSB);
169- auto converted_lsb_addr =
170- static_cast <uint8_t >(fdc1004::Registers::MEAS1_LSB);
171- if (measure_mode == fdc1004::MeasureConfigMode::TWO) {
172- converted_msb_addr =
173- static_cast <uint8_t >(fdc1004::Registers::MEAS2_MSB);
174- converted_lsb_addr =
175- static_cast <uint8_t >(fdc1004::Registers::MEAS2_LSB);
176- poller.multi_register_poll (
177- fdc1004::ADDRESS, converted_msb_addr, 2 , converted_lsb_addr, 2 ,
178- number_reads, DELAY, own_queue,
179- utils::build_id (fdc1004::ADDRESS, converted_msb_addr, tags));
180- } else {
181- poller.multi_register_poll (
182- fdc1004::ADDRESS, converted_msb_addr, 2 , converted_lsb_addr, 2 ,
183- number_reads, DELAY, own_queue,
184- utils::build_id (fdc1004::ADDRESS, converted_msb_addr, tags));
185- }
179+ poller.single_register_poll (
180+ fdc1004::ADDRESS,
181+ static_cast <uint8_t >(fdc1004::Registers::FDC_CONF), 2 , number_reads,
182+ DELAY, own_queue,
183+ utils::build_id (fdc1004::ADDRESS,
184+ static_cast <uint8_t >(fdc1004::Registers::FDC_CONF),
185+ tags));
186186 }
187187
188188 auto poll_continuous_capacitance (can::ids::SensorId _id, uint8_t tags,
189189 uint8_t binding) -> void {
190190 set_sensor_id (_id);
191191 auto delay = delay_or_disable (binding);
192- auto converted_msb_addr =
193- static_cast <uint8_t >(fdc1004::Registers::MEAS1_MSB);
194- auto converted_lsb_addr =
195- static_cast <uint8_t >(fdc1004::Registers::MEAS1_LSB);
196- if (measure_mode == fdc1004::MeasureConfigMode::TWO) {
197- converted_msb_addr =
198- static_cast <uint8_t >(fdc1004::Registers::MEAS2_MSB);
199- converted_lsb_addr =
200- static_cast <uint8_t >(fdc1004::Registers::MEAS2_LSB);
201- poller.continuous_multi_register_poll (
202- fdc1004::ADDRESS, converted_msb_addr, 2 , converted_lsb_addr, 2 ,
203- delay, own_queue,
204- utils::build_id (fdc1004::ADDRESS, converted_msb_addr, tags));
205- } else {
206- poller.continuous_multi_register_poll (
207- fdc1004::ADDRESS, converted_msb_addr, 2 , converted_lsb_addr, 2 ,
208- delay, own_queue,
209- utils::build_id (fdc1004::ADDRESS, converted_msb_addr, tags));
210- }
192+ poller.continuous_single_register_poll (
193+ fdc1004::ADDRESS,
194+ static_cast <uint8_t >(fdc1004::Registers::FDC_CONF), 2 , delay,
195+ own_queue,
196+ utils::build_id (fdc1004::ADDRESS,
197+ static_cast <uint8_t >(fdc1004::Registers::FDC_CONF),
198+ tags));
211199 }
212200
213201 auto stop_continuous_polling (uint32_t transaction_id) -> void {
214- auto converted_msb_addr =
215- static_cast <uint8_t >(fdc1004::Registers::MEAS1_MSB);
216- auto converted_lsb_addr =
217- static_cast <uint8_t >(fdc1004::Registers::MEAS1_LSB);
218- if (measure_mode == fdc1004::MeasureConfigMode::TWO) {
219- converted_msb_addr =
220- static_cast <uint8_t >(fdc1004::Registers::MEAS2_MSB);
221- converted_lsb_addr =
222- static_cast <uint8_t >(fdc1004::Registers::MEAS2_LSB);
202+ poller.continuous_single_register_poll (
203+ fdc1004::ADDRESS,
204+ static_cast <uint8_t >(fdc1004::Registers::FDC_CONF), 2 , STOP_DELAY,
205+ own_queue, transaction_id);
206+ }
207+
208+ void handle_fdc_response (i2c::messages::TransactionResponse &m) {
209+ uint16_t reg_int = 0 ;
210+ static_cast <void >(bit_utils::bytes_to_int (
211+ m.read_buffer .cbegin (), m.read_buffer .cend (), reg_int));
212+ auto fdc = read_register<fdc1004::FDCConf>(reg_int).value ();
213+ auto measurement_done =
214+ fdc1004_utils::measurement_ready (fdc, measure_mode);
215+ if (measurement_done) {
216+ // Start a single-shot, two-register transaction for the data.
217+ send_followup (m);
218+ } else {
219+ i2c::messages::MaxMessageBuffer buffer = {
220+ static_cast <uint8_t >(fdc1004::Registers::FDC_CONF)};
221+ // Retrigger the same exact reading
222+ writer.transact (fdc1004::ADDRESS, 1 , buffer, 2 , m.id , own_queue);
223223 }
224- poller.continuous_multi_register_poll (
225- fdc1004::ADDRESS, converted_msb_addr, 2 , converted_lsb_addr, 2 ,
226- STOP_DELAY, own_queue, transaction_id);
227224 }
228225
229226 void handle_ongoing_response (i2c::messages::TransactionResponse &m) {
@@ -233,6 +230,7 @@ class FDC1004 {
233230 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
234231 polling_results[m.id .transaction_index ]));
235232 if (m.id .transaction_index == 0 ) {
233+ send_followup (m);
236234 return ;
237235 }
238236
@@ -244,19 +242,12 @@ class FDC1004 {
244242 auto raw_capacitance = fdc1004_utils::convert_reads (polling_results[0 ],
245243 polling_results[1 ]);
246244
247- if (!data_stable[int (sensor_id)]) {
248- raw_capacitance = filter.compute (raw_capacitance);
249- data_stable.set (int (sensor_id), filter.stop_filter ());
250- }
251-
252245 auto capacitance = fdc1004_utils::convert_capacitance (
253246 raw_capacitance, 1 , current_offset_pf);
254247
255- if (data_stable[int (sensor_id)]) {
256- auto new_offset =
257- fdc1004_utils::update_offset (capacitance, current_offset_pf);
258- set_offset (new_offset);
259- }
248+ auto new_offset =
249+ fdc1004_utils::update_offset (capacitance, current_offset_pf);
250+ set_offset (new_offset);
260251
261252 if (max_capacitance_sync) {
262253 if (capacitance > fdc1004::MAX_CAPACITANCE_READING) {
@@ -291,6 +282,7 @@ class FDC1004 {
291282 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
292283 baseline_results[m.id .transaction_index ]));
293284 if (m.id .transaction_index == 0 ) {
285+ send_followup (m);
294286 return ;
295287 }
296288 measurement += fdc1004_utils::convert_reads (baseline_results[0 ],
@@ -350,7 +342,6 @@ class FDC1004 {
350342 OwnQueue &own_queue;
351343 hardware::SensorHardwareBase &hardware;
352344
353- ot_utils::filters::SimpleMovingAverage<int32_t > filter{};
354345 uint8_t sensor_binding{2 };
355346 fdc1004::FDC1004RegisterMap _registers{};
356347 bool _initialized = false ;
@@ -371,10 +362,49 @@ class FDC1004 {
371362 bool echoing = false ;
372363 bool bind_sync = false ;
373364 bool max_capacitance_sync = false ;
374- std::bitset<2 > data_stable{" 00" };
375365 std::array<uint16_t , 2 > baseline_results{};
376366 std::array<uint16_t , 2 > polling_results{};
377367
368+ auto send_followup (i2c::messages::TransactionResponse &m) -> void {
369+ auto address = utils::reg_from_id<uint8_t >(m.id .token );
370+ uint8_t followup_address = 0 ;
371+ auto tags = utils::tags_from_token (m.id .token );
372+ i2c::messages::TransactionIdentifier id = m.id ;
373+ switch (address) {
374+ case static_cast <uint8_t >(fdc1004::Registers::FDC_CONF):
375+ // After CONF, read MSB for transaction index 0
376+ followup_address =
377+ (measure_mode == fdc1004::MeasureConfigMode::ONE)
378+ ? static_cast <uint8_t >(fdc1004::Registers::MEAS1_MSB)
379+ : static_cast <uint8_t >(fdc1004::Registers::MEAS2_MSB);
380+ id.transaction_index = 0 ;
381+ break ;
382+ case static_cast <uint8_t >(fdc1004::Registers::MEAS1_MSB):
383+ // After MSB, read LSB for index 1
384+ followup_address =
385+ static_cast <uint8_t >(fdc1004::Registers::MEAS1_LSB);
386+ id.transaction_index = 1 ;
387+ break ;
388+ case static_cast <uint8_t >(fdc1004::Registers::MEAS2_MSB):
389+ // After MSB, read LSB for index 1
390+ followup_address =
391+ static_cast <uint8_t >(fdc1004::Registers::MEAS2_LSB);
392+ id.transaction_index = 1 ;
393+ break ;
394+ default :
395+ // If this isn't one of the hardcoded regs, do nothing
396+ return ;
397+ }
398+
399+ i2c::messages::MaxMessageBuffer buffer;
400+ buffer[0 ] = followup_address;
401+
402+ // Overwrite the token to get the updated address
403+ id.token = utils::build_id (fdc1004::ADDRESS, followup_address, tags);
404+ // This maintains the entire transaction ID of the original request.
405+ writer.transact (fdc1004::ADDRESS, 1 , buffer, 2 , id, own_queue);
406+ }
407+
378408 auto build_mode_1_configuration_register () -> fdc1004::ConfMeasure1 {
379409 _registers.config_measure_1 .CHA =
380410 static_cast <uint8_t >(fdc1004::CHA::CIN1);
0 commit comments