rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
Public Member Functions | Data Fields
HellenBoardIdFinder< NumPins > Class Template Reference

#include <hellen_board_id.h>

Inheritance diagram for HellenBoardIdFinder< NumPins >:
Inheritance graph
[legend]
Collaboration diagram for HellenBoardIdFinder< NumPins >:
Collaboration graph
[legend]

Public Member Functions

 HellenBoardIdFinder (brain_pin_e(&rP)[NumPins])
 
bool measureChargingTimes (int i, float &Tc1_us, float &Tc2_us)
 
bool measureChargingTimesAveraged (int i, float &Tc1_us, float &Tc2_us)
 
- Public Member Functions inherited from HellenBoardIdFinderBase
float calc (float Tc1_us, float Tc2_us, float Rest, float C, bool testOnlyMajorSeries, float *Rmeasured, float *Cest, int *rIdx)
 
float findClosestResistor (float R, bool testOnlyMajorSeries, int *rIdx)
 
float calcEstimatedResistance (float Tc1_us, float C)
 

Data Fields

brain_pin_e(& rPins )[NumPins]
 
HellenBoardIdFinderState state
 
- Data Fields inherited from HellenBoardIdFinderBase
HellenBoardIdFinderState state
 

Detailed Description

template<size_t NumPins>
class HellenBoardIdFinder< NumPins >

Definition at line 64 of file hellen_board_id.h.

Constructor & Destructor Documentation

◆ HellenBoardIdFinder()

template<size_t NumPins>
HellenBoardIdFinder< NumPins >::HellenBoardIdFinder ( brain_pin_e(&)  rP[NumPins])
inline

Definition at line 67 of file hellen_board_id.h.

67: rPins(rP) {}
brain_pin_e(& rPins)[NumPins]

Member Function Documentation

◆ measureChargingTimes()

template<size_t NumPins>
bool HellenBoardIdFinder< NumPins >::measureChargingTimes ( int  i,
float Tc1_us,
float Tc2_us 
)

Definition at line 178 of file hellen_board_id.cpp.

178 {
179#if EFI_PROD_CODE && defined( HELLEN_BOARD_ID_PIN_1) && !defined(HW_HELLEN_SKIP_BOARD_TYPE)
180 chSemReset(&state.boardId_wake, 0);
181
182 // full charge/discharge time, and also 'timeout' time
183 const int Tf_us = 50000; // 50 ms is more than enough to "fully" discharge the capacitor with any two resistors used at the same time.
184
185 // 1. Fully discharge the capacitor through both resistors (faster)
186 for (size_t k = 0; k < NumPins; k++) {
187 palClearPad(getBrainPinPort(rPins[k]), getBrainPinIndex(rPins[k]));
188 palSetPadMode(getBrainPinPort(rPins[k]), getBrainPinIndex(rPins[k]), PAL_MODE_OUTPUT_PUSHPULL);
189 }
190 // wait max. time because we don't know the resistor values yet
191 chThdSleepMicroseconds(Tf_us);
192
193 // use one pin as an charge/discharge controlling output
196 palSetPadMode(state.rOutputPinPort, state.rOutputPinIdx, PAL_MODE_OUTPUT_PUSHPULL);
197
198 // use another pin as an input to detect 0->1 crossings
199 int inputIdx = 1 - i;
202 // set only high-Z input mode, no pull-ups/pull-downs allowed!
203 palSetPadMode(state.rInputPinPort, state.rInputPinIdx, PAL_MODE_INPUT);
204 efiExtiEnablePin("boardId", rPins[inputIdx], PAL_EVENT_MODE_RISING_EDGE, hellenBoardIdInputCallback, (void *)&state);
205
206 int pinState = palReadPad(state.rInputPinPort, state.rInputPinIdx);
207 if (pinState != 0) {
208 // the input pin state should be low when the capacitor is fully discharged
209 efiPrintf("* Board detection error!");
210 return false;
211 }
212
213 // Timestamps:
214 // t1 = Starts charging from 0v
215 // t2 = Threshold reached, starts discharging
216 // t3 = Random voltage reached, starts charging again
217 // t4 = Threshold reached again, process finished.
218
219 // 2. Start charging until the input pin triggers (V01 threshold is reached)
221 efitick_t t1 = getTimeNowNt();
223 chSemWaitTimeout(&state.boardId_wake, TIME_US2I(Tf_us));
224 efitick_t t2 = state.timeChargeNt;
225
226 // 3. At the moment, the discharging has already been started!
227 // Meanwhile we need to do some checks - until some pre-selected voltage is presumably reached.
228
229 // if voltage didn't change on the input pin (or changed impossibly fast), then the charging didn't start,
230 // meaning there's no capacitor and/or resistors on these pins.
231 if (t2 - t1 < US2NT(100)) {
232 efiPrintf("* Hellen Board ID circuitry wasn't detected! Aborting!");
233 return false;
234 }
235
236 // 4. calculate the first charging time
237 efidur_t Tc1_nt = t2 - t1;
238 Tc1_us = NT2USF(Tc1_nt);
239 // We use the same 'charging time' to discharge the capacitor to some random voltage below the threshold voltage.
240 efidur_t Td_nt = Tc1_nt;
241
242 // 5. And now just wait for the rest of the discharge process...
243 // Spin wait since chThdSleepMicroseconds() lacks the resolution we need
244 efitick_t t3 = t2 + Td_nt;
245 while (getTimeNowNt() < t3) ;
246
247 // the input pin state should be low when the capacitor is discharged to Vl
248 pinState = palReadPad(state.rInputPinPort, state.rInputPinIdx);
249
250 // 6. And immediately begin charging again until the threshold voltage is reached!
253
254 // Wait for the charging completion
255 chSemReset(&state.boardId_wake, 0);
256 chSemWaitTimeout(&state.boardId_wake, TIME_US2I(Tf_us));
257 efitick_t t4 = state.timeChargeNt;
258
259 // 7. calculate the second charge time
260 Tc2_us = NT2USF(t4 - t3);
261
262 float Td_us = NT2USF(Td_nt);
263#ifdef HELLEN_BOARD_ID_DEBUG
264 efiPrintf("* dTime2-1 = %d", (int)(t2 - t1));
265 efiPrintf("* dTime3-2 = %d", (int)(t3 - t2));
266 efiPrintf("* dTime4-3 = %d", (int)(t4 - t3));
267 efiPrintf("* Tc1 = %f, Tc2 = %f, Td = %f", Tc1_us, Tc2_us, Td_us);
268#endif /* HELLEN_BOARD_ID_DEBUG */
269
270 // sanity checks
271 if (pinState != 0) {
272 efiPrintf("* Board detection error! (Td=%f is too small)", Td_us);
273 return false;
274 }
275
276 if (t4 <= t3) {
277 efiPrintf("* Estimates are out of limit! Something went wrong. Aborting!");
278 return false;
279 }
280
281 efiExtiDisablePin(rPins[inputIdx]);
282#endif /* EFI_PROD_CODE */
283 return true;
284}
HellenBoardIdFinderState state
void efiExtiDisablePin(brain_pin_e brainPin)
int efiExtiEnablePin(const char *msg, brain_pin_e brainPin, uint32_t mode, ExtiCallback cb, void *cb_data)
efitick_t getTimeNowNt()
Definition efitime.cpp:19
static void hellenBoardIdInputCallback(void *arg, efitick_t nowNt)
int getBrainPinIndex(Gpio brainPin)
ioportid_t getBrainPinPort(brain_pin_e brainPin)
efitick_t efidur_t
Here is the call graph for this function:

◆ measureChargingTimesAveraged()

template<size_t NumPins>
bool HellenBoardIdFinder< NumPins >::measureChargingTimesAveraged ( int  i,
float Tc1_us,
float Tc2_us 
)

Definition at line 287 of file hellen_board_id.cpp.

287 {
288 const int numTries = 3;
289
290 Tc1_us = 0;
291 Tc2_us = 0;
292 for (int tries = 0; tries < numTries; tries++) {
293 // get the charging times
294 float Tc1i_us = 0, Tc2i_us = 0;
295 if (!measureChargingTimes(i, Tc1i_us, Tc2i_us))
296 return false;
297 Tc1_us += Tc1i_us;
298 Tc2_us += Tc2i_us;
299 }
300
301 // averaging
302 Tc1_us /= numTries;
303 Tc2_us /= numTries;
304
305 return true;
306}
bool measureChargingTimes(int i, float &Tc1_us, float &Tc2_us)

Referenced by detectHellenBoardId().

Here is the caller graph for this function:

Field Documentation

◆ rPins

template<size_t NumPins>
brain_pin_e(& HellenBoardIdFinder< NumPins >::rPins)[NumPins]

Definition at line 74 of file hellen_board_id.h.

◆ state

template<size_t NumPins>
HellenBoardIdFinderState HellenBoardIdFinder< NumPins >::state

Definition at line 75 of file hellen_board_id.h.

Referenced by detectHellenBoardId().


The documentation for this class was generated from the following files: