2015-07-10 06:01:56 -07:00
/**
* @ file trigger_decoder . cpp
*
* @ date Dec 24 , 2013
2015-12-31 13:02:30 -08:00
* @ author Andrey Belomutskiy , ( c ) 2012 - 2016
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/>.
*/
# include "main.h"
# 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"
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"
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
static OutputPin triggerDecoderErrorPin ;
EXTERN_ENGINE
;
static cyclic_buffer < int > errorDetection ;
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 */
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
2016-01-11 14:01:33 -08:00
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 ;
}
2016-01-11 14:01:33 -08:00
bool TriggerState : : isValidIndex ( DECLARE_ENGINE_PARAMETER_F ) {
2015-09-24 19:02:47 -07:00
return currentCycle . current_index < TRIGGER_SHAPE ( size ) ;
}
2015-07-10 06:01:56 -07:00
float TriggerState : : getTriggerDutyCycle ( int index ) {
float time = prevTotalTime [ index ] ;
return 100 * time / prevCycleDuration ;
}
static trigger_wheel_e eventIndex [ 6 ] = { T_PRIMARY , T_PRIMARY , T_SECONDARY , T_SECONDARY , T_CHANNEL_3 , T_CHANNEL_3 } ;
2015-10-31 13:02:10 -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 )
# 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
} \
2015-09-08 20:01:07 -07:00
if ( engineConfiguration - > useOnlyFrontForTrigger ) { currentCycle . current_index + + ; } \
currentCycle . current_index + + ; \
2015-07-10 06:01:56 -07:00
}
# define nextRevolution() { \
if ( cycleCallback ! = NULL ) { \
cycleCallback ( this ) ; \
} \
2015-09-08 20:01:07 -07:00
memcpy ( prevTotalTime , currentCycle . totalTimeNt , sizeof ( prevTotalTime ) ) ; \
2015-07-10 06:01:56 -07:00
prevCycleDuration = nowNt - startOfCycleNt ; \
startOfCycleNt = nowNt ; \
2015-09-08 20:01:07 -07:00
resetCurrentCycleState ( ) ; \
2015-07-10 06:01:56 -07:00
totalRevolutionCounter + + ; \
runningRevolutionCounter + + ; \
totalEventCountBase + = TRIGGER_SHAPE ( size ) ; \
}
/**
* @ 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
*/
void TriggerState : : decodeTriggerEvent ( trigger_event_e const signal , efitime_t nowNt DECLARE_ENGINE_PARAMETER_S ) {
efiAssertVoid ( signal < = SHAFT_3RD_UP , " unexpected signal " ) ;
trigger_wheel_e triggerWheel = eventIndex [ signal ] ;
if ( ! engineConfiguration - > useOnlyFrontForTrigger & & curSignal = = prevSignal ) {
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
2015-07-10 06:01:56 -07:00
if ( isLessImportant ( signal ) ) {
2015-09-13 07:01:39 -07:00
# if EFI_UNIT_TEST || defined(__DOXYGEN__)
2015-07-10 06:01:56 -07:00
if ( printTriggerDebug ) {
2015-09-22 20:01:31 -07:00
printf ( " %s isLessImportant %s %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 ) ,
nowNt ) ;
2015-07-10 06:01:56 -07:00
}
# endif
/**
* For less important events we simply increment the index .
*/
nextTriggerEvent ( )
;
2015-07-15 21:07:25 -07:00
if ( TRIGGER_SHAPE ( gapBothDirections ) & & considerEventForGap ( ) ) {
2015-07-10 06:01:56 -07:00
isFirstEvent = false ;
2015-12-27 13:02:44 -08:00
thirdPreviousDuration = durationBeforePrevious ;
2015-09-11 22:02:28 -07:00
durationBeforePrevious = toothed_previous_duration ;
toothed_previous_duration = currentDuration ;
2015-07-10 06:01:56 -07:00
toothed_previous_time = nowNt ;
}
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 ) ;
}
# endif
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
2015-09-13 07:01:39 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2015-07-10 06:01:56 -07:00
// scheduleMsg(&logger, "from %f to %f %d %d", triggerConfig->syncRatioFrom, triggerConfig->syncRatioTo, currentDuration, shaftPositionState->toothed_previous_duration);
// scheduleMsg(&logger, "ratio %f", 1.0 * currentDuration/ shaftPositionState->toothed_previous_duration);
# else
2015-09-23 20:01:40 -07:00
if ( toothed_previous_duration ! = 0 ) {
2015-07-10 06:01:56 -07:00
// printf("ratio %f: cur=%d pref=%d\r\n", 1.0 * currentDuration / shaftPositionState->toothed_previous_duration,
// currentDuration, shaftPositionState->toothed_previous_duration);
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 ) ) {
/**
* Here I prefer to have two multiplications instead of one division , that ' s a micro - optimization
*/
2015-12-27 13:02:44 -08:00
isSynchronizationPoint =
currentDuration > toothed_previous_duration * TRIGGER_SHAPE ( syncRatioFrom )
2015-09-23 20:01:40 -07:00
& & currentDuration < toothed_previous_duration * TRIGGER_SHAPE ( syncRatioTo )
& & toothed_previous_duration > durationBeforePrevious * TRIGGER_SHAPE ( secondSyncRatioFrom )
& & toothed_previous_duration < durationBeforePrevious * TRIGGER_SHAPE ( secondSyncRatioTo )
2015-12-27 13:02:44 -08:00
// this is getting a little out of hand, any ideas?
& & durationBeforePrevious > thirdPreviousDuration * TRIGGER_SHAPE ( thirdSyncRatioFrom )
& & durationBeforePrevious < thirdPreviousDuration * TRIGGER_SHAPE ( thirdSyncRatioTo )
;
2015-07-10 06:01:56 -07:00
2015-09-11 22:02:28 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2015-09-25 06:06:35 -07:00
if ( engineConfiguration - > isPrintTriggerSynchDetails | | someSortOfTriggerError ) {
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 */
2015-09-23 20:01:40 -07:00
float gap = 1.0 * currentDuration / toothed_previous_duration ;
2015-09-25 06:06:35 -07:00
float prevGap = 1.0 * toothed_previous_duration / durationBeforePrevious ;
2015-12-27 13:02:44 -08:00
float gap3 = 1.0 * durationBeforePrevious / thirdPreviousDuration ;
2015-09-11 22:02:28 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2015-12-28 06:01:40 -08:00
scheduleMsg ( logger , " gap=%f/%f/%f @ %d while expected %f/%f/%f and %f/%f error=%d " , gap , prevGap , gap3 , currentCycle . current_index , TRIGGER_SHAPE ( syncRatioFrom ) , TRIGGER_SHAPE ( syncRatioTo ) , TRIGGER_SHAPE ( secondSyncRatioFrom ) , TRIGGER_SHAPE ( secondSyncRatioTo ) , someSortOfTriggerError ) ;
2015-07-10 06:01:56 -07:00
# else
2015-09-23 20:01:40 -07:00
actualSynchGap = gap ;
2015-12-27 13:02:44 -08:00
print ( " current gap %f/%f/%f c=%d prev=%d \r \n " , gap , prevGap , gap3 , currentDuration , toothed_previous_duration ) ;
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 {
/**
* in case of noise the counter could be above the expected number of events
*/
int d = engineConfiguration - > useOnlyFrontForTrigger ? 2 : 1 ;
isSynchronizationPoint = ! shaft_is_synchronized | | ( currentCycle . current_index > = TRIGGER_SHAPE ( size ) - d ) ;
2015-07-10 06:01:56 -07: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 ) ) ;
}
# endif
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 ] ) ;
triggerDecoderErrorPin . setValue ( isDecodingError ) ;
if ( isDecodingError ) {
lastDecodingErrorTime = getTimeNowNt ( ) ;
2015-09-25 06:06:35 -07:00
someSortOfTriggerError = true ;
2015-09-23 20:01:40 -07:00
totalTriggerErrorCounter + + ;
2015-09-25 06:06:35 -07:00
if ( engineConfiguration - > 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 ( ) ) {
warning ( OBD_PCM_Processor_Fault , " trigger decoding issue. expected %d/%d/%d got %d/%d/%d " ,
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
2015-09-23 20:01:40 -07:00
nextRevolution ( ) ;
} else {
nextTriggerEvent ( )
;
}
2015-07-10 06:01:56 -07:00
2015-12-27 13:02:44 -08:00
thirdPreviousDuration = durationBeforePrevious ;
2015-09-23 20:01:40 -07:00
durationBeforePrevious = toothed_previous_duration ;
toothed_previous_duration = currentDuration ;
toothed_previous_time = nowNt ;
2015-09-13 13:01:38 -07:00
}
2015-09-24 19:02:47 -07:00
if ( ! isValidIndex ( PASS_ENGINE_PARAMETER_F ) ) {
warning ( OBD_PCM_Processor_Fault , " unexpected eventIndex=%d while size %d " , currentCycle . current_index , TRIGGER_SHAPE ( size ) ) ;
2015-09-25 06:06:35 -07:00
lastDecodingErrorTime = getTimeNowNt ( ) ;
someSortOfTriggerError = true ;
}
if ( someSortOfTriggerError ) {
if ( getTimeNowNt ( ) - lastDecodingErrorTime > US2NT ( US_PER_SECOND_LL ) ) {
someSortOfTriggerError = false ;
}
2015-09-24 19:02:47 -07:00
}
2015-09-13 15:01:23 -07:00
if ( boardConfiguration - > sensorChartMode = = SC_RPM_ACCEL | | boardConfiguration - > sensorChartMode = = SC_DETAILED_RPM ) {
2015-09-13 13:01:38 -07:00
angle_t currentAngle = TRIGGER_SHAPE ( eventAngles [ currentCycle . current_index ] ) ;
// todo: make this '90' depend on cylinder count?
angle_t prevAngle = currentAngle - 90 ;
fixAngle ( prevAngle ) ;
2015-09-13 15:01:23 -07:00
// todo: prevIndex should be pre-calculated
int prevIndex = TRIGGER_SHAPE ( triggerIndexByAngle [ ( int ) prevAngle ] ) ;
2015-09-13 13:01:38 -07:00
// now let's get precise angle for that event
prevAngle = TRIGGER_SHAPE ( eventAngles [ prevIndex ] ) ;
2016-01-24 22:02:55 -08:00
// todo: re-implement this as a subclass. we need two instances of
// uint32_t time = nowNt - timeOfLastEvent[prevIndex];
2015-09-13 13:01:38 -07:00
angle_t angleDiff = currentAngle - prevAngle ;
// todo: angle diff should be pre-calculated
fixAngle ( angleDiff ) ;
2016-01-24 22:02:55 -08:00
// float r = (60000000.0 / 360 * US_TO_NT_MULTIPLIER) * angleDiff / time;
2015-09-13 13:01:38 -07:00
# if EFI_SENSOR_CHART || defined(__DOXYGEN__)
2015-09-13 15:01:23 -07:00
if ( boardConfiguration - > sensorChartMode = = SC_DETAILED_RPM ) {
2016-01-24 22:02:55 -08:00
// scAddData(currentAngle, r);
2015-09-13 15:01:23 -07:00
} else {
2016-01-24 22:02:55 -08:00
// scAddData(currentAngle, r / instantRpmValue[prevIndex]);
2015-09-13 15:01:23 -07:00
}
2015-09-13 13:01:38 -07:00
# endif
2016-01-24 22:02:55 -08:00
// instantRpmValue[currentCycle.current_index] = r;
// timeOfLastEvent[currentCycle.current_index] = nowNt;
2015-09-13 13:01:38 -07:00
}
2015-07-10 06:01:56 -07:00
}
2016-01-14 21:01:42 -08:00
angle_t getEngineCycle ( operation_mode_e operationMode ) {
2015-07-10 06:01:56 -07:00
return operationMode = = TWO_STROKE ? 360 : 720 ;
}
2015-09-23 20:01:40 -07:00
void addSkippedToothTriggerEvents ( trigger_wheel_e wheel , TriggerShape * s , int totalTeethCount , int skippedCount ,
float toothWidth , float offset , float engineCycle , float filterLeft , float filterRight ) {
2015-07-10 06:01:56 -07:00
efiAssertVoid ( totalTeethCount > 0 , " total count " ) ;
efiAssertVoid ( skippedCount > = 0 , " skipped count " ) ;
for ( int i = 0 ; i < totalTeethCount - skippedCount - 1 ; i + + ) {
float angleDown = engineCycle / totalTeethCount * ( i + ( 1 - toothWidth ) ) ;
float angleUp = engineCycle / totalTeethCount * ( i + 1 ) ;
2015-10-31 13:02:10 -07:00
s - > addEvent ( offset + angleDown , wheel , TV_RISE , filterLeft , filterRight ) ;
s - > addEvent ( offset + angleUp , wheel , TV_FALL , filterLeft , filterRight ) ;
2015-07-10 06:01:56 -07:00
}
2015-09-23 20:01:40 -07:00
float angleDown = engineCycle / totalTeethCount * ( totalTeethCount - skippedCount - 1 + ( 1 - toothWidth ) ) ;
2015-10-31 13:02:10 -07:00
s - > addEvent ( offset + angleDown , wheel , TV_RISE , filterLeft , filterRight ) ;
s - > addEvent ( offset + engineCycle , wheel , TV_FALL , filterLeft , filterRight ) ;
2015-07-10 06:01:56 -07:00
}
void initializeSkippedToothTriggerShapeExt ( TriggerShape * s , int totalTeethCount , int skippedCount ,
operation_mode_e operationMode ) {
efiAssertVoid ( totalTeethCount > 0 , " totalTeethCount is zero " ) ;
2015-10-30 16:06:55 -07:00
efiAssertVoid ( s ! = NULL , " TriggerShape is NULL " ) ;
s - > initialize ( operationMode , false ) ;
2015-07-10 06:01:56 -07:00
s - > setTriggerSynchronizationGap ( skippedCount + 1 ) ;
s - > isSynchronizationNeeded = ( skippedCount ! = 0 ) ;
addSkippedToothTriggerEvents ( T_PRIMARY , s , totalTeethCount , skippedCount , 0.5 , 0 , getEngineCycle ( operationMode ) ,
2015-09-23 20:01:40 -07:00
NO_LEFT_FILTER , NO_RIGHT_FILTER ) ;
2015-07-10 06:01:56 -07:00
}
static void configureOnePlusOne ( TriggerShape * s , operation_mode_e operationMode ) {
float engineCycle = getEngineCycle ( operationMode ) ;
2015-10-29 11:02:52 -07:00
s - > initialize ( FOUR_STROKE_CAM_SENSOR , true ) ;
2015-07-10 06:01:56 -07:00
2015-10-31 13:02:10 -07:00
s - > addEvent ( 180 , T_PRIMARY , TV_RISE ) ;
s - > addEvent ( 360 , T_PRIMARY , TV_FALL ) ;
2015-07-10 06:01:56 -07:00
2015-10-31 13:02:10 -07:00
s - > addEvent ( 540 , T_SECONDARY , TV_RISE ) ;
s - > addEvent ( 720 , T_SECONDARY , TV_FALL ) ;
2015-07-10 06:01:56 -07:00
s - > isSynchronizationNeeded = false ;
}
static void configureOnePlus60_2 ( TriggerShape * s , operation_mode_e operationMode ) {
2015-10-29 11:02:52 -07:00
s - > initialize ( FOUR_STROKE_CAM_SENSOR , true ) ;
2015-07-10 06:01:56 -07:00
int totalTeethCount = 60 ;
int skippedCount = 2 ;
2015-10-31 13:02:10 -07:00
s - > addEvent ( 2 , T_PRIMARY , TV_RISE ) ;
2015-07-10 06:01:56 -07:00
addSkippedToothTriggerEvents ( T_SECONDARY , s , totalTeethCount , skippedCount , 0.5 , 0 , 360 , 2 , 20 ) ;
2015-10-31 13:02:10 -07:00
s - > addEvent ( 20 , T_PRIMARY , TV_FALL ) ;
2015-07-10 06:01:56 -07:00
addSkippedToothTriggerEvents ( T_SECONDARY , s , totalTeethCount , skippedCount , 0.5 , 0 , 360 , 20 , NO_RIGHT_FILTER ) ;
addSkippedToothTriggerEvents ( T_SECONDARY , s , totalTeethCount , skippedCount , 0.5 , 360 , 360 , NO_LEFT_FILTER ,
2015-09-23 20:01:40 -07:00
NO_RIGHT_FILTER ) ;
2015-07-10 06:01:56 -07:00
s - > isSynchronizationNeeded = false ;
}
/**
* External logger is needed because at this point our logger is not yet initialized
*/
void TriggerShape : : initializeTriggerShape ( Logging * logger DECLARE_ENGINE_PARAMETER_S ) {
2016-01-09 08:01:43 -08:00
const trigger_config_s * triggerConfig = & engineConfiguration - > trigger ;
2015-09-13 07:01:39 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
efiAssertVoid ( getRemainingStack ( chThdSelf ( ) ) > 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
TriggerShape * triggerShape = this ;
2015-07-10 06:01:56 -07:00
switch ( triggerConfig - > type ) {
case TT_TOOTHED_WHEEL :
initializeSkippedToothTriggerShapeExt ( triggerShape , triggerConfig - > customTotalToothCount ,
triggerConfig - > customSkippedToothCount , engineConfiguration - > operationMode ) ;
break ;
case TT_MAZDA_MIATA_NA :
2015-10-10 13:01:25 -07:00
initializeMazdaMiataNaShape ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_MAZDA_MIATA_NB :
2015-10-10 13:01:25 -07:00
initializeMazdaMiataNbShape ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_DODGE_NEON_1995 :
2015-10-10 13:01:25 -07:00
configureNeon1995TriggerShape ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
break ;
2015-09-05 20:02:46 -07:00
case TT_DODGE_STRATUS :
2015-10-10 13:01:25 -07:00
configureDodgeStratusTriggerShape ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-09-05 20:02:46 -07:00
break ;
2015-07-10 06:01:56 -07:00
case TT_DODGE_NEON_2003 :
2015-10-10 13:01:25 -07:00
configureNeon2003TriggerShape ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_FORD_ASPIRE :
configureFordAspireTriggerShape ( triggerShape ) ;
break ;
case TT_GM_7X :
// todo: fix this configureGmTriggerShape(triggerShape);
configureFordAspireTriggerShape ( triggerShape ) ;
break ;
case TT_MAZDA_DOHC_1_4 :
2015-10-10 13:01:25 -07:00
configureMazdaProtegeLx ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_ONE_PLUS_ONE :
configureOnePlusOne ( triggerShape , engineConfiguration - > operationMode ) ;
break ;
case TT_ONE_PLUS_TOOTHED_WHEEL_60_2 :
configureOnePlus60_2 ( triggerShape , engineConfiguration - > operationMode ) ;
break ;
case TT_ONE :
setToothedWheelConfiguration ( triggerShape , 1 , 0 , engineConfiguration - > operationMode ) ;
break ;
case TT_MAZDA_SOHC_4 :
2015-10-10 13:01:25 -07:00
configureMazdaProtegeSOHC ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
break ;
case TT_MINI_COOPER_R50 :
configureMiniCooperTriggerShape ( triggerShape ) ;
break ;
case TT_TOOTHED_WHEEL_60_2 :
setToothedWheelConfiguration ( triggerShape , 60 , 2 , engineConfiguration - > operationMode ) ;
break ;
case TT_60_2_VW :
setVwConfiguration ( triggerShape ) ;
break ;
case TT_TOOTHED_WHEEL_36_1 :
setToothedWheelConfiguration ( triggerShape , 36 , 1 , engineConfiguration - > operationMode ) ;
break ;
case TT_HONDA_ACCORD_CD_TWO_WIRES :
configureHondaAccordCD ( triggerShape , false , true , T_CHANNEL_3 , T_PRIMARY , 0 ) ;
break ;
case TT_HONDA_ACCORD_CD :
configureHondaAccordCD ( triggerShape , true , true , T_CHANNEL_3 , T_PRIMARY , 0 ) ;
break ;
case TT_HONDA_ACCORD_1_24 :
configureHondaAccordCD ( triggerShape , true , false , T_PRIMARY , T_PRIMARY , 10 ) ;
break ;
case TT_HONDA_ACCORD_CD_DIP :
configureHondaAccordCDDip ( triggerShape ) ;
break ;
case TT_MITSU :
initializeMitsubishi4g18 ( triggerShape ) ;
break ;
case TT_DODGE_RAM :
2015-10-10 13:01:25 -07:00
initDodgeRam ( triggerShape PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
break ;
2015-09-10 19:01:35 -07:00
case TT_36_2_2_2 :
initialize36_2_2_2 ( triggerShape ) ;
break ;
2015-12-14 18:01:30 -08:00
case TT_2JZ :
initialize2jzGE ( triggerShape ) ;
break ;
2015-09-19 16:01:46 -07:00
case TT_NISSAN :
initializeNissan ( triggerShape ) ;
break ;
2015-12-27 12:02:51 -08:00
case TT_ROVER_K :
initializeRoverK ( triggerShape ) ;
break ;
2015-07-10 06:01:56 -07:00
default :
firmwareError ( " initializeTriggerShape() not implemented: %d " , triggerConfig - > type ) ;
return ;
}
wave . checkSwitchTimes ( getSize ( ) ) ;
2016-01-24 22:02:55 -08:00
/**
* 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
*/
TriggerState state ;
state . reset ( ) ;
calculateTriggerSynchPoint ( & state PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
}
static void onFindIndex ( TriggerState * state ) {
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 ,
trigger_config_s const * triggerConfig DECLARE_ENGINE_PARAMETER_S ) {
2015-09-13 07:01:39 -07:00
# if EFI_PROD_CODE || defined(__DOXYGEN__)
2015-09-23 20:01:40 -07:00
efiAssert ( getRemainingStack ( chThdSelf ( ) ) > 128 , " findPos " , - 1 ) ;
2015-09-13 07:01:39 -07:00
# endif
2015-07-10 06:01:56 -07:00
errorDetection . clear ( ) ;
2015-09-13 13:01:38 -07:00
efiAssert ( 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
2015-07-10 06:01:56 -07:00
// todo: should this variable be declared 'static' to reduce stack usage?
TriggerStimulatorHelper helper ;
2015-09-23 18:02:33 -07:00
uint32_t index = helper . doFindTrigger ( shape , triggerConfig , state PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
if ( index = = EFI_ERROR_CODE ) {
return index ;
}
2015-09-13 13:01:38 -07:00
efiAssert ( state - > getTotalRevolutionCounter ( ) = = 1 , " totalRevolutionCounter " , EFI_ERROR_CODE ) ;
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 ?
*/
2015-09-13 13:01:38 -07:00
state - > cycleCallback = onFindIndex ;
2015-07-10 06:01:56 -07:00
2015-09-23 20:01:40 -07:00
helper . assertSyncPositionAndSetDutyCycle ( index , state , shape , triggerConfig PASS_ENGINE_PARAMETER ) ;
2015-07-10 06:01:56 -07:00
return index % shape - > getSize ( ) ;
}
void initTriggerDecoderLogger ( Logging * sharedLogger ) {
logger = sharedLogger ;
}
void initTriggerDecoder ( void ) {
2015-09-13 07:01:39 -07:00
# if (EFI_PROD_CODE || EFI_SIMULATOR) || defined(__DOXYGEN__)
2015-09-23 20:01:40 -07:00
outputPinRegisterExt2 ( " trg_err " , & triggerDecoderErrorPin , boardConfiguration - > triggerErrorPin ,
& boardConfiguration - > triggerErrorPinMode ) ;
2015-07-10 06:01:56 -07:00
# endif
}
# endif /* EFI_SHAFT_POSITION_INPUT */