Skip to content

Commit c634bd5

Browse files
committed
Closes #4 - missing pitches.h
1 parent 0b6ce1e commit c634bd5

14 files changed

+289
-67
lines changed

src/ADCUtils.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,27 +85,39 @@
8585
#define ADC_TEMPERATURE_CHANNEL_MUX 15
8686
#define ADC_1_1_VOLT_CHANNEL_MUX 12
8787
#define ADC_GND_CHANNEL_MUX 13
88+
#define ADC_CHANNEL_MUX_MASK 0x0F
8889

8990
#elif defined(__AVR_ATtiny87__) || defined(__AVR_ATtiny167__)
9091
#define ADC_ISCR_CHANNEL_MUX 3
9192
#define ADC_TEMPERATURE_CHANNEL_MUX 11
9293
#define ADC_1_1_VOLT_CHANNEL_MUX 12
9394
#define ADC_GND_CHANNEL_MUX 14
9495
#define ADC_VCC_4TH_CHANNEL_MUX 13
96+
#define ADC_CHANNEL_MUX_MASK 0x1F
9597

9698
#elif defined(__AVR_ATmega328P__)
9799
#define ADC_TEMPERATURE_CHANNEL_MUX 8
98100
#define ADC_1_1_VOLT_CHANNEL_MUX 14
99101
#define ADC_GND_CHANNEL_MUX 15
102+
#define ADC_CHANNEL_MUX_MASK 0x0F
103+
104+
#elif defined(__AVR_ATmega644P__)
105+
#define ADC_TEMPERATURE_CHANNEL_MUX // not existent
106+
#define ADC_1_1_VOLT_CHANNEL_MUX 0x1E
107+
#define ADC_GND_CHANNEL_MUX 0x1F
108+
#define ADC_CHANNEL_MUX_MASK 0x0F
100109

101110
#elif defined(__AVR_ATmega32U4__)
102111
#define ADC_TEMPERATURE_CHANNEL_MUX 0x27
103112
#define ADC_1_1_VOLT_CHANNEL_MUX 0x1E
104113
#define ADC_GND_CHANNEL_MUX 0x1F
114+
#define ADC_CHANNEL_MUX_MASK 0x3F
105115

106116
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
107117
#define ADC_1_1_VOLT_CHANNEL_MUX 0x1E
108118
#define ADC_GND_CHANNEL_MUX 0x1F
119+
#define ADC_CHANNEL_MUX_MASK 0x1F
120+
109121
#define INTERNAL INTERNAL1V1
110122

111123
#else
@@ -164,7 +176,10 @@ uint16_t waitAndReadADCChannelWithReferenceAndRestoreADMUXAndReference(uint8_t a
164176
uint16_t readADCChannelWithOversample(uint8_t aADCChannelNumber, uint8_t aOversampleExponent);
165177
void setADCChannelAndReferenceForNextConversion(uint8_t aADCChannelNumber, uint8_t aReference);
166178
uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aOversampleExponent);
167-
uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples);
179+
uint32_t readADCChannelMultiSamples(uint8_t aPrescale, uint16_t aNumberOfSamples);
180+
uint16_t readADCChannelMultiSamplesWithReference(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples);
181+
uint32_t readADCChannelMultiSamplesWithReferenceAndPrescaler(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aPrescale,
182+
uint16_t aNumberOfSamples);
168183
uint16_t readADCChannelWithReferenceMax(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aNumberOfSamples);
169184
uint16_t readADCChannelWithReferenceMaxMicros(uint8_t aADCChannelNumber, uint8_t aReference, uint16_t aMicrosecondsToAquire);
170185
uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aDelay,
@@ -199,7 +214,8 @@ void resetCounterForVCCUndervoltageMultipleTimes();
199214
bool isVCCUndervoltage();
200215
bool isVCCEmergencyUndervoltage();
201216
bool isVCCOvervoltage();
202-
bool isVCCOvervoltageSimple();
217+
bool isVCCOvervoltageSimple(); // Version using readVCCVoltageMillivoltSimple()
218+
bool isVCCTooHighSimple(); // Version not using readVCCVoltageMillivoltSimple()
203219

204220
#endif // defined(__AVR__) ...
205221

src/ADCUtils.hpp

Lines changed: 100 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -161,12 +161,15 @@ uint8_t checkAndWaitForReferenceAndChannelToSwitch(uint8_t aADCChannelNumber, ui
161161
if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && (aReference == INTERNAL || aReference == INTERNAL2V56)) {
162162
#else
163163
if ((tOldADMUX & MASK_FOR_ADC_REFERENCE) != tNewReference && aReference == INTERNAL) {
164+
#endif
165+
#if defined(LOCAL_DEBUG)
166+
Serial.println(F("Switch from DEFAULT to INTERNAL"));
164167
#endif
165168
/*
166169
* Switch reference from DEFAULT to INTERNAL
167170
*/
168171
delayMicroseconds(8000); // experimental value is >= 7600 us for Nano board and 6200 for Uno board
169-
} else if ((tOldADMUX & 0x0F) != aADCChannelNumber) {
172+
} else if ((tOldADMUX & ADC_CHANNEL_MUX_MASK) != aADCChannelNumber) {
170173
if (aADCChannelNumber == ADC_1_1_VOLT_CHANNEL_MUX) {
171174
/*
172175
* Internal 1.1 Volt channel requires <= 200 us for Nano board
@@ -249,9 +252,10 @@ uint16_t readADCChannelWithReferenceOversampleFast(uint8_t aADCChannelNumber, ui
249252

250253
/*
251254
* Returns sum of all sample values
252-
* Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino by ADC_PRESCALE in ADCUtils.h.
255+
* Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino by ADC_PRESCALE (=ADC_PRESCALE128) in ADCUtils.h.
256+
* @ param aNumberOfSamples If > 64 an overflow may occur.
253257
*/
254-
uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples) {
258+
uint16_t readADCChannelMultiSamplesWithReference(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aNumberOfSamples) {
255259
uint16_t tSumValue = 0;
256260
ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);
257261

@@ -275,6 +279,65 @@ uint16_t readADCChannelWithReferenceMultiSamples(uint8_t aADCChannelNumber, uint
275279
return tSumValue;
276280
}
277281

282+
/*
283+
* Returns sum of all sample values
284+
* Conversion time is defined as 0.104 milliseconds for 16 MHz Arduino for ADC_PRESCALE128 in ADCUtils.h.
285+
* @ param aPrescale can be one of ADC_PRESCALE2, ADC_PRESCALE4, 8, 16, 32, 64, 128.
286+
* ADC_PRESCALE32 is recommended for excellent linearity and fast readout of 26 microseconds
287+
* @ param aNumberOfSamples If > 16k an overflow may occur.
288+
*/
289+
uint32_t readADCChannelMultiSamplesWithReferenceAndPrescaler(uint8_t aADCChannelNumber, uint8_t aReference, uint8_t aPrescale,
290+
uint16_t aNumberOfSamples) {
291+
uint32_t tSumValue = 0;
292+
ADMUX = aADCChannelNumber | (aReference << SHIFT_VALUE_FOR_REFERENCE);
293+
294+
ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.
295+
// ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag
296+
ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | aPrescale);
297+
298+
for (uint16_t i = 0; i < aNumberOfSamples; i++) {
299+
/*
300+
* wait for free running conversion to finish.
301+
* Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.
302+
*/
303+
loop_until_bit_is_set(ADCSRA, ADIF);
304+
305+
ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished
306+
// Add value
307+
tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here
308+
// tSumValue += (ADCH << 8) | ADCL; // this does NOT work!
309+
}
310+
ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)
311+
return tSumValue;
312+
}
313+
314+
/*
315+
* Returns sum of all sample values
316+
* Assumes, that channel and reference are still set to the right values
317+
* @ param aNumberOfSamples If > 16k an overflow may occur.
318+
*/
319+
uint32_t readADCChannelMultiSamples(uint8_t aPrescale, uint16_t aNumberOfSamples) {
320+
uint32_t tSumValue = 0;
321+
322+
ADCSRB = 0; // Free running mode. Only active if ADATE is set to 1.
323+
// ADSC-StartConversion ADATE-AutoTriggerEnable ADIF-Reset Interrupt Flag
324+
ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADATE) | _BV(ADIF) | aPrescale);
325+
326+
for (uint16_t i = 0; i < aNumberOfSamples; i++) {
327+
/*
328+
* wait for free running conversion to finish.
329+
* Do not wait for ADSC here, since ADSC is only low for 1 ADC Clock cycle on free running conversion.
330+
*/
331+
loop_until_bit_is_set(ADCSRA, ADIF);
332+
333+
ADCSRA |= _BV(ADIF); // clear bit to enable recognizing next conversion has finished
334+
// Add value
335+
tSumValue += ADCL | (ADCH << 8); // using WordUnionForADCUtils does not save space here
336+
// tSumValue += (ADCH << 8) | ADCL; // this does NOT work!
337+
}
338+
ADCSRA &= ~_BV(ADATE); // Disable auto-triggering (free running mode)
339+
return tSumValue;
340+
}
278341
/*
279342
* use ADC_PRESCALE32 which gives 26 us conversion time and good linearity
280343
* @return the maximum value of aNumberOfSamples samples.
@@ -408,7 +471,7 @@ uint16_t readUntil4ConsecutiveValuesAreEqual(uint8_t aADCChannelNumber, uint8_t
408471
*/
409472
float getVCCVoltageSimple(void) {
410473
// use AVCC with (optional) external capacitor at AREF pin as reference
411-
float tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
474+
float tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
412475
return ((1023 * 1.1 * 4) / tVCC);
413476
}
414477

@@ -419,7 +482,7 @@ float getVCCVoltageSimple(void) {
419482
*/
420483
uint16_t getVCCVoltageMillivoltSimple(void) {
421484
// use AVCC with external capacitor at AREF pin as reference
422-
uint16_t tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
485+
uint16_t tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
423486
return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCC);
424487
}
425488

@@ -459,6 +522,9 @@ uint16_t getVCCVoltageMillivolt(void) {
459522
return ((1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT) / tVCC);
460523
}
461524

525+
/*
526+
* Does not set sVCCVoltageMillivolt
527+
*/
462528
uint16_t printVCCVoltageMillivolt(Print *aSerial) {
463529
aSerial->print(F("VCC="));
464530
uint16_t tVCCVoltageMillivolt = getVCCVoltageMillivolt();
@@ -480,7 +546,7 @@ void readAndPrintVCCVoltageMillivolt(Print *aSerial) {
480546
*/
481547
void readVCCVoltageSimple(void) {
482548
// use AVCC with (optional) external capacitor at AREF pin as reference
483-
float tVCC = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
549+
float tVCC = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
484550
sVCCVoltage = (1023 * (((float) ADC_INTERNAL_REFERENCE_MILLIVOLT) / 1000) * 4) / tVCC;
485551
}
486552

@@ -491,7 +557,7 @@ void readVCCVoltageSimple(void) {
491557
*/
492558
void readVCCVoltageMillivoltSimple(void) {
493559
// use AVCC with external capacitor at AREF pin as reference
494-
uint16_t tVCCVoltageMillivoltRaw = readADCChannelWithReferenceMultiSamples(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
560+
uint16_t tVCCVoltageMillivoltRaw = readADCChannelMultiSamplesWithReference(ADC_1_1_VOLT_CHANNEL_MUX, DEFAULT, 4);
495561
sVCCVoltageMillivolt = (1023L * ADC_INTERNAL_REFERENCE_MILLIVOLT * 4) / tVCCVoltageMillivoltRaw;
496562
}
497563

@@ -556,7 +622,7 @@ bool isVCCUSBPowered(Print *aSerial) {
556622
aSerial->print(F("USB powered is "));
557623
bool tReturnValue;
558624
if (VOLTAGE_USB_POWERED_LOWER_THRESHOLD_MILLIVOLT
559-
< sVCCVoltageMillivolt && sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT) {
625+
< sVCCVoltageMillivolt&& sVCCVoltageMillivolt < VOLTAGE_USB_POWERED_UPPER_THRESHOLD_MILLIVOLT) {
560626
tReturnValue = true;
561627
aSerial->print(F("true "));
562628
} else {
@@ -649,6 +715,7 @@ void resetCounterForVCCUndervoltageMultipleTimes() {
649715
* Raw reading of 1.1 V is 221 at 5.1 V.
650716
* Raw reading of 1.1 V is 214 at 5.25 V (+5 %).
651717
* Raw reading of 1.1 V is 204 at 5.5 V (+10 %).
718+
* Raw reading of 1.1 V is 1126000 / VCC_MILLIVOLT
652719
* @return true if 5 % overvoltage reached
653720
*/
654721
bool isVCCOvervoltage() {
@@ -660,6 +727,21 @@ bool isVCCOvervoltageSimple() {
660727
return (sVCCVoltageMillivolt > VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT);
661728
}
662729

730+
// Version not using readVCCVoltageMillivoltSimple()
731+
bool isVCCTooHighSimple() {
732+
ADMUX = ADC_1_1_VOLT_CHANNEL_MUX | (DEFAULT << SHIFT_VALUE_FOR_REFERENCE);
733+
// ADCSRB = 0; // Only active if ADATE is set to 1.
734+
// ADSC-StartConversion ADIF-Reset Interrupt Flag - NOT free running mode
735+
ADCSRA = (_BV(ADEN) | _BV(ADSC) | _BV(ADIF) | ADC_PRESCALE128); // 128 -> 104 microseconds per ADC conversion at 16 MHz --- Arduino default
736+
// wait for single conversion to finish
737+
loop_until_bit_is_clear(ADCSRA, ADSC);
738+
739+
// Get value
740+
uint16_t tRawValue = ADCL | (ADCH << 8);
741+
742+
return tRawValue < 1126000 / VCC_OVERVOLTAGE_THRESHOLD_MILLIVOLT;
743+
}
744+
663745
/*
664746
* Temperature sensor is enabled by selecting the appropriate channel.
665747
* Different formula for 328P and 328PB!
@@ -671,18 +753,21 @@ float getCPUTemperatureSimple(void) {
671753
return 0.0;
672754
#else
673755
// use internal 1.1 volt as reference. 4 times oversample. Assume the signal has noise, but never verified :-(
674-
uint16_t tTempRaw = readADCChannelWithReferenceOversample(ADC_TEMPERATURE_CHANNEL_MUX, INTERNAL, 2);
756+
uint16_t tTemperatureRaw = readADCChannelWithReferenceOversample(ADC_TEMPERATURE_CHANNEL_MUX, INTERNAL, 2);
675757
#if defined(LOCAL_DEBUG)
676758
Serial.print(F("TempRaw="));
677-
Serial.println(tTempRaw);
759+
Serial.println(tTemperatureRaw);
678760
#endif
679761

680762
#if defined(__AVR_ATmega328PB__)
681-
tTempRaw -= 245;
682-
return (float)tTempRaw;
763+
tTemperatureRaw -= 245;
764+
return (float)tTemperatureRaw;
765+
#elif defined(__AVR_ATtiny85__)
766+
tTemperatureRaw -= 273; // 273 and 1.1666 are values from the datasheet
767+
return (float)tTemperatureRaw / 1.1666;
683768
#else
684-
tTempRaw -= 317;
685-
return (float) tTempRaw / 1.22;
769+
tTemperatureRaw -= 317;
770+
return (float) tTemperatureRaw / 1.22;
686771
#endif
687772
#endif
688773
}
@@ -704,7 +789,7 @@ float getCPUTemperature(void) {
704789
}
705790

706791
#else // defined(ADC_UTILS_ARE_AVAILABLE)
707-
// Dummy definition of functions defined in ADCUtils to compile examples without errors
792+
// Dummy definition of functions defined in ADCUtils to compile examples for non AVR platforms without errors
708793
/*
709794
* Persistent storage for VCC value
710795
*/

src/DebugLevel.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
/*
22
* DebugLevel.h
3-
* Include to propagate debug levels
3+
* Include to propagate debug levels to each other
44
*
5-
* Copyright (C) 2016-2020 Armin Joachimsmeyer
5+
* TRACE // Information you need to understand details of a function or if you hunt a bug.
6+
* DEBUG // Information need to understand the operating of your program. E.g. function calls and values of control variables.
7+
* INFO // Information you want to see in regular operation to see what the program is doing. E.g. "Now playing Muppets melody".
8+
* WARN // Information that the program may encounter problems, like small Heap/Stack area.
9+
* ERROR // Informations to explain why the program will not run. E.g. not enough Ram for all created objects.
10+
*
11+
*
12+
* Copyright (C) 2016-2024 Armin Joachimsmeyer
613
* Email: armin.joachimsmeyer@gmail.com
714
*
815
* This file is part of Arduino-Utils https://github.com/ArminJo/Arduino-Utils.
@@ -25,7 +32,7 @@
2532
#ifndef _DEBUGLEVEL_H
2633
#define _DEBUGLEVEL_H
2734

28-
// Propagate debug level
35+
// Propagate different debug level
2936
#if defined(TRACE) // Information you need to understand details of a function or if you hunt a bug.
3037
# if !defined(DEBUG)
3138
#define DEBUG // Information need to understand the operating of your program. E.g. function calls and values of control variables.

src/HCSR04.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,15 @@
7070
//#define USE_PIN_CHANGE_INTERRUPT_D0_TO_D7 // using PCINT2_vect - PORT D
7171
//#define USE_PIN_CHANGE_INTERRUPT_D8_TO_D13 // using PCINT0_vect - PORT B - Pin 13 is feedback output
7272
//#define USE_PIN_CHANGE_INTERRUPT_A0_TO_A5 // using PCINT1_vect - PORT C
73+
#if __has_include("digitalWriteFast.h")
7374
#include "digitalWriteFast.h"
75+
#else
76+
#define pinModeFast pinMode
77+
#define digitalReadFast digitalRead
78+
#define digitalWriteFast digitalWrite
79+
#define digitalToggleFast(P) digitalWrite(P, ! digitalRead(P))
80+
#endif
81+
7482
#include "HCSR04.h"
7583

7684
//#define DEBUG
@@ -132,6 +140,7 @@ void initUSDistancePin(uint8_t aTriggerOutEchoInPin) {
132140
#if !defined (TRIGGER_OUT_PIN)
133141
sTriggerOutPin = aTriggerOutEchoInPin;
134142
#endif
143+
(void) aTriggerOutEchoInPin;
135144
sHCSR04Mode = HCSR04_MODE_USE_1_PIN;
136145
}
137146

src/LightweightServo.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ void deinitLightweightServoPin9_10(bool aUsePin9, bool aUsePin10) {
118118
}
119119

120120
/*
121-
* If value is below 180 then assume degree, otherwise assume microseconds
122-
* If aUpdateFast then enable starting a new output pulse if more than 5 ms since last one, some servo might react faster in this mode.
123-
* If aUsePin9 is false, then Pin10 is used
121+
* @param aDegree - If value is below 180 then assume degree, otherwise assume microseconds
122+
* @param aUpdateFast - If true, enable starting a new output pulse if more than 5 ms since last one, some servo might react faster in this mode.
123+
* @param aUsePin9 - If false, then Pin10 is used
124124
* 236 / 186(without auto init) bytes code size
125125
*/
126126
int writeLightweightServo(int aDegree, bool aUsePin9, bool aUpdateFast) {

src/LongUnion.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ union LongUnion {
8787
struct {
8888
WordUnion LowWord;
8989
WordUnion HighWord;
90-
} WordUnion;
90+
} TwoWordUnions;
9191
uint8_t UBytes[4]; // seems to have the same code size as using struct UByte
9292
int8_t Bytes[4]; // Bytes[0] is LowByte
9393
uint16_t UWords[2];
@@ -122,7 +122,7 @@ union LongLongUnion {
122122
WordUnion MidLowWord;
123123
WordUnion MidHighWord;
124124
WordUnion HighWord;
125-
} WordUnion;
125+
} FourWordUnions;
126126
struct {
127127
uint32_t LowLong;
128128
uint32_t HighLong;
@@ -134,7 +134,7 @@ union LongLongUnion {
134134
struct {
135135
LongUnion LowLong;
136136
LongUnion HighLong;
137-
} LongUnion;
137+
} TwoLongUnions;
138138
uint8_t UBytes[8]; // seems to have the same code size as using struct UByte
139139
int8_t Bytes[8];
140140
uint16_t UWords[4];

src/MecanumWheelCarPWMMotorControl.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@ void MecanumWheelCarPWMMotorControl::setDirection(uint8_t aRequestedDirection) {
243243
uint8_t tBackRightMotorDirection;
244244

245245
/*
246-
* We set all for straight or movements to the left, movements to the right are implemented by just swapping left and right motors
246+
* We set all for straight or movements to the left, movements to the right are implemented by just swapping left and right motors
247247
*/
248-
if (aRequestedDirection & DIRECTION_TURN) {
248+
if (aRequestedDirection & DIRECTION_TURN_MASK) {
249249
/*
250250
* TURN requested
251251
* We have TURN and FOWARD -> turn center is front axis, TURN and BACKWARD -> turn center is back axis

0 commit comments

Comments
 (0)