/**************************************************************************//**
 * \file 		type.h
 * \brief 	Типы данных, не зависящие от проекта.
 * \author	Шанин А.М.
 * \author	email: adnega@mail.ru
 * \author	(C) Ярославль, 2015
 * \version	v0.1
 * \date 		12.03.2015
 *****************************************************************************/
#ifndef	__TYPE_H__
#define	__TYPE_H__

/******************************************************************************
 *	DEFINE
 *****************************************************************************/
typedef	unsigned char		BYTE;										//!< Беззнаковый целый 8-бит.
typedef	unsigned short	WORD;										//!< Беззнаковый целый 16-бит.
typedef unsigned long		DWORD;									//!< Беззнаковый целый 32-бита.
typedef volatile unsigned long	tTIMER;					//!< Беззнаковый целый 32-бита.

//-----------------------------------------------------------------------------
// Определения
//-----------------------------------------------------------------------------
																//!  Номер управляющего UDP-порта (5001)
#define	ETH_TABLO_CONTROL_PORT	(5001)

#define NAME_SIZE			(32)			//!< Длинна имени табло (32)
#define RNUM_SIZE			(256)			//!< Число переменных типа NUM (256)
#define CNUM_SIZE			(256)			//!< Число переменных типа CNUM (256)
#define NVNUM_SIZE		(256)			//!< Число переменных типа NVNUM (256)
#define RSTR_NUM			(32)			//!< Число переменных типа RSTR (32)
#define RSTR_SIZE			(128)			//!< Размер переменной типа RSTR (128)
#define CSTR_NUM			(32)			//!< Число переменных типа CSTR (32)
#define CSTR_SIZE			(128)			//!< Размер переменной типа CSTR (128)
#define NVSTR_NUM			(2)				//!< Число переменных типа NVSTR (2)
#define NVSTR_SIZE		(1024)		//!< Размер переменной типа NVSTR (1024)
#define TIMER_NUM			(64)			//!< Число переменных типа TIMER (64)

#define TO_UDP_DEBUG	(30000UL)	//!< Время вывода отладочных сообщений, мс. (30 с).

//-----------------------------------------------------------------------------
//! \struct sMAC_ADR
//! \brief MAC-адрес
//! Подробнее о MAC-адресе \ref PAGE_ADDR
//-----------------------------------------------------------------------------
typedef struct sMAC_ADR
{
	union
	{
		struct
		{
			WORD		id;								//!< старшие 2 байта формата ID-ID:SR-SR-SR-SR
			DWORD		serial;						//!< младшие 4 байта формата ID-ID:SR-SR-SR-SR
		};
		struct
		{
			DWORD		dw;								//!< для быстрого сравнения адресов
			WORD		w;								//!< для быстрого сравнения адресов
		};
		BYTE			a[6];							//!< побайтовый доступ
	};
} sMAC_ADR;

//-----------------------------------------------------------------------------
//! \struct sIP_ADR
//! \brief IP-адрес (или маска, шлюз)
//! Подробнее об IP-адресе \ref PAGE_ADDR
//-----------------------------------------------------------------------------
typedef struct sIP_ADR
{
	union
	{
		DWORD			ip;								//!< для быстрого сравнения адресов
		BYTE			a[4];							//!< побайтовый доступ
	};
} sIP_ADR;

//-----------------------------------------------------------------------------
//! \enum eRPF_STR
//! \brief Профиль отображения строки 
//-----------------------------------------------------------------------------
enum eRPF_STR
{
	PRF_STR_NONE = 0,							//!< Профиль не определен (0) [из конфигурации]
	PRF_STR_LEFT,									//!< Выравнивание по левому краю (1)
	PRF_STR_CENTER,								//!< Выравнивание по центру (2)
	PRF_STR_RIGHT,								//!< Выравнивание по правому краю (3)
	PRF_STR_LSCROLL,							//!< Выравнивание по левому краю с горизонтальным скроллингом (4)
	PRF_STR_CSCROLL,							//!< Выравнивание по центру с горизонтальным скроллингом (5)
	PRF_STR_RSCROLL,							//!< Выравнивание по правому краю с горизонтальным скроллингом (6)
	PRF_STR_LOW,									//!< Бегущая строка с низкой скоростью (7)
	PRF_STR_MEDIUM,								//!< Бегущая строка со средней скоростью (8)
	PRF_STR_HIGH,									//!< Бегущая строка с высокой скоростью (9)
	PRF_STR_SPEED,								//!< Бегущая строка с заданной скоростью [не используется]
};

//-----------------------------------------------------------------------------
//! \enum eTIMER_STATE
//! \brief Состояния/команды таймера
//-----------------------------------------------------------------------------
enum eTIMER_STATE
{
	TIMER_STATE_STOP = 0,					//!< Таймер остановлен / Остановить таймер (0)
	TIMER_STATE_RUN,							//!< Таймер активен / Запустить таймер (1)
	TIMER_STATE_RESTART,					//!< ... / Перезапустить таймер (2)
};

//-----------------------------------------------------------------------------
//! \struct sTIMER
//! \brief Структура данных таймера
//-----------------------------------------------------------------------------
typedef struct sTIMER
{
	DWORD				current;					//!< Текущее значение таймера
	DWORD				from;							//!< Начальное значение таймера
	DWORD				to;								//!< Конечное значение таймера
	BYTE				cur_state;				//!< Текущее состояние таймера
	BYTE				new_state;				//!< Новое состояние таймера
	union
	{
		WORD			flags;						//!< Флаги таймера
		struct
		{
			WORD		f_restart:1;			//!< Автоматический перезапуск (0)
			WORD		f_siren:1;				//!< Управление сиреной (1)
			WORD		f_hide:1;					//!< Скрыть показания (2)
																//!  Скрывать показания неактивного таймера (3)
			WORD		f_hide_inactive:1;
			WORD		f_slave:1;				//!< Подчиненный таймер (4)
			WORD		f_master:3;				//!< Управляющий таймер (7-5)
			WORD		f_reserv:8;				//!< Резерв (15-8)
		};
	};
} sTIMER;

//-----------------------------------------------------------------------------
//!	\enum eAUTOBRIGHT
//! \brief Автоматическое управление яркостью
//-----------------------------------------------------------------------------
enum eAUTOBRIGHT
{
	AUTOBRIGHT_ON = 0,						//!< Автояркость включена (0)
	AUTOBRIGHT_OFF,								//!< Автояркость выключена (1)
};

/**************************************************************************//**
\mainpage Описание протокола взаимодействия с табло.
\note Протокол действителен для табло с прошивкой \b u653 (мегапрошивка).
\author Шанин А.М.\n
email: adnega@mail.ru
\version v0.2
\date 15.06.2016г.

\line _

\section SEC_LINK Взаимодействие с табло.

Табло может взаимодействовать с управляющим ПК по сети Ethernet. Для обмена информацией используютя UDP-датаграммы (протокол UDP/IP).

Табло может принимать команды:
- адресованные ему персонально,
- адресованные всем табло его типа (например, при поиске всех табло данного типа в сети),
- адресованные всем табло (например, при поиске всех табло в сети).

Табло принимает команды на UDP-порт #ETH_TABLO_CONTROL_PORT.
Ответы отправляются в тот порт, с которого они были отправлены с управляющего ПК.

Пример (\a IP-ПК - IP-адрес управляющего ПК; \a UDP-ПК - UDP-порт на управляющем ПК; \a IP-ТАБЛО - IP-адрес табло):
- \b "запрос ПК" \a IP-ПК : \a UDP-ПК -> \a IP-ТАБЛО : #ETH_TABLO_CONTROL_PORT.
- \b "ответ табло" \a IP-ТАБЛО : #ETH_TABLO_CONTROL_PORT -> \a IP-ПК : \a UDP-ПК.

Как правило взаимодействие происходит в двух вариантах:
- \a запрос данных;
- \a установка данных.

Команды \a запроса данных начинаются с \b ETH_GET_ (пакеты соответственно с \b sPACKET_GET_). \n
Команды \a установки данных начинаются с \b ETH_SET_ (пакеты соответственно с \b sPACKET_SET_). \n
В ответ на команды \a запроса и на команды \a установки возвращается ответ, начинающийся с \b ETH_ANS_ (пакеты соответственно с \b sPACKET_ANS_).

Для установки нового режима отображения служит команда #ETH_SET_MODE (пакет sPACKET_SET_MODE). \n

\warning Перечень доступных режимов, номера и типы связанных с этими режимами объектов можно узнать из конфигурации.

\line _

\section SEC_OBJECTS Объекты табло.

Табло поддерживает несколько источников данных для отображения. К источникам, управляемым по Ethernet, относятся:
- \b NVSTR - энергонезависые ASCII-Z строки (сохраняются при потере питания). Размер строки \b NVSTR #NVSTR_SIZE. Число строк \b NVSTR #NVSTR_NUM.
- \b RSTR - оперативные ASCII-Z строки (обнуляются при потере питания, перезагрузке). Размер строки \b RSTR #RSTR_SIZE. Число строк \b RSTR #RSTR_NUM.
- \b CSTR - константные ASCII-Z строки (не могут быть изменены, жестко заданы в конфигурации). Размер строки \b CSTR #CSTR_SIZE. Число строк \b CSTR #CSTR_NUM.
- \b NVNUM - энергонезависые 32-битные числа (сохраняются при потере питания). Число переменных \b NVNUM #NVNUM_SIZE.
- \b RNUM - оперативные 32-битные числа (обнуляются при потере питания, перезагрузке). Число переменных \b RNUM #RNUM_SIZE.
- \b CNUM - константные 32-битные числа (не могут быть изменены, жестко заданы в конфигурации). Число переменных \b CNUM #CNUM_SIZE.
- \b TIMER - универсальные таймеры для отсчета времени. Число переменных \b TIMER #TIMER_NUM.

Для объектов доступны команды \a запроса (чтения) и \a установки (записи) (за исключением \b CSTR и \b CNUM).

В пакетах передаются массивы элементов. Для указания номера объекта в пакете используется вспомогательный массив индексов.
Индексы отсчитываются от нуля. Если индекс больше допустимого, то данный элемент массива игнорируется.
Рекомендуется для таких целей использовать индекс \b 0xFF для \b NVSTR, \b RSTR, \b CSTR, \b TIMER, и \b 0xFFFF для \b NVNUM, \b RNUM, \b CNUM.

Пример запроса строк \b RSTR:
- \a запрос : \n
\b index - 0, 1, 12, 30, 78, 0xFF, 0xFF, 0xFF - запросить строки с индексами 0, 1, 12, 30, 78.
- \a ответ : \n
\b index - 0, 1, 12, 30, 0xFF (т.к. 78 строки RSTR не существует), 0xFF, 0xFF, 0xFF; \n
\b profile - профили строк с индексами 0, 1, 12, 30, und, und, und, und; \n
\b rstr - содержимое строк с индексами 0, 1, 12, 30, '', '', '', ''.

\page PAGE_COMMAND Общий вид UDP-пакетов.
Общий вид UDP-пакетов:
- mac - MAC-адрес контроллера или \b FF:FF:FF:FF:FF:FF для широковещательных пакетов;
- cmd - код команды или ответа на команду (\b ETH_CMD_xxx, \b ETH_ANS_xxx);
- type - тип табло #ETH_TABLO_TYPE или #ETH_TABLO_TYPE_BR;
- p_id - идентификатор пакета. Устанавливается ПК, в ответе табло возвращает установленное значение;
- data - данные пакета.

\page PAGE_ADDR Адреса MAC и IP.
MAC-адрес представляется в виде массива из 6 байт. Значения неоходимо размещать в массиве в обратном (big endian) порядке\n
Например, MAC-адрес 12:34:56:78:90:AB в массиве записывается так:
- [0] = 0x12
- [1] = 0x34
- [2] = 0x56
- [3] = 0x78
- [4] = 0x90
- [5] = 0xAB

IP-адрес представляется в виде массива из 4 байт. Значения неоходимо размещать в массиве в обратном (big endian) порядке\n
Например, IP-адрес 192.168.0.1 в массиве записывается так:
- [0] = 192
- [1] = 168
- [2] = 0
- [3] = 1

\note В формате IP-адреса хранятся не только IP-адреса (ip), но и маска подсети (mask) со шлюзом (gw).

\page PAGE_BRIGHT Яркость табло.
Яркость табло может принимать следующие значения:
- 0 - отображение отключено;
- 1 - минимальная яркость;
- от 2 до 99 - промежуточные значения яркости;
- 100 - максимальная яркость.

\page PAGE_DATETIME Дата и время.
Дата и время определяется как число секунд от начала эпохи 01.01.2000 00:00:00.

\page PAGE_CONFIG Параметры пакета конфигурации.
Конфигурация содержит следующие поля:

\section S_SAFE int safe
Температурный монитор. Указывает номер датчика для контроля:
- 0 - выключен;
- 1 - температура CPU (ядра);
- 2 - температура PCB (печатной платы);
- 3..6 - температура с внешних проводных датчиков;
- 7 - средняя температура всех внешних проводных датчиков.

\note Функционал температурного монитора не реализован.

\section S_T_MIN short t_min
Нижняя граница контроля в градусах Цельсия, 1/16 градуса.\n
При снижении температуры на контролирующем датчике ниже этого значения, табло выключается с периодической индикацией сообщения "COLD".\n
Рекомендуется задавать не ниже -40C.\n
Пример расчета для температуры "-40C": t_min = -40 * 16 = -640.
\note Функционал температурного монитора не реализован.

\section S_T_MAX short t_max
Верхняя граница контроля в градусах Цельсия, 1/16 градуса.\n
При превышении температуры на контролирующем датчике выше этого значения, табло выключается с периодической индикацией сообщения "HOT".\n
Рекомендуется задавать не выше +85C.\n
Пример расчета для температуры "+85C": t_max = 85 * 16 = 1360.
\note Функционал температурного монитора не реализован.

\section S_TO_WATCHDOG int to_watchdog
Сторожевой таймер в секундах. Если в течении установленного времени табло не произведет обмен с управляющим ПК, то табло автоматически перезагрузится.
\warning При значениях менее 600 секунд сторожевой таймер не активен!

\section S_AUTOBRIGHT DWORD autobright
Автоматическое управление яркостью.\n
Позволяет отключать управление яркостью табло по данным со встроенного датчика освещенности.
См. \ref eAUTOBRIGHT.

\section S_TO_TIMER_SIREN DWORD to_timer_siren
Таймаут сирены для таймеров в миллисекундах.

\page PAGE_DEBUG Отладка по сети.
При включенной отладке отладочные сообщения порциями по 128 символов отправляются UDP-датаграммами на IP-адрес,
с которого отладка была включена, в порт 5010. Таймаут включения отладочных сообщений #TO_UDP_DEBUG.
Для непрерывной работы нужно посылать пакет sPACKET_UDP_DEBUG не реже #TO_UDP_DEBUG.
Младший бит поля \ref sPACKET_UDP_DEBUG::flags определяет включение отладки:
- 0 - отладка выключена;
- 1 - отладочные сообщения отправляются.

******************************************************************************/
#endif // __TYPE_H__
/******************************************************************************
 * КОНЕЦ ФАЙЛА
 *****************************************************************************/
