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



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

Фрагмент исходного кода
/** 
 *           RMC-M224S
 * 	@file  	application.c
 *  	@brief 	
 *  	@internal
*  	Revision:     ver 1_3
 *  	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();
}

Made on
Tilda