Программный модуль для мультиварки RMC-CBD100S. Версия 4.31



ПО является неотъемлемой частью мультиварки RMC-CBD100S, отдельно потребителю не поставляется и эксплуатируется только в составе устройства.

Фрагмент исходного кода
/**    RMC-CBD100S
 *      @file  	application.c
 *  	@brief 	
*  	Revision:     ver 4_31
*/
	
/* Includes ------------------------------------------------------------------*/
#include <string.h>
#include "application.h"
#include "application_parameter.h"
#include "app_uart.h"

#include "soft_key.h"
#include "lcd.h"
#include "led.h"
#include "logic.h"
#include "logic_setting.h"
#include "radio_fm.h"
#include "err.h"
#include "power_memory.h"
#include "logic_radio.h"
#include "update_fw.h"
#include "demo.h"
#include "rtc.h"
#include "test_dev.h"
#include "blank.h"

/* Private defines -----------------------------------------------------------*/
/* Private types -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static uint8_t activ_bowl;
static app_str app_s;

/* Private function prototypes -----------------------------------------------*/
/* Активация чашы */
static void app_bowl_activ(uint8_t deactiv_bowl, uint8_t t_activ_bowl);
static void appl_go_begin_state(uint8_t bowl);
static void app_cook_time_handler(uint8_t bowl);
static void app_cook_time_l_handler(void);
static void app_cook_time_r_handler(void);

static void app_pairing_handler(void);
static void app_unpairing_handler(void);
static void app_setting_handler(void);
static void app_radio_handler(void);
static void app_update_fw_handler(void);
static void app_cook_reach_temp(void);


static bool app_cook_end_state[2] = {false,false};
static void app_set_cook_end(uint8_t bowl_end);
static void app_cook_end_l(void);
static void app_cook_end_r(void);

/* Function ------------------------------------------------------------------*/
void application_init(void)
{
  logic_call_str logic_call_s;
  
  /* Инициализация кнопок и энкодера */
  soft_key_init();
  /* Инициализация модуля приготовления*/
  cooking_init(&app_s.prog[APP_BOWL_L], &app_s.prog[APP_BOWL_R], app_cook_reach_temp);
  /* Инициализация индикации */
  lcd_init();
  led_init();
  /* Инициализация флешки для перепрошивки */
  update_fw_init();
  /* Инициализация радио */
  logic_radio_init();
  /* Инициализация настроек прибора */
  logic_setting_init();
  /* Инициализация включения прибора */
  logic_call_s.logic_menu_time_out = appl_go_begin_state;
  logic_call_s.logic_out_cook_in_reheat = app_cook_time_handler;
  logic_init(logic_call_s);
  
  power_memory_init(&app_s);
  
  /* Таймер обработки времени готовки */
  timer_create(TIMER_LOGIC_COOK_L, TIMER_MINUTE(1), SOFT_HANDLER_RESET, app_cook_time_l_handler);
  timer_create(TIMER_LOGIC_COOK_R, TIMER_MINUTE(1), SOFT_HANDLER_RESET, app_cook_time_r_handler);
  timer_create(TIMER_PAIRING, TIMER_SECOND(30), SOFT_HANDLER_STOP, app_pairing_handler);
  timer_create(TIMER_UNPAIRING, TIMER_SECOND(5), SOFT_HANDLER_STOP, app_unpairing_handler);
  timer_create(TIMER_SETTING, TIMER_SECOND(5), SOFT_HANDLER_STOP, app_setting_handler);
  timer_create(TIMER_APP_RADIO, TIMER_SECOND(60), SOFT_HANDLER_STOP, app_radio_handler);
  timer_create(TIMER_UPDATE_FW, TIMER_SECOND(5), SOFT_HANDLER_STOP, app_update_fw_handler);
  timer_create(TIMER_COOK_END_L, TIMER_SECOND(15), SOFT_HANDLER_STOP, app_cook_end_l);
  timer_create(TIMER_COOK_END_R, TIMER_SECOND(15), SOFT_HANDLER_STOP, app_cook_end_r);
  timer_create(TIMER_COOK_END_R, TIMER_SECOND(15), SOFT_HANDLER_STOP, app_cook_end_r);
  
  /* Инит стейта */
  for(uint8_t i=0; i<2; i++) app_s.state[i] = APPL_BEGIN_STATE;
  activ_bowl = APP_BOWL_NONE;
  logic_start();
  
  /* Проверка входа в режим работы с тестовыми параметрами */
  if(soft_key_get_press_ok() == KEY_OK_PRESS) test_dev_set(TEST_DEV_FL_ACTIV);
  else test_dev_set(TEST_DEV_FL_NONE);
  
  /* Переход в режим ожидания */
  if(power_memory_get(&app_s) == NONE_SAVE_PROGRAM){
    logic_set_state(&app_s, activ_bowl);
  }
  /* Если был сбой программы переходим на программу готовки */
  else{
    if(app_s.state[APP_BOWL_R] > APPL_PROGRAM_STATE && app_s.state[APP_BOWL_R] < APPL_REHEAT_STATE)
    {
      app_s.state[APP_BOWL_R] = APPL_PROGRAM_STATE;
      app_s.state[APP_BOWL_R] = logic_start_program(&app_s, APP_BOWL_R);
      /* Запускаем таймер отсчета времени готовки */
      timer_reset_start(TIMER_LOGIC_COOK_R);
    }
    if(app_s.state[APP_BOWL_R] != APPL_BEGIN_STATE) activ_bowl = APP_BOWL_R;

    if(app_s.state[APP_BOWL_L] > APPL_PROGRAM_STATE && app_s.state[APP_BOWL_L] < APPL_REHEAT_STATE)
    {
      app_s.state[APP_BOWL_L] = APPL_PROGRAM_STATE;
      app_s.state[APP_BOWL_L] = logic_start_program(&app_s, APP_BOWL_L);
      /* Запускаем таймер отсчета времени готовки */
      timer_reset_start(TIMER_LOGIC_COOK_L);
    }
    if(app_s.state[APP_BOWL_L] != APPL_BEGIN_STATE) activ_bowl = APP_BOWL_L;
    
    if(activ_bowl != APP_BOWL_NONE) logic_rtc_ind_clr();
  }
}


void application_process(void)
{
  static soft_key_s app_key;
  
  /* Считываем состояние кнопок и энкодера */
  if(app_s.state[0] != APPL_API_FW_UPDATE_STATE){
    soft_key_get(&app_key);
  }else{
    app_key.key = S_KEY_NONE;
    app_key.encoder_fl = ENCODER_FL_NONE;
  }
  
  /* Если нажали кнопку(и) */
  if(app_key.key != S_KEY_NONE || app_key.encoder_fl == ENCODER_FL_OK)
  {
    if((app_key.key == S_KEY_OK) || (app_key.key >= S_KEY_L && app_key.key <= S_KEY_SET)) BEEP();
    if(app_get_cook_end(APP_BOWL_L)) app_cook_end_l();
    if(app_get_cook_end(APP_BOWL_R)) app_cook_end_r();
    
    /* =========================================================================
    * Если включаем/выключаем блокировку клавиатуры
    * ========================================================================*/
    if(app_key.key == S_KEY_LOCK && app_s.state[0] != APPL_DEMO_STATE)
    {
      /* Блокировка не возможна в режиме настройки программы приготовления */
      if(logic_setting_get_lock() == LS_LOCK_ON || (app_s.state[0] != APPL_PROGRAM_STATE && app_s.state[1] != APPL_PROGRAM_STATE))
      {
        logic_setting_set_lock();
      }
    }
    /* =========================================================================
    * Если включаем/выключаем демо режим
    * ========================================================================*/
    else if(app_key.key == S_KEY_LONG_DEMO)
    {
      if(app_s.state[0] == APPL_BEGIN_STATE && app_s.state[1] == APPL_BEGIN_STATE && logic_radio_get_state() == L_RADIO_OFF)
      {
        app_s.state[0] = APPL_DEMO_STATE;
        app_s.state[1] = APPL_DEMO_STATE;
        demo_start();
      }else if(app_s.state[0] == APPL_DEMO_STATE){
        app_s.state[0] = APPL_BEGIN_STATE;
        app_s.state[1] = APPL_BEGIN_STATE;
        demo_stop();
      }
      return;
    }
    
    if(app_s.state[0] == APPL_DEMO_STATE) return;
    
    if(logic_setting_get_lock() == LS_LOCK_OFF)
    {
      /* =======================================================================
      * Если активно радио
      * ======================================================================*/
      uint8_t rd_st = logic_radio_get_state();
      if(rd_st == L_RADIO_ACTIV || rd_st == L_RADIO_AUTO_SEEK)
      {
        /* Проверка флага энкодера */
        if(app_key.encoder_fl == ENCODER_FL_OK){
          /* Если изменилось значение энкодера */
          logic_radio_encoder_check(app_key.encoder_adr);
          timer_reset_start(TIMER_APP_RADIO);
        }
        /* Проверка кнопок */
        switch(app_key.key)
        {
        case S_KEY_OFF_OK: /* Переключение настраиваемого параметра */
          {
            timer_reset_start(TIMER_APP_RADIO);
            logic_radio_setting();
            break;
          }
        case S_KEY_LONG_OK: /* Автопоиск станции */
          {
            timer_reset_start(TIMER_APP_RADIO);
            logic_radio_setting_auto_freq();
            break;
          }
        case S_KEY_SET: /* Настройка громкости */
          {
            timer_reset_start(TIMER_APP_RADIO);
            logic_radio_setting_volume();
            break;
          }
        case S_KEY_OFF_ESC: /* Переключение в фоновый режим */
          {
            timer_stop(TIMER_APP_RADIO);
            app_radio_handler();
            break;
          }
        case S_KEY_LONG_ESC: /* Выключение радио */
          {
            timer_stop(TIMER_APP_RADIO);
            logic_radio_off();
            logic_set_ind_current_state(&app_s, activ_bowl);
            break;
          }
        default: break;
        }
      }
      /* =======================================================================
      * Активация радио
      * ======================================================================*/
      else if(app_key.key == S_KEY_RADIO)
      {
        if(app_s.state[0] != APPL_PAIRING_STATE && \
           app_s.state[0] != APPL_UNPAIRING_STATE && \
           app_s.state[0] != APPL_SETTING_STATE){
              appl_deactiv_all_setting();
              logic_radio_activ();
              timer_reset_start(TIMER_APP_RADIO);
            }
      }
      /* =======================================================================
      * Активация чашы (проверка кнопок S_KEY_L, S_KEY_R)
      * ======================================================================*/
      else if(app_key.key == S_KEY_L || app_key.key == S_KEY_R)
      {
        uint8_t p_bowl_act = activ_bowl;
        uint8_t t_bowl_act;
        
        /* Определяем активную чашу */
        if(app_key.key == S_KEY_L) t_bowl_act = APP_BOWL_L; else t_bowl_act = APP_BOWL_R;
        /* Активируем чашу */
        app_bowl_activ(p_bowl_act, t_bowl_act);
      }
      /* =========================================================================
      * Проверка остальных кнопок 
      * ========================================================================*/
      else{
        /* Если не активна ни одна чаша */
        if(activ_bowl == APP_BOWL_NONE)
        {
          uint8_t state_bowl_none = APPL_BEGIN_STATE;
          
          if(app_s.state[0] == app_s.state[1]) state_bowl_none = app_s.state[0];
          
          switch(state_bowl_none)
          {
            /* Состояние ожидания */
          case APPL_BEGIN_STATE:
            {
              switch(app_key.key)
              {
              case S_KEY_BIG_LONG_OK: /* Запускаем пейринг */
                {
                  app_s.state[0] = APPL_PAIRING_STATE;
                  app_s.state[1] = APPL_PAIRING_STATE;
                  timer_reset_start(TIMER_PAIRING);
                  BEEP_PAIRING();
                  break;
                }
              case S_KEY_UNPAIRING: /* Запускаем анпейринг */
                {
                  if(logic_radio_get_state() != L_RADIO_OFF) logic_radio_off();
                  app_s.state[0] = APPL_UNPAIRING_STATE;
                  app_s.state[1] = APPL_UNPAIRING_STATE;
                  timer_reset_start(TIMER_UNPAIRING);
                  /* Удаление радиостанций */
                  logic_radio_clear_all_freq();
                  /* Удаление флага отключения звуков */
                  logic_setting_set_sound(1);
                  BEEP_UNPAIRING();
                  break;
                }
              case S_KEY_LONG_SET: /* Запускаем настройку параметров мультиварки */
                {
                  app_s.state[0] = APPL_SETTING_STATE;
                  app_s.state[1] = APPL_SETTING_STATE;
                  logic_setting_next_params();
                  BEEP();
                  timer_reset_start(TIMER_SETTING);
                  break;
                }
                
              default: break;
              }
              break;
            }
            /* Состояние настройки параметров мультиварки */
          case APPL_SETTING_STATE:
            {
              /* Проверка флага энкодера */
              if(app_key.encoder_fl == ENCODER_FL_OK){
                /* Если изменилось значение энкодера */
                logic_setting_encoder_check(app_key.encoder_adr);
                timer_reset_start(TIMER_SETTING);
              }
              /* Проверка кнопок */
              switch(app_key.key)
              {
              case S_KEY_OK: /* Переключение настраиваемого параметра */
                {
                  timer_reset_start(TIMER_SETTING);
                  if(logic_setting_next_params()){
                    timer_stop(TIMER_SETTING);
                    /* Выход из режима настройки */
                    logic_setting_exit();
                    app_s.state[0] = APPL_BEGIN_STATE;
                    app_s.state[1] = APPL_BEGIN_STATE;
                  }
                  break;
                } 
              default: break;
              }
              break;
            }
          }
        }
        /* Если есть активная чаша */
        else{/*APP_BOWL_L(R)*/
          switch(app_s.state[activ_bowl])
          {       
            /* ============= Режим настройки программы приготовления ==================== */
          case APPL_PROGRAM_STATE:
            {
              /* Проверка флага энкодера */
              if(app_key.encoder_fl == ENCODER_FL_OK)
              {
                /* Если изменилась программа */
                if(app_key.encoder_adr == &app_s.prog[activ_bowl].program_num){
                  logic_seting_program(&app_s, activ_bowl, LCD_SET);
                }
                /* Если изменялась температура */
                else if(app_key.encoder_adr == &app_s.prog[activ_bowl].cook_temp_ind){
                  logic_check_seting_temp(&app_s.prog[activ_bowl], activ_bowl);
                }
                /* Если изменялся продукт */
                else if(app_key.encoder_adr == &app_s.prog[activ_bowl].product_num){
                  logic_check_seting_product(&app_s.prog[activ_bowl], activ_bowl);
                }
                /* Если изменялось время приготовления */
                else if(app_key.encoder_adr == &app_s.prog[activ_bowl].cook_time){
                  logic_check_seting_time(&app_s.prog[activ_bowl], activ_bowl);
                }
                /* Если изменялось время отложенного старта */
                else if(app_key.encoder_adr == &app_s.prog[activ_bowl].post_ponement_time){
                  logic_check_seting_dtime(&app_s.prog[activ_bowl], activ_bowl);
                }
              }
              
              switch(app_key.key)
              {
                /* Выход из режима настройки параметров готовки */
              case S_KEY_LONG_ESC:
                {
                  appl_go_begin_state(activ_bowl);
                  break;
                }
               /* Возврат изменяемого параметра */
              case S_KEY_OFF_ESC:
                {
                  if(logic_return_param_setting(&app_s, activ_bowl) == false){
                    app_s.prog[activ_bowl].program_num = APPL_HEATING_PROG;
                    app_s.state[activ_bowl] = logic_start_program(&app_s, activ_bowl);
                    /* Запускаем таймер отсчета времени готовки */
                    if(activ_bowl == APP_BOWL_L) timer_reset_start(TIMER_LOGIC_COOK_L);
                    else timer_reset_start(TIMER_LOGIC_COOK_R);
                  }
                  break;
                }
                /* Выбор программы, изменение подпараметра */
              case S_KEY_OFF_OK:
                {
                  logic_set_param_setting(&app_s, activ_bowl);
                  break;
                }
                /* Запуск программы приготовления */
              case S_KEY_LONG_OK:
                {
                  app_s.state[activ_bowl] = logic_start_program(&app_s, activ_bowl);
                  /* Запускаем таймер отсчета времени готовки */
                  if(activ_bowl == APP_BOWL_L) timer_reset_start(TIMER_LOGIC_COOK_L);
                  else timer_reset_start(TIMER_LOGIC_COOK_R);
                  break;
                }
                /* Переключение настраиваемого параметра */
              case S_KEY_SET:
                {
                  logic_set_new_param_setting(&app_s, activ_bowl);
                  break;
                }
                
              default: break;
              }
              break;
            }
            /* ============= Режим отложеного старта ==================================== */
          case APPL_START_DELAY_STATE:
            {
              switch(app_key.key)
              {
                /* Выход в режим ожидания */
              case S_KEY_LONG_ESC:
                {
                  /* Останавливаем таймер отсчета времени готовки */
                  if(activ_bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
                  else timer_stop(TIMER_LOGIC_COOK_R);
                  appl_go_begin_state(activ_bowl);
                  break;
                }
                /* Вывод времени к которому должно приготовиться блюдо */
              case S_KEY_SET:
                {
                  logic_out_time_cook_end(&app_s, activ_bowl);
                  break;
                }
                /* Переключение подогрева */
              case S_KEY_OFF_OK:
                {
                  logic_set_keep(&app_s.prog[activ_bowl], activ_bowl, LG_KEEP_INVER);
                  break;
                }

              default: break;
              }
              break;
            }
            /* ============= Режим ожидания закладки продуктов ========================== */
          case APPL_WAIT_STATE:
            { 
              switch(app_key.key)
              {
                /* Запуск программы Паста */
              case S_KEY_OK:
                {
                  app_s.state[activ_bowl] = logic_start_program(&app_s, activ_bowl);
                  /* Запускаем таймер отсчета времени готовки */
                  if(activ_bowl == APP_BOWL_L) timer_reset_start(TIMER_LOGIC_COOK_L);
                  else timer_reset_start(TIMER_LOGIC_COOK_R);
                  break;
                }
                /* Выход в режим ожидания */
              case S_KEY_LONG_ESC:
                {
                  /* Останавливаем таймер отсчета времени готовки */
                  if(activ_bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
                  else timer_stop(TIMER_LOGIC_COOK_R);
                  appl_go_begin_state(activ_bowl);
                  break;
                }
                
              default: break;
              }
              break;
            }
            /* ============= Режим нагрева до установленой температуры ================== */
          case APPL_BOOST_STATE:
            /* ============= Режим приготовления ======================================== */
          case APPL_COOKING_STATE:
            {
              /* Проверка флага энкодера */
              if(app_key.encoder_fl == ENCODER_FL_OK)
              {
                /* Если изменялась температура */
                if(app_key.encoder_adr == &app_s.prog[activ_bowl].cook_temp_ind){
                  logic_check_mch_temp(&app_s.prog[activ_bowl], activ_bowl);
                }
                /* Если изменялось время приготовления */
                else if(app_key.encoder_adr == &app_s.prog[activ_bowl].cook_time){
                  logic_check_mch_time(&app_s.prog[activ_bowl], activ_bowl);
                }
              }
              
              switch(app_key.key)
              {
                /* Изменение параметра настройки */
              case S_KEY_SET:
                {
                  logic_mch_set_param_cooking(&app_s, activ_bowl);
                  break;
                }
                /* Сохранение параметра настройки */
              case S_KEY_OFF_OK:
                {
                  /* Программа "Экспресс" не имеет параметров настройки */
                  if(app_s.prog[activ_bowl].program_num == APPL_EXPRESS_COOK_PROG) break;
                  if(logic_mch_save_params() == false){
                    logic_set_keep(&app_s.prog[activ_bowl], activ_bowl, LG_KEEP_INVER);
                  }
                  break;
                }
                /* Выход в режим ожидания */
              case S_KEY_LONG_ESC:
                {
                  /* Останавливаем таймер отсчета времени готовки */
                  if(activ_bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
                  else timer_stop(TIMER_LOGIC_COOK_R);
                  appl_go_begin_state(activ_bowl);
                  break;
                }
                
              default: break;
              }
              break;
            }
            /* ============= Режим подогрева (разогрева) ================================ */
          case APPL_REHEAT_STATE:
            {
              switch(app_key.key)
              {
                /* Выход в режим ожидания */
              case S_KEY_LONG_ESC:
                {
                  /* Останавливаем таймер отсчета времени готовки */
                  if(activ_bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
                  else timer_stop(TIMER_LOGIC_COOK_R);
                  appl_go_begin_state(activ_bowl);
                  break;
                }
                
              default: break;
              }
              break;
            }
            /* ============= Режим ошибки готовки ======================================= */
          case APPL_ERROR_STATE:
            {
              break;
            }
            /* ============= Режим подключения к устройству ============================= */
          case APPL_PAIRING_STATE:
            {
              break;
            }
            /* ============= Режим демонстрации ========================================= */
          case APPL_DEMO_STATE:
            {
              break;
            }
            /* ============= Режим тестирования ========================================= */
          case APPL_TEST_STATE:
            {
              break;
            }
          }
        }
      }
    }
  }
  
  /* Проверка статуса готовки */
  for(uint8_t i=0; i<2; i++)
  {
    uint8_t t_state_cook;
    t_state_cook = cooking_get(i);
    if(t_state_cook == STAGE_ENDOFBOOST)
    {
      if(app_s.prog[i].program_num == APPL_PASTA_PROG)
      {
        if(app_s.state[i] != APPL_WAIT_STATE){
          BEEP_COOK_END();
          app_s.state[i] = APPL_WAIT_STATE;
        }
      }else{
        BEEP_END_DTIME_BO0ST();
        app_s.state[i] = logic_start_program(&app_s, i);
        /* Запускаем таймер отсчета времени готовки */
        if(i == APP_BOWL_L) timer_reset_start(TIMER_LOGIC_COOK_L);
        else timer_reset_start(TIMER_LOGIC_COOK_R);
      }   
    }
    else if(t_state_cook == STAGE_NONE)
    {
      if(app_s.state[i] == APPL_COOKING_STATE){
        BEEP_COOK_END();
        app_set_cook_end(i);
        app_s.state[i] = logic_start_program(&app_s, i);
        appl_go_begin_state(i);
      }
    }
    /* Проверка ошибок готовки */
    if(error_get(i) != NO_ERR){
      if(app_s.state[i] != APPL_ERROR_STATE){
        app_s.state[i] = APPL_ERROR_STATE;
        BEEP_ERROR();
      }
    }
  }

  /* Обновление индикации автопоиска радио */
  if(logic_radio_get_state() == L_RADIO_AUTO_SEEK)
  {
    logic_radio_auto_freq_update();
    timer_reset_start(TIMER_APP_RADIO);
  }
  
  /* Обновление логики */
  logic_set_state(&app_s, activ_bowl);
  
  /* Если установлен флаг тестового режима */
  if(test_dev_get() == TEST_DEV_FL_ACTIV){
    if(app_s.state[0] != APPL_BEGIN_STATE || app_s.state[1] != APPL_BEGIN_STATE){
      if(timer_active(TIMER_TEST) == TIMER_STOP){
        timer_create(TIMER_TEST, TIMER_SECOND(1), SOFT_HANDLER_RESET, logic_set_ind_test_params);
        timer_start(TIMER_TEST);
        logic_set_ind_test_params();
      }
    }else{
      if(timer_active(TIMER_TEST) == TIMER_ACTIVE){
        timer_stop(TIMER_TEST);
      }
    }
  }
  
  /* Обновление верхней части дисплея */
  lcd_update();
}

/* Деактивация любых режимов настройки */
void appl_deactiv_all_setting(void)
{
  /* Деактивация настройки параметров программы в режиме APPL_PROGRAM_STATE */
  logic_menu_set_handler();
  /* Деактивация мастер шеф если был включен */
  logic_master_chief_handler();
  /* Деактивация радио */
  if(logic_radio_get_state() == L_RADIO_ACTIV){
    timer_stop(TIMER_APP_RADIO);
    app_radio_handler();
  }
  
}

/* Private function prototypes -----------------------------------------------*/
/* Активация чашы */
static void app_bowl_activ(uint8_t deactiv_bowl, uint8_t t_activ_bowl)
{
  if(app_s.state[0] == APPL_PAIRING_STATE || \
     app_s.state[0] == APPL_UNPAIRING_STATE || \
     app_s.state[0] == APPL_SETTING_STATE) return;
  
  activ_bowl = t_activ_bowl;
  /* Если изменилась активная чаша */
  if(deactiv_bowl != activ_bowl){
    /* Деактивируем старую чашу */
    if(deactiv_bowl != APP_BOWL_NONE){
      switch(app_s.state[deactiv_bowl])
      {
      case APPL_PROGRAM_STATE:
        {
          app_s.state[deactiv_bowl] = APPL_BEGIN_STATE;
          logic_menu_set_handler();
          break;
        }
      case APPL_START_DELAY_STATE:
        {
          break;
        }
      case APPL_WAIT_STATE:
        {
          break;
        }
      case APPL_BOOST_STATE:
      case APPL_COOKING_STATE:
        {
          logic_master_chief_handler();
          break;
        }
      case APPL_REHEAT_STATE:
        {
          break;
        }
      }
    }
  }

  /* Активируем новую чашу */
  switch(app_s.state[activ_bowl])
  {
  case APPL_BEGIN_STATE:
  case APPL_PROGRAM_STATE:
    {
      /* Выставляем номер программы по умолчанию */
      app_s.prog[activ_bowl].program_num = APPL_MULTI_COOK_PROG;
      /* Выставляем статус настройки программы */
      app_s.state[activ_bowl] = APPL_PROGRAM_STATE;
      break;
    }
  }
}

/* Переход в режим ожидания */
static void appl_go_begin_state(uint8_t bowl)
{
  uint8_t bowl_n;
  
  app_s.state[bowl] = APPL_BEGIN_STATE;
  
  if(bowl == APP_BOWL_L) bowl_n = APP_BOWL_R;
  else bowl_n = APP_BOWL_L;
  if(app_s.state[bowl_n] == APPL_BEGIN_STATE){
    activ_bowl = APP_BOWL_NONE;
  }else activ_bowl = bowl_n;
}

static void app_cook_time_handler(uint8_t bowl)
{
  /* Если вышло время этапа приготовления */
  if(LG_COOK_WORK_NEXT == logic_cook_time_work(&app_s, bowl))
  {
    switch(app_s.state[bowl])
    {
      /* Если был этап отложенного старта */
    case APPL_START_DELAY_STATE:
      {
        BEEP_END_DTIME_BO0ST();
        app_s.state[bowl] = logic_start_program(&app_s, bowl);
        break;
      }
      /* Если был этап разгона */
    case APPL_BOOST_STATE:
      {
        app_s.state[bowl] = logic_start_program(&app_s, bowl);
        /* Если подогрев не включен */
        if(app_s.state[bowl] == APPL_BEGIN_STATE)
        {
          /* Останавливаем таймер отсчета времени готовки */
          if(bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
          else timer_stop(TIMER_LOGIC_COOK_R);
          appl_go_begin_state(bowl);
        }
        break;
      }
      /* Если был этап готовки */
    case APPL_COOKING_STATE:
      {
        BEEP_COOK_END();
        app_set_cook_end(bowl);
        app_s.state[bowl] = logic_start_program(&app_s, bowl);
        /* Если подогрев не включен */
        if(app_s.state[bowl] == APPL_BEGIN_STATE)
        {
          /* Останавливаем таймер отсчета времени готовки */
          if(bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
          else timer_stop(TIMER_LOGIC_COOK_R);
          appl_go_begin_state(bowl);
        }
        break;
      }
      /* Если был этап подогрева */
    case APPL_REHEAT_STATE:
      {
        /* Останавливаем таймер отсчета времени готовки */
        if(bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
        else timer_stop(TIMER_LOGIC_COOK_R);
        /* Переходим в режим ожидания */
        app_s.state[bowl] = APPL_BEGIN_STATE;
        BEEP_REHEAT_END();
        appl_go_begin_state(bowl);
        break;
      }
    }
  }
}

static void app_cook_time_l_handler(void)
{
  app_cook_time_handler(APP_BOWL_L);
}

static void app_cook_time_r_handler(void)
{
  app_cook_time_handler(APP_BOWL_R);
}

static void app_pairing_handler(void)
{
  app_s.state[0] = APPL_BEGIN_STATE;
  app_s.state[1] = APPL_BEGIN_STATE;
  BEEP_ERROR();
}

static void app_unpairing_handler(void)
{
  app_s.state[0] = APPL_BEGIN_STATE;
  app_s.state[1] = APPL_BEGIN_STATE;
}

static void app_setting_handler(void)
{
  app_s.state[0] = APPL_BEGIN_STATE;
  app_s.state[1] = APPL_BEGIN_STATE;
  logic_setting_exit();
}

static void app_radio_handler(void)
{
  logic_radio_deactiv();
  logic_set_ind_current_state(&app_s, activ_bowl);
}

static void app_update_fw_handler(void)
{
  app_s.state[0] = APPL_BEGIN_STATE;
  app_s.state[1] = APPL_BEGIN_STATE;
  blank_off(BLANK_MODE);
  update_fw_erase_page();
  BEEP_ERROR();
}

static void app_cook_reach_temp(void)
{
  BEEP_REACH_TEMP();
}


static void app_set_cook_end(uint8_t bowl_end)
{
  if(bowl_end == APP_BOWL_L)
  {
    app_cook_end_state[0] = true;
    timer_reset_start(TIMER_COOK_END_L);
  }
  else if(bowl_end == APP_BOWL_R)
  {
    app_cook_end_state[1] = true;
    timer_reset_start(TIMER_COOK_END_R);
  }
}

bool app_get_cook_end(uint8_t bowl_end)
{
  if(bowl_end == APP_BOWL_L) return app_cook_end_state[0];
  else if(bowl_end == APP_BOWL_R) return app_cook_end_state[1];
  return false;
}

/* Сбрасываем надпись "Готово" */
static void app_cook_end_l(void)
{
  timer_stop(TIMER_COOK_END_L);
  app_cook_end_state[0] = false;
  logic_set_ind_current_state(&app_s, activ_bowl);
}

/* Сбрасываем надпись "Готово" */
static void app_cook_end_r(void)
{
  timer_stop(TIMER_COOK_END_R);
  app_cook_end_state[1] = false;
  logic_set_ind_current_state(&app_s, activ_bowl);
}

/*******************************************************************************
 * Set functions app
 ******************************************************************************/
/**
 * api_set_program - установка программы готовки
 */
RmcErrorTypeDef api_set_program(uint8_t bowl, uint8_t prog, uint8_t prod, uint8_t hour, uint8_t min, uint8_t temp, uint8_t keep)
{
  if(bowl > APP_BOWL_R) return RMC_ERROR_NOT_CARRY_OUT;
  /* Если состояние не равно ожиданию */
  if(app_s.state[bowl] != APPL_BEGIN_STATE && app_s.state[bowl] != APPL_PROGRAM_STATE) return RMC_ERROR_NOT_CARRY_OUT;
  /* Если не допустимая программа */
  prog = app_convert_uart_appl_prog(prog);
  if(prog > APPL_KEEP_COOK_PROG) return RMC_ERROR_NOT_CARRY_OUT;
  /* Если не допустимый продукт */
  if(prod > 4) return RMC_ERROR_NOT_CARRY_OUT;
  if(cook_param_get_num_prod(prog) == 1 && prod != 0) return RMC_ERROR_NOT_CARRY_OUT;
  /* Если не допустимое время */
  if(hour > 23 || min > 59 || keep > 1) return RMC_ERROR_NOT_CARRY_OUT;
  /* Если не допустимая температура */
  if(temp < APP_TEMP_MIN || temp > APP_TEMP_MAX){
    if(temp != APP_TEMP_NONE) return RMC_ERROR_NOT_CARRY_OUT;
  }
  
  uint8_t p_bowl_act = activ_bowl;    
  /* Активируем чашу */
  app_bowl_activ(p_bowl_act, bowl);
  
  app_s.prog[bowl].program_num = prog;
  if(prod == 0) app_s.prog[bowl].product_num = 0xFF;
  else app_s.prog[bowl].product_num = prod - 1;
  if(temp == APP_TEMP_NONE) app_s.prog[bowl].cook_temp_ind = cook_param_get_cook_temp(app_s.prog[bowl].program_num);
  else app_s.prog[bowl].cook_temp_ind = temp;
  app_s.prog[bowl].cook_time = (uint16_t)hour*60 + min;
  
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_set_change_program - установка параметров программы при готовке
 */
RmcErrorTypeDef api_set_change_program(uint8_t bowl, uint8_t hour, uint8_t min, uint8_t temp, uint8_t keep)
{
  if(bowl > APP_BOWL_R) return RMC_ERROR_NOT_CARRY_OUT;
  
  if(app_s.state[bowl] != APPL_START_DELAY_STATE &&\
     app_s.state[bowl] != APPL_BOOST_STATE &&\
     app_s.state[bowl] != APPL_COOKING_STATE) return RMC_ERROR_NOT_CARRY_OUT;

  /* Если не допустимое время */
  if(hour > 23 || min > 59 || keep > 1) return RMC_ERROR_NOT_CARRY_OUT;
  /* Если не допустимая температура */
  if(temp < 35 || temp > 180) return RMC_ERROR_NOT_CARRY_OUT;
  
  /* Сбрасываем мастер шеф если был включен */
  logic_master_chief_handler();
  
  /* Если изменилась температура */
  if(app_s.prog[bowl].cook_temp_ind != temp){
    uint8_t state_lcd = LCD_CLR;
    uint8_t temp_80 = app_s.prog[bowl].cook_temp_ind;
    
    app_s.prog[bowl].cook_temp_ind = temp;
    /* Если изменилась температура */
    if(app_s.prog[bowl].cook_temp_ind != cook_param_get_cook_temp(app_s.prog[bowl].program_num || \
      app_s.prog[bowl].program_num == APPL_MULTI_COOK_PROG)){
      state_lcd = LCD_SET;
    }
    logic_setting_params_work_program(&app_s.prog[bowl]);
    lcd_set_temp(bowl, app_s.prog[bowl].cook_temp_ind, LCD_TEMP_C, state_lcd);
    /* Установка максимального времени готовки */
    lg_menu_set_max_time(&app_s.prog[bowl], bowl);
    
    /* Установка подогрева */
    if(temp_80 < LG_KEEP_MIN_TEMP && app_s.prog[bowl].cook_temp_ind >= LG_KEEP_MIN_TEMP){
      logic_set_keep(&app_s.prog[bowl], bowl, LG_KEEP_SET);
    }else if(temp_80 >= LG_KEEP_MIN_TEMP && app_s.prog[bowl].cook_temp_ind < LG_KEEP_MIN_TEMP){
      logic_set_keep(&app_s.prog[bowl], bowl, LG_KEEP_RESET);
    }
  }
  
  /* Установка подогрева */
  if(keep == 0) logic_set_keep(&app_s.prog[bowl], bowl, LG_KEEP_RESET);
  else logic_set_keep(&app_s.prog[bowl], bowl, LG_KEEP_SET);
  
  /* Если изменилось время приготовления */
  uint16_t time_new = ((uint16_t)hour*60 + (uint16_t)min);
  if(app_s.prog[bowl].cook_time != time_new){
    if(time_new > cook_param_get_max_time(app_s.prog[bowl].program_num)){
      //lcd_update();
      return RMC_ERROR_NOT_CARRY_OUT;
    }
    app_s.prog[bowl].cook_time = time_new;
    if(app_s.prog[bowl].cook_time == 0){
      app_cook_time_handler(bowl);
      return RMC_ERROR_CARRY_OUT_COMPLETELY;
    }
      
    lcd_set_time(bowl, app_s.prog[bowl].cook_time, LCD_SET);
    lcd_set_image_time(bowl, LCD_SET);
  }
  
  //lcd_update();
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_set_reserv_tim - установка отложенного старта
 */
RmcErrorTypeDef api_set_reserv_time(uint8_t bowl, uint8_t hour, uint8_t min, uint8_t en, uint8_t blank)
{
  if(app_s.state[bowl] != APPL_PROGRAM_STATE) return RMC_ERROR_NOT_CARRY_OUT;
  
  if(bowl > APP_BOWL_R) return RMC_ERROR_NOT_CARRY_OUT;
  if(hour > 23 || min > 59) return RMC_ERROR_NOT_CARRY_OUT;
  if(en > 1) return RMC_ERROR_NOT_CARRY_OUT;
  
  /* Если в программе не возможно включить подогрев */
  if(en == 1 && app_s.prog[bowl].post_ponement_en == COOK_DE) return RMC_ERROR_NOT_CARRY_OUT;
  /* Если отложенный старт выключаем */
  if(en == 0){
    app_s.prog[bowl].post_ponement_time = NOT_DTIME; 
    return RMC_ERROR_CARRY_OUT_COMPLETELY;
  }
  
  RTC_TimeTypeDef RTC_Time;
  /* Get time */
  rtc_get_time(&RTC_Time);
  uint16_t time_post = RTC_Time.RTC_Hours*60+RTC_Time.RTC_Minutes;
  uint16_t time_set = hour*60+min;
  
  /* Если текущее время меньше установленного */
  if(time_post < time_set) time_post = (time_set - time_post);
  /* Если текущее время больше установленного */
  else time_post = ((time_set + 24*60) - time_post);
  
  app_s.prog[bowl].post_ponement_time = time_post;
  
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_start - запуск программы
 */
RmcErrorTypeDef api_start(uint8_t bowl)
{
  if(bowl > APP_BOWL_R) return RMC_ERROR_NOT_CARRY_OUT;
  if(app_s.state[bowl] != APPL_PROGRAM_STATE) return RMC_ERROR_NOT_CARRY_OUT;
  
  activ_bowl = bowl;
  app_s.state[activ_bowl] = logic_start_program(&app_s, activ_bowl);
  /* Запускаем таймер отсчета времени готовки */
  if(activ_bowl == APP_BOWL_L) timer_reset_start(TIMER_LOGIC_COOK_L);
  else timer_reset_start(TIMER_LOGIC_COOK_R);
  
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_stop - остановка программы
 */
RmcErrorTypeDef api_stop(uint8_t bowl)
{
  if(bowl > APP_BOWL_R) return RMC_ERROR_NOT_CARRY_OUT;
  if(app_s.state[bowl] == APPL_BEGIN_STATE) return RMC_ERROR_NOT_CARRY_OUT;
  
  activ_bowl = bowl;
  /* Останавливаем таймер отсчета времени готовки */
  if(activ_bowl == APP_BOWL_L) timer_stop(TIMER_LOGIC_COOK_L);
  else timer_stop(TIMER_LOGIC_COOK_R);
  appl_go_begin_state(activ_bowl);
  
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_set_fm_data - установка радиостанций
 */
RmcErrorTypeDef api_set_fm_data(uint8_t index, uint8_t *data)
{
  /* Задаем частоты радиостанций */
  logic_radio_set_freq_all(data);
  logic_radio_set_num(index);
  if(logic_radio_get_state() != L_RADIO_OFF){
    if(logic_radio_get_state() == L_RADIO_ACTIV) timer_reset_start(TIMER_APP_RADIO);
    logic_radio_on_idex();
  }
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_set_switch_fm - включение радио
 */
RmcErrorTypeDef api_set_switch_fm(uint8_t off_on, uint8_t rez)
{
  if(off_on > 1) return RMC_ERROR_NOT_CARRY_OUT;
  
  if(off_on == 0){
    timer_stop(TIMER_APP_RADIO);
    logic_radio_off();
  }else{
    logic_radio_activ();
    timer_reset_start(TIMER_APP_RADIO);
  }
  
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_set_volume - установка громкости
 */
RmcErrorTypeDef api_set_volume(uint8_t buz_en, uint8_t vol_radio)
{
  if(buz_en > 1) return RMC_ERROR_NOT_CARRY_OUT;
  if(vol_radio > RADIO_VOLUME_MAX) return RMC_ERROR_NOT_CARRY_OUT;
  logic_setting_set_sound(buz_en);
  radio_set_volume(vol_radio);
  
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_set_language - установка языка
 */
RmcErrorTypeDef api_set_language(uint8_t language)
{
  return RMC_ERROR_NOT_CARRY_OUT;
}

/**
 * api_set_product - установка продукта
 */
RmcErrorTypeDef api_set_product(uint8_t bowl, uint8_t product)
{
  return RMC_ERROR_NOT_CARRY_OUT;
}

/**
 * api_set_cooking_time - установка времени готовки
 */
RmcErrorTypeDef api_set_cooking_time(uint8_t bowl, uint8_t hour, uint8_t min, uint8_t blank)
{
  if(bowl > APP_BOWL_R) return RMC_ERROR_NOT_CARRY_OUT;
  
  if(app_s.state[bowl] != APPL_START_DELAY_STATE &&\
     app_s.state[bowl] != APPL_BOOST_STATE &&\
     app_s.state[bowl] != APPL_COOKING_STATE) return RMC_ERROR_NOT_CARRY_OUT;

  /* Если не допустимое время */
  if(hour > 23 || min > 59) return RMC_ERROR_NOT_CARRY_OUT;
  
  /* Сбрасываем мастер шеф если был включен */
  logic_master_chief_handler();
  
  /* Если изменилось время приготовления */
  uint16_t time_new = ((uint16_t)hour*60 + (uint16_t)min);
  if(app_s.prog[bowl].cook_time != time_new){
    if(time_new > cook_param_get_max_time(app_s.prog[bowl].program_num)){
      return RMC_ERROR_NOT_CARRY_OUT;
    }
    app_s.prog[bowl].cook_time = time_new;
    if(app_s.prog[bowl].cook_time == 0){
      app_cook_time_handler(bowl);
      return RMC_ERROR_CARRY_OUT_COMPLETELY;
    }
      
    lcd_set_time(bowl, app_s.prog[bowl].cook_time, LCD_SET);
    lcd_set_image_time(bowl, LCD_SET);
  }

  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_set_cooking_temp - установка температуры готовки
 */
RmcErrorTypeDef api_set_cooking_temp(uint8_t bowl, uint8_t temp)
{
  if(bowl > APP_BOWL_R) return RMC_ERROR_NOT_CARRY_OUT;
  
  if(app_s.state[bowl] != APPL_START_DELAY_STATE &&\
     app_s.state[bowl] != APPL_BOOST_STATE &&\
     app_s.state[bowl] != APPL_COOKING_STATE) return RMC_ERROR_NOT_CARRY_OUT;

  /* Если не допустимая температура */
  if(temp < 35 || temp > 180) return RMC_ERROR_NOT_CARRY_OUT;
  
  /* Сбрасываем мастер шеф если был включен */
  logic_master_chief_handler();
  
  /* Если изменилась температура */
  if(app_s.prog[bowl].cook_temp_ind != temp){
    uint8_t state_lcd = LCD_CLR;
    uint8_t temp_80 = app_s.prog[bowl].cook_temp_ind;
    
    app_s.prog[bowl].cook_temp_ind = temp;
    /* Если изменилась температура */
    if(app_s.prog[bowl].cook_temp_ind != cook_param_get_cook_temp(app_s.prog[bowl].program_num || \
      app_s.prog[bowl].program_num == APPL_MULTI_COOK_PROG)){
      state_lcd = LCD_SET;
    }
    logic_setting_params_work_program(&app_s.prog[bowl]);
    lcd_set_temp(bowl, app_s.prog[bowl].cook_temp_ind, LCD_TEMP_C, state_lcd);
    /* Установка максимального времени готовки */
    lg_menu_set_max_time(&app_s.prog[bowl], bowl);
    
    /* Установка подогрева */
    if(temp_80 < LG_KEEP_MIN_TEMP && app_s.prog[bowl].cook_temp_ind >= LG_KEEP_MIN_TEMP){
      logic_set_keep(&app_s.prog[bowl], bowl, LG_KEEP_SET);
    }else if(temp_80 >= LG_KEEP_MIN_TEMP && app_s.prog[bowl].cook_temp_ind < LG_KEEP_MIN_TEMP){
      logic_set_keep(&app_s.prog[bowl], bowl, LG_KEEP_RESET);
    }
  }
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_reset_pairing - выход из режима перинга
 */
RmcErrorTypeDef api_reset_pairing(void)
{
  if(app_s.state[0] == APPL_PAIRING_STATE){
    timer_stop(TIMER_PAIRING);
    app_s.state[0] = APPL_BEGIN_STATE;
    app_s.state[1] = APPL_BEGIN_STATE;
    BEEP_PAIRING_OK();
    return RMC_ERROR_CARRY_OUT_COMPLETELY;
  }
  return RMC_ERROR_NOT_CARRY_OUT;
}

/**
 * api_set_launch_auto_seek - автопоис радиостанции
 */
RmcErrorTypeDef api_set_launch_auto_seek(uint8_t auto_seek)
{
  if(auto_seek > 1) return RMC_ERROR_NOT_CARRY_OUT;
  
  if(auto_seek == 1){
    logic_radio_setting_auto_freq();
  }else{
    logic_radio_activ();
  }
  timer_reset_start(TIMER_APP_RADIO);
  
  return RMC_ERROR_CARRY_OUT_COMPLETELY;
}

/**
 * api_update_fw_request - запуск процесса обновления прошивки
 */
RmcErrorTypeDef api_update_fw_request(uint16_t size, uint16_t ver)
{
  RmcErrorTypeDef rmc_err = RMC_ERROR_NOT_CARRY_OUT;
  
  if(app_s.state[0] != APPL_BEGIN_STATE || app_s.state[1] != APPL_BEGIN_STATE) return rmc_err;
  if(logic_radio_get_state() != L_RADIO_OFF) logic_radio_off();
  
  if(update_fw_request(size, ver) != OK) return rmc_err;
  rmc_err = RMC_ERROR_CARRY_OUT_COMPLETELY;
  
  app_s.state[0] = APPL_API_FW_UPDATE_STATE;
  app_s.state[1] = APPL_API_FW_UPDATE_STATE;
  blank_on_data(BLANK_MODE, BLANK_MODE_ONE_LO, 0, 0, logic_ind_fw_update, 0);
  timer_reset_start(TIMER_UPDATE_FW);
  
  return rmc_err;
}

/**
 * api_transmit_fw_data - запись данных прошивки
 */
RmcErrorTypeDef api_transmit_fw_data(uint16_t index, uint8_t size, uint8_t *data)
{
  RmcErrorTypeDef rmc_err = RMC_ERROR_NOT_CARRY_OUT;
  
  if(app_s.state[0] != APPL_API_FW_UPDATE_STATE) return rmc_err;
  
  if(update_fw_receiver_data(index, size, data) != OK)
  {
    timer_stop(TIMER_UPDATE_FW);
    app_update_fw_handler();
  }else rmc_err = RMC_ERROR_CARRY_OUT_COMPLETELY;
  
  timer_reset(TIMER_UPDATE_FW);
  return rmc_err;
}

/**
 * api_implement_fw_update - запуск процесса перепрошивки
 */
RmcErrorTypeDef api_implement_fw_update(uint32_t crc32)
{
  RmcErrorTypeDef rmc_err = RMC_ERROR_NOT_CARRY_OUT;
  
  if(app_s.state[0] != APPL_API_FW_UPDATE_STATE) return rmc_err;
  
  timer_stop(TIMER_UPDATE_FW);
  
  if(update_fw_crc32(crc32) == OK) rmc_err = RMC_ERROR_CARRY_OUT_COMPLETELY;
  else app_update_fw_handler();
  
  app_s.state[0] = APPL_BEGIN_STATE;
  app_s.state[1] = APPL_BEGIN_STATE;
  
  return rmc_err;
}

/*******************************************************************************
 * Get functions app
 ******************************************************************************/
/**
 * api_get_full_program - запрос параметров установленной программы
 */
void api_get_full_program(uint8_t bowl, uint8_t *date_prog)
{
  date_prog[0] = bowl;
  memset(&date_prog[1], 0, 8);
  
  if(bowl > APP_BOWL_R) return;
  if(app_s.state[bowl] == APPL_BEGIN_STATE) return;
  /* Program */
  date_prog[1] = app_convert_appl_uart_prog(app_s.prog[bowl].program_num);
  /* Product */
  if(app_s.prog[bowl].product_num == NOT_PROD) date_prog[2] = 0;
  else date_prog[2] = app_s.prog[bowl].product_num + 1;
  date_prog[3] = (uint8_t)app_s.prog[bowl].cook_temp_ind;
  /* Время приготовления */
  uint16_t time = cook_param_get_time_prod(app_s.prog[bowl].program_num, app_s.prog[bowl].product_num);
  date_prog[4] = time/60; //?????????????????????????
  date_prog[5] = time%60;
  /* Осталось времени приготовления */
  date_prog[6] = app_s.prog[bowl].cook_time/60;
  date_prog[7] = app_s.prog[bowl].cook_time%60; //??????????????????????????
  date_prog[8] = app_s.prog[bowl].keep_en;
}

/**
 * api_get_full_program - запрос температуры нижних и верхних датчиков
 */
void api_get_temp(uint8_t *temp_bot_top)
{
  /* Not date */
  memset(temp_bot_top, 0, 4);
}

/**
 * api_get_fm_data - запрос полного состояния радио
 */
void api_get_fm_data(uint8_t *fm_data)
{
  uint8_t st_rd = logic_radio_get_state();
  switch(st_rd)
  {
  case L_RADIO_OFF: st_rd = 0; break;
  case L_RADIO_ACTIV:
  case L_RADIO_DEACTIV: st_rd = 1; break;
  case L_RADIO_AUTO_SEEK: st_rd = 2; break;
  }
  fm_data[0] = st_rd;
  fm_data[1] = logic_radio_get_num();
  logic_radio_get_freq_all(&fm_data[2]);
}

/**
 * api_get_reserv_time - запрос времени отложенного старта
 */
void api_get_reserv_time(uint8_t *time)
{
  time[0] = app_s.prog[0].post_ponement_time/60;
  time[1] = app_s.prog[0].post_ponement_time%60;
  
  time[2] = app_s.prog[1].post_ponement_time/60;
  time[3] = app_s.prog[1].post_ponement_time%60;
}

/**
 * api_get_cooking_state - запрос состояния чаш
 */
void api_get_cooking_state(uint8_t *state)
{
  /* Ошибки готовки */
  state[0] = error_get(APP_BOWL_L);
  state[0] |= error_get(APP_BOWL_R);
  state[1] = 0;
  /* Состояние чаш */
  for(uint8_t i=0; i<2; i++)
  {
    switch(app_s.state[i])
    {
    case APPL_PROGRAM_STATE:     state[i+2] = APP_PROGRAM_STATE;     break;
    case APPL_START_DELAY_STATE: state[i+2] = APP_START_DELAY_STATE; break;
    case APPL_BOOST_STATE:       state[i+2] = APP_BOOST_STATE;       break;
    case APPL_WAIT_STATE:        state[i+2] = APP_WAIT_STATE;        break;
    case APPL_COOKING_STATE:     state[i+2] = APP_COOKING_STATE;     break;
    case APPL_REHEAT_STATE:      state[i+2] = APPL_REHEAT_STATE;     break;
    default:                     state[i+2] = APP_BEGIN_STATE;       break;
    }
  }
}

/**
 * api_get_language - запрос установленого языка
 */
uint8_t api_get_language(void)
{
  return logic_setting_get_language();
}

/**
 * api_get_fw_version - запрос версии прошики и статуса перепрошивки
 */
void api_get_fw_version(uint8_t *version)
{
  uint16_t ver = update_fw_version(); // Текущая версия прошивки
  uint16_t index = update_fw_index();
  uint16_t backup_area = update_fw_backup_area();
  
  /* Текущая версия прошивки */
  version[0] = (uint8_t)((ver&0xFF00)>>8);
  version[1] = (uint8_t)(ver&0x00FF);
  /* Стейт обновления прошивки */
  version[2] = update_fw_state();
  version[3] = (uint8_t)((index&0xFF00)>>8);
  version[4] = (uint8_t)(index&0x00FF);
  version[5] = update_fw_flash_result();
  version[6] = (uint8_t)((backup_area&0xFF00)>>8);
  version[7] = (uint8_t)(backup_area&0x00FF);
}

/**
 * api_get_volume - запрос громкости радио и состояние звуковых сигналов
 */
void api_get_volume(uint8_t *volume)
{
  if(logic_setting_get_sound() == LS_SOUND_ON) volume[0] = 1;
  else volume[0] = 0;
  volume[1] = radio_get_volume();
}

/**
 * api_get_pairing_state - запрос флагов перинга и анперинга
 */
void api_get_pairing_state(uint8_t *pairing_state)
{
  if(app_s.state[0] == APPL_PAIRING_STATE) pairing_state[0] = 1;
  else pairing_state[0] = 0;
  
  if(app_s.state[0] == APPL_UNPAIRING_STATE) pairing_state[1] = 1;
  else pairing_state[1] = 0;
}

Made on
Tilda