Пример #1
0
//If any error occurs, the CE is light up for a fixed time. If the problem persists (eg corrupted the program code),
//then the CE will be turned on continuously. At the start of program CE lights up for 0.5 seconds. for indicating
//of the operability.
void ce_check_engine(struct ecudata_t* d, volatile s_timer8_t* ce_control_time_counter)
{
 uint16_t temp_errors;

 check(d);

 //If the timer counted the time, then turn off the CE
 if (s_timer_is_action(*ce_control_time_counter))
 {
  ce_set_state(CE_STATE_OFF);
  d->ce_state = 0; //<--doubling
 }

 //If at least one error is present  - turn on CE and start timer
 if (ce_state.ecuerrors!=0)
 {
  s_timer_set(*ce_control_time_counter, CE_CONTROL_STATE_TIME_VALUE);
  ce_set_state(CE_STATE_ON);
  d->ce_state = 1;  //<--doubling
 }

 temp_errors = (ce_state.merged_errors | ce_state.ecuerrors);
 //check for error which is still not in merged_errors
 if (temp_errors!=ce_state.merged_errors)
 {
  //Because at the time of appearing of a new error, EEPROM can be busy (for example, saving options),
  //then it is necessary to run deffered operation, which will be automatically executed as soon as the EEPROM
  //will be released.
  sop_set_operation(SOP_SAVE_CE_MERGED_ERRORS);
 }

 ce_state.merged_errors = temp_errors;

 //copy error's bits into the cache for transferring
 d->ecuerrors_for_transfer|= ce_state.ecuerrors;
}
Пример #2
0
void process_uart_interface(struct ecudata_t* d)
{
 uint8_t descriptor;

 //Following code executes at start up only if bluetooth is enabled and only 1 time
 if (d->param.bt_flags & _BV(BTF_USE_BT))
 {
  if (!bt_set_baud(d, d->param.uart_divisor))
   return;

  if (d->bt_name[0] && d->bt_pass[0])
   if (!bt_set_namepass(d))
    return;
 }

 if (uart_is_packet_received())//приняли новый фрейм ?
 {
  descriptor = uart_recept_packet(d);
  switch(descriptor)
  {
   case TEMPER_PAR:
   case CARBUR_PAR:
   case IDLREG_PAR:
   case ANGLES_PAR:
   case STARTR_PAR:
   case ADCCOR_PAR:
   case CHOKE_PAR:
    //если были изменены параметры то сбрасываем счетчик времени
    s_timer16_set(save_param_timeout_counter, SAVE_PARAM_TIMEOUT_VALUE);
    break;

   case MISCEL_PAR:
#ifdef HALL_OUTPUT
    ckps_set_hall_pulse(d->param.hop_start_cogs, d->param.hop_durat_cogs);
#endif
    s_timer16_set(save_param_timeout_counter, SAVE_PARAM_TIMEOUT_VALUE);
    break;

   case FUNSET_PAR:
#ifdef REALTIME_TABLES
    sop_set_operation(SOP_SELECT_TABLSET);
#endif
    //если были изменены параметры то сбрасываем счетчик времени
    s_timer16_set(save_param_timeout_counter, SAVE_PARAM_TIMEOUT_VALUE);
    break;

   case OP_COMP_NC:
    if (_AB(d->op_actn_code, 0) == OPCODE_EEPROM_PARAM_SAVE) //приняли команду сохранения параметров
    {
     sop_set_operation(SOP_SAVE_PARAMETERS);
     _AB(d->op_actn_code, 0) = 0; //обработали
    }
    if (_AB(d->op_actn_code, 0) == OPCODE_CE_SAVE_ERRORS) //приняли команду чтения сохраненных кодов ошибок
    {
     sop_set_operation(SOP_READ_CE_ERRORS);
     _AB(d->op_actn_code, 0) = 0; //обработали
    }
    if (_AB(d->op_actn_code, 0) == OPCODE_READ_FW_SIG_INFO) //приняли команду чтения и передачи информации о прошивке
    {
     sop_set_operation(SOP_SEND_FW_SIG_INFO);
     _AB(d->op_actn_code, 0) = 0; //обработали
    }
#ifdef REALTIME_TABLES
    if (_AB(d->op_actn_code, 0) == OPCODE_LOAD_TABLSET) //приняли команду выбора нового набора таблиц
    {
     sop_set_operation(SOP_LOAD_TABLSET);
     _AB(d->op_actn_code, 0) = 0; //обработали
    }
    if (_AB(d->op_actn_code, 0) == OPCODE_SAVE_TABLSET) //приняли команду сохранения набора таблиц для указанного типа топлива
    {
     sop_set_operation(SOP_SAVE_TABLSET);
     _AB(d->op_actn_code, 0) = 0; //обработали
    }
#endif
#ifdef DIAGNOSTICS
    if (_AB(d->op_actn_code, 0) == OPCODE_DIAGNOST_ENTER) //"enter diagnostic mode" command has been received
    {
     //this function will send confirmation answer and start diagnostic mode (it will has its own separate loop)
     diagnost_start();
     _AB(d->op_actn_code, 0) = 0; //обработали
    }
    if (_AB(d->op_actn_code, 0) == OPCODE_DIAGNOST_LEAVE) //"leave diagnostic mode" command has been received
    {
     //this function will send confirmation answer and reset device
     diagnost_stop();
     _AB(d->op_actn_code, 0) = 0; //обработали
    }
#endif
    if (_AB(d->op_actn_code, 0) == OPCODE_RESET_EEPROM) //reset EEPROM command received
    {
     if (_AB(d->op_actn_code, 1) == 0xAA) //second byte must be 0xAA
      sop_set_operation(SOP_SEND_NC_RESET_EEPROM);
     _AB(d->op_actn_code, 0) = 0; //processed
    }
    break;

   case CE_SAVED_ERR:
    sop_set_operation(SOP_SAVE_CE_ERRORS);
    break;

   case CKPS_PAR:
    //если были изменены параметры ДПКВ, то немедленно применяем их на работающем двигателе и сбрасываем счетчик времени
    ckps_set_cyl_number(d->param.ckps_engine_cyl);  //<--обязательно в первую очередь!
    ckps_set_cogs_num(d->param.ckps_cogs_num, d->param.ckps_miss_num);
    ckps_set_edge_type(d->param.ckps_edge_type);
#ifdef SECU3T
    cams_vr_set_edge_type(d->param.ref_s_edge_type); //REF_S (ДНО)
#endif
    ckps_set_cogs_btdc(d->param.ckps_cogs_btdc);
    ckps_set_merge_outs(d->param.merge_ign_outs);

#ifndef DWELL_CONTROL
    ckps_set_ignition_cogs(d->param.ckps_ignit_cogs);
#endif
    s_timer16_set(save_param_timeout_counter, SAVE_PARAM_TIMEOUT_VALUE);

#ifdef HALL_SYNC
    ckps_select_input(d->param.hall_flags & _BV(HSF_USECKPINP)); //select input (CKPS or PS)
#endif
    break;

   case KNOCK_PAR:
    //аналогично для контороля детонации, обязательно после CKPS_PAR!
    //инициализируем процессор детонации в случае если он не использовался, а теперь поступила команда его использовать.
    if (!d->use_knock_channel_prev && d->param.knock_use_knock_channel)
     if (!knock_module_initialize())
     {//чип сигнального процессора детонации неисправен - зажигаем СЕ
      ce_set_error(ECUERROR_KSP_CHIP_FAILED);
     }

    knock_set_band_pass(d->param.knock_bpf_frequency);
    //gain устанавливается в каждом рабочем цикле
    knock_set_int_time_constant(d->param.knock_int_time_const);
    ckps_set_knock_window(d->param.knock_k_wnd_begin_angle, d->param.knock_k_wnd_end_angle);
    ckps_use_knock_channel(d->param.knock_use_knock_channel);

    //запоминаем состояние флага для того чтобы потом можно было определить нужно инициализировать
    //процессор детонации или нет.
    d->use_knock_channel_prev = d->param.knock_use_knock_channel;

    //если были изменены параметры то сбрасываем счетчик времени
    s_timer16_set(save_param_timeout_counter, SAVE_PARAM_TIMEOUT_VALUE);
    break;

   case SECUR_PAR:
    if (d->bt_name[0] && d->bt_pass[0])
     bt_start_set_namepass();
    s_timer16_set(save_param_timeout_counter, SAVE_PARAM_TIMEOUT_VALUE);
    break;
  }

  //мы обработали принятые данные - приемник ничем теперь не озабочен
  uart_notify_processed();
 }

 //периодически передаем фреймы с данными
 if (s_timer_is_action(send_packet_interval_counter))
 {
  if (!uart_is_sender_busy())
  {
   uint8_t desc = uart_get_send_mode();
   uart_send_packet(d, 0);                  //теперь передатчик озабочен передачей данных
#ifdef DEBUG_VARIABLES
   if (SENSOR_DAT==desc || ADCRAW_DAT==desc || CE_ERR_CODES==desc || DIAGINP_DAT==desc)
    sop_set_operation(SOP_DBGVAR_SENDING); //additionally we will send packet with debug information
#endif

   s_timer_set(send_packet_interval_counter, d->param.uart_period_t_ms);

   //после передачи очищаем кеш ошибок, передача битов ошибок осуществляется только в 1 из 2 пакетов
   if (SENSOR_DAT==desc || CE_ERR_CODES==desc)
    d->ecuerrors_for_transfer = 0;
  }
 }
}
Пример #3
0
uint8_t bt_set_baud(struct ecudata_t *d, uint16_t baud)
{
 if (255 == bts.btbr_mode)
  return 1; //not enabled/stopped

 switch(bts.btbr_mode)
 {
  //wait some time before we start to send first AT command
  case 0:
   ++bts.btbr_mode;
   bts.strt_t1 = s_timer_gtc();    //set timer
   return 0;
  case 1:
   if ((s_timer_gtc() - bts.strt_t1) >= AT_COMMAND_STRT_TIME)
    ++bts.btbr_mode;
   return 0;

  //Send command on 9600 baud
  case 2:
   SET_BRR(CBR_9600);
   append_tx_buff_with_at_baud_cmd(baud);
   ++bts.btbr_mode;
   bts.strt_t1 = s_timer_gtc();    //set timer
   break;
  case 3:                          //wait some time
   if ((s_timer_gtc() - bts.strt_t1) >= AT_COMMAND_TIME)
    ++bts.btbr_mode;
   return 0;

  //Send command on 19200 baud
  case 4:
   if (!uart_is_sender_busy())
   {
    SET_BRR(CBR_19200);
    append_tx_buff_with_at_baud_cmd(baud);
    ++bts.btbr_mode;
    bts.strt_t1 = s_timer_gtc();   //set timer
    break;
   }
   else return 0;                  //busy
  case 5:                          //wait some time
   if ((s_timer_gtc() - bts.strt_t1) >= AT_COMMAND_TIME)
    ++bts.btbr_mode;
   return 0;

  //Send command on 38400 baud
  case 6:
   if (!uart_is_sender_busy())
   {
    SET_BRR(CBR_38400);
    append_tx_buff_with_at_baud_cmd(baud);
    ++bts.btbr_mode;
    bts.strt_t1 = s_timer_gtc();   //set timer
    break;
   }
   else return 0;                  //busy
  case 7:                          //wait some time
   if ((s_timer_gtc() - bts.strt_t1) >= AT_COMMAND_TIME)
    ++bts.btbr_mode;
   return 0;

  //Send command on 57600 baud
  case 8:
   if (!uart_is_sender_busy())
   {
    SET_BRR(CBR_57600);
    append_tx_buff_with_at_baud_cmd(baud);
    ++bts.btbr_mode;
    bts.strt_t1 = s_timer_gtc();   //set timer
    break;
   }
   else return 0;                  //busy
  case 9:                          //wait some time
   if ((s_timer_gtc() - bts.strt_t1) >= AT_COMMAND_TIME)
    ++bts.btbr_mode;
   return 0;

  //Finishing...
  case 10:
   if (!uart_is_sender_busy())
   {
    SET_BRR(baud);                 //return old baud rate back
    ++bts.btbr_mode;
    //reset flag and save parameters
    d->param.bt_flags&=~(1 << 1);
    sop_set_operation(SOP_SAVE_PARAMETERS);
   }
   return 0;

  default:
   return 1; //stopped
 }

 //Start background process of packet sending
 uart_begin_send();
 return 0;
}