@ -1,32 +1,34 @@ 
			
		
	
		
		
			
				
					
					struct  sample_t  torque_meas ;            // last 3 motor torques produced by the eps
 int  toyota_no_dsu_car  =  0 ;                 // ch-r and camry don't have the DSU
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					int  toyota_giraffe_switch_1  =  0 ;           // is giraffe switch 1 high?
  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// global torque limit
 // global torque limit
  
			
		
	
		
		
			
				
					
					const  int  MAX_TORQUE  =  1500 ;        // max torque cmd allowed ever
 const  int  TOYOTA_ MAX_TORQUE=  1500 ;        // max torque cmd allowed ever
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// rate based torque limit + stay within actually applied
 // rate based torque limit + stay within actually applied
  
			
		
	
		
		
			
				
					
					// packet is sent at 100hz, so this limit is 1000/sec
 // packet is sent at 100hz, so this limit is 1000/sec
  
			
		
	
		
		
			
				
					
					const  int  MAX_RATE_UP  =  10 ;         // ramp up slow
 const  int  TOYOTA_ MAX_RATE_UP=  10 ;         // ramp up slow
  
			
				
				
			
		
	
		
		
			
				
					
					const  int  MAX_RATE_DOWN  =  25 ;       // ramp down fast
 const  int  TOYOTA_ MAX_RATE_DOWN=  25 ;       // ramp down fast
  
			
				
				
			
		
	
		
		
			
				
					
					const  int  MAX_TORQUE_ERROR  =  350 ;   // max torque cmd in excess of torque motor
 const  int  TOYOTA_ MAX_TORQUE_ERROR=  350 ;   // max torque cmd in excess of torque motor
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// real time torque limit to prevent controls spamming
 // real time torque limit to prevent controls spamming
  
			
		
	
		
		
			
				
					
					// the real time limit is 1500/sec
 // the real time limit is 1500/sec
  
			
		
	
		
		
			
				
					
					const  int  MAX_RT_DELTA  =  375 ;       // max delta torque allowed for real time checks
 const  int  TOYOTA_ MAX_RT_DELTA=  375 ;       // max delta torque allowed for real time checks
  
			
				
				
			
		
	
		
		
			
				
					
					const  int  RT_INTERVAL  =  250000 ;     // 250ms between real time checks
 const  int  TOYOTA_ RT_INTERVAL=  250000 ;     // 250ms between real time checks
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// longitudinal limits
 // longitudinal limits
  
			
		
	
		
		
			
				
					
					const  int  MAX_ACCEL  =  1500 ;         // 1.5 m/s2
 const  int  TOYOTA_ MAX_ACCEL=  1500 ;         // 1.5 m/s2
  
			
				
				
			
		
	
		
		
			
				
					
					const  int  MIN_ACCEL  =  - 3000 ;        // 3.0 m/s2
 const  int  TOYOTA_ MIN_ACCEL=  - 3000 ;        // 3.0 m/s2
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// global actuation limit state
 // global actuation limit state
  
			
		
	
		
		
			
				
					
					int  actuation_limits  =  1 ;                // by default steer limits are imposed
 int  toyota_ actuation_limits=  1 ;           // by default steer limits are imposed
  
			
				
				
			
		
	
		
		
			
				
					
					int  dbc_eps_torque_factor  =  100 ;    // conversion factor for STEER_TORQUE_EPS in %: see dbc file
 int  toyota_ dbc_eps_torque_factor=  100 ;    // conversion factor for STEER_TORQUE_EPS in %: see dbc file
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					// state of torque limits
 // state of torque limits
  
			
		
	
		
		
			
				
					
					int  desired_torque_last  =  0 ;        // last desired steer torque
 int  toyota_desired_torque_last  =  0 ;        // last desired steer torque
  
			
				
				
			
		
	
		
		
			
				
					
					int  rt_torque_last  =  0 ;             // last desired torque for real time check
 int  toyota_rt_torque_last  =  0 ;             // last desired torque for real time check
  
			
				
				
			
		
	
		
		
			
				
					
					uint32_t  ts_last  =  0 ; uint32_t  toyota_ts_last  =  0 ;  
			
				
				
			
		
	
		
		
			
				
					
					int  cruise_engaged_last  =  0 ;            // cruise state
 int  toyota_cruise_engaged_last  =  0 ;        // cruise state
  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					struct  sample_t  toyota_torque_meas ;        // last 3 motor torques produced by the eps
  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  toyota_rx_hook ( CAN_FIFOMailBox_TypeDef  * to_push )  { static  void  toyota_rx_hook ( CAN_FIFOMailBox_TypeDef  * to_push )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -36,26 +38,38 @@ static void toyota_rx_hook(CAN_FIFOMailBox_TypeDef *to_push) { 
			
		
	
		
		
			
				
					
					    torque_meas_new  =  to_signed ( torque_meas_new ,  16 ) ;      torque_meas_new  =  to_signed ( torque_meas_new ,  16 ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // scale by dbc_factor
      // scale by dbc_factor
   
			
		
	
		
		
			
				
					
					    torque_meas_new  =  ( torque_meas_new  *  dbc_eps_torque_factor )  /  100 ;      torque_meas_new  =  ( torque_meas_new  *  toyota_ dbc_eps_torque_factor)  /  100 ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // increase torque_meas by 1 to be conservative on rounding
      // increase torque_meas by 1 to be conservative on rounding
   
			
		
	
		
		
			
				
					
					    torque_meas_new  + =  ( torque_meas_new  >  0  ?  1  :  - 1 ) ;      torque_meas_new  + =  ( torque_meas_new  >  0  ?  1  :  - 1 ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					    // update array of sample
      // update array of sample
   
			
		
	
		
		
			
				
					
					    update_sample ( & torque_meas ,  torque_meas_new ) ;      update_sample ( & toyota_to rque_meas ,  torque_meas_new ) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  }    }   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  // enter controls on rising edge of ACC, exit controls on ACC off
    // enter controls on rising edge of ACC, exit controls on ACC off
   
			
		
	
		
		
			
				
					
					  if  ( ( to_push - > RIR > > 21 )  = =  0x1D2 )  {    if  ( ( to_push - > RIR > > 21 )  = =  0x1D2 )  {   
			
		
	
		
		
			
				
					
					    // 4 bits: 55-52
      // 4 bits: 55-52
   
			
		
	
		
		
			
				
					
					    int  cruise_engaged  =  to_push - > RDHR  &  0xF00000 ;      int  cruise_engaged  =  to_push - > RDHR  &  0xF00000 ;   
			
		
	
		
		
			
				
					
					    if  ( cruise_engaged  & &  ! cruise_engaged_last )  {      if  ( cruise_engaged  & &  ! toyota_ cruise_engaged_last)  {   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					      controls_allowed  =  1 ;        controls_allowed  =  1 ;   
			
		
	
		
		
			
				
					
					    }  else  if  ( ! cruise_engaged )  {      }  else  if  ( ! cruise_engaged )  {   
			
		
	
		
		
			
				
					
					      controls_allowed  =  0 ;        controls_allowed  =  0 ;   
			
		
	
		
		
			
				
					
					    }      }   
			
		
	
		
		
			
				
					
					    cruise_engaged_last  =  cruise_engaged ;      toyota_ cruise_engaged_last=  cruise_engaged ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  }    }   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  int  bus  =  ( to_push - > RDTR  > >  4 )  &  0xF ;   
			
		
	
		
		
			
				
					
					  // 0x680 is a radar msg only found in dsu-less cars
   
			
		
	
		
		
			
				
					
					  if  ( ( to_push - > RIR > > 21 )  = =  0x680  & &  ( bus  = =  1 ) )  {   
			
		
	
		
		
			
				
					
					    toyota_no_dsu_car  =  1 ;   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  // 0x2E4 is lkas cmd. If it is on bus 0, then giraffe switch 1 is high
   
			
		
	
		
		
			
				
					
					  if  ( ( to_push - > RIR > > 21 )  = =  0x2E4  & &  ( bus  = =  0 ) )  {   
			
		
	
		
		
			
				
					
					    toyota_giraffe_switch_1  =  1 ;   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  int  toyota_tx_hook ( CAN_FIFOMailBox_TypeDef  * to_send )  { static  int  toyota_tx_hook ( CAN_FIFOMailBox_TypeDef  * to_send )  {  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -70,8 +84,8 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { 
			
		
	
		
		
			
				
					
					    if  ( ( to_send - > RIR > > 21 )  = =  0x343 )  {      if  ( ( to_send - > RIR > > 21 )  = =  0x343 )  {   
			
		
	
		
		
			
				
					
					      int  desired_accel  =  ( ( to_send - > RDLR  &  0xFF )  < <  8 )  |  ( ( to_send - > RDLR  > >  8 )  &  0xFF ) ;        int  desired_accel  =  ( ( to_send - > RDLR  &  0xFF )  < <  8 )  |  ( ( to_send - > RDLR  > >  8 )  &  0xFF ) ;   
			
		
	
		
		
			
				
					
					      desired_accel  =  to_signed ( desired_accel ,  16 ) ;        desired_accel  =  to_signed ( desired_accel ,  16 ) ;   
			
		
	
		
		
			
				
					
					      if  ( controls_allowed  & &  actuation_limits )  {        if  ( controls_allowed  & &  toyota_ actuation_limits)  {   
			
				
				
			
		
	
		
		
			
				
					
					        int  violation  =  max_limit_check ( desired_accel ,  MAX_ACCEL ,  MIN_ACCEL ) ;          int  violation  =  max_limit_check ( desired_accel ,  TOYOTA_ MAX_ACCEL,  TOYOTA_ MIN_ACCEL) ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					        if  ( violation )  return  0 ;          if  ( violation )  return  0 ;   
			
		
	
		
		
			
				
					
					      }  else  if  ( ! controls_allowed  & &  ( desired_accel  ! =  0 ) )  {        }  else  if  ( ! controls_allowed  & &  ( desired_accel  ! =  0 ) )  {   
			
		
	
		
		
			
				
					
					        return  0 ;          return  0 ;   
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -87,25 +101,26 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { 
			
		
	
		
		
			
				
					
					      uint32_t  ts  =  TIM2 - > CNT ;        uint32_t  ts  =  TIM2 - > CNT ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					      // only check if controls are allowed and actuation_limits are imposed
        // only check if controls are allowed and actuation_limits are imposed
   
			
		
	
		
		
			
				
					
					      if  ( controls_allowed  & &  actuation_limits )  {        if  ( controls_allowed  & &  toyota_ actuation_limits)  {   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        // *** global torque limit check ***
          // *** global torque limit check ***
   
			
		
	
		
		
			
				
					
					        violation  | =  max_limit_check ( desired_torque ,  MAX_TORQUE ,  - MAX_TORQUE ) ;          violation  | =  max_limit_check ( desired_torque ,  TOYOTA_ MAX_TORQUE,  - TOYOTA_ MAX_TORQUE) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        // *** torque rate limit check ***
          // *** torque rate limit check ***
   
			
		
	
		
		
			
				
					
					        violation  | =  dist_to_meas_check ( desired_torque ,  desired_torque_last ,  & torque_meas ,  MAX_RATE_UP ,  MAX_RATE_DOWN ,  MAX_TORQUE_ERROR ) ;          violation  | =  dist_to_meas_check ( desired_torque ,  toyota_desired_torque_last ,  
  
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					          & toyota_torque_meas ,  TOYOTA_MAX_RATE_UP ,  TOYOTA_MAX_RATE_DOWN ,  TOYOTA_MAX_TORQUE_ERROR ) ;   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        // used next time
          // used next time
   
			
		
	
		
		
			
				
					
					        desired_torque_last  =  desired_torque ;          toyota_ desired_torque_last=  desired_torque ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        // *** torque real time rate limit check ***
          // *** torque real time rate limit check ***
   
			
		
	
		
		
			
				
					
					        violation  | =  rt_rate_limit_check ( desired_torque ,  rt_torque_last ,  MAX_RT_DELTA ) ;          violation  | =  rt_rate_limit_check ( desired_torque ,  toyota_ rt_torque_last,  TOYOTA_ MAX_RT_DELTA) ;   
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					        // every RT_INTERVAL set the new limits
          // every RT_INTERVAL set the new limits
   
			
		
	
		
		
			
				
					
					        uint32_t  ts_elapsed  =  get_ts_elapsed ( ts ,  ts_last ) ;          uint32_t  ts_elapsed  =  get_ts_elapsed ( ts ,  toyota_t s_last ) ;   
			
				
				
			
		
	
		
		
			
				
					
					        if  ( ts_elapsed  >  RT_INTERVAL )  {          if  ( ts_elapsed  >  TOYOTA_ RT_INTERVAL)  {   
			
				
				
			
		
	
		
		
			
				
					
					          rt_torque_last  =  desired_torque ;            toyota_ rt_torque_last=  desired_torque ;   
			
				
				
			
		
	
		
		
			
				
					
					          ts_last  =  ts ;            toyota_t s_last  =  ts ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					        }          }   
			
		
	
		
		
			
				
					
					      }        }   
			
		
	
		
		
			
				
					
					      
       
  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -116,9 +131,9 @@ static int toyota_tx_hook(CAN_FIFOMailBox_TypeDef *to_send) { 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					      // reset to 0 if either controls is not allowed or there's a violation
        // reset to 0 if either controls is not allowed or there's a violation
   
			
		
	
		
		
			
				
					
					      if  ( violation  | |  ! controls_allowed )  {        if  ( violation  | |  ! controls_allowed )  {   
			
		
	
		
		
			
				
					
					        desired_torque_last  =  0 ;          toyota_ desired_torque_last=  0 ;   
			
				
				
			
		
	
		
		
			
				
					
					        rt_torque_last  =  0 ;          toyota_ rt_torque_last=  0 ;   
			
				
				
			
		
	
		
		
			
				
					
					        ts_last  =  ts ;          toyota_t s_last  =  ts ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					      }        }   
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					      if  ( violation )  {        if  ( violation )  {   
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -138,11 +153,19 @@ static int toyota_tx_lin_hook(int lin_num, uint8_t *data, int len) { 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  toyota_init ( int16_t  param )  { static  void  toyota_init ( int16_t  param )  {  
			
		
	
		
		
			
				
					
					  controls_allowed  =  0 ;    controls_allowed  =  0 ;   
			
		
	
		
		
			
				
					
					  actuation_limits  =  1 ;    toyota_actuation_limits  =  1 ;   
			
				
				
			
		
	
		
		
			
				
					
					  dbc_eps_torque_factor  =  param ;    toyota_giraffe_switch_1  =  0 ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					  toyota_dbc_eps_torque_factor  =  param ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  int  toyota_fwd_hook ( int  bus_num ,  CAN_FIFOMailBox_TypeDef  * to_fwd )  { static  int  toyota_fwd_hook ( int  bus_num ,  CAN_FIFOMailBox_TypeDef  * to_fwd )  {  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  // forward cam to radar and viceversa if car is dsu-less, except lkas cmd and hud
   
			
		
	
		
		
			
				
					
					  if  ( ( bus_num  = =  0  | |  bus_num  = =  2 )  & &  toyota_no_dsu_car  & &  ! toyota_giraffe_switch_1 )  {   
			
		
	
		
		
			
				
					
					    int  addr  =  to_fwd - > RIR > > 21 ;   
			
		
	
		
		
			
				
					
					    bool  is_lkas_msg  =  ( addr  = =  0x2E4  | |  addr  = =  0x412 )  & &  bus_num  = =  2 ;   
			
		
	
		
		
			
				
					
					    return  is_lkas_msg ?  - 1  :  ( uint8_t ) ( ~ bus_num  &  0x2 ) ;   
			
		
	
		
		
			
				
					
					  }   
			
		
	
		
		
			
				
					
					  return  - 1 ;    return  - 1 ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -157,8 +180,9 @@ const safety_hooks toyota_hooks = { 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					static  void  toyota_nolimits_init ( int16_t  param )  { static  void  toyota_nolimits_init ( int16_t  param )  {  
			
		
	
		
		
			
				
					
					  controls_allowed  =  0 ;    controls_allowed  =  0 ;   
			
		
	
		
		
			
				
					
					  actuation_limits  =  0 ;    toyota_actuation_limits  =  0 ;   
			
				
				
			
		
	
		
		
			
				
					
					  dbc_eps_torque_factor  =  param ;    toyota_giraffe_switch_1  =  0 ;   
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					  toyota_dbc_eps_torque_factor  =  param ;   
			
		
	
		
		
			
				
					
					} }  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					const  safety_hooks  toyota_nolimits_hooks  =  { const  safety_hooks  toyota_nolimits_hooks  =  {