2015-07-10 06:01:56 -07:00
/**
* @ file trigger_decoder . cpp
*
* @ date Dec 24 , 2013
2018-01-20 17:55:31 -08:00
* @ author Andrey Belomutskiy , ( c ) 2012 - 2018
2015-07-10 06:01:56 -07:00
*
* This file is part of rusEfi - see http : //rusefi.com
*
* rusEfi is free software ; you can redistribute it and / or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation ; either
* version 3 of the License , or ( at your option ) any later version .
*
* rusEfi is distributed in the hope that it will be useful , but WITHOUT ANY WARRANTY ; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License along with this program .
* If not , see < http : //www.gnu.org/licenses/>.
*/
2018-09-16 19:26:57 -07:00
# include "global.h"
2015-07-10 06:01:56 -07:00
# if EFI_SHAFT_POSITION_INPUT || defined(__DOXYGEN__)
# include "obd_error_codes.h"
# include "trigger_decoder.h"
# include "cyclic_buffer.h"
# include "trigger_mazda.h"
# include "trigger_chrysler.h"
# include "trigger_gm.h"
# include "trigger_bmw.h"
# include "trigger_mitsubishi.h"
2015-09-10 19:01:35 -07:00
# include "trigger_subaru.h"
2015-09-19 16:01:46 -07:00
# include "trigger_nissan.h"
2015-12-14 18:01:30 -08:00
# include "trigger_toyota.h"
2015-12-27 12:02:51 -08:00
# include "trigger_rover.h"
2016-05-27 19:02:56 -07:00
# include "trigger_honda.h"
2018-08-25 17:05:17 -07:00
# include "trigger_vw.h"
2015-07-10 06:01:56 -07:00
# include "trigger_structure.h"
# include "efiGpio.h"
# include "engine.h"
2015-09-12 18:03:09 -07:00
# include "engine_math.h"
2015-09-13 13:01:38 -07:00
# include "trigger_central.h"
2015-09-23 18:02:33 -07:00
# include "trigger_simulator.h"
2017-01-03 14:01:42 -08:00
# include "trigger_universal.h"
2018-02-03 13:06:34 -08:00
# include "rfiutil.h"
2015-09-12 18:03:09 -07:00
2015-09-13 09:01:42 -07:00
# if EFI_SENSOR_CHART || defined(__DOXYGEN__)
2015-09-12 18:03:09 -07:00
# include "sensor_chart.h"
# endif
2015-07-10 06:01:56 -07:00
EXTERN_ENGINE
;
2017-12-13 18:17:32 -08:00
static TriggerState initState CCM_OPTIONAL ;
2015-07-10 06:01:56 -07:00
static cyclic_buffer < int > errorDetection ;
2016-05-17 21:03:11 -07:00
static bool isInitializingTrigger = false ; // #286 miata NA config - sync error on startup
2015-07-10 06:01:56 -07:00
2015-09-05 20:02:46 -07:00
# if ! EFI_PROD_CODE || defined(__DOXYGEN__)
2015-07-10 06:01:56 -07:00
bool printTriggerDebug = false ;
float actualSynchGap ;
# endif /* ! EFI_PROD_CODE */
2017-05-12 19:31:02 -07:00
# if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
extern TunerStudioOutputChannels tsOutputChannels ;
# endif /* EFI_UNIT_TEST */
2015-07-10 06:01:56 -07:00
static Logging * logger ;
efitick_t lastDecodingErrorTime = US2NT ( - 10000000LL ) ;
2015-09-25 06:06:35 -07:00
// the boolean flag is a performance optimization so that complex comparison is avoided if no error
2017-12-06 15:38:25 -08:00
static bool someSortOfTriggerError = false ;
2015-07-10 06:01:56 -07:00
/**
* @ return TRUE is something is wrong with trigger decoding
*/
2016-01-11 14:01:33 -08:00
bool isTriggerDecoderError ( void ) {
2015-07-10 06:01:56 -07:00
return errorDetection . sum ( 6 ) > 4 ;
}
2017-05-15 20:28:49 -07:00
bool TriggerState : : isValidIndex ( DECLARE_ENGINE_PARAMETER_SIGNATURE ) {
2015-09-24 19:02:47 -07:00
return currentCycle . current_index < TRIGGER_SHAPE ( size ) ;
}
2015-07-10 06:01:56 -07:00
static trigger_wheel_e eventIndex [ 6 ] = { T_PRIMARY , T_PRIMARY , T_SECONDARY , T_SECONDARY , T_CHANNEL_3 , T_CHANNEL_3 } ;
2016-06-11 20:02:58 -07:00
static trigger_value_e eventType [ 6 ] = { TV_FALL , TV_RISE , TV_FALL , TV_RISE , TV_FALL , TV_RISE } ;
2015-07-10 06:01:56 -07:00
# define getCurrentGapDuration(nowNt) \
( isFirstEvent ? 0 : ( nowNt ) - toothed_previous_time )
2017-03-03 19:07:25 -08:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
# define PRINT_INC_INDEX if (printTriggerDebug) {\
printf ( " nextTriggerEvent index=%d \r \n " , currentCycle . current_index ) ; \
}
# else
# define PRINT_INC_INDEX {}
# endif /* EFI_UNIT_TEST */
2015-07-10 06:01:56 -07:00
# define nextTriggerEvent() \
{ \
2015-09-12 13:01:43 -07:00
uint32_t prevTime = currentCycle . timeOfPreviousEventNt [ triggerWheel ] ; \
2015-07-10 06:01:56 -07:00
if ( prevTime ! = 0 ) { \
/* even event - apply the value*/ \
2015-09-08 20:01:07 -07:00
currentCycle . totalTimeNt [ triggerWheel ] + = ( nowNt - prevTime ) ; \
currentCycle . timeOfPreviousEventNt [ triggerWheel ] = 0 ; \
2015-07-10 06:01:56 -07:00
} else { \
/* odd event - start accumulation */ \
2015-09-08 20:01:07 -07:00
currentCycle . timeOfPreviousEventNt [ triggerWheel ] = nowNt ; \
2015-07-10 06:01:56 -07:00
} \
2016-02-27 20:03:34 -08:00
if ( engineConfiguration - > useOnlyRisingEdgeForTrigger ) { currentCycle . current_index + + ; } \
2015-09-08 20:01:07 -07:00
currentCycle . current_index + + ; \
2017-03-03 19:07:25 -08:00
PRINT_INC_INDEX ; \
2015-07-10 06:01:56 -07:00
}
2017-03-18 18:36:51 -07:00
# define considerEventForGap() (!TRIGGER_SHAPE(useOnlyPrimaryForSync) || isPrimary)
2017-03-18 18:42:17 -07:00
# define needToSkipFall(type) ((!TRIGGER_SHAPE(gapBothDirections)) && (( TRIGGER_SHAPE(useRiseEdge)) && (type != TV_RISE)))
# define needToSkipRise(type) ((!TRIGGER_SHAPE(gapBothDirections)) && ((!TRIGGER_SHAPE(useRiseEdge)) && (type != TV_FALL)))
2017-03-18 18:36:51 -07:00
# define isLessImportant(type) (needToSkipFall(type) || needToSkipRise(type) || (!considerEventForGap()) )
2018-02-05 14:25:01 -08:00
TriggerState : : TriggerState ( ) {
reset ( ) ;
}
2017-03-18 18:36:51 -07:00
2018-02-05 14:25:01 -08:00
void TriggerState : : reset ( ) {
triggerCycleCallback = NULL ;
shaft_is_synchronized = false ;
toothed_previous_time = 0 ;
2018-10-21 09:03:08 -07:00
2018-10-21 08:27:14 -07:00
memset ( toothDurations , 0 , sizeof ( toothDurations ) ) ;
2018-02-05 14:25:01 -08:00
totalRevolutionCounter = 0 ;
totalTriggerErrorCounter = 0 ;
orderingErrorCounter = 0 ;
currentDuration = 0 ;
curSignal = SHAFT_PRIMARY_FALLING ;
prevSignal = SHAFT_PRIMARY_FALLING ;
startOfCycleNt = 0 ;
resetRunningCounters ( ) ;
resetCurrentCycleState ( ) ;
memset ( expectedTotalTime , 0 , sizeof ( expectedTotalTime ) ) ;
totalEventCountBase = 0 ;
isFirstEvent = true ;
}
int TriggerState : : getCurrentIndex ( ) {
return currentCycle . current_index ;
}
2018-02-05 14:29:16 -08:00
void TriggerState : : incrementTotalEventCounter ( ) {
totalRevolutionCounter + + ;
}
bool TriggerState : : isEvenRevolution ( ) {
return totalRevolutionCounter & 1 ;
}
void TriggerState : : resetCurrentCycleState ( ) {
memset ( currentCycle . eventCount , 0 , sizeof ( currentCycle . eventCount ) ) ;
memset ( currentCycle . timeOfPreviousEventNt , 0 , sizeof ( currentCycle . timeOfPreviousEventNt ) ) ;
memset ( currentCycle . totalTimeNt , 0 , sizeof ( currentCycle . totalTimeNt ) ) ;
currentCycle . current_index = 0 ;
}
2018-03-03 16:26:59 -08:00
void TriggerState : : onSynchronizationLost ( DECLARE_ENGINE_PARAMETER_SIGNATURE ) {
shaft_is_synchronized = false ;
2018-03-10 17:58:51 -08:00
// Needed for early instant-RPM detection
engine - > rpmCalculator . setStopSpinning ( PASS_ENGINE_PARAMETER_SIGNATURE ) ;
2018-03-03 16:26:59 -08:00
}
2015-07-10 06:01:56 -07:00
/**
* @ brief Trigger decoding happens here
2015-08-22 08:02:10 -07:00
* This method is invoked every time we have a fall or rise on one of the trigger sensors .
2015-07-10 06:01:56 -07:00
* This method changes the state of trigger_state_s data structure according to the trigger event
2015-08-22 08:02:10 -07:00
* @ param signal type of event which just happened
* @ param nowNt current time
2015-07-10 06:01:56 -07:00
*/
2017-05-15 20:28:49 -07:00
void TriggerState : : decodeTriggerEvent ( trigger_event_e const signal , efitime_t nowNt DECLARE_ENGINE_PARAMETER_SUFFIX ) {
2018-07-25 20:03:04 -07:00
efiAssertVoid ( CUSTOM_ERR_6640 , signal < = SHAFT_3RD_RISING , " unexpected signal " ) ;
2015-07-10 06:01:56 -07:00
trigger_wheel_e triggerWheel = eventIndex [ signal ] ;
2016-06-11 20:02:58 -07:00
trigger_value_e type = eventType [ signal ] ;
2015-07-10 06:01:56 -07:00
2017-05-25 20:23:51 -07:00
if ( ! CONFIG ( useOnlyRisingEdgeForTrigger ) & & curSignal = = prevSignal ) {
2015-07-10 06:01:56 -07:00
orderingErrorCounter + + ;
}
prevSignal = curSignal ;
curSignal = signal ;
2015-09-08 20:01:07 -07:00
currentCycle . eventCount [ triggerWheel ] + + ;
2015-07-10 06:01:56 -07:00
efitime_t currentDurationLong = getCurrentGapDuration ( nowNt ) ;
/**
* For performance reasons , we want to work with 32 bit values . If there has been more then
* 10 seconds since previous trigger event we do not really care .
*/
currentDuration =
currentDurationLong > 10 * US2NT ( US_PER_SECOND_LL ) ? 10 * US2NT ( US_PER_SECOND_LL ) : currentDurationLong ;
2016-01-11 14:01:33 -08:00
bool isPrimary = triggerWheel = = T_PRIMARY ;
2015-07-15 20:07:51 -07:00
2016-06-14 00:02:57 -07:00
if ( isLessImportant ( type ) ) {
2015-09-13 07:01:39 -07:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
2015-07-10 06:01:56 -07:00
if ( printTriggerDebug ) {
2018-04-25 23:11:51 -07:00
printf ( " %s isLessImportant %s now=%lld index=%d \r \n " ,
2015-07-10 06:01:56 -07:00
getTrigger_type_e ( engineConfiguration - > trigger . type ) ,
2015-09-22 20:01:31 -07:00
getTrigger_event_e ( signal ) ,
2017-03-03 19:07:25 -08:00
nowNt ,
currentCycle . current_index ) ;
2015-07-10 06:01:56 -07:00
}
2017-05-25 20:23:51 -07:00
# endif /* EFI_UNIT_TEST */
2015-07-10 06:01:56 -07:00
/**
* For less important events we simply increment the index .
*/
nextTriggerEvent ( )
;
2015-09-13 13:01:38 -07:00
} else {
2015-07-10 06:01:56 -07:00
2015-09-22 20:01:31 -07:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
if ( printTriggerDebug ) {
printf ( " %s event %s %d \r \n " ,
getTrigger_type_e ( engineConfiguration - > trigger . type ) ,
getTrigger_event_e ( signal ) ,
nowNt ) ;
}
2017-05-25 20:23:51 -07:00
# endif /* EFI_UNIT_TEST */
2015-09-22 20:01:31 -07:00
2015-09-23 20:01:40 -07:00
isFirstEvent = false ;
2015-07-10 06:01:56 -07:00
// todo: skip a number of signal from the beginning
2018-10-21 09:29:41 -07:00
toothDurations [ 0 ] = currentDuration ;
2015-09-13 07:01:39 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2018-10-21 09:29:41 -07:00
// scheduleMsg(&logger, "from %.2f to %.2f %d %d", triggerConfig->syncRatioFrom, triggerConfig->syncRatioTo, toothDurations[0], shaftPositionState->toothDurations[1]);
// scheduleMsg(&logger, "ratio %.2f", 1.0 * toothDurations[0]/ shaftPositionState->toothDurations[1]);
2015-07-10 06:01:56 -07:00
# else
2017-03-03 18:49:55 -08:00
if ( printTriggerDebug ) {
2018-10-21 09:29:41 -07:00
printf ( " ratio %.2f: current=%d previous=%d \r \n " , 1.0 * toothDurations [ 0 ] / toothDurations [ 1 ] ,
toothDurations [ 0 ] , toothDurations [ 1 ] ) ;
2015-09-23 20:01:40 -07:00
}
2015-07-10 06:01:56 -07:00
# endif
2016-01-11 14:01:33 -08:00
bool isSynchronizationPoint ;
2015-07-10 06:01:56 -07:00
2015-09-23 20:01:40 -07:00
if ( TRIGGER_SHAPE ( isSynchronizationNeeded ) ) {
2017-03-04 17:19:14 -08:00
// this is getting a little out of hand, any ideas?
2017-05-25 20:23:51 -07:00
if ( CONFIG ( debugMode ) = = DBG_TRIGGER_SYNC ) {
2017-05-12 19:31:02 -07:00
# if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
2018-10-21 09:29:41 -07:00
float currentGap = 1.0 * toothDurations [ 0 ] / toothDurations [ 1 ] ;
2017-05-13 05:14:13 -07:00
tsOutputChannels . debugFloatField1 = currentGap ;
2017-05-13 05:25:47 -07:00
tsOutputChannels . debugFloatField2 = currentCycle . current_index ;
2017-05-12 19:31:02 -07:00
# endif /* EFI_UNIT_TEST */
}
2018-10-21 09:29:41 -07:00
bool isGapCondition [ GAP_TRACKING_LENGHT ] ;
for ( int i = 0 ; i < GAP_TRACKING_LENGHT ; i + + ) {
2018-10-21 09:36:39 -07:00
isGapCondition [ i ] = cisnan ( TRIGGER_SHAPE ( syncronizationRatioFrom [ i ] ) ) | | ( toothDurations [ i ] > toothDurations [ i + 1 ] * TRIGGER_SHAPE ( syncronizationRatioFrom [ i ] )
& & toothDurations [ i ] < toothDurations [ i + 1 ] * TRIGGER_SHAPE ( syncronizationRatioTo [ i ] ) ) ;
2018-10-21 09:29:41 -07:00
}
2017-03-04 17:19:14 -08:00
2015-09-23 20:01:40 -07:00
/**
* Here I prefer to have two multiplications instead of one division , that ' s a micro - optimization
*/
2018-10-21 09:29:41 -07:00
isSynchronizationPoint = isGapCondition [ 0 ]
& & isGapCondition [ 1 ]
& & isGapCondition [ 2 ] ;
2015-07-10 06:01:56 -07:00
2015-09-11 22:02:28 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2017-05-25 20:23:51 -07:00
if ( CONFIG ( isPrintTriggerSynchDetails ) | | ( someSortOfTriggerError & & ! CONFIG ( silentTriggerError ) ) ) {
2015-07-10 06:01:56 -07:00
# else
2015-09-23 20:01:40 -07:00
if ( printTriggerDebug ) {
2015-07-10 06:01:56 -07:00
# endif /* EFI_PROD_CODE */
2018-10-21 09:18:15 -07:00
float gap = 1.0 * currentDuration / toothDurations [ 1 ] ;
float prevGap = 1.0 * toothDurations [ 1 ] / toothDurations [ 2 ] ;
float gap3 = 1.0 * toothDurations [ 2 ] / toothDurations [ 3 ] ;
2015-09-11 22:02:28 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2018-01-23 09:05:14 -08:00
scheduleMsg ( logger , " %d: cur=%.2f/prev=%.2f/3rd=%.2f @ %d while expected from %.2f to %.2f and 2nd from %.2f to %.2f and 3rd from %.2f to %.2f error=%d " ,
2017-01-09 19:02:05 -08:00
getTimeNowSeconds ( ) ,
2016-01-30 19:03:36 -08:00
gap , prevGap , gap3 ,
currentCycle . current_index ,
2018-10-21 08:17:47 -07:00
TRIGGER_SHAPE ( syncronizationRatioFrom [ 0 ] ) , TRIGGER_SHAPE ( syncronizationRatioTo [ 0 ] ) ,
2018-10-21 06:31:58 -07:00
TRIGGER_SHAPE ( syncronizationRatioFrom [ 1 ] ) , TRIGGER_SHAPE ( syncronizationRatioTo [ 1 ] ) ,
TRIGGER_SHAPE ( syncronizationRatioFrom [ 2 ] ) , TRIGGER_SHAPE ( syncronizationRatioTo [ 2 ] ) ,
2017-11-19 19:31:01 -08:00
someSortOfTriggerError ) ;
2018-10-21 08:27:14 -07:00
for ( int i = 0 ; i < GAP_TRACKING_LENGHT ; i + + ) {
scheduleMsg ( logger , " %d: " , i ) ;
}
2015-07-10 06:01:56 -07:00
# else
2015-09-23 20:01:40 -07:00
actualSynchGap = gap ;
2018-10-21 09:18:15 -07:00
print ( " current gap %.2f/%.2f/%.2f c=%d prev=%d \r \n " , gap , prevGap , gap3 , currentDuration , toothDurations [ 1 ] ) ;
2015-07-10 06:01:56 -07:00
# endif /* EFI_PROD_CODE */
2015-09-23 20:01:40 -07:00
}
2015-07-10 06:01:56 -07:00
2015-09-23 20:01:40 -07:00
} else {
/**
2017-03-03 18:57:28 -08:00
* We are here in case of a wheel without synchronization - we just need to count events ,
* synchronization point simply happens once we have the right number of events
*
* in case of noise the counter could be above the expected number of events , that ' s why ' more or equals ' and not just ' equals '
2015-09-23 20:01:40 -07:00
*/
2017-03-03 18:49:55 -08:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
2018-04-25 23:11:51 -07:00
if ( printTriggerDebug ) {
printf ( " sync=%d index=%d size=%d \r \n " ,
2017-03-03 18:49:55 -08:00
shaft_is_synchronized ,
currentCycle . current_index ,
TRIGGER_SHAPE ( size ) ) ;
2018-04-25 23:11:51 -07:00
}
2017-05-25 20:23:51 -07:00
# endif /* EFI_UNIT_TEST */
int endOfCycleIndex = TRIGGER_SHAPE ( size ) - ( CONFIG ( useOnlyRisingEdgeForTrigger ) ? 2 : 1 ) ;
2017-03-03 18:49:55 -08:00
2017-03-03 18:57:28 -08:00
2017-03-03 18:59:00 -08:00
isSynchronizationPoint = ! shaft_is_synchronized | | ( currentCycle . current_index > = endOfCycleIndex ) ;
2015-07-10 06:01:56 -07:00
2017-03-03 21:43:53 -08:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
2017-05-25 20:23:51 -07:00
if ( printTriggerDebug ) {
printf ( " isSynchronizationPoint=%d index=%d size=%d \r \n " ,
isSynchronizationPoint ,
currentCycle . current_index ,
TRIGGER_SHAPE ( size ) ) ;
}
# endif /* EFI_UNIT_TEST */
2017-03-03 21:43:53 -08:00
2015-09-23 20:01:40 -07:00
}
2015-07-10 06:01:56 -07:00
2015-09-13 07:01:39 -07:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
2015-07-10 06:01:56 -07:00
if ( printTriggerDebug ) {
printf ( " %s isSynchronizationPoint=%d index=%d %s \r \n " ,
getTrigger_type_e ( engineConfiguration - > trigger . type ) ,
2015-09-08 20:01:07 -07:00
isSynchronizationPoint , currentCycle . current_index ,
2015-07-10 06:01:56 -07:00
getTrigger_event_e ( signal ) ) ;
}
2017-05-25 20:23:51 -07:00
# endif /* EFI_UNIT_TEST */
2015-07-10 06:01:56 -07:00
2015-09-23 20:01:40 -07:00
if ( isSynchronizationPoint ) {
2015-07-10 06:01:56 -07:00
2015-09-23 20:01:40 -07:00
/**
* We can check if things are fine by comparing the number of events in a cycle with the expected number of event .
*/
bool isDecodingError = currentCycle . eventCount [ 0 ] ! = TRIGGER_SHAPE ( expectedEventCount [ 0 ] )
| | currentCycle . eventCount [ 1 ] ! = TRIGGER_SHAPE ( expectedEventCount [ 1 ] )
| | currentCycle . eventCount [ 2 ] ! = TRIGGER_SHAPE ( expectedEventCount [ 2 ] ) ;
2016-09-14 16:03:00 -07:00
enginePins . triggerDecoderErrorPin . setValue ( isDecodingError ) ;
2016-12-16 18:02:54 -08:00
if ( isDecodingError & & ! isInitializingTrigger ) {
2017-05-22 12:30:39 -07:00
if ( engineConfiguration - > debugMode = = DBG_TRIGGER_SYNC ) {
2017-05-12 19:31:02 -07:00
# if ! EFI_UNIT_TEST || defined(__DOXYGEN__)
tsOutputChannels . debugIntField1 = currentCycle . eventCount [ 0 ] ;
tsOutputChannels . debugIntField2 = currentCycle . eventCount [ 1 ] ;
tsOutputChannels . debugIntField3 = currentCycle . eventCount [ 2 ] ;
# endif /* EFI_UNIT_TEST */
}
2017-01-15 12:06:23 -08:00
warning ( CUSTOM_SYNC_COUNT_MISMATCH , " trigger not happy current %d/%d/%d expected %d/%d/%d " ,
2016-11-08 19:02:47 -08:00
currentCycle . eventCount [ 0 ] ,
currentCycle . eventCount [ 1 ] ,
currentCycle . eventCount [ 2 ] ,
TRIGGER_SHAPE ( expectedEventCount [ 0 ] ) ,
TRIGGER_SHAPE ( expectedEventCount [ 1 ] ) ,
TRIGGER_SHAPE ( expectedEventCount [ 2 ] ) ) ;
2015-09-23 20:01:40 -07:00
lastDecodingErrorTime = getTimeNowNt ( ) ;
2015-09-25 06:06:35 -07:00
someSortOfTriggerError = true ;
2015-09-23 20:01:40 -07:00
totalTriggerErrorCounter + + ;
2017-12-06 15:38:25 -08:00
if ( CONFIG ( isPrintTriggerSynchDetails ) | | someSortOfTriggerError ) {
2015-09-13 07:01:39 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2015-09-23 20:01:40 -07:00
scheduleMsg ( logger , " error: synchronizationPoint @ index %d expected %d/%d/%d got %d/%d/%d " ,
currentCycle . current_index , TRIGGER_SHAPE ( expectedEventCount [ 0 ] ) ,
TRIGGER_SHAPE ( expectedEventCount [ 1 ] ) , TRIGGER_SHAPE ( expectedEventCount [ 2 ] ) ,
currentCycle . eventCount [ 0 ] , currentCycle . eventCount [ 1 ] , currentCycle . eventCount [ 2 ] ) ;
2015-07-10 06:01:56 -07:00
# endif /* EFI_PROD_CODE */
2015-09-23 20:01:40 -07:00
}
2015-07-10 06:01:56 -07:00
}
2015-09-23 20:01:40 -07:00
errorDetection . add ( isDecodingError ) ;
2015-07-10 06:01:56 -07:00
2015-09-23 20:01:40 -07:00
if ( isTriggerDecoderError ( ) ) {
2016-12-25 18:02:31 -08:00
warning ( CUSTOM_OBD_TRG_DECODING , " trigger decoding issue. expected %d/%d/%d got %d/%d/%d " ,
2015-09-23 20:01:40 -07:00
TRIGGER_SHAPE ( expectedEventCount [ 0 ] ) , TRIGGER_SHAPE ( expectedEventCount [ 1 ] ) ,
TRIGGER_SHAPE ( expectedEventCount [ 2 ] ) , currentCycle . eventCount [ 0 ] , currentCycle . eventCount [ 1 ] ,
currentCycle . eventCount [ 2 ] ) ;
}
2015-07-10 06:01:56 -07:00
2015-09-23 20:01:40 -07:00
shaft_is_synchronized = true ;
// this call would update duty cycle values
nextTriggerEvent ( )
;
2015-07-10 06:01:56 -07:00
2018-02-05 14:25:01 -08:00
2018-04-25 23:11:51 -07:00
if ( triggerCycleCallback ! = NULL ) {
triggerCycleCallback ( this ) ;
}
startOfCycleNt = nowNt ;
resetCurrentCycleState ( ) ;
incrementTotalEventCounter ( ) ;
runningRevolutionCounter + + ;
totalEventCountBase + = TRIGGER_SHAPE ( size ) ;
2018-02-05 14:25:01 -08:00
2017-03-03 21:43:53 -08:00
2017-03-03 21:46:02 -08:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
2017-03-03 21:43:53 -08:00
if ( printTriggerDebug ) {
printf ( " index=%d %d \r \n " ,
currentCycle . current_index ,
runningRevolutionCounter ) ;
}
2017-03-03 21:46:02 -08:00
# endif /* EFI_UNIT_TEST */
2018-04-25 23:11:51 -07:00
} else { /* if (!isSynchronizationPoint) */
2015-09-23 20:01:40 -07:00
nextTriggerEvent ( )
;
}
2015-07-10 06:01:56 -07:00
2018-10-21 09:18:15 -07:00
toothDurations [ 3 ] = toothDurations [ 2 ] ;
2018-10-21 09:03:08 -07:00
toothDurations [ 2 ] = toothDurations [ 1 ] ;
2018-10-21 09:18:15 -07:00
toothDurations [ 1 ] = currentDuration ;
2015-09-23 20:01:40 -07:00
toothed_previous_time = nowNt ;
2015-09-13 13:01:38 -07:00
}
2017-05-15 20:28:49 -07:00
if ( ! isValidIndex ( PASS_ENGINE_PARAMETER_SIGNATURE ) & & ! isInitializingTrigger ) {
2016-08-26 13:03:22 -07:00
// let's not show a warning if we are just starting to spin
2018-07-24 16:58:32 -07:00
if ( GET_RPM ( ) ! = 0 ) {
2016-08-26 13:03:22 -07:00
warning ( CUSTOM_SYNC_ERROR , " sync error: index #%d above total size %d " , currentCycle . current_index , TRIGGER_SHAPE ( size ) ) ;
lastDecodingErrorTime = getTimeNowNt ( ) ;
someSortOfTriggerError = true ;
}
2015-09-25 06:06:35 -07:00
}
if ( someSortOfTriggerError ) {
if ( getTimeNowNt ( ) - lastDecodingErrorTime > US2NT ( US_PER_SECOND_LL ) ) {
someSortOfTriggerError = false ;
}
2015-09-24 19:02:47 -07:00
}
2017-12-03 21:04:47 -08:00
runtimeStatistics ( nowNt PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-09-13 13:01:38 -07:00
2018-03-10 17:58:51 -08:00
// Needed for early instant-RPM detection
if ( ! isInitializingTrigger ) {
engine - > rpmCalculator . setSpinningUp ( nowNt PASS_ENGINE_PARAMETER_SUFFIX ) ;
}
2015-07-10 06:01:56 -07:00
}
/**
* External logger is needed because at this point our logger is not yet initialized
*/
2017-05-15 20:28:49 -07:00
void TriggerShape : : initializeTriggerShape ( Logging * logger DECLARE_ENGINE_PARAMETER_SUFFIX ) {
2016-01-09 08:01:43 -08:00
const trigger_config_s * triggerConfig = & engineConfiguration - > trigger ;
2018-02-03 13:06:34 -08:00
# if !EFI_UNIT_TEST
// we have a confusing threading model so some synchronization would not hurt
bool alreadyLocked = lockAnyContext ( ) ;
# endif /* EFI_UNIT_TEST */
2015-09-13 07:01:39 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2018-07-25 20:03:04 -07:00
efiAssertVoid ( CUSTOM_ERR_6641 , getRemainingStack ( chThdGetSelfX ( ) ) > 256 , " init t " ) ;
2016-01-09 08:01:43 -08:00
scheduleMsg ( logger , " initializeTriggerShape(%s/%d) " , getTrigger_type_e ( triggerConfig - > type ) , ( int ) triggerConfig - > type ) ;
2015-07-10 06:01:56 -07:00
# endif
2015-09-13 07:01:39 -07:00
2017-03-12 19:55:41 -07:00
shapeDefinitionError = false ;
2015-07-10 06:01:56 -07:00
switch ( triggerConfig - > type ) {
case TT_TOOTHED_WHEEL :
2017-03-01 18:31:39 -08:00
initializeSkippedToothTriggerShapeExt ( this , triggerConfig - > customTotalToothCount ,
2017-05-15 20:28:49 -07:00
triggerConfig - > customSkippedToothCount , engineConfiguration - > operationMode PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_MAZDA_MIATA_NA :
2017-05-15 20:28:49 -07:00
initializeMazdaMiataNaShape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2016-11-03 14:03:11 -07:00
case TT_MAZDA_MIATA_NB1 :
2017-05-15 20:28:49 -07:00
initializeMazdaMiataNb1Shape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-11-14 20:01:47 -08:00
break ;
case TT_MAZDA_MIATA_VVT_TEST :
2017-05-15 20:28:49 -07:00
initializeMazdaMiataVVtTestShape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2016-10-04 11:00:58 -07:00
case TT_MIATA_VVT :
2017-05-15 20:28:49 -07:00
initializeMazdaMiataNb2Crank ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-11-13 20:02:33 -08:00
break ;
2016-10-04 11:00:58 -07:00
2015-07-10 06:01:56 -07:00
case TT_DODGE_NEON_1995 :
2017-05-15 20:28:49 -07:00
configureNeon1995TriggerShape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2018-03-01 03:01:15 -08:00
case TT_DODGE_NEON_1995_ONLY_CRANK :
configureNeon1995TriggerShapeOnlyCrank ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
break ;
2015-09-05 20:02:46 -07:00
case TT_DODGE_STRATUS :
2017-05-15 20:28:49 -07:00
configureDodgeStratusTriggerShape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-09-05 20:02:46 -07:00
break ;
2016-09-21 09:03:07 -07:00
case TT_DODGE_NEON_2003_CAM :
2017-05-15 20:28:49 -07:00
configureNeon2003TriggerShapeCam ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-09-21 14:02:13 -07:00
break ;
2016-09-21 09:03:07 -07:00
case TT_DODGE_NEON_2003_CRANK :
2017-05-15 20:28:49 -07:00
configureNeon2003TriggerShapeCam ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
// configureNeon2003TriggerShapeCrank(triggerShape PASS_ENGINE_PARAMETER_SUFFIX);
2015-07-10 06:01:56 -07:00
break ;
case TT_FORD_ASPIRE :
2017-05-15 20:28:49 -07:00
configureFordAspireTriggerShape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_GM_7X :
2017-05-15 20:28:49 -07:00
configureGmTriggerShape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_MAZDA_DOHC_1_4 :
2017-05-15 20:28:49 -07:00
configureMazdaProtegeLx ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_ONE_PLUS_ONE :
2017-05-15 20:28:49 -07:00
configureOnePlusOne ( this , engineConfiguration - > operationMode PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2016-08-16 19:05:36 -07:00
case TT_3_1_CAM :
2017-05-15 20:28:49 -07:00
configure3_1_cam ( this , engineConfiguration - > operationMode PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-08-16 19:05:36 -07:00
break ;
2015-07-10 06:01:56 -07:00
case TT_ONE_PLUS_TOOTHED_WHEEL_60_2 :
2017-05-15 20:28:49 -07:00
configureOnePlus60_2 ( this , engineConfiguration - > operationMode PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_ONE :
2017-05-15 20:28:49 -07:00
setToothedWheelConfiguration ( this , 1 , 0 , engineConfiguration - > operationMode PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_MAZDA_SOHC_4 :
2017-05-15 20:28:49 -07:00
configureMazdaProtegeSOHC ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_MINI_COOPER_R50 :
2017-05-15 20:28:49 -07:00
configureMiniCooperTriggerShape ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_TOOTHED_WHEEL_60_2 :
2017-05-15 20:28:49 -07:00
setToothedWheelConfiguration ( this , 60 , 2 , engineConfiguration - > operationMode PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_60_2_VW :
2017-05-15 20:28:49 -07:00
setVwConfiguration ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_TOOTHED_WHEEL_36_1 :
2017-05-15 20:28:49 -07:00
setToothedWheelConfiguration ( this , 36 , 1 , engineConfiguration - > operationMode PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2017-02-13 21:02:59 -08:00
case TT_HONDA_4_24_1 :
2017-05-15 20:28:49 -07:00
configureHonda_1_4_24 ( this , true , true , T_CHANNEL_3 , T_PRIMARY , 0 PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2017-02-13 21:02:59 -08:00
case TT_HONDA_4_24 :
2017-05-15 20:28:49 -07:00
configureHonda_1_4_24 ( this , false , true , T_NONE , T_PRIMARY , 0 PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2017-02-13 20:03:19 -08:00
case TT_HONDA_1_24 :
2017-05-15 20:28:49 -07:00
configureHonda_1_4_24 ( this , true , false , T_PRIMARY , T_NONE , 10 PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2016-10-15 20:03:28 -07:00
case TT_HONDA_ACCORD_1_24_SHIFTED :
2017-05-15 20:28:49 -07:00
configureHondaAccordShifted ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-10-15 20:03:28 -07:00
break ;
2017-02-13 22:03:01 -08:00
case TT_HONDA_1_4_24 :
2017-05-15 20:28:49 -07:00
configureHondaAccordCDDip ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2016-05-27 19:02:56 -07:00
case TT_HONDA_CBR_600 :
2017-05-15 20:28:49 -07:00
configureHondaCbr600 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-05-27 19:02:56 -07:00
break ;
2016-07-09 11:02:36 -07:00
case TT_HONDA_CBR_600_CUSTOM :
2017-05-15 20:28:49 -07:00
configureHondaCbr600custom ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-07-09 11:02:36 -07:00
break ;
2017-02-22 18:13:04 -08:00
case TT_MITSUBISHI :
2017-05-15 20:28:49 -07:00
initializeMitsubishi4g18 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_DODGE_RAM :
2017-05-15 20:28:49 -07:00
initDodgeRam ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
break ;
2017-01-23 18:03:11 -08:00
case TT_JEEP_18_2_2_2 :
2017-05-15 20:28:49 -07:00
initJeep18_2_2_2 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2017-01-23 13:03:46 -08:00
break ;
2017-01-02 16:03:36 -08:00
case TT_SUBARU_7_6 :
2017-05-15 20:28:49 -07:00
initializeSubaru7_6 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2017-01-02 16:03:36 -08:00
break ;
2015-09-10 19:01:35 -07:00
case TT_36_2_2_2 :
2017-05-15 20:28:49 -07:00
initialize36_2_2_2 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-09-10 19:01:35 -07:00
break ;
2016-06-13 13:03:13 -07:00
case TT_2JZ_3_34 :
2017-05-15 20:28:49 -07:00
initialize2jzGE3_34 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-06-13 13:03:13 -07:00
break ;
case TT_2JZ_1_12 :
2017-05-15 20:28:49 -07:00
initialize2jzGE1_12 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-12-14 18:01:30 -08:00
break ;
2017-03-18 17:18:21 -07:00
case TT_NISSAN_SR20VE :
2017-05-15 20:28:49 -07:00
initializeNissanSR20VE_4 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-09-19 16:01:46 -07:00
break ;
2017-04-02 14:59:01 -07:00
case TT_NISSAN_SR20VE_360 :
2017-05-15 20:28:49 -07:00
initializeNissanSR20VE_4_360 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2017-04-02 14:36:59 -07:00
break ;
2015-12-27 12:02:51 -08:00
case TT_ROVER_K :
2017-05-15 20:28:49 -07:00
initializeRoverK ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-12-27 12:02:51 -08:00
break ;
2016-05-22 10:07:12 -07:00
case TT_GM_LS_24 :
2017-05-15 20:28:49 -07:00
initGmLS24 ( this PASS_ENGINE_PARAMETER_SUFFIX ) ;
2016-05-22 10:07:12 -07:00
break ;
2015-07-10 06:01:56 -07:00
default :
2017-03-19 14:03:42 -07:00
shapeDefinitionError = true ;
warning ( CUSTOM_ERR_NO_SHAPE , " initializeTriggerShape() not implemented: %d " , triggerConfig - > type ) ;
2015-07-10 06:01:56 -07:00
}
2018-02-03 13:06:34 -08:00
if ( ! shapeDefinitionError ) {
wave . checkSwitchTimes ( getSize ( ) ) ;
/**
* this instance is used only to initialize ' this ' TriggerShape instance
* # 192 BUG real hardware trigger events could be coming even while we are initializing trigger
*/
initState . reset ( ) ;
calculateTriggerSynchPoint ( & initState PASS_ENGINE_PARAMETER_SUFFIX ) ;
2018-02-03 17:16:14 -08:00
if ( engine - > triggerCentral . triggerShape . getSize ( ) = = 0 ) {
firmwareError ( CUSTOM_ERR_TRIGGER_ZERO , " triggerShape size is zero " ) ;
}
engine - > engineCycleEventCount = getLength ( ) ;
2018-02-03 13:06:34 -08:00
}
version + + ;
# if !EFI_UNIT_TEST
if ( ! alreadyLocked ) {
unlockAnyContext ( ) ;
}
# endif
2018-03-10 17:58:51 -08:00
// Moved here from mainTriggerCallback()
prepareOutputSignals ( PASS_ENGINE_PARAMETER_SIGNATURE ) ;
2015-07-10 06:01:56 -07:00
}
2018-02-05 14:30:19 -08:00
static void onFindIndexCallback ( TriggerState * state ) {
2015-07-10 06:01:56 -07:00
for ( int i = 0 ; i < PWM_PHASE_MAX_WAVE_PER_PWM ; i + + ) {
// todo: that's not the best place for this intermediate data storage, fix it!
2015-09-08 20:01:07 -07:00
state - > expectedTotalTime [ i ] = state - > currentCycle . totalTimeNt [ i ] ;
2015-07-10 06:01:56 -07:00
}
}
/**
* Trigger shape is defined in a way which is convenient for trigger shape definition
* On the other hand , trigger decoder indexing begins from synchronization event .
*
* This function finds the index of synchronization event within TriggerShape
*/
2015-09-23 20:01:40 -07:00
uint32_t findTriggerZeroEventIndex ( TriggerState * state , TriggerShape * shape ,
2017-05-15 20:28:49 -07:00
trigger_config_s const * triggerConfig DECLARE_ENGINE_PARAMETER_SUFFIX ) {
2015-09-13 07:01:39 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2018-07-25 20:30:00 -07:00
efiAssert ( CUSTOM_ERR_ASSERT , getRemainingStack ( chThdGetSelfX ( ) ) > 128 , " findPos " , - 1 ) ;
2015-09-13 07:01:39 -07:00
# endif
2016-05-17 21:03:11 -07:00
isInitializingTrigger = true ;
2015-07-10 06:01:56 -07:00
errorDetection . clear ( ) ;
2018-07-25 20:30:00 -07:00
efiAssert ( CUSTOM_ERR_ASSERT , state ! = NULL , " NULL state " , - 1 ) ;
2015-07-10 06:01:56 -07:00
2015-09-13 13:01:38 -07:00
state - > reset ( ) ;
2015-09-13 07:01:39 -07:00
2017-02-23 11:00:03 -08:00
if ( shape - > shapeDefinitionError ) {
return 0 ;
}
2015-07-10 06:01:56 -07:00
// todo: should this variable be declared 'static' to reduce stack usage?
TriggerStimulatorHelper helper ;
2018-02-05 14:41:05 -08:00
uint32_t syncIndex = helper . findTriggerSyncPoint ( shape , state PASS_ENGINE_PARAMETER_SUFFIX ) ;
2017-03-04 05:55:53 -08:00
if ( syncIndex = = EFI_ERROR_CODE ) {
2016-05-17 21:03:11 -07:00
isInitializingTrigger = false ;
2017-03-04 05:55:53 -08:00
return syncIndex ;
2015-07-10 06:01:56 -07:00
}
2018-07-25 20:30:00 -07:00
efiAssert ( CUSTOM_ERR_ASSERT , state - > getTotalRevolutionCounter ( ) = = 1 , " findZero_revCounter " , EFI_ERROR_CODE ) ;
2015-07-10 06:01:56 -07:00
2017-03-04 05:55:53 -08:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
if ( printTriggerDebug ) {
2017-03-04 06:06:06 -08:00
printf ( " findTriggerZeroEventIndex: syncIndex located %d! \r \n " , syncIndex ) ;
2017-03-04 05:55:53 -08:00
}
# endif /* EFI_UNIT_TEST */
2015-07-10 06:01:56 -07:00
/**
* Now that we have just located the synch point , we can simulate the whole cycle
* in order to calculate expected duty cycle
*
* todo : add a comment why are we doing ' 2 * shape - > getSize ( ) ' here ?
*/
2018-02-05 14:30:19 -08:00
state - > triggerCycleCallback = onFindIndexCallback ;
2015-07-10 06:01:56 -07:00
2018-02-05 14:44:10 -08:00
helper . assertSyncPositionAndSetDutyCycle ( syncIndex , state , shape PASS_ENGINE_PARAMETER_SUFFIX ) ;
2015-07-10 06:01:56 -07:00
2016-05-17 21:03:11 -07:00
isInitializingTrigger = false ;
2017-03-04 05:55:53 -08:00
return syncIndex % shape - > getSize ( ) ;
2015-07-10 06:01:56 -07:00
}
void initTriggerDecoderLogger ( Logging * sharedLogger ) {
logger = sharedLogger ;
}
void initTriggerDecoder ( void ) {
2017-04-21 13:20:06 -07:00
# if EFI_GPIO_HARDWARE || defined(__DOXYGEN__)
2017-04-21 15:11:36 -07:00
enginePins . triggerDecoderErrorPin . initPin ( " trg_err " , boardConfiguration - > triggerErrorPin ,
2015-09-23 20:01:40 -07:00
& boardConfiguration - > triggerErrorPinMode ) ;
2017-04-21 13:20:06 -07:00
# endif /* EFI_GPIO_HARDWARE */
2015-07-10 06:01:56 -07:00
}
# endif /* EFI_SHAFT_POSITION_INPUT */