Программный модуль для мультиварки RMC-M223S. v.1.9
ПО является неотъемлемой частью мультиварки RMC-M223S, отдельно потребителю не поставляется и эксплуатируется только в составе устройства.
/**
* RMC-M223S
* @file application.c
* @brief
* @internal
* Revision: ver 1_9
* Compiler: armcc
*/
/********* HEADER FILE INCLUDES *************************************************/
#include "app_error.h"
#include "nrf_soc.h"
#include "app_util_platform.h"
#include "r4s_lib.h"
#include "r4s_lib_external.h"
#include "r4s_slave.h"
#include "r4s_slave_external.h"
#include "config.h"
#include "application.h"
#include "application_api.h"
#include "Driver_Header.h"
#include "logic_multi_cook.h"
#include "matr_butt.h"
/********* DEFINES **************************************************************/
/********* MACROS ***************************************************************/
/********* GLOBAL VARIABLES *****************************************************/
/********* LOCAL VARIABLES ******************************************************/
static uint8_t app_state = APPL_BEGIN_STATE; /* состояние */
static bool app_pairing_flag = false; /* флаг pairing */
static bool app_unpairing_flag = false; /* флаг unpairing */
static cook_complex_prog* app_cook;
/********* FUNCTION PROTOTYPES **************************************************/
static void pairing_connect(void);
static void pairing_de_connect(void);
static void pairing_handler(void);
/********* FUNCTIONS IMPLEMENTATION *********************************************/
/********************************************************************************
* Application
********************************************************************************/
void application_init(void)
{
soft_keyb_init();
temp_init();
heat_init();
error_init();
blank_init();
lock_butt_init();
logic_multi_cook_init();
app_cook = logic_get_program();
timer_create(TIMER_PAIRING, TIMER_SECOND(30), SOFT_HANDLER_STOP, pairing_handler);
if(error_get() != NO_ERR) logic_mode_error();
else if(matr_butt_get_key_test() == 1) test_mode();
else{
BEEP();
logic_mode_standby();
}
}
/********************************************************************************
*
********************************************************************************/
void application_process(void)
{
static uint16_t state_key = 0;
if(app_state != APPL_ERROR_STATE){
if(error_get() != NO_ERR) logic_mode_error();
}
state_key = soft_keyb_get(); // Считываем значение кнопок
if(state_key != KEY_NOT){ // Если нажата кнопка обрабатываем ее
if(state_key <= MENU_KEY) BEEP();
switch(app_state)
{
/* Обработка кнопок в режиме ожидания */
case APPL_BEGIN_STATE:
{
if(lock_butt_get() == LOCK_BUTT_ON){ // Блокировка панели
if(state_key == LONG_MENU_KEY) lock_butt_set(LOCK_BUTT_OFF);
else lock_butt_ind();
}else{
switch(state_key)
{
case OFF_MENU_KEY: logic_mode_menu(LOGIC_MENU_ON); break;
case START_KEY: logic_start_express(); break;
case LONG_MENU_KEY: lock_butt_set(LOCK_BUTT_ON); break;
case ESC_KEY: logic_go_keepwarm(LOGIC_HEATING); break;
case LONG_DELAY_KEY: logic_buz_on_off(LOGIC_BUZ_INV); break;
case PARING_KEY: pairing_connect(); break;
case UNPARING_KEY: pairing_de_connect(); break;
case DEMO_KEY: demo_mode(DEMO_MODE_ON); break;
//case TEST_KEY: test_mode(); break;
}
}
break;
}
/* Обработка кнопок в режиме меню (выбора параметров) */
case APPL_PROGRAM_STATE:
{
switch(state_key)
{
case MENU_KEY: logic_mode_menu(LOGIC_MENU_PLUS); break;
case PLUS_KEY:
case LONG_PLUS_KEY: logic_menu_plus_param(); break;
case MINUS_KEY:
case LONG_MINUS_KEY: logic_menu_minus_param(); break;
case ESC_KEY: logic_menu_esc(); break;
case TEMP_KEY: logic_menu_temp(); break;
case TIME_KEY: logic_menu_time(); break;
case DELAY_KEY: logic_menu_dtime(); break;
case START_KEY: logic_mode_cooking(); break;
}
break;
}
/* Обработка кнопок в режиме отложенного старта */
case APPL_START_DELAY_STATE:
{
if(lock_butt_get() == LOCK_BUTT_ON){ // Блокировка панели
if(state_key == LONG_MENU_KEY) lock_butt_set(LOCK_BUTT_OFF);
else lock_butt_ind();
}else{
switch(state_key)
{
case ESC_KEY: logic_mode_standby(); break;
case DELAY_KEY: logic_out_dtime(); break;
case START_KEY: logic_cook_set_keep(LOGIC_KEEP_INV); break;// Инверсия keep
case LONG_MENU_KEY: lock_butt_set(LOCK_BUTT_ON); break;
}
}
break;
}
/* Обработка кнопок в режиме приготовления */
case APPL_BOOST_STATE:
case APPL_WAIT_STATE:
case APPL_COOKING_STATE:
{
if(lock_butt_get() == LOCK_BUTT_ON){ // Блокировка панели
if(state_key == LONG_MENU_KEY) lock_butt_set(LOCK_BUTT_OFF);
else lock_butt_ind();
}else{
switch(state_key)
{
case ESC_KEY:
{
if(mch_get_active() == MCH_DE_ACTIVE) logic_mode_standby();
else mch_clear_params();
break;
}
/* Master chief */
case TEMP_KEY: mch_temp_activ(); break;
case TIME_KEY: mch_time_activ(); break;
case LONG_MINUS_KEY:
case MINUS_KEY: mch_minus_params(); break;
case LONG_PLUS_KEY:
case PLUS_KEY: mch_plus_params(); break;
/* End Master chief */
case LONG_MENU_KEY: lock_butt_set(LOCK_BUTT_ON); break;
case START_KEY: logic_cook_set_keep(LOGIC_KEEP_INV); break;// Инверсия keep
}
}
break;
}
/* Обработка кнопок в режиме подогрева */
case APPL_REHEAT_STATE:
{
if(lock_butt_get() == LOCK_BUTT_ON){ // Блокировка панели
if(state_key == LONG_MENU_KEY) lock_butt_set(LOCK_BUTT_OFF);
else lock_butt_ind();
}else{
switch(state_key)
{
case ESC_KEY: logic_mode_standby(); break;
case LONG_MENU_KEY: lock_butt_set(LOCK_BUTT_ON); break;
}
}
break;
}
case APPL_DEMO_STATE:
{
if(state_key == DEMO_KEY) demo_mode(DEMO_MODE_OFF);
break;
}
case APPL_ERROR_STATE: break;
case APPL_PAIRING_STATE: break;
/* Обработка кнопок в тестовом режиме */
case APPL_TEST_STATE: test_mode_set_key(state_key); break;
/* End parametrs */
default: break;
}
}
}
void application_set_state(uint8_t state)
{
if(state > APPL_TEST_STATE) return;
app_state = state;
}
uint8_t application_get_state(void)
{
return app_state;
}
/********************************************************************************
* Applications
* описание в application_api.h
********************************************************************************/
/**
* @brief Получить версию ПО
*/
uint16_t api_get_version(void)
{
return FIRMWARE_VER;
}
/**
* @brief Получить состояние.
*/
uint8_t api_get_state(void)
{
return app_state;
}
/**
* @brief Запуск программы
*/
bool api_start(void)
{
if(app_state == APPL_PROGRAM_STATE) // Если мы в режиме меню
{
if(app_cook->program_num == APPL_EXPRESS_PROG){ BEEP(); logic_start_express();}
else if(app_cook->program_num == APPL_HEATING_PROG){ BEEP() logic_go_keepwarm(LOGIC_HEATING);}
else { BEEP(); logic_mode_cooking();}
return true;
}
return false;
}
/**
* @brief Остановка программы (переход в состояние ожидания)
*/
bool api_stop(void)
{
if(app_state != APPL_ERROR_STATE){ BEEP(); logic_mode_standby();}
return true;
}
/**
* @brief Получить время, оставшееся до конца готовки
*/
uint16_t api_get_end_time(void)
{
// оставшееся время варки и время отложенного старты
if(app_state == APPL_START_DELAY_STATE) return app_cook->post_ponement_time;
if(app_cook->program_num == APPL_HEATING_PROG) return logic_get_keep_time();
return app_cook->cook_time;
}
/**
* @brief Получить время подогрева/разогрева
*/
uint16_t api_get_reheat_time(void)
{
return logic_get_keep_time();
}
/**
* @brief Установить программу
*/
bool api_set_program(uint8_t prog)
{
if(prog > APPL_PROG_MAX) return false;
if(app_state == APPL_BEGIN_STATE || app_state == APPL_PROGRAM_STATE)
{
app_state = APPL_PROGRAM_STATE;
cooking_set_state(STAGE_NONE);
app_cook->program_num = prog;
if(prog < (APPL_PROG_MAX-1)) logic_mode_menu(LOGIC_MENU_NONE);
return true;
}
return false;
}
/**
* @brief Установить температуру
*/
bool api_set_cook_temp(uint8_t temp)
{
if(temp == 0) return true;
if(temp < 35 || temp > 180) return false;
if(app_state == APPL_PROGRAM_STATE || \
app_state == APPL_START_DELAY_STATE || \
app_state == APPL_BOOST_STATE || \
app_state == APPL_COOKING_STATE) // Если режим меню или готовки
{
if(app_state == APPL_PROGRAM_STATE) timer_reset(TIMER_1MIN_MENU);
if(app_cook->cook_temp_ind == temp) return true;
uint8_t temp_80 = app_cook->cook_temp_ind;
if(app_cook->cook_temp_ind > temp){ // Если температура <
uint8_t tem = app_cook->cook_temp_ind - temp;
app_cook->cook_temp_ind = temp;
app_cook->cook_temp -= tem;
}else{ // Если температура >
uint8_t tem = temp - app_cook->cook_temp_ind;
app_cook->cook_temp_ind = temp;
app_cook->cook_temp += tem;
}
if(app_cook->program_num == APPL_MULTICOOK_PROG){
if(app_cook->cook_temp_ind > 99) app_cook->cook_temp = app_cook->cook_temp_ind + 5;
}
if(temp >= 80 && temp_80 < 80){ // Ставим флаг автоподогрева
if(app_cook->keep_time > 0) app_cook->keep_en = COOK_EN;
}else if(temp < 80 && temp_80 >= 80){
app_cook->keep_en = COOK_DE;
}
if(app_state != APPL_PROGRAM_STATE){ // Индикация автоподогрева
if(app_cook->keep_en == COOK_EN) soft_ind_key(LED_BUT_ESC, IND_SET);
else soft_ind_key(LED_BUT_ESC, IND_CLR);
}
app_cook->bot_temp_warm = cook_param_get_d_warm(app_cook->program_num, app_cook->cook_temp);
app_cook->bot_temp_stat = cook_param_get_d_stat(app_cook->program_num, app_cook->cook_temp);
app_cook->top_temp_stat = cook_param_get_top_stat(app_cook->program_num, app_cook->cook_temp);
if(app_cook->cook_temp_ind > 150){
app_cook->max_time = 2*60;
if(app_cook->cook_time > app_cook->max_time){
app_cook->cook_time = app_cook->max_time;
}
}else{
app_cook->max_time = cook_param_get_max_time(app_cook->program_num);
}
if(app_state != APPL_START_DELAY_STATE) soft_ind_time(app_cook->cook_time, IND_SET);
return true;
}
return false;
}
/**
* @brief Установить время готовки
*/
bool api_set_cook_time(uint16_t time)
{
if(app_state == APPL_PROGRAM_STATE || \
app_state == APPL_START_DELAY_STATE || \
app_state == APPL_BOOST_STATE || \
app_state == APPL_COOKING_STATE) // Если режим меню или готовки
{
if(app_state == APPL_PROGRAM_STATE){
timer_reset(TIMER_1MIN_MENU); // Сбрасываем таймер перехода в STANDBY_MODE
if(app_cook->min_time > time) return false; // Проверка задаваемого вермени варки
}
if(app_cook->max_time < time) return false; // Проверка задаваемого вермени варки
app_cook->cook_time = time;
/* Исправление бага №57 в версии 1_2 */
if(app_state != APPL_PROGRAM_STATE){
if(app_cook->cook_time == 0){
logic_mode_standby();
BEEP();
return true;
}
}
/* Конец бага №57 */
if(app_state != APPL_START_DELAY_STATE) soft_ind_time(app_cook->cook_time, IND_SET);
return true;
}
return false;
}
/**
* @brief Считать программу
*/
uint8_t api_get_program(void)
{
return app_cook->program_num;
}
/**
* @brief Считать температуру
*/
uint8_t api_get_cook_temp(void)
{
if(app_cook->program_num == APPL_HEATING_PROG) return 70;
if(app_state == APPL_REHEAT_STATE) return 70;
return app_cook->cook_temp_ind;
}
/**
* @brief Считать время готовки
*/
uint16_t api_get_cook_time(void)
{
return app_cook->cook_time;
}
/**
* @brief Установить время отложеного старта
*/
bool api_set_defered_start(uint16_t dtime)
{
if(dtime > (24*60)) return false;
if(app_cook->post_ponement_en == COOK_DE && dtime != (uint16_t)NOT_DTIME) return false;
if(app_state != APPL_PROGRAM_STATE) return false;
app_cook->post_ponement_time = dtime;
return true;
}
/**
* @brief Считать время отложеного старта
*/
uint16_t api_get_defered_start(void)
{
return app_cook->post_ponement_time;
}
/**
* @brief Установить подогрев
*/
bool api_set_reheat(uint8_t state)
{
if(state > APPL_REHEAT_ON) return false;
if(app_state == APPL_PROGRAM_STATE){
if(app_cook->keep_en == COOK_EN)
{
if(state == APPL_REHEAT_OFF) app_cook->keep_en = COOK_DE;
return true;
}else{
if(state == APPL_REHEAT_OFF) return true;
if(app_cook->keep_time > 0 && app_cook->cook_temp_ind >= 80){
app_cook->keep_en = COOK_EN;
return true;
}
return false;
}
}
if(app_state != APPL_START_DELAY_STATE &&\
app_state != APPL_BOOST_STATE &&\
app_state != APPL_COOKING_STATE) return false;
if(app_cook->keep_time == 0) return false;
logic_cook_set_keep(state);
BEEP();
return true;
}
/**
* @brief Считать статус подогрева
*/
uint8_t api_get_reheat(void)
{
return app_cook->keep_en;
}
/**
* @brief Считать ошибку
*/
uint8_t api_get_error(void)
{
return error_get();
}
/**************************************
* Дополнительные команды
*************************************/
/**
* @brief Установить звуковые сигналы
*/
bool api_set_sound(uint8_t state)
{
if(state > APPL_SOUND_ON) return false;
logic_buz_on_off(state);
return true;
}
/**
* @brief Считать состояние звуковых сигналов
*/
uint8_t api_get_sound(void)
{
return buz_get();
}
/**
* @brief Установить блокировку
*/
bool api_set_lock(uint8_t state)
{
if(state > LOCK_BUTT_ON) return false;
lock_butt_set(state);
return true;
}
/**
* @brief Считать состояние блокировки
*/
uint8_t api_get_lock(void)
{
return lock_butt_get();
}
/**
* @brief Получить флаг pairing -а.
*/
bool api_is_pairing(void)
{
return app_pairing_flag;
}
/**
* @brief Выход из pairingа.
*/
void api_exti_pairing(void)
{
app_pairing_flag = false;
buz_beep_x(3);
logic_mode_standby();
}
/**
* описание в application_api.h
*/
bool api_is_unpairing(void)
{
return app_unpairing_flag;
}
/**
* описание в application_api.h
*/
void api_clr_unpairing(void)
{
app_unpairing_flag = false;
}
/**
* @brief Переход в режим обновления прошивки
*
* @param none
*
* @return:: 1 - устройство перешло в режим обновления прошивки
* @return:: 0 - устройство НЕ перешло в режим обновления прошивки
*/
uint8_t api_enter_fw_update_state(void)
{
if(app_state == APPL_BEGIN_STATE){
app_state = APP_API_FW_UPDATE_STATE;
logic_fw_update();
return 1;
}
return 0;
}
/**
* @brief Функция оповещает application о том что идет обновление прошивки
*/
void api_fw_update_proc(void)
{
}
/********* FUNCTION PROTOTYPES **************************************************/
static void pairing_connect(void)
{
app_state = APPL_PAIRING_STATE;
buz_beep_x(3);
soft_ind_pairing_start();
timer_reset_start(TIMER_PAIRING);
app_pairing_flag = true;
}
static void pairing_de_connect(void)
{
app_unpairing_flag = true;
BEEP_LONG();
soft_ind_unpairing();
}
static void pairing_handler(void)
{
app_pairing_flag = false;
buz_beep_x(2);
logic_mode_standby();
}