#include <includes.h>
#include "data.h"
#include "datadesc.h"
#include "menu.h"
#include "menudesc.h"
#include "fram_map.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include "control.h"
#include "fiscal.h"
#include "time.h"
#include "CRC16.h"
#include "modem_task.h"
#include "modem.h"
#include "keyboard.h"
#include "fram.h"
#include "host_app.h"
#include "music_tsk.h"
#include "score_tsk.h"
#include "mode.h"
#include "ftp_app.h"

#include "rfid-spi.h"
#include "mfrc522data.h"

extern CPU_INT32U modem_status;
extern CPU_INT08U start_pass_ok;
extern int player_conn;
extern void PlayMusicFile(int file_index);

/*************************************
  Индекс канала
*************************************/
CPU_INT32U  ChannelIndex=0;
TRangeValueULONG const ChannelIndexRange = {0, CHANNELS_NUM-1};
#if defined(BOARD_SOLARIUM_VLAD)
CPU_INT08U const ChannelIndexName[] = "  СОЛЯРИй";
#else
CPU_INT08U const ChannelIndexName[] = "    ПОСТ";
#endif
CPU_INT08U const* ChannelItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"};

void OnChangeChannelIndex()
{
#if defined(BOARD_CENTRAL_CARWASH)
    PostUserEvent(EVENT_REREAD_SIGNAL_LEVEL); 
#endif
}

TDataDescStruct const ChannelIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  &ChannelIndex,            // указатель на переменную или адрес FRAM
  (void*)&ChannelIndexRange,       // указатель на границы параметра
  OnChangeChannelIndex,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  ChannelIndexName,         // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ChannelItems,             // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Индекс канала в меню канальной статистии
*************************************/
CPU_INT08U const ChannelStIndexName[] = "КОР.СЧ.ПОСТ";

TDataDescStruct const ChannelStIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  &ChannelIndex,            // указатель на переменную или адрес FRAM
  (void*)&ChannelIndexRange,       // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  ChannelStIndexName,         // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ChannelItems,             // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Индекс канала в меню канальной статистии
*************************************/
CPU_INT08U const ChannelStLongIndexName[] = "ДЛ.СЧ.КАНАЛ";

TDataDescStruct const ChannelStLongIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  &ChannelIndex,            // указатель на переменную или адрес FRAM
  (void*)&ChannelIndexRange,       // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  ChannelStLongIndexName,         // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ChannelItems,             // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Последнее время отправки email
*************************************/
extern TRangeValueULONG const WorkTimeRange;

TDataDescStruct const LastEmailSendTime = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, LastEmailTime),            // указатель на переменную или адрес FRAM
  (void*)&WorkTimeRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  NULL,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Включение канала
*************************************/
TRangeValueULONG const EnableChannelRange = {0, 1};
CPU_INT08U const EnableChannelName[] = "Включить";
CPU_INT08U const EnableChannelList_str0[] = "нет";
CPU_INT08U const EnableChannelList_str1[] = "да";
CPU_INT08U const *EnableChannelList[] = {EnableChannelList_str0, EnableChannelList_str1};


TDataDescStruct const EnableChannelDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.Enable),            // указатель на переменную или адрес FRAM
  (void*)&EnableChannelRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableChannelName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableChannelList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  IP-адрес поста
*************************************/
CPU_INT08U const PostIpAddrName[] = "IP";

TDataDescStruct const PostIpAddrDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.post_ip),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostIpAddrName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0xC0A80065
};

/*************************************
  Статус связи с постом
*************************************/
CPU_INT08U const PostIpStatusName[] = "Статус";
TRangeValueULONG const PostIpStatusNameRange = {0, 1};
CPU_INT08U const PostIpStatusNameList_str0[] = "оффлайн";
CPU_INT08U const PostIpStatusNameList_str1[] = "онлайн";
CPU_INT08U const *PostIpStatusNameList[] = {PostIpStatusNameList_str0, PostIpStatusNameList_str1};
CPU_INT32U PostStatus[CHANNELS_NUM];

TDataDescStruct const PostIpStatusDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)&PostStatus,            // указатель на переменную или адрес FRAM
  (void*)&PostIpStatusNameRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostIpStatusName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  (void*)&PostIpStatusNameList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0
};

/*************************************
  IP-адрес банковского терминала
*************************************/
CPU_INT08U const TerminalIpAddrName[] = "IP";

TDataDescStruct const TerminalIpAddrDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.terminal_ip),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  TerminalIpAddrName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0xC0A8006E
};

/*************************************
  Использовать запрет выбора поста
*************************************/
TRangeValueULONG const SelectProtectNameRange = {0, 1};
CPU_INT08U const SelectProtectNameName[] = "Запрет выбора";
CPU_INT08U const SelectProtectNameList_str0[] = "нет";
CPU_INT08U const SelectProtectNameList_str1[] = "да";
CPU_INT08U const *SelectProtectNameList[] = {SelectProtectNameList_str0, SelectProtectNameList_str1};


TDataDescStruct const SelectProtectDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.select_protect),            // указатель на переменную или адрес FRAM
  (void*)&SelectProtectNameRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SelectProtectNameName,      // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  SelectProtectNameList,      // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1                           
};

/*************************************
  Цена импульса контроллера ПОСТА
*************************************/
TRangeValueULONG const PostImpCostRange = {1, 9999};
CPU_INT08U const PostImpCostName[] = "Руб./имп.";

TDataDescStruct const PostImpCostDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.imp_cost),            // указатель на переменную или адрес FRAM
  (void*)&PostImpCostRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostImpCostName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  10                           // значение по умолчанию
};

/*************************************
  Длина импульса контроллера ПОСТА
*************************************/
TRangeValueULONG const PostImpLenRange = {1, 9999};
CPU_INT08U const PostImpLenName[] = "Дл.имп.,мс";

TDataDescStruct const PostLenCostDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.imp_len),            // указатель на переменную или адрес FRAM
  (void*)&PostImpLenRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostImpLenName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  50                           // значение по умолчанию
};

/*************************************
  Длина паузы импульса контроллера ПОСТА
*************************************/
TRangeValueULONG const PostImpPauseLenRange = {0, 9999};
CPU_INT08U const PostImpPauseLenName[] = "Дл.паузы,мс";

TDataDescStruct const PostPauseLenCostDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.pause_len),            // указатель на переменную или адрес FRAM
  (void*)&PostImpPauseLenRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostImpPauseLenName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  150                           // значение по умолчанию
};

/*************************************
  Пауза до выдачи импульсов контроллера ПОСТА
*************************************/
TRangeValueULONG const PostPauseRange = {0, 60};
CPU_INT08U const PostPauseName[] = "Пауза";

TDataDescStruct const PostPauseDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.pause),            // указатель на переменную или адрес FRAM
  (void*)&PostPauseRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostPauseName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           // значение по умолчанию
};


/*************************************
  Цена минуты
*************************************/
TRangeValueULONG const PostMinutePriceRange = {1, 999};
CPU_INT08U const PostMinutePriceName[] = "Стоим.мин.";

TDataDescStruct const PostMinutePriceDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.minute_cost),            // указатель на переменную или адрес FRAM
  (void*)&PostMinutePriceRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostMinutePriceName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  20                           // значение по умолчанию
};

/*************************************
  Название канала
*************************************/
TRangeValueULONG const NameChannelRange = {0, 2};
CPU_INT08U const NameChannelName[] = "Название";
CPU_INT08U const NameChannelList_str0[] = "#";
CPU_INT08U const NameChannelList_str1[] = "Солярий";
CPU_INT08U const NameChannelList_str2[] = "Устройство";
CPU_INT08U const *NameChannelList[] = {NameChannelList_str0, NameChannelList_str1, NameChannelList_str2};


TDataDescStruct const NameChannelDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.Name),            // указатель на переменную или адрес FRAM
  (void*)&NameChannelRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  NameChannelName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  NameChannelList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Название кнопки СТАРТ (СТАРТ или ПУСК)
*************************************/
TRangeValueULONG const StartButtonNameRange = {0, 1};
CPU_INT08U const StartButtonNameName[] = "Кнопка";
CPU_INT08U const StartButtonNameList_str0[] = "СТАРТ";
CPU_INT08U const StartButtonNameList_str1[] = "ПУСК";
CPU_INT08U const *StartButtonNameList[] = {StartButtonNameList_str0, StartButtonNameList_str1};


TDataDescStruct const StartButtonNameDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, StartButtonName),            // указатель на переменную или адрес FRAM
  (void*)&StartButtonNameRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  StartButtonNameName,      // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  StartButtonNameList,      // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  Включение купюроприемника
*************************************/
TRangeValueULONG const EnableValidatorRange = {0, 1};
CPU_INT08U const EnableValidatorName[] = "Купюропр-к";
CPU_INT08U const OnOffList_str0[] = "выкл.";
CPU_INT08U const OnOffList_str1[] = "вкл.";
CPU_INT08U const *EnableValidatorList[] = {OnOffList_str0, OnOffList_str1};


TDataDescStruct const EnableValidatorDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableValidator),            // указатель на переменную или адрес FRAM
  (void*)&EnableValidatorRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableValidatorName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableValidatorList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           // значение по умолчанию
};

/*************************************
  Включение модема
*************************************/
TRangeValueULONG const EnableModemRange = {0, 1};
CPU_INT08U const EnableModemName[] = "Модем";
CPU_INT08U const *EnableModemList[] = {OnOffList_str0, OnOffList_str1};

void OnchangeEnableModem(void)
{
    CPU_INT32U en = 0;
    GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX);
    
    if (en)
    {
        if (!IsModemConn())
        {
            modem_status = 2;
        }
        else if (!IsModemConf())
        {
            modem_status = 1;
        }
        PostModemTask(MODEM_TASK_RECONNECT);
    }
}

TDataDescStruct const EnableModemDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableModem),            // указатель на переменную или адрес FRAM
  (void*)&EnableModemRange,     // указатель на границы параметра
  OnchangeEnableModem,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableModemName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableModemList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Включить оповещение об ошибках по e-mail
*************************************/
TRangeValueULONG const EnableEmailErrorSendRange = {0, 1};
CPU_INT08U const EnableEmailErrorSendName[] = "Опов.об ош.";
CPU_INT08U const *EnableEmailErrorSendList[] = {OnOffList_str0, OnOffList_str1};

TDataDescStruct const EnableEmailErrorSendDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableEmailErrorSend),            // указатель на переменную или адрес FRAM
  (void*)&EnableEmailErrorSendRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableEmailErrorSendName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableEmailErrorSendList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Статус подключения модема
*************************************/
CPU_INT08U const ModemStatusName[] = "Статус";
CPU_INT08U const ModemStatusList_str0[] = "OK";
CPU_INT08U const ModemStatusList_str1[] = "Ош.конф.";
CPU_INT08U const ModemStatusList_str2[] = "Нет связи";
CPU_INT08U const *ModemStatusList[] = {ModemStatusList_str0, ModemStatusList_str1, ModemStatusList_str2};

TDataDescStruct const ModemStatusDesc = {
  DATA_DESC_VIEW,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &modem_status,           // указатель на переменную или адрес FRAM
  NULL,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,      // смещение между элементами в массиве
  ModemStatusName, // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ModemStatusList,// указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Включить отправку журналов по e-mail
*************************************/
CPU_INT08U const EnableEmailJournalSendName[] = "Отпр.журналы";

TDataDescStruct const EnableEmailJournalSendDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableEmailJournalSend),            // указатель на переменную или адрес FRAM
  (void*)&EnableEmailErrorSendRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableEmailJournalSendName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableEmailErrorSendList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Очищать журнал после отправки по e-mail НЕ ИСПОЛЬЗУЕТСЯ
*************************************/
CPU_INT08U const ClearJournalAfterSendName[] = "Оч.журналы";

TDataDescStruct const ClearJournalAfterSendDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.ClearJournalAfterSend),            // указатель на переменную или адрес FRAM
  (void*)&EnableEmailErrorSendRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  ClearJournalAfterSendName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableEmailErrorSendList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
Время отправки статистики, час : мин
*************************************/
TRangeValueULONG const StatSendHourRange = {0, 60*24 - 1};
CPU_INT08U const StatSendHourName[] = "Tотпр.";

TDataDescStruct const StatSendHourMinDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_HOUR_MIN,    // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.StatSendHourMin),            // указатель на переменную или адрес FRAM
  (void*)&StatSendHourRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  StatSendHourName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  9                           
};

/*************************************
  Включение монетоприемника
*************************************/
TRangeValueULONG const EnableCoinRange = {0, 1};
CPU_INT08U const EnableCoinName[] = "Монетопр-к";
CPU_INT08U const *EnableCoinList[] = {OnOffList_str0, OnOffList_str1};

void OnchangeEnableCoin(void)
{
}

TDataDescStruct const EnableCoinDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableCoinAcceptor),            // указатель на переменную или адрес FRAM
  (void*)&EnableCoinRange,     // указатель на границы параметра
  OnchangeEnableCoin,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableCoinName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableCoinList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Включение абонемента
*************************************/
TRangeValueULONG const EnableAbonementRange = {0, 1};
CPU_INT08U const EnableAbonementName[] = "Абонемент";
CPU_INT08U const *EnableAbonementList[] = {OnOffList_str0, OnOffList_str1};

void OnchangeEnableAbonement(void)
{
}

TDataDescStruct const EnableAbonementDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableAbonementAcceptor),            // указатель на переменную или адрес FRAM
  (void*)&EnableAbonementRange,     // указатель на границы параметра
  OnchangeEnableAbonement,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableAbonementName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableAbonementList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
 Количество использований абонемента в день
*************************************/
TRangeValueULONG const CountUseAbonementRange = {1, 9};
CPU_INT08U const CountUseAbonementName[] = "Кол.использ.";

void OnchangeCountUseAbonement(void)
{
}

TDataDescStruct const CountUseAbonementDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  0,                        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.CountUseAbonement),            // указатель на переменную или адрес FRAM
  (void*)&CountUseAbonementRange,     // указатель на границы параметра
  OnchangeCountUseAbonement,          // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  CountUseAbonementName,    // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  2
};

/*************************************
  Команда на очистку статистики абонементов 
*************************************/
CPU_INT32U ClearStatAbonementCmd = 0;

TRangeValueULONG const InitByDefaultAbonementRange = {0, 1};

extern void ClearAbonementCounters(void);

CPU_INT08U const ClearAbonementCmdName[] = "Очистка";
CPU_INT08U const ClearAbonementCmdList_str0[] = "нет";
CPU_INT08U const ClearAbonementCmdList_str1[] = "да";
CPU_INT08U const *ClearAbonementCmdList[] = {ClearAbonementCmdList_str0, ClearAbonementCmdList_str1};

void OnChangeClearStatAbonementCmd(void)
{
  if (ClearStatAbonementCmd)
    {
        while (1) 
        {
            if (picc_is_new_card_present())
            {
                if (picc_read_card_serial()) 
                {
                    init_mifare_card_data();
                    write_mifare_card();
                    stop_card_working();
                    break;
                }
            }

            OSTimeDly(100);
        }

        ClearStatAbonementCmd = 0;
    }
}

TDataDescStruct const ClearStatAbonementCmdDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&ClearStatAbonementCmd,                // указатель на переменную или адрес FRAM
  (void*)&InitByDefaultAbonementRange,           // указатель на границы параметра
  OnChangeClearStatAbonementCmd,                     // функция по изменению
  0,       // смещение между элементами в массиве
  ClearAbonementCmdName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ClearAbonementCmdList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Цена импульса монетоприемника
*************************************/
TRangeValueULONG const CoinPerPulseRange = {1, 9999};
CPU_INT08U const CoinPerPulseName[] = "Руб./имп.";

TDataDescStruct const CoinPerPulseDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.CoinPerPulse),            // указатель на переменную или адрес FRAM
  (void*)&CoinPerPulseRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  CoinPerPulseName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  10                           // значение по умолчанию
};

/*************************************
  Длина импульса монетоприемника
*************************************/
TRangeValueULONG const CoinPulseLenRange = {10, 1000};
CPU_INT08U const CoinPulseLenName[] = "Длина имп.,мс";

TDataDescStruct const CoinPulseLenDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CoinPulseLen),            // указатель на переменную или адрес FRAM
  (void*)&CoinPulseLenRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  CoinPulseLenName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  50                           // значение по умолчанию
};

char const CoinPulseLenDescId[] = "CoinPulseLenDesc";

/*************************************
  Длина паузы монетоприемника
*************************************/
TRangeValueULONG const CoinPauseLenRange = {5, 1000};
CPU_INT08U const CoinPauseLenName[] = "Длина паузы,мс";

TDataDescStruct const CoinPauseLenDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CoinPauseLen),            // указатель на переменную или адрес FRAM
  (void*)&CoinPauseLenRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  CoinPauseLenName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  20                           // значение по умолчанию
};

char const CoinPauseLenDescId[] = "CoinPauseLenDesc";

/*************************************
  Допуск длины импульса монетоприемника
*************************************/
TRangeValueULONG const CoinPulseDeltaRange = {10, 1000};
CPU_INT08U const CoinPulseDeltaName[] = "Допуск,мс";

TDataDescStruct const CoinPulseDeltaDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CoinPulseDelta),            // указатель на переменную или адрес FRAM
  (void*)&CoinPulseDeltaRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  CoinPulseDeltaName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  20                           // значение по умолчанию
};

char const CoinPulseDeltaDescId[] = "CoinPulseDeltaDesc";

/*************************************
  Включение ФР
*************************************/
TRangeValueULONG const EnableFiscalRange = {0, 1};
CPU_INT08U const EnableFiscalName[] = "ФР";
CPU_INT08U const *EnableFiscalList[] = {OnOffList_str0, OnOffList_str1};

TDataDescStruct const EnableFiscalDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableFiscal),            // указатель на переменную или адрес FRAM
  (void*)&EnableFiscalRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableFiscalName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableFiscalList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Игнор ошибок ФР
*************************************/
TRangeValueULONG const DisableFiscalErrorsRange = {0, 1};
CPU_INT08U const DisableFiscalErrorsName[] = "Игнорир.ош.ФР";
CPU_INT08U const DisableFiscalErrorsList_str0[] = "нет";
CPU_INT08U const DisableFiscalErrorsList_str1[] = "да";
CPU_INT08U const *DisableFiscalErrorsList[] = {DisableFiscalErrorsList_str0, DisableFiscalErrorsList_str1};

TDataDescStruct const DisableFiscalErrorsDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.DisableFiscalErrors),            // указатель на переменную или адрес FRAM
  (void*)&DisableFiscalErrorsRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  DisableFiscalErrorsName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  DisableFiscalErrorsList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Время идущего сеанса
*************************************/
CPU_INT32U  WorkTime[CHANNELS_NUM];
TRangeValueULONG const WorkTimeRange = {0, 0xffffffffL};
CPU_INT08U const WorkTimeName[] = "Вр.работы";

TDataDescStruct const WorkTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  &WorkTime,                // указатель на переменную или адрес FRAM
  (void*)&WorkTimeRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  WorkTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};


/*************************************
  Тайм-аут перед запуском поканально
*************************************/
TRangeValueULONG const TimeOutBeforeRange = {0, 999};
CPU_INT08U const TimeOutBeforeName[] = "Пауза до,сек.";

TDataDescStruct const TimeOutBeforeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.TimeOutBefore),                // указатель на переменную или адрес FRAM
  (void*)&TimeOutBeforeRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  TimeOutBeforeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  30                           
};

/*************************************
  Тайм-аут после работы поканально
*************************************/
TRangeValueULONG const TimeOutAfterRange = {0, 99};
CPU_INT08U const TimeOutAfterName[] = "Пауза после,мин.";

TDataDescStruct const TimeOutAfterDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.TimeOutAfter),                // указатель на переменную или адрес FRAM
  (void*)&TimeOutAfterRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  TimeOutAfterName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  3                           
};

/*************************************
  Максимальное время поканально, мин.
*************************************/
TRangeValueULONG const MaxWorkTimeRange = {1, 999};
CPU_INT08U const MaxWorkTimeName[] = "Tmax,мин.";

TDataDescStruct const MaxWorkTimeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.MaxWorkTime),                // указатель на переменную или адрес FRAM
  (void*)&MaxWorkTimeRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  MaxWorkTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  20                           
};

/*************************************
  Минимальное время поканально, мин.
*************************************/
TRangeValueULONG const MinWorkTimeRange = {1, 999};
CPU_INT08U const MinWorkTimeName[] = "Tmin,мин.";

TDataDescStruct const MinWorkTimeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.MinWorkTime),                // указатель на переменную или адрес FRAM
  (void*)&MinWorkTimeRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  MinWorkTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  5                           
};

/*************************************
  Настройка выходных
*************************************/
TRangeValueULONG const WeekEndRange = {0, 4};
CPU_INT08U const WeekEndName[] = "Выходные:";
CPU_INT08U const WeekEndList_str0[] = "нет";
CPU_INT08U const WeekEndList_str1[] = "пт-вс";
CPU_INT08U const WeekEndList_str2[] = "сб-вс";
CPU_INT08U const WeekEndList_str3[] = "пт-сб";
CPU_INT08U const WeekEndList_str4[] = "пт-пн";
CPU_INT08U const *WeekEndList[] = {WeekEndList_str0, WeekEndList_str1, WeekEndList_str2, WeekEndList_str3, WeekEndList_str4, NULL};

TDataDescStruct const WeekEndDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.WeekEnd),            // указатель на переменную или адрес FRAM
  (void*)&WeekEndRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  WeekEndName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  WeekEndList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Настройка отложенного старта
*************************************/
TRangeValueULONG const DeferredStartRange = {0, 1};
CPU_INT08U const DeferredStartName[] = "Отлож.старт";
CPU_INT08U const DeferredStart_str0[] = "нет";
CPU_INT08U const DeferredStart_str1[] = "да";
CPU_INT08U const *DeferredStartList[] = {DeferredStart_str0, DeferredStart_str1, NULL};

TDataDescStruct const DeferredStartDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DefferedStartEnabled),            // указатель на переменную или адрес FRAM
  (void*)&DeferredStartRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  DeferredStartName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  DeferredStartList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Индекс при настройке цен
*************************************/
TRangeValueULONG const PeriodIndexRange = {0, 0xffffffff/*CHANNELS_NUM*PRICE_PERIODS_NUM-1*/};
CPU_INT08U const PeriodIndexName[] = "";
CPU_INT08U const *PeriodWeekendIndexList[] = {
                                              "КАН.1 ПЕР.1 ВЫХ.",
                                              "КАН.1 ПЕР.2 ВЫХ.",
                                              "КАН.1 ПЕР.3 ВЫХ.",
                                              "КАН.1 ПЕР.4 ВЫХ.",
                                              "КАН.2 ПЕР.1 ВЫХ.",
                                              "КАН.2 ПЕР.2 ВЫХ.",
                                              "КАН.2 ПЕР.3 ВЫХ.",
                                              "КАН.2 ПЕР.4 ВЫХ.",
                                              "КАН.3 ПЕР.1 ВЫХ.",
                                              "КАН.3 ПЕР.2 ВЫХ.",
                                              "КАН.3 ПЕР.3 ВЫХ.",
                                              "КАН.3 ПЕР.4 ВЫХ.",
                                              "КАН.4 ПЕР.1 ВЫХ.",
                                              "КАН.4 ПЕР.2 ВЫХ.",
                                              "КАН.4 ПЕР.3 ВЫХ.",
                                              "КАН.4 ПЕР.4 ВЫХ.",
                                              "КАН.5 ПЕР.1 ВЫХ.",
                                              "КАН.5 ПЕР.2 ВЫХ.",
                                              "КАН.5 ПЕР.3 ВЫХ.",
                                              "КАН.5 ПЕР.4 ВЫХ.",
                                              "КАН.6 ПЕР.1 ВЫХ.",
                                              "КАН.6 ПЕР.2 ВЫХ.",
                                              "КАН.6 ПЕР.3 ВЫХ.",
                                              "КАН.6 ПЕР.4 ВЫХ.",
                                              "КАН.7 ПЕР.1 ВЫХ.",
                                              "КАН.7 ПЕР.2 ВЫХ.",
                                              "КАН.7 ПЕР.3 ВЫХ.",
                                              "КАН.7 ПЕР.4 ВЫХ.",
                                              "КАН.8 ПЕР.1 ВЫХ.",
                                              "КАН.8 ПЕР.2 ВЫХ.",
                                              "КАН.8 ПЕР.3 ВЫХ.",
                                              "КАН.8 ПЕР.4 ВЫХ.",
                                              "КАН.9 ПЕР.1 ВЫХ.",
                                              "КАН.9 ПЕР.2 ВЫХ.",
                                              "КАН.9 ПЕР.3 ВЫХ.",
                                              "КАН.9 ПЕР.4 ВЫХ.",
                                              "КАН.10 ПЕР.1 ВЫХ.",
                                              "КАН.10 ПЕР.2 ВЫХ.",
                                              "КАН.10 ПЕР.3 ВЫХ.",
                                              "КАН.10 ПЕР.4 ВЫХ.",
                                               NULL};

CPU_INT32U PeriodIndex = 0;

void OnChangePeriodIndex(void)
{
  if ((PeriodIndex == 0xffffffff) || (PeriodIndex < ChannelIndex*PRICE_PERIODS_NUM)) PeriodIndex = (ChannelIndex+1)*PRICE_PERIODS_NUM-1;
  else if (PeriodIndex >= (ChannelIndex+1)*PRICE_PERIODS_NUM) PeriodIndex = (ChannelIndex)*PRICE_PERIODS_NUM;
}

TDataDescStruct const PeriodWeekendIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)&PeriodIndex,            // указатель на переменную или адрес FRAM
  (void*)&PeriodIndexRange,     // указатель на границы параметра
  OnChangePeriodIndex,                     // функция по изменению
  0,       // смещение между элементами в массиве
  PeriodIndexName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  PeriodWeekendIndexList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

CPU_INT08U const *PeriodWeekdaysIndexList[] = {
                                              "КАН.1 ПЕР.1 БУД.",
                                              "КАН.1 ПЕР.2 БУД.",
                                              "КАН.1 ПЕР.3 БУД.",
                                              "КАН.1 ПЕР.4 БУД.",
                                              "КАН.2 ПЕР.1 БУД.",
                                              "КАН.2 ПЕР.2 БУД.",
                                              "КАН.2 ПЕР.3 БУД.",
                                              "КАН.2 ПЕР.4 БУД.",
                                              "КАН.3 ПЕР.1 БУД.",
                                              "КАН.3 ПЕР.2 БУД.",
                                              "КАН.3 ПЕР.3 БУД.",
                                              "КАН.3 ПЕР.4 БУД.",
                                              "КАН.4 ПЕР.1 БУД.",
                                              "КАН.4 ПЕР.2 БУД.",
                                              "КАН.4 ПЕР.3 БУД.",
                                              "КАН.4 ПЕР.4 БУД.",
                                              "КАН.5 ПЕР.1 БУД.",
                                              "КАН.5 ПЕР.2 БУД.",
                                              "КАН.5 ПЕР.3 БУД.",
                                              "КАН.5 ПЕР.4 БУД.",
                                              "КАН.6 ПЕР.1 БУД.",
                                              "КАН.6 ПЕР.2 БУД.",
                                              "КАН.6 ПЕР.3 БУД.",
                                              "КАН.6 ПЕР.4 БУД.",
                                              "КАН.7 ПЕР.1 БУД.",
                                              "КАН.7 ПЕР.2 БУД.",
                                              "КАН.7 ПЕР.3 БУД.",
                                              "КАН.7 ПЕР.4 БУД.",
                                              "КАН.8 ПЕР.1 БУД.",
                                              "КАН.8 ПЕР.2 БУД.",
                                              "КАН.8 ПЕР.3 БУД.",
                                              "КАН.8 ПЕР.4 БУД.",
                                              "КАН.9 ПЕР.1 БУД.",
                                              "КАН.9 ПЕР.2 БУД.",
                                              "КАН.9 ПЕР.3 БУД.",
                                              "КАН.9 ПЕР.4 БУД.",
                                              "КАН.10 ПЕР.1 БУД.",
                                              "КАН.10 ПЕР.2 БУД.",
                                              "КАН.10 ПЕР.3 БУД.",
                                              "КАН.10 ПЕР.4 БУД.",
                                               NULL};
TDataDescStruct const PeriodWeekdaysIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)&PeriodIndex,            // указатель на переменную или адрес FRAM
  (void*)&PeriodIndexRange,     // указатель на границы параметра
  OnChangePeriodIndex,                     // функция по изменению
  0,       // смещение между элементами в массиве
  PeriodIndexName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  PeriodWeekdaysIndexList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};


/*************************************
  Цена по выходным
*************************************/
TRangeValueULONG const PriceWeekendRange = {1, MAX_PRICE};
CPU_INT08U const PriceWeekendName[] = "Цена,руб.";

TDataDescStruct const PriceWeekendDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekendIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.Price_Weekend),                // указатель на переменную или адрес FRAM
  (void*)&PriceWeekendRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PriceWeekendName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  15                           
};

/*************************************
  Цена по будням
*************************************/
TRangeValueULONG const PriceWeekdaysRange = {1, MAX_PRICE};
CPU_INT08U const PriceWeekdaysName[] = "Цена,руб.";

TDataDescStruct const PriceWeekdaysDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekdaysIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.Price_Weekdays),                // указатель на переменную или адрес FRAM
  (void*)&PriceWeekdaysRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PriceWeekdaysName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  15                         
};


/*************************************
  Время за цену по выходным
*************************************/
TRangeValueULONG const PriceTimeWeekendRange = {1, 999};
CPU_INT08U const PriceTimeWeekendName[] = "За время,мин.";

TDataDescStruct const PriceTimeWeekendDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekendIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekend),                // указатель на переменную или адрес FRAM
  (void*)&PriceTimeWeekendRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PriceTimeWeekendName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1                           
};

/*************************************
  Время за цену по будням
*************************************/
TRangeValueULONG const PriceTimeWeekdaysRange = {1, 999};
CPU_INT08U const PriceTimeWeekdaysName[] = "За время,мин.";

TDataDescStruct const PriceTimeWeekdaysDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekdaysIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.PriceTime_Weekdays),                // указатель на переменную или адрес FRAM
  (void*)&PriceTimeWeekdaysRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PriceTimeWeekdaysName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1                           
};


/*************************************
  Начало периодов по будням
*************************************/
TRangeValueULONG const T_Start_WeekdaysRange = {0, 24};
CPU_INT08U const T_Start_WeekdaysName[] = "Начало,ч";

TDataDescStruct const T_Start_WeekdaysDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekdaysIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekdays),                // указатель на переменную или адрес FRAM
  (void*)&T_Start_WeekdaysRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  T_Start_WeekdaysName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Конец периодов по будням
*************************************/
TRangeValueULONG const T_End_WeekdaysRange = {0, 24};
CPU_INT08U const T_End_WeekdaysName[] = "Конец,ч";

TDataDescStruct const T_End_WeekdaysDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekdaysIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekdays),                // указатель на переменную или адрес FRAM
  (void*)&T_End_WeekdaysRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  T_End_WeekdaysName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  24                           
};


/*************************************
  Начало периодов по выходным
*************************************/
TRangeValueULONG const T_Start_WeekendRange = {0, 24};
CPU_INT08U const T_Start_WeekendName[] = "Начало,ч";

TDataDescStruct const T_Start_WeekendDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekendIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.T_Start_Weekend),                // указатель на переменную или адрес FRAM
  (void*)&T_Start_WeekendRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  T_Start_WeekendName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Конец периодов по выходным
*************************************/
TRangeValueULONG const T_End_WeekendRange = {0, 24};
CPU_INT08U const T_End_WeekendName[] = "Конец,ч";

TDataDescStruct const T_End_WeekendDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM*PRICE_PERIODS_NUM,             // размер массива
  &PeriodWeekendIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.T_End_Weekend),                // указатель на переменную или адрес FRAM
  (void*)&T_End_WeekendRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  T_End_WeekendName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  24                           
};


/*************************************
  Команда инициализации по умолчанию
*************************************/
CPU_INT32U InitByDefault = 0;

TRangeValueULONG const InitByDefaultRange = {0, 1};
CPU_INT08U const InitByDefaultName[] = "Инициализация";
CPU_INT08U const InitByDefaultList_str0[] = "нет";
CPU_INT08U const InitByDefaultList_str1[] = "да";
CPU_INT08U const *InitByDefaultList[] = {InitByDefaultList_str0, InitByDefaultList_str1};

extern void ClearTerminalInfo();

void ClearPrecheckText()
{
  #if defined(BOARD_CENTRAL_CARWASH)
  CPU_INT16U crc_calc;
  SetArrayFram((unsigned short)offsetof(TFramMap, precheck_text), PRETEXT_LINE_COUNT * 40, 0x00);
  crc_calc = crc16_fram((unsigned short)offsetof(TFramMap, precheck_text), PRETEXT_LINE_COUNT * 40);
  WriteArrayFram((unsigned short)offsetof(TFramMap, precheck_crc), sizeof(CPU_INT16U), (unsigned char *)&crc_calc);
  #endif
}

void InitPrecheckText()
{
  #if defined(BOARD_CENTRAL_CARWASH)
  CPU_INT16U crc_calc, crc_read;
  
  crc_calc = crc16_fram((unsigned short)offsetof(TFramMap, precheck_text), PRETEXT_LINE_COUNT * 40);
  ReadArrayFram((unsigned short)offsetof(TFramMap, precheck_crc), sizeof(CPU_INT16U), (unsigned char *)&crc_read);
  
  if (crc_calc != crc_read)
  {
    ClearPrecheckText();
  }
  #endif
}

int ReadPrecheckText(char *buf, int i)
{
   #if defined(BOARD_CENTRAL_CARWASH)
   ReadArrayFram((unsigned short)offsetof(TFramMap, precheck_text) + 40 * i, 40, (unsigned char *)buf);
   buf[40] = 0;
   return strlen(buf);
   #else
   return 0;
   #endif
}

void OnChangeInitByDefault(void)
{
    int i = 0;
    if (InitByDefault == 0) return;
    while (AllDataArray[i].ptr != NULL)
    {
        if (AllDataArray[i].ptr != &SystemTimeEditDesc)
            InitDescByDefault(AllDataArray[i].ptr);
        i++;
    }
  
    CPU_INT32U ip;
    
    ip = 0xC0A80065;
    SetData(&PostIpAddrDesc, &ip, 0, DATA_FLAG_DIRECT_INDEX);   
    ip = 0xC0A80066;
    SetData(&PostIpAddrDesc, &ip, 1, DATA_FLAG_DIRECT_INDEX);   
    ip = 0xC0A80067;
    SetData(&PostIpAddrDesc, &ip, 2, DATA_FLAG_DIRECT_INDEX);   
    ip = 0xC0A80068;
    SetData(&PostIpAddrDesc, &ip, 3, DATA_FLAG_DIRECT_INDEX);   
    ip = 0xC0A80069;
    SetData(&PostIpAddrDesc, &ip, 4, DATA_FLAG_DIRECT_INDEX);   
    ip = 0xC0A8006A;
    SetData(&PostIpAddrDesc, &ip, 5, DATA_FLAG_DIRECT_INDEX);   
    ip = 0xC0A8006B;
    SetData(&PostIpAddrDesc, &ip, 6, DATA_FLAG_DIRECT_INDEX);   
    ip = 0xC0A8006C;
    SetData(&PostIpAddrDesc, &ip, 7, DATA_FLAG_DIRECT_INDEX);   

    ClearTerminalInfo();
        
    CPU_INT32U money;
    
    money = 50;
    SetData(&SelectedMoneyDesc, &money, 0, DATA_FLAG_DIRECT_INDEX);   
    money = 100;
    SetData(&SelectedMoneyDesc, &money, 1, DATA_FLAG_DIRECT_INDEX);   
    money = 150;
    SetData(&SelectedMoneyDesc, &money, 2, DATA_FLAG_DIRECT_INDEX);   
    money = 200;
    SetData(&SelectedMoneyDesc, &money, 3, DATA_FLAG_DIRECT_INDEX);   
    money = 250;
    SetData(&SelectedMoneyDesc, &money, 4, DATA_FLAG_DIRECT_INDEX);   
    money = 300;
    SetData(&SelectedMoneyDesc, &money, 5, DATA_FLAG_DIRECT_INDEX);   
    money = 0;
    SetData(&SelectedMoneyDesc, &money, 6, DATA_FLAG_DIRECT_INDEX);   
    money = 0;
    SetData(&SelectedMoneyDesc, &money, 7, DATA_FLAG_DIRECT_INDEX);   

    CPU_INT32U action;
    
    action = KEY_ACTION_UP;
    SetData(&KeyActionDesc, &action, 0, DATA_FLAG_DIRECT_INDEX);   
    action = KEY_ACTION_DOWN;
    SetData(&KeyActionDesc, &action, 1, DATA_FLAG_DIRECT_INDEX);   
    action = KEY_ACTION_EMPTY;
    SetData(&KeyActionDesc, &action, 2, DATA_FLAG_DIRECT_INDEX);   
    action = KEY_ACTION_LEFT;
    SetData(&KeyActionDesc, &action, 3, DATA_FLAG_DIRECT_INDEX);   
    action = KEY_ACTION_RIGHT;
    SetData(&KeyActionDesc, &action, 4, DATA_FLAG_DIRECT_INDEX);   
    action = KEY_ACTION_EMPTY;
    SetData(&KeyActionDesc, &action, 5, DATA_FLAG_DIRECT_INDEX);   
    action = KEY_ACTION_EMPTY;
    SetData(&KeyActionDesc, &action, 6, DATA_FLAG_DIRECT_INDEX);   
    action = KEY_ACTION_EMPTY;
    SetData(&KeyActionDesc, &action, 7, DATA_FLAG_DIRECT_INDEX);   

    ClearPrecheckText();

#if defined(BOARD_SOLARIUM_VLAD)
        
    for (i = 0; i < SOLAR_MODES_COUNT; i++)
    {
        CPU_INT32U temp32;
        temp32 = 18;
        SetData(&SolarLampsCountDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_COLLATEN, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 36;
        SetData(&SolarLampsCountDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_UF, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 54;
        SetData(&SolarLampsCountDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_MAX, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 1800;
        SetData(&SolarPricePerMinuteDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_COLLATEN, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 2100;
        SetData(&SolarPricePerMinuteDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_UF, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 3900;
        SetData(&SolarPricePerMinuteDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_MAX, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 20;
        SetData(&SolarMaximumTimeMinutesDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_COLLATEN, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 16;
        SetData(&SolarMaximumTimeMinutesDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_UF, DATA_FLAG_DIRECT_INDEX);   
        temp32 = 14;
        SetData(&SolarMaximumTimeMinutesDesc, &temp32, SOLAR_MODES_COUNT * i + SOLAR_MODE_MAX, DATA_FLAG_DIRECT_INDEX);   
    }   
    
    CPU_INT32U temp32;
    temp32 = 0;
    SetData(&DiscountBeginHourDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 7;
    SetData(&DiscountEndHourDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 8;
    SetData(&DiscountBeginHourDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 11;
    SetData(&DiscountEndHourDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 12;
    SetData(&DiscountBeginHourDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 19;
    SetData(&DiscountEndHourDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 20;
    SetData(&DiscountBeginHourDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);
    temp32 = 23;
    SetData(&DiscountEndHourDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);

    temp32 = 1;
    SetData(&ScoreRs485AddressDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 2;
    SetData(&ScoreRs485AddressDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 3;
    SetData(&ScoreRs485AddressDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 16;
    SetData(&ScoreRs485AddressDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);
    temp32 = 19;
    SetData(&ScoreRs485AddressDesc, &temp32, 4, DATA_FLAG_DIRECT_INDEX);
    temp32 = 22;
    SetData(&ScoreRs485AddressDesc, &temp32, 5, DATA_FLAG_DIRECT_INDEX);
    
    temp32 = 10;
    SetData(&SkinCollatenMaxTimeDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 20;
    SetData(&SkinCollatenMaxTimeDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 40;
    SetData(&SkinCollatenMaxTimeDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 60;
    SetData(&SkinCollatenMaxTimeDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);

    temp32 = 5;
    SetData(&SkinUFMaxTimeDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 10;
    SetData(&SkinUFMaxTimeDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 18;
    SetData(&SkinUFMaxTimeDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 25;
    SetData(&SkinUFMaxTimeDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);

    temp32 = 2;
    SetData(&SkinMaximalMaxTimeDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 5;
    SetData(&SkinMaximalMaxTimeDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 10;
    SetData(&SkinMaximalMaxTimeDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 15;
    SetData(&SkinMaximalMaxTimeDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);

    temp32 = 0;
    SetData(&SolarControlChannelDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 1;
    SetData(&SolarControlChannelDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 2;
    SetData(&SolarControlChannelDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
        
    temp32 = 3000;
    SetData(&AbonementMoneyDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 600;
    SetData(&AbonementBonusDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);
    temp32 = 45;
    SetData(&AbonementBestBeforeDesc, &temp32, 0, DATA_FLAG_DIRECT_INDEX);

    temp32 = 6000;
    SetData(&AbonementMoneyDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 1800;
    SetData(&AbonementBonusDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);
    temp32 = 90;
    SetData(&AbonementBestBeforeDesc, &temp32, 1, DATA_FLAG_DIRECT_INDEX);

    temp32 = 12000;
    SetData(&AbonementMoneyDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 4800;
    SetData(&AbonementBonusDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);
    temp32 = 180;
    SetData(&AbonementBestBeforeDesc, &temp32, 2, DATA_FLAG_DIRECT_INDEX);

    temp32 = 24000;
    SetData(&AbonementMoneyDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);
    temp32 = 10800;
    SetData(&AbonementBonusDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);
    temp32 = 360;
    SetData(&AbonementBestBeforeDesc, &temp32, 3, DATA_FLAG_DIRECT_INDEX);

#endif
    
    InitByDefault = 0;
}


TDataDescStruct const InitByDefaultDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&InitByDefault,                // указатель на переменную или адрес FRAM
  (void*)&InitByDefaultRange,           // указатель на границы параметра
  OnChangeInitByDefault,                     // функция по изменению
  0,       // смещение между элементами в массиве
  InitByDefaultName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  InitByDefaultList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};


/*************************************
  Команда выполнить сверку
*************************************/
CPU_INT32U MakeSverkaCmd = 0;

TRangeValueULONG const MakeSverkaRange = {0, 1};
CPU_INT08U const MakeSverkaName[] = "Сверка";
CPU_INT08U const *MakeSverkaList[] = {InitByDefaultList_str0, InitByDefaultList_str1};

void OnChangeMakeSverka()
{
    if (MakeSverkaCmd)
    {
        MakeSverkaCmd = 0;
        SetTermCommand(TERM_COMMAND_MAKE_SVERKA, NULL);
    }
}

TDataDescStruct const MakeSverkaDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&MakeSverkaCmd,                // указатель на переменную или адрес FRAM
  (void*)&MakeSverkaRange,           // указатель на границы параметра
  OnChangeMakeSverka,                     // функция по изменению
  0,       // смещение между элементами в массиве
  MakeSverkaName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  MakeSverkaList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Команда выполнить синхронизацию
*************************************/
CPU_INT32U MakeSyncCmd = 0;

CPU_INT08U const MakeSyncName[] = "Синхронизация";

void OnChangeMakeSync()
{
    if (MakeSyncCmd)
    {
        MakeSyncCmd = 0;
        SetTermCommand(TERM_COMMAND_MAKE_SYNCHRO, NULL);
    }
}


TDataDescStruct const MakeSyncDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&MakeSyncCmd,                // указатель на переменную или адрес FRAM
  (void*)&MakeSverkaRange,           // указатель на границы параметра
  OnChangeMakeSync,                     // функция по изменению
  0,       // смещение между элементами в массиве
  MakeSyncName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  MakeSverkaList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Команда на печать Z-отчета
*************************************/
CPU_INT32U PrintZReportCmd = 0;

CPU_INT08U const PrintZReportName[] = "Z-отчет";
CPU_INT08U const PrintZReportList_str0[] = "нет";
CPU_INT08U const PrintZReportList_str1[] = "печать";
CPU_INT08U const *PrintZReportList[] = {PrintZReportList_str0, PrintZReportList_str1};


void OnChangePrintZReportCmd(void)
{
}

TDataDescStruct const PrintZReportDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&PrintZReportCmd,                // указатель на переменную или адрес FRAM
  (void*)&InitByDefaultRange,           // указатель на границы параметра
  OnChangePrintZReportCmd,                     // функция по изменению
  0,       // смещение между элементами в массиве
  PrintZReportName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  PrintZReportList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};


/*************************************
  Команда на печать X-отчета
*************************************/
CPU_INT32U PrintXReportCmd = 0;

CPU_INT08U const PrintXReportName[] = "X-отчет";

void OnChangePrintXReportCmd(void)
{
}

TDataDescStruct const PrintXReportDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&PrintXReportCmd,                // указатель на переменную или адрес FRAM
  (void*)&InitByDefaultRange,           // указатель на границы параметра
  OnChangePrintXReportCmd,                     // функция по изменению
  0,       // смещение между элементами в массиве
  PrintXReportName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  PrintZReportList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Ошибка в журнале ошибок
*************************************/
TRangeValueULONG const ErrorNumberRange = {0, JOURNAL_EVENTS_COUNT - 1};
CPU_INT08U const *ErrorNumberList0[JOURNAL_EVENTS_COUNT] = {"нет", "", "", "",
                                        "", "", "", "",
                                        "", "", "", "",
                                        "", "", "", "", "", "",
                                        "", "", "", "", "", "", "",
                                       "ошибка связи с", 
                                       "ошибка работы", 
                                       "1Ch60h-выбр.купюры", 
                                       "1Ch61h-выбр.купюры",
                                       "1Ch64h-выбр.купюры",
                                       "1Ch65h-выбр.купюры",
                                       "1Ch66h-выбр.купюры",
                                       "1Ch67h-выбр.купюры",
                                       "1Ch68h-выбр.купюры",
                                       "1Ch69h-выбр.купюры",
                                       "1Ch6Ch-выбр.купюры",
                                       "к/п:41h-кассета",
                                       "к/п:42h-кассета",
                                       "к/п:43h-замин в ",
                                       "к/п:44h-замин",
                                       "к/п:45h-попытка",
                                       "к/п:50h-ошибка",
                                       "к/п:51h-ошибка скор.",
                                       "к/п:52h-ошибка",
                                       "к/п:53h-ошибка мех.",
                                       "к/п:54h-кассета",
                                       "к/п:65h-ошибка",
                                       "к/п:66h-ошибка",
                                       "к/п:67h-ошибка емк.",
                                       "ошибка", 
                                       "",
                                       "ошибка",
                                       "ошибка",
                                       "", "", "", "",
                                       "", "", "", "",

                                       "ФР:01h-Неизвестная",
                                       "ФР:02h-Неверное",
                                       "ФР:03h-Ошибка ФН",
                                       "ФР:04h-Ошибка КС",
                                       "ФР:05h-Закончен срок",  
                                       "ФР:06h-Архив ФН", 
                                       "ФР:07h-Неверные дата", 
                                       "ФР:08h-Нет ", 
                                       "ФР:09h-Некорр.", 
                                       "ФР:10h-Превышение", 
                                       "ФР:11h-Нет", 
                                       "ФР:12h-Исчерпан",
                                       "ФР:14h-Исчерпан", 
                                       "ФР:15h-Исчерпан", 
                                       "ФР:16h-Смена более",
                                       "ФР:17h-Неверная", 
                                      "ФР:20h-Сообщение", 
                                      "ФР:2Fh-Таймаут ",
                                      "ФР:30h-ФН ", 
                                      "ФР:33h-Некорректные", 
                                      "ФР:34h-Нет", 
                                      "ФР:35h-Некорректный", 
                                      "ФР:36h-Некорректные", 
                                      "ФР:37h-Команда", 
                                      "ФР:38h-Ошибка", 
                                      "ФР:39h-Внутренняя", 
                                      "ФР:3Ah-Переполнение", 
                                      "ФР:3Ch-Смена", 
                                      "ФР:3Dh-Смена", 
                                      "ФР:3Eh-Переполнение", 
                                      "ФР:3Fh-Переполнение", 
                                      "ФР:40h-Переполнение", 
                                      "ФР:41h-Переполнение", 
                                      "ФР:42h-Переполнение", 
                                      "ФР:43h-Переполнение", 
                                      "ФР:44h-Переполнение", 
                                      "ФР:45h-Cумма", 
                                      "ФР:46h-Не хватает", 
                                      "ФР:47h-Переполнение", 
                                      "ФР:48h-Переполнение", 
                                      "ФР:49h-Опер.невозм.", 
                                      "ФР:4Ah-Открыт чек", 
                                      "ФР:4Bh-Буфер чека", 
                                      "ФР:4Ch-Переполнение", 
                                      "ФР:4Dh-Вносимая", 
                                      "ФР:4Eh-Смена", 
                                      "ФР:4Fh-Неверный пароль", 
                                      "ФР:50h-Идет печать", 
                                      "ФР:51h-Переполнение", 
                                      "ФР:52h-Переполнение", 
                                      "ФР:53h-Переполнение", 
                                      "ФР:54h-Переполнение", 
                                      "ФР:55h-Чек закрыт", 
                                      "ФР:56h-Нет док.", 
                                      "ФР:58h-Ожидание", 
                                      "ФР:59h-Документ", 
                                      "ФР:5Bh-Переполнение", 
                                      "ФР:5Ch-Понижено", 
                                      "ФР:5Dh-Таблица", 
                                      "ФР:5Eh-Некорректная",
                                      "ФР:5Fh-Отриц.", 
                                      "ФР:60h-Переполнение",
                                      "ФР:61h-Переполнение",
                                      "ФР:62h-Переполнение",
                                      "ФР:63h-Переполнение",
                                      "ФР:65h-Не хватает",
                                      "ФР:66h-Переполнение",
                                      "ФР:68h-Не хватает",
                                      "ФР:69h-Переполнение",
                                      "ФР:6Ah-Ошибка",
                                      "ФР:6Bh-Нет чековой",
                                      "ФР:6Ch-Нет контр.",
                                      "ФР:6Dh-Не хватает",
                                      "ФР:6Eh-Переполнение",
                                      "ФР:6Fh-Переполнение",
                                      "ФР:71h-Ошибка", 
                                      "ФР:72h-Команда не", 
                                      "ФР:73h-Команда не", 
                                      "ФР:74h-Ошибка ОЗУ", 
                                      "ФР:75h-Ошибка", 
                                      "ФР:77h-Принтер:", 
                                      "ФР:78h-Замена ПО", 
                                      "ФП:7Ah-Поле не", 
                                      "ФР:7Bh-Ошибка", 
                                      "ФР:7Ch-Не совпадает", 
                                      "ФР:7Dh-Неверный", 
                                      "ФР:7Eh-Неверное", 
                                      "ФР:7Fh-Переполнение", 
                                      "ФР:84h-Переполнение", 
                                      "ФР:85h-Переполнение", 
                                      "ФР:86h-Переполнение", 
                                      "ФР:87h-Переполнение", 
                                      "ФР:88h-Переполнение", 
                                      "ФР:89h-Переполнение", 
                                      "ФР:8Ah-Переполнение", 
                                      "ФР:8Bh-Переполнение", 
                                      "ФР:8Ch-Отриц.", 
                                      "ФР:8Dh-Отрицательный", 
                                      "ФР:8Eh-Нулевой итог", 
                                      "ФР:90h-Поле прев.", 
                                      "ФР:91h-Выход за", 
                                      "ФР:92h-Наложение", 
                                      "ФР:93h-Восстановление", 
                                      "ФР:94h-Исчерпан", 
                                      "ФР:C0h-Контроль", 
                                      "ФР:C2h-Превышение", 
                                      "ФР:C4h-Несовпадение", 
                                      "ФР:C7h-Поле не", 
                                      "ФР:С8h-Отсутствуют"

};

TDataDescStruct const JournalErrorNumberDesc0 = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  EVENT_RECORDS_COUNT,             // размер массива
  &EventJournalIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, EventRecords[0].event),                // указатель на переменную или адрес FRAM
  (void*)&ErrorNumberRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(TEventRecord),       // смещение между элементами в массиве
  NULL,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  (void*)ErrorNumberList0,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

CPU_INT08U const *ErrorNumberList1[JOURNAL_EVENTS_COUNT] = {"", "", "", "",
                                        "", "", "", "",
                                        "", "", "", "",
                                        "", "", "", "", "", "",
                                        "", "", "", "", "", "", "",
                                       "купюроприемником", 
                                       "купюроприемника", 
                                       "при замине", 
                                       "по маг.датчику",
                                       "при транспорт.",
                                       "по идентификации",
                                       "по верификации ",
                                       "по оптич.датчику ",
                                       "по запрету",
                                       "по емкост.датчику",
                                       "по длине",
                                       "заполнена",
                                       "отсутствует",
                                       "купюроприемнике",
                                       "в кассете",
                                       "обмана",
                                       "стекерного мотора",
                                       "транспорт.мотора",
                                       "транспорт.мотора",
                                       "выравнивания",
                                       "отсутствует",
                                       "оптики",
                                       "маг.датчика",
                                       "датчика",
                                       "модема", 
                                       "",
                                       "связи с ФР", 
                                       "", "", "", "", 
                                       "", "", "", "", 
                                       "", 
                                       
                                       "команда",  // ФР:01h
                                       "состояние ФН",                  
                                       "",
                                       "",                                       
                                       "эксплуатации ФН",
                                       "переполнен",
                                       "и/или время",
                                       "запрошенных данных",
                                       "знач.пар.к-ды",
                                       "разм.TLV данных",
                                       "трансп.соед.",
                                       "ресурс КС",
                                       "ресурс хранения",
                                       "ресурс ожидания",
                                       "24 часов",
                                       "разница во времени",
                                        "от ОФД не принято",
                                        "обмена с ФН",
                                        "не отвечает",
                                        "параметры в к-де",
                                        "данных",
                                        "параметр",
                                        "параметры",    // 36h
                                        "не поддерживается",
                                        "в ПЗУ",
                                        "ошибка ПО ККТ",
                                        "нак.по надб.",
                                        "откр.-операция невозм.",
                                        "закр.-операция невозм.",       //3Dh
                                        "накоп.по секциям",
                                        "накоп.по скидкам",
                                        "диапазона скидок",
                                        "диапазона оплаты",
                                        "диапазона оплаты 2",
                                        "диапазона оплаты 3",
                                        "диапазона оплаты 4",
                                        "меньше итога чека",
                                        "наличности в кассе",
                                        "накопления по налогам",
                                        "итога чека",
                                        "в откр.чеке",
                                        "операция невозможна",
                                        "переполнен",
                                        "накоп.по налогам",
                                        "безнал.сумма больше",
                                        "превысила 24 часа",
                                        "",
                                        "пред.команды",
                                        "накоплений в смене",
                                        "накоплений 2 в смене",
                                        "накоплений 3 в смене",
                                        "накоплений 4 в смене",
                                        "операция невозм.",
                                        "для повтора",
                                        "команды продолжения",
                                        "открыт другим оп.",
                                        "диапазона надбавок",
                                        "напряжение 24В",
                                        "не определена",
                                        "операция",
                                        "итог чека",
                                        "при умножении",
                                        "диапазона цены",
                                        "диапазона кол-ва",
                                        "диапазона отдела",
                                        "денег в секции",
                                        "денег в секции",
                                        "денег по налогам",
                                        "денег по налогам",
                                        "питания",
                                        "ленты",
                                        "ленты",
                                        "денег по налогу",
                                        "денег по налогу",
                                        "по выплате в смене",
                                        "отрезчика",
                                        "поддерж.",
                                        "поддерж.",
                                        "",
                                        "питания",
                                        "нет сигнала",
                                        "",
                                        "редактируется",
                                        "оборудования",
                                        "дата",
                                        "формат даты",
                                        "значение в поле длины",
                                        "диапазона итога чека",
                                        "наличности",
                                        "по продажам",
                                        "по покупкам",
                                        "по возвратам продаж",
                                        "по возвратам покупок",
                                        "по внесению в смене",
                                        "по надбавкам в чеке",
                                        "по скидкам в чеке",
                                        "итог надбавки",
                                        "итог скидки в чеке",
                                        "чека",
                                        "размер в настройках",
                                        "границу поля печати",
                                        "полей",
                                        "ОЗУ прошло успешно",
                                        "лимит операций в чеке",
                                        "даты и времени",
                                        "напряжения",
                                        "номеров смен",
                                        "редактируется",
                                        "импульсы тахо."
};

TDataDescStruct const JournalErrorNumberDesc1 = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  EVENT_RECORDS_COUNT,             // размер массива
  &EventJournalIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, EventRecords[0].event),                // указатель на переменную или адрес FRAM
  (void*)&ErrorNumberRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(TEventRecord),       // смещение между элементами в массиве
  NULL,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  (void*)ErrorNumberList1,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  Строка с ошибкой по-английски
*************************************/
CPU_INT08U const *ErrorNumberListEng[JOURNAL_EVENTS_COUNT] = 
{
  "Net oshibki", "", "", "",
  "", "", "", "",
  "", "", "", "",
  "", "", "", "",
  "", "", "", "",
  "", "", "", "", "",
  "Oshibka svyazi c kupuropriemnikom",  
  "Kriticheskaya oshibka kupuropriemnika",
  "Vybros kupury po mag.datchiku",
  "Vybros kupury pri transportirovke",
  "Vybros kupury po identifikacii",
  "Vybros kupury po verifikacii",
  "Vybros kupury po opt.datchiku",
  "Vybros kupury po zapretu",
  "Vybros kupury po emk.datchiku",
  "Vybros kupury po dline",
  "Kasseta zapolnena",
  "Kasseta otsutstvuet",
  "Zamin v kupuropriemnike",
  "Zamin v kassete",
  "Popytka obmana",
  "Oshibka stekernogo motora",
  "Oshibka skorosti transp.motora",
  "Oshibka transp.motora",
  "Oshibka mehanizmavyravnivaniya",
  "Kasseta otsutstvuet",
  "Oshibka optiki",
  "Oshibka magn.datchika",
  "Oshibka emk.datchika",
  "Nekriticheskaya oshibka kupuropriemnika",

  "Oshibka svyazi s modemom",
  "",
  "Oshibka svyazi s FR", 
  "", "", "", "", 
  "", "", "", "",   
  
  "Oshibka FR 0x01",
  "Oshibka FR 0x02",
  "Oshibka FR 0x03",
  "Oshibka FR 0x04",
  "Oshibka FR 0x05",
  "Oshibka FR 0x06",
  "Oshibka FR 0x07",
  "Oshibka FR 0x08",
  "Oshibka FR 0x09",
  "Oshibka FR 0x10",
  "Oshibka FR 0x11",
  "Oshibka FR 0x12",
  "Oshibka FR 0x14",
  "Oshibka FR 0x15",
  "Oshibka FR 0x16",
  "Oshibka FR 0x17",
  "Oshibka FR 0x20",
  "Oshibka FR 0x2F",
  "Oshibka FR 0x30",
  "Oshibka FR 0x33",
  "Oshibka FR 0x34",
  "Oshibka FR 0x35",
  "Oshibka FR 0x36",
  "Oshibka FR 0x37",
  "Oshibka FR 0x38",
  "Oshibka FR 0x39",
  "Oshibka FR 0x3A",
  "Oshibka FR 0x3C",
  "Oshibka FR 0x3D",
  "Oshibka FR 0x3E",
  "Oshibka FR 0x3F",
  "Oshibka FR 0x40",
  "Oshibka FR 0x41",
  "Oshibka FR 0x42",
  "Oshibka FR 0x43",
  "Oshibka FR 0x44",
  "Oshibka FR 0x45",
  "Oshibka FR 0x46",
  "Oshibka FR 0x47",
  "Oshibka FR 0x48",
  "Oshibka FR 0x49",
  "Oshibka FR 0x4A",
  "Oshibka FR 0x4B",
  "Oshibka FR 0x4C",
  "Oshibka FR 0x4D",
  "Oshibka FR 0x4E",
  "Oshibka FR 0x4F",
  "Oshibka FR 0x50",
  "Oshibka FR 0x51",
  "Oshibka FR 0x52",
  "Oshibka FR 0x53",
  "Oshibka FR 0x54",
  "Oshibka FR 0x55",
  "Oshibka FR 0x56",
  "Oshibka FR 0x58",
  "Oshibka FR 0x59",
  "Oshibka FR 0x5B",
  "Oshibka FR 0x5C",
  "Oshibka FR 0x5D",
  "Oshibka FR 0x5E",
  "Oshibka FR 0x5F",
  "Oshibka FR 0x60",
  "Oshibka FR 0x61",
  "Oshibka FR 0x62",
  "Oshibka FR 0x63",
  "Oshibka FR 0x65",
  "Oshibka FR 0x66",
  "Oshibka FR 0x68",
  "Oshibka FR 0x69",
  "Oshibka FR 0x6A",
  "Oshibka FR 0x6B",
  "Oshibka FR 0x6C",
  "Oshibka FR 0x6D",
  "Oshibka FR 0x6E",
  "Oshibka FR 0x6F",
  "Oshibka FR 0x71",
  "Oshibka FR 0x72",
  "Oshibka FR 0x73",
  "Oshibka FR 0x74",
  "Oshibka FR 0x75",
  "Oshibka FR 0x77",
  "Oshibka FR 0x78",
  "Oshibka FR 0x7A",
  "Oshibka FR 0x7B",
  "Oshibka FR 0x7C",
  "Oshibka FR 0x7D",
  "Oshibka FR 0x7E",
  "Oshibka FR 0x7F",
  "Oshibka FR 0x84",
  "Oshibka FR 0x85",
  "Oshibka FR 0x86",
  "Oshibka FR 0x87",
  "Oshibka FR 0x88",
  "Oshibka FR 0x89",
  "Oshibka FR 0x8A",
  "Oshibka FR 0x8B",
  "Oshibka FR 0x8C",
  "Oshibka FR 0x8D",
  "Oshibka FR 0x8E",
  "Oshibka FR 0x90",
  "Oshibka FR 0x91",
  "Oshibka FR 0x92",
  "Oshibka FR 0x93",
  "Oshibka FR 0x94",
  "Oshibka FR 0xC0",
  "Oshibka FR 0xC2",
  "Oshibka FR 0xC4",
  "Oshibka FR 0xC7",
  "Oshibka FR 0xC8"
};
  
TDataDescStruct const JournalErrorNumberDescEng = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  EVENT_RECORDS_COUNT,             // размер массива
  &EventJournalIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, EventRecords[0].event),                // указатель на переменную или адрес FRAM
  (void*)&ErrorNumberRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(TEventRecord),       // смещение между элементами в массиве
  NULL,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  (void*)ErrorNumberList1,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


TDataDescStruct const JournalErrorNumberDescCode = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  EVENT_RECORDS_COUNT,             // размер массива
  &EventJournalIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, EventRecords[0].event),                // указатель на переменную или адрес FRAM
  NULL,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(TEventRecord),       // смещение между элементами в массиве
  NULL,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

TDataDescStruct const JournalErrorNumberDescTime = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  EVENT_RECORDS_COUNT,             // размер массива
  &EventJournalIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, EventRecords[0].time),                // указатель на переменную или адрес FRAM
  NULL,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(TEventRecord),       // смещение между элементами в массиве
  NULL,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Индекс при просмотре журнала событий
*************************************/
TRangeValueULONG const EventJournalIndexRange = {0, 0xffffffff};
#if defined(BOARD_SOLARIUM_WEB)
CPU_INT08U const EventJournalIndexName[] = "ЗАПИСЬ #";
#else
CPU_INT08U const EventJournalIndexName[] = "Запись #";
#endif
CPU_INT32U EventJournalIndex = 0;

void OnChangeEventJournalIndex(void)
{
  TEventRecord record;

  if (EventJournalIndex == 0xffffffff) EventJournalIndex = EVENT_RECORDS_COUNT - 1;
  else if (EventJournalIndex > EVENT_RECORDS_COUNT - 1) EventJournalIndex = 0;

  GetEventRecord(&record, EventJournalIndex);
  PrintEventJournalRecord(&record, str_EventNumber, str_EventData);
}

TDataDescStruct const EventJournalIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)&EventJournalIndex,            // указатель на переменную или адрес FRAM
  (void*)&EventJournalIndexRange,     // указатель на границы параметра
  OnChangeEventJournalIndex,                     // функция по изменению
  0,       // смещение между элементами в массиве
  EventJournalIndexName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Время события в журнале событий
*************************************/
TDataDescStruct const JournalEventTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  EVENT_RECORDS_COUNT,             // размер массива
  &EventJournalIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, EventRecords[0].time),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(TEventRecord),       // смещение между элементами в массиве
  NULL,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Системное время
*************************************/
extern CPU_INT32U SystemTime;

TDataDescStruct const SystemTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)&SystemTime,            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  NULL,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


void OnSetTime(void)
{
  TRTC_Data rtc;
  Sec2Date(&rtc, SystemTime);
  RTC_SetTime(&rtc);
}

TDataDescStruct const SystemTimeEditDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_TIME,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)&SystemTime,            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  OnSetTime,                     // функция по изменению
  0,       // смещение между элементами в массиве
  NULL,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  Команда на очистку журналов
*************************************/
CPU_INT32U ClearJournalCmd = 0;

CPU_INT08U const ClearJournalCmdName[] = "Очистка";
CPU_INT08U const ClearJournalCmdList_str0[] = "нет";
CPU_INT08U const ClearJournalCmdList_str1[] = "да";
CPU_INT08U const *ClearJournalCmdList[] = {ClearJournalCmdList_str0, ClearJournalCmdList_str1};

void OnChangeClearJournalCmd(void)
{
  if (ClearJournalCmd)
    {
      ClearEventJournal();
      ClearJournalCmd = 0;
      JournalInit();
    }
}

TDataDescStruct const ClearJournalCmdDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&ClearJournalCmd,                // указатель на переменную или адрес FRAM
  (void*)&InitByDefaultRange,           // указатель на границы параметра
  OnChangeClearJournalCmd,                     // функция по изменению
  0,       // смещение между элементами в массиве
  ClearJournalCmdName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ClearJournalCmdList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};


/*************************************
  Общий счетчик числа запусков
*************************************/
#if defined(BOARD_SOLARIUM_WEB)
CPU_INT08U const CounterRunName[] = "ЗАПУСКИ";
#else
CPU_INT08U const CounterRunName[] = "Запуски";
#endif

TDataDescStruct const CounterRunDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterRun),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterRunName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик денег
*************************************/
CPU_INT08U const CounterMoneyName[] = "Деньги,руб.";
CPU_INT08U const CounterCardName[] = "Банк,руб.";
CPU_INT08U const CounterAbonementName[] = "Абонем.,руб.";

TDataDescStruct const CounterMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterMoney),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterMoneyName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик безнала
*************************************/
TDataDescStruct const CounterCardDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterCard),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterCardName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик абонемента
*************************************/
TDataDescStruct const CounterAbonementDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterAbonement),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterAbonementName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик времени работы
*************************************/
#if defined(BOARD_SOLARIUM_WEB)
CPU_INT08U const CounterTimeName[] = "ВР.РАБ.";
#else
CPU_INT08U const CounterTimeName[] = "Вр.раб.";
#endif

TDataDescStruct const CounterTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_COUNT,     // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterTime),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterTimeName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  Общий счетчик числа запусков ДЛИННЫЙ
*************************************/
TDataDescStruct const CounterLongRunDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterRunLong),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterRunName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик денег ДЛИННЫЙ 
*************************************/
TDataDescStruct const CounterLongMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterMoneyLong),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterMoneyName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик безнала ДЛИННЫЙ 
*************************************/
TDataDescStruct const CounterLongCardDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterCardLong),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterCardName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик абонемента ДЛИННЫЙ 
*************************************/
TDataDescStruct const CounterLongAbonementDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterAbonementLong),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterAbonementName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общий счетчик времени работы
*************************************/
TDataDescStruct const CounterLongTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_COUNT,     // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterTimeLong),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterTimeName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик числа запусков
*************************************/
TDataDescStruct const CounterChannelRunDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterChannelRun[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterRunName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик денег
*************************************/
TDataDescStruct const CounterChannelMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,              // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterChannelMoney[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterMoneyName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик безнала
*************************************/
TDataDescStruct const CounterChannelCardDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,              // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterChannelCard[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterCardName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик абонемента
*************************************/
TDataDescStruct const CounterChannelAbonementDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,              // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterChannelAbonement[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterCardName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик времени работы
*************************************/
TDataDescStruct const CounterChannelTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_COUNT,     // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterChannelTime),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterTimeName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  Канальный счетчик числа запусков
*************************************/
TDataDescStruct const CounterChannelRunLongDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterChannelRunLong[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterRunName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик денег
*************************************/
TDataDescStruct const CounterChannelMoneyLongDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,              // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterChannelMoneyLong[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterMoneyName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик безнала
*************************************/
TDataDescStruct const CounterChannelCardLongDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,              // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterChannelCardLong[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterCardName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик безнала
*************************************/
TDataDescStruct const CounterChannelAbonementLongDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,              // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterChannelAbonementLong[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterAbonementName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Канальный счетчик времени работы
*************************************/
TDataDescStruct const CounterChannelTimeLongDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_COUNT,     // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelStIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CountersLong.CounterChannelTimeLong),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterTimeName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Команда на очистку статистики 
*************************************/
CPU_INT32U ClearStatCmd = 0;

CPU_INT08U const ClearStatCmdName[] = "Очистка";

#if defined(BOARD_SOLARIUM_VLAD)
extern void SolarClearAllCounters(void);
extern void SolarClearLampsCounters(CPU_INT08U ch);
#endif

void OnChangeClearStatCmd(void)
{
  if (ClearStatCmd)
    {
      ClearCounters();
#if defined(BOARD_SOLARIUM_VLAD)
      SolarClearAllCounters();
#endif
      ClearStatCmd = 0;
    }
}

TDataDescStruct const ClearStatCmdDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&ClearStatCmd,                // указатель на переменную или адрес FRAM
  (void*)&InitByDefaultRange,           // указатель на границы параметра
  OnChangeClearStatCmd,                     // функция по изменению
  0,       // смещение между элементами в массиве
  ClearJournalCmdName,             // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ClearJournalCmdList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};


/*************************************
  Разрешение автоматического закрытия смен
*************************************/
TRangeValueULONG const EnableFiscalDayClearRange = {0, 1};
CPU_INT08U const EnableFiscalDayClearName[] = "Закр.смены";
CPU_INT08U const *EnableFiscalDayClearList[] = {"Руч.", "Авто", "Буфер"};

TDataDescStruct const EnableFiscalDayClearDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnableFiscalDayClear),            // указатель на переменную или адрес FRAM
  (void*)&EnableFiscalDayClearRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableFiscalDayClearName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableFiscalDayClearList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           // значение по умолчанию
};


/*************************************
  Настройка чека
*************************************/
TRangeValueULONG const BillFormatRange = {0, 1};
CPU_INT08U const BillFormatName[] = "Чек:";
CPU_INT08U const BillFormatList_str0[] = "кол-во*цена";
CPU_INT08U const BillFormatList_str1[] = "сумма";
CPU_INT08U const *BillFormatList[] = {BillFormatList_str0, BillFormatList_str1};

TDataDescStruct const BillFormatDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.BillFormat),            // указатель на переменную или адрес FRAM
  (void*)&BillFormatRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  BillFormatName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  BillFormatList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Система налогообложения
*************************************/
TRangeValueULONG const TaxSystemRange = {0, 5};
CPU_INT08U const TaxSystemName[] = "Система нал.";
CPU_INT08U const TaxSystemList_str0[] = "ОСН";
CPU_INT08U const TaxSystemList_str1[] = "УСН д";
CPU_INT08U const TaxSystemList_str2[] = "УСН д-р";
CPU_INT08U const TaxSystemList_str3[] = "ЕНВД";
CPU_INT08U const TaxSystemList_str4[] = "ЕСП";
CPU_INT08U const TaxSystemList_str5[] = "ПСН";

CPU_INT08U const *TaxSystemList[] = {TaxSystemList_str0, TaxSystemList_str1, TaxSystemList_str2, TaxSystemList_str3, TaxSystemList_str4, TaxSystemList_str5};

TDataDescStruct const TaxSystemDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, TaxSystem),            // указатель на переменную или адрес FRAM
  (void*)&TaxSystemRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  TaxSystemName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  TaxSystemList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Индекс налога
*************************************/
TRangeValueULONG const TaxFormatRange = {0, 6};
CPU_INT08U const TaxFormatName[] = "Налог:";
CPU_INT08U const TaxFormatList_str0[] = "откл.";
CPU_INT08U const TaxFormatList_str1[] = "  1  ";
CPU_INT08U const TaxFormatList_str2[] = "  2  ";
CPU_INT08U const TaxFormatList_str3[] = "  3  ";
CPU_INT08U const TaxFormatList_str4[] = "  4  ";
CPU_INT08U const TaxFormatList_str5[] = "  5  ";
CPU_INT08U const TaxFormatList_str6[] = "  6  ";
CPU_INT08U const *TaxFormatList[] = {TaxFormatList_str0, TaxFormatList_str1, TaxFormatList_str2, TaxFormatList_str3, TaxFormatList_str4, TaxFormatList_str5, TaxFormatList_str6};

TDataDescStruct const TaxFormatDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, TaxFormat),            // указатель на переменную или адрес FRAM
  (void*)&TaxFormatRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  TaxFormatName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  TaxFormatList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Предмет расчета
*************************************/
TRangeValueULONG const SubjSellRange = {0, 2};
CPU_INT08U const SubjSellName[] = "Предм.расчета";
CPU_INT08U const SubjSellList_str0[] = "ТОВАР";
CPU_INT08U const SubjSellList_str1[] = "РАБОТА";
CPU_INT08U const SubjSellList_str2[] = "УСЛУГА";
CPU_INT08U const *SubjSellList[] = {SubjSellList_str0, SubjSellList_str1, SubjSellList_str2};

TDataDescStruct const SubjSellDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SubjSell),            // указатель на переменную или адрес FRAM
  (void*)&SubjSellRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  SubjSellName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  SubjSellList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Тип команд работы с чеком
*************************************/
TRangeValueULONG const CommandV2Range = {0, 1};
CPU_INT08U const CommandV2Name[] = "Тип команд";
CPU_INT08U const CommandV2List_str0[] = "старый";
CPU_INT08U const CommandV2List_str1[] = "V2";
CPU_INT08U const *CommandV2List[] = {CommandV2List_str0, CommandV2List_str1};

TDataDescStruct const CommandV2Desc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, CommandV2),            // указатель на переменную или адрес FRAM
  (void*)&CommandV2Range,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  CommandV2Name,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  CommandV2List,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1                           
};

/*************************************
  Название услуги
*************************************/
TRangeValueULONG const ServiceNameRange = {0, 1};
CPU_INT08U const ServiceNameName[] = "";
#if defined(BOARD_SOLARIUM_VLAD)
CPU_INT08U const *ServiceNameList[] = {"Услуги загара в солярии", "Услуги"};
#else
CPU_INT08U const *ServiceNameList[] = {"Услуги мойки", "Услуги"};
#endif

TDataDescStruct const ServiceNameDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.ServiceName),            // указатель на переменную или адрес FRAM
  (void*)&ServiceNameRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  ServiceNameName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ServiceNameList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           // значение по умолчанию
};

/*************************************
  Дескриптор для энергонезависимого сохранения текущих денег
*************************************/
TDataDescStruct const AcceptedMoneyDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FRAM_AcceptedMoney),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Дескриптор Crc16 энергонезависимого сохранения текущих денег
*************************************/
TDataDescStruct const AcceptedMoneyCRC16Desc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, crc_AcceptedMoney),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  Дескриптор пароля
*************************************/
TRangeValueULONG const PassRange = {0, 9999};
CPU_INT08U const PassName[] = "ПАРОЛb";

void OnChangePass(void)
{
  // обновим CRC пароля  
  CPU_INT32U pass,crc;
  GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX);      
  crc = crc16((unsigned char*)&pass, sizeof(CPU_INT32U));
  SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX);
}

TDataDescStruct const PassDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Pass),            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangePass,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&PassName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  DEFAULT_PASSWORD                           
};

CPU_INT08U const PassNameAdmin[] = "АДМИН.";

TDataDescStruct const PassDescAdmin = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Pass),            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangePass,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&PassNameAdmin,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  DEFAULT_PASSWORD                           
};

/*************************************
  Дескриптор CRC пароля
*************************************/
TDataDescStruct const PassCRCDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, crc_Pass),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Дескриптор временного пароля
*************************************/
CPU_INT32U TempPass = 0;

#if defined(BOARD_SOLARIUM_VLAD)
extern void PrintHelloMenu(void);
extern void PrintSelectChMenu(CPU_INT08U blink);
#endif

void OnChangeTempPass(void)
{
  CPU_INT32U pass;
  GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX);
    
  if (GetCurrentMenu() == SetPassMenuPanel)
  { 
      #if defined(BOARD_SOLARIUM_VLAD)
      // установка нового пароля
      if (pass != TempPass)
      {
        SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass);
        GoToPreviousMenu(); GoToMenu(ErrorPassPanel);
      }
      else {GoToPreviousMenu(); GoToMenu(AllPasswordsMenuPanel);}
      #else
      // установка нового пароля
      if (pass != TempPass)
      {
        SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass);
        GoToPreviousMenu(); GoToMenu(ErrorPassPanel);
      }
      else {GoToPreviousMenu(); GoToMenu(SetNewPassMenuPanel);}
      #endif
  }
  else if (GetCurrentMenu() == ResetSettingsMenuPanel)
    { // сброс настроек
      if (pass != TempPass) 
      {
        SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass);
        GoToPreviousMenu(); GoToMenu(ErrorPassPanel);
      }
      else {InitByDefault = 1; OnChangeInitByDefault(); GoToPreviousMenu(); GoToMenu(SettingsIsReset);}
    }
  else if (GetCurrentMenu() == ClearStatMenu)
    { // очистка статистики
      if (pass != TempPass)
      {
        SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass);
        GoToPreviousMenu(); GoToMenu(ErrorPassPanel);
      }
      else
      {
          #ifdef CONFIG_FTP_CLIENT_ENABLE
          CPU_INT32U enabled;
          GetData(&FtpEnableDesc, &enabled, 0, DATA_FLAG_SYSTEM_INDEX);
          if (enabled)
          {
              time_to_ftp |= FTP_FLAG_SEND_COUNTERS | FTP_FLAG_CLEAR_COUNTERS;
              GoToPreviousMenu(); 
              GoToMenu(FtpUploadInProgressMenu);
          }
          else
          #endif
          {
              ClearStatCmd = 1; 
              OnChangeClearStatCmd(); 
              GoToPreviousMenu(); 
              GoToMenu(StatIsReset);
          }
      }
    }
  else if (GetCurrentMenu() == ClearJournalMenuPanel)
    { // очистка журнала
      if (pass != TempPass) 
      {
        SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass);
        GoToPreviousMenu(); GoToMenu(ErrorPassPanel);
      }
      else
      {
          #ifdef CONFIG_FTP_CLIENT_ENABLE
          CPU_INT32U enabled;
          GetData(&FtpEnableDesc, &enabled, 0, DATA_FLAG_SYSTEM_INDEX);
          if (enabled)
          {
              time_to_ftp |= FTP_FLAG_SEND_COUNTERS | FTP_FLAG_CLEAR_LOGS;
              GoToPreviousMenu(); 
              GoToMenu(FtpUploadInProgressMenu);
          }
          else
          #endif
          {
              ClearJournalCmd = 1; 
              OnChangeClearJournalCmd(); 
              GoToPreviousMenu(); 
              GoToMenu(JournalIsReset);
          }
      }
    }
#if defined(BOARD_SOLARIUM_VLAD)
  else if (GetCurrentMenu() == ReqCleaningPassMenuPanel)
  {
      GetData(&PassDescCleaning, &pass, 0, DATA_FLAG_SYSTEM_INDEX);
      if (pass == TempPass)
      {
        PostUserEvent(EVENT_PASS_OK);
      }
      else
      {
        PostUserEvent(EVENT_PASS_FAIL);
      }
  }
  else if (GetCurrentMenu() == ReqServicePassMenuPanel)
  {
      GetData(&PassDescService, &pass, 0, DATA_FLAG_SYSTEM_INDEX);
      if (pass == TempPass)
      {
        PostUserEvent(EVENT_PASS_OK);
      }
      else
      {
        PostUserEvent(EVENT_PASS_FAIL);
      }
  }
  else if (GetCurrentMenu() == ReqTestPassMenuPanel)
  {
      GetData(&PassDescTest, &pass, 0, DATA_FLAG_SYSTEM_INDEX);
      if (pass == TempPass)
      {
        PostUserEvent(EVENT_PASS_OK);
      }
      else
      {
        PostUserEvent(EVENT_PASS_FAIL);
      }
  }
  else if (GetCurrentMenu() == ClearLampsMenu)
  {
      if (pass != TempPass)
      {
        SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass);
        GoToPreviousMenu(); GoToMenu(ErrorPassPanel);
      }
      else
      {
          SolarClearLampsCounters(ChannelIndex);
          GoToPreviousMenu();
      }
  }
  else if (GetCurrentMenu() == ReqStartupPassMenuPanel)
  {
      if (pass != TempPass)
      {
          start_pass_ok = 0;
          SaveEventRecord(0, JOURNAL_EVENT_PASS_FAIL, TempPass);
          GoToMenu(ErrorPassPanel);
      }
      else
      {
          start_pass_ok = 1;
          if (GetMode() == MODE_WORK) {SetMenu(WORK_MENU);}
          else SetMenu(SERVICE_MENU);
      }
  }
#endif
  
}

TDataDescStruct const PassTempDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&TempPass,            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangeTempPass,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&PassName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

#if defined(BOARD_CENTRAL_CARWASH)
CPU_INT08U const PassTempName1[] = "    ПАРОЛb";
#else
CPU_INT08U const PassTempName1[] = "ПАРОЛb";
#endif

TDataDescStruct const PassTempDesc1 = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&TempPass,            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangeTempPass,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&PassTempName1,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

TRangeValueULONG const MasterPassRange = {0, 4000000000};
CPU_INT08U const MasterPassTempName[] = "ПАРОЛb";

void OnChangeMasterPass(void)
{
    CPU_INT32U pass, crc;
        
    if (TempPass == MASTER_PASSWORD)
    {
        TempPass = 0;
        pass = DEFAULT_PASSWORD;
        crc = crc16((unsigned char*)&pass, sizeof(CPU_INT32U));
        SetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX);
        SetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX);
        
        GoToPreviousMenu();
        GoToPreviousMenu();
        GoToMenu(SetNewPassMenuPanel);
    }
}

TDataDescStruct const MasterPassTempDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&TempPass,            // указатель на переменную или адрес FRAM
  (void*)&MasterPassRange,                     // указатель на границы параметра
  OnChangeMasterPass,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&MasterPassTempName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

#if !defined(BOARD_SOLARIUM_WEB)
    CPU_INT08U const PassTempName2[] = "   ПАРОЛb";
#endif

TDataDescStruct const PassTempDesc2 = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)&TempPass,            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangeTempPass,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  #if !defined(BOARD_SOLARIUM_WEB)
  (void*)&PassTempName2,           // указатель на строку названия параметра
  #else 
  NULL,
  #endif
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Команда послать тестовое сообщение
*************************************/
CPU_INT08U const SendTestEmailName[] = "Отпр.тест";
CPU_INT32U send_test;

void OnChangeSendTestEmail(void)
{
    if (send_test)
    {
        PostModemTask(MODEM_TASK_SEND_TEST_MSG);
        send_test = 0;
    }
}

TDataDescStruct const SendTestEmailDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)&send_test,            // указатель на переменную или адрес FRAM
  (void*)&EnableEmailErrorSendRange,     // указатель на границы параметра
  OnChangeSendTestEmail,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  SendTestEmailName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  DisableFiscalErrorsList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};


/*************************************
  Индекс номинала купюры для просмотра счетчиков по номиналам
*************************************/
CPU_INT32U  BillnomViewIndex;
TRangeValueULONG const BillnomIndexRange = {0, 23};
CPU_INT08U const BillnomName[] = "   НОМИНАЛ #";
CPU_INT08U const* BillnomItems[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                                    "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24"};

TDataDescStruct const BillnomIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  &BillnomViewIndex,            // указатель на переменную или адрес FRAM
  (void*)&BillnomIndexRange,       // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  BillnomName,         // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  BillnomItems,             // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Значение номинала купюры для просмотра счетчиков
*************************************/
extern CPU_INT32U BillNominals[24];
CPU_INT08U const BillnomValName[] = "Значение,руб.";

TDataDescStruct const BillnomDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  24,                       // размер массива
  (void*)&BillnomIndexDesc,        // указатель на дескриптор индекса массива
  (void*)&BillNominals,            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  BillnomValName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Счетчики номиналов купюр в купюрнике
*************************************/
CPU_INT08U const BillnomCountersName[] = "Кол-во";

TDataDescStruct const BillnomCountersDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  24,                        // размер массива
  &BillnomIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.CounterBillNominals[0]),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  BillnomCountersName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Общее количество купюр в купюрнике
*************************************/
CPU_INT08U const BillCounterName[] = "Всего купюр";

TDataDescStruct const BillCounterDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, Counters.BillsCount),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  BillCounterName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  ID устройства 
*************************************/
CPU_INT08U const DeviceIDName[] = "ID уст-ва";
TRangeValueULONG const DeviceIDRange = {0, 9999};

TDataDescStruct const DeviceIDDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.DeviceId),            // указатель на переменную или адрес FRAM
  (void*)&DeviceIDRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  DeviceIDName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Признак отправки сообщения об инкассации
*************************************/
TDataDescStruct const IncasSendFlagDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, IncasEmailFlag),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Деньги от последней инкассации
*************************************/
TDataDescStruct const IncasMoneyDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, IncasMoney),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  IP-адрес свой
*************************************/
void OnChangeIpMask()
{
    CPU_INT32U ip, mask;
    GetData(&IpAddrDesc, &ip, 0, DATA_FLAG_SYSTEM_INDEX);  
    GetData(&NetMaskDesc, &mask, 0, DATA_FLAG_SYSTEM_INDEX);  
    NetIP_CfgAddrThisHost(ip, mask);
}
#if defined(BOARD_SOLARIUM_WEB)    
CPU_INT08U const IpAddrName[] = "АДРЕС";
#else
CPU_INT08U const IpAddrName[] = "IP";
#endif

TDataDescStruct const IpAddrDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ip),            // указатель на переменную или адрес FRAM
  (void*)&DeferredStartRange,     // указатель на границы параметра
  OnChangeIpMask,                     // функция по изменению
  0,       // смещение между элементами в массиве
  IpAddrName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  DeferredStartList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
#if defined(BOARD_SOLARIUM_WEB)
  0xC0A800FA
#else
  0xC0A80064
#endif
};

/*************************************
  Меска сети
*************************************/
#if defined(BOARD_SOLARIUM_WEB)
CPU_INT08U const NetMaskName[] = "МАСКА";
#else
CPU_INT08U const NetMaskName[] = "MSK";
#endif

TDataDescStruct const NetMaskDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, netmask),            // указатель на переменную или адрес FRAM
  (void*)&DeferredStartRange,     // указатель на границы параметра
  OnChangeIpMask,                     // функция по изменению
  0,       // смещение между элементами в массиве
  NetMaskName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  DeferredStartList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0xFFFF0000
};

/*************************************
  Шлюз
*************************************/

void OnChangeGateway()
{
    CPU_INT32U gw;
    GetData(&GatewayDesc, &gw, 0, DATA_FLAG_SYSTEM_INDEX);  
    NetIP_CfgAddrDfltGateway(gw);
}

#if defined(BOARD_SOLARIUM_WEB)
CPU_INT08U const GatewayName[] = "ШЛЮЗ";
#else 
CPU_INT08U const GatewayName[] = "GW";
#endif

TDataDescStruct const GatewayDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, gateway),            // указатель на переменную или адрес FRAM
  (void*)&DeferredStartRange,     // указатель на границы параметра
  OnChangeGateway,                     // функция по изменению
  0,       // смещение между элементами в массиве
  GatewayName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  DeferredStartList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0xC0A80001
};

/*************************************
  Время последней инкассации
*************************************/
TDataDescStruct const IncasTimeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, IncasTime),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Включить печать отчетов открытия/закрытия смены на бумагу
*************************************/
TRangeValueULONG const EnablePrintReportsRange = {0, 1};
CPU_INT08U const EnablePrintReportsName[] = "Печать отчетов";
CPU_INT08U const *EnablePrintReportsList[] = {OnOffList_str0, OnOffList_str1};

TDataDescStruct const EnablePrintReportsDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.EnablePrintReports),            // указатель на переменную или адрес FRAM
  (void*)&EnablePrintReportsRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnablePrintReportsName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnablePrintReportsList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1                           
};


/*************************************
  Порт для подключения к банковскому терминалу
*************************************/
TRangeValueULONG const TermPortRange = {1, 65535};
CPU_INT08U const TermPortName[] = "Порт";

TDataDescStruct const TerminalPortDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,             // размер массива
  NULL,     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.terminal_port),            // указатель на переменную или адрес FRAM
  (void*)&TermPortRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  TermPortName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  62801                          // значение по умолчанию
};

/*************************************
  Использовать банковский терминал
*************************************/
TRangeValueULONG const EnableTerminalRange = {0, 1};
CPU_INT08U const EnableTerminalName[] = "Включить";
CPU_INT08U const *EnableTerminalList[] = {OnOffList_str0, OnOffList_str1};

TDataDescStruct const EnableTerminalDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.terminal_enable),            // указатель на переменную или адрес FRAM
  (void*)&EnableTerminalRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableTerminalName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableTerminalList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

#if defined(CONFIG_TERMINAL_ENABLE)
/*************************************
  Протокол банковского терминала
*************************************/
TRangeValueULONG const TerminalProtocolRange = {0, 1};
CPU_INT08U const TerminalProtocolName[] = "Протокол";
CPU_INT08U const TerminalProtocol_str0[] = "ttk2";
CPU_INT08U const TerminalProtocol_str1[] = "vtk";
CPU_INT08U const *TerminalProtocolList[] = {TerminalProtocol_str0, TerminalProtocol_str1};

void OnChangeTerminalProtocolDesc(void)
{
    CPU_INT32U port;
    CPU_INT32U proto;
    GetData(&TerminalProtocolDesc, &proto, 0, DATA_FLAG_SYSTEM_INDEX);
    if (proto == TERMINAL_PROTOCOL_TTK2)
    {
        port = 62501;
        SetData(&TerminalPortDesc, &port, 0, DATA_FLAG_SYSTEM_INDEX);
    }
    else if (proto == TERMINAL_PROTOCOL_VTK)
    { 
        port = 62801;
        SetData(&TerminalPortDesc, &port, 0, DATA_FLAG_SYSTEM_INDEX);
    }
}

TDataDescStruct const TerminalProtocolDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, TerminalProtocol),            // указатель на переменную или адрес FRAM
  (void*)&TerminalProtocolRange,     // указатель на границы параметра
  OnChangeTerminalProtocolDesc,                     // функция по изменению
  0,       // смещение между элементами в массиве
  TerminalProtocolName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  TerminalProtocolList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
#if defined(BOARD_SOLARIUM_VLAD)
  TERMINAL_PROTOCOL_VTK
#else
  TERMINAL_PROTOCOL_TTK2
#endif 
  
};
char const TerminalProtocolDescId[] = "TerminalProtocolDesc";
#endif

/*************************************
  Индекс кнопки для назначения суммы
*************************************/
CPU_INT32U  KeyMoneyIndex = 0;
TRangeValueULONG const KeyMoneyRange = {0, MONEY_KEY_COUNT - 1};
CPU_INT08U const KeyMoneyName[] = "   КНОПКА";
CPU_INT08U const* KeyMoneyItems[] = {"1", "2", "3", "4", "5", "6", "7", "8"};

TDataDescStruct const KeyMoneyDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,             // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  &KeyMoneyIndex,            // указатель на переменную или адрес FRAM
  (void*)&KeyMoneyRange,       // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  KeyMoneyName,         // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  KeyMoneyItems,             // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};

/*************************************
  Назначение количества денег на кнопки для банковского терминала
*************************************/
TRangeValueULONG const SelectedMoneyRange = {0, 10000};
CPU_INT08U const SelectedMoneyName[] = "Сумма";

TDataDescStruct const SelectedMoneyDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  MONEY_KEY_COUNT,                        // размер массива
  (void*)&KeyMoneyDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.terminal_money_table[0]),            // указатель на переменную или адрес FRAM
  (void*)&SelectedMoneyRange,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SelectedMoneyName,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};


/*************************************
  Действие для цифровой кнопки
*************************************/
TRangeValueULONG const KeyActionRange = {0, 6};
CPU_INT08U const KeyActionName[] = "Действие";
CPU_INT08U const* KeyActionItems[] = {"Нет", "Влево", "Вправо", "Вниз", "Вверх", "OK", "Отмена"};

void CheckKeysCorrect()
{
    CPU_INT16U crc, crc_calc;
    CPU_INT32U action[MONEY_KEY_COUNT];

    ReadArrayFram(offsetof(TFramMap, DeviceConfig.key_action[0]), sizeof(CPU_INT32U) * MONEY_KEY_COUNT, (unsigned char *)action);
    
    crc_calc = crc16((unsigned char*)action, sizeof(CPU_INT32U) * MONEY_KEY_COUNT);
    ReadArrayFram(offsetof(TFramMap, keys_crc), sizeof(CPU_INT16U), (unsigned char *)&crc);

    if (crc_calc != crc)
    {
        CPU_INT32U action;
        
        action = KEY_ACTION_UP;
        SetData(&KeyActionDesc, &action, 0, DATA_FLAG_DIRECT_INDEX);   
        action = KEY_ACTION_DOWN;
        SetData(&KeyActionDesc, &action, 1, DATA_FLAG_DIRECT_INDEX);   
        action = KEY_ACTION_EMPTY;
        SetData(&KeyActionDesc, &action, 2, DATA_FLAG_DIRECT_INDEX);   
        action = KEY_ACTION_LEFT;
        SetData(&KeyActionDesc, &action, 3, DATA_FLAG_DIRECT_INDEX);   
        action = KEY_ACTION_RIGHT;
        SetData(&KeyActionDesc, &action, 4, DATA_FLAG_DIRECT_INDEX);   
        action = KEY_ACTION_EMPTY;
        SetData(&KeyActionDesc, &action, 5, DATA_FLAG_DIRECT_INDEX);   
        action = KEY_ACTION_EMPTY;
        SetData(&KeyActionDesc, &action, 6, DATA_FLAG_DIRECT_INDEX);   
        action = KEY_ACTION_EMPTY;
        SetData(&KeyActionDesc, &action, 7, DATA_FLAG_DIRECT_INDEX);   
        ReadArrayFram(offsetof(TFramMap, DeviceConfig.key_action[0]), sizeof(CPU_INT32U) * MONEY_KEY_COUNT, (unsigned char *)action);
        crc_calc = crc16((unsigned char*)action, sizeof(CPU_INT32U) * MONEY_KEY_COUNT);
        WriteArrayFram(offsetof(TFramMap, keys_crc), sizeof(CPU_INT16U), (unsigned char *)&crc_calc);
    }
}

void OnChangeKeyAction()
{
    const CPU_INT32U mustbe[4] = {KEY_ACTION_DOWN, KEY_ACTION_UP};

    // отслеживаем - всегда должны быть стрелочки
    for (int i = 0; i < 2; i++)
    {
        int fix = 1;
        for (int key = 0; key < MONEY_KEY_COUNT - 2; key++)
        {
            CPU_INT32U action;
            GetData(&KeyActionDesc, &action, key, DATA_FLAG_DIRECT_INDEX);   
            if (action == mustbe[i])
            {
                fix = 0;
                break;
            }
        }
        if (fix)
        {
            for (int key = 0; key < MONEY_KEY_COUNT - 2; key++)
            {
                CPU_INT32U action;
                GetData(&KeyActionDesc, &action, key, DATA_FLAG_DIRECT_INDEX);   
                if (action == KEY_ACTION_EMPTY)
                {
                    action = mustbe[i];
                    SetData(&KeyActionDesc, &action, key, DATA_FLAG_DIRECT_INDEX);   
                    break;
                }
            }
        }
    }

    CPU_INT32U action[MONEY_KEY_COUNT];
    ReadArrayFram(offsetof(TFramMap, DeviceConfig.key_action[0]), sizeof(CPU_INT32U) * MONEY_KEY_COUNT, (unsigned char *)action);
    CPU_INT16U crc_calc = crc16((unsigned char*)action, sizeof(CPU_INT32U) * MONEY_KEY_COUNT);
    WriteArrayFram(offsetof(TFramMap, keys_crc), sizeof(CPU_INT16U), (unsigned char *)&crc_calc);
}


TDataDescStruct const KeyActionDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  MONEY_KEY_COUNT,                        // размер массива
  (void*)&KeyMoneyDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DeviceConfig.key_action[0]),            // указатель на переменную или адрес FRAM
  (void*)&KeyActionRange,                     // указатель на границы параметра
  OnChangeKeyAction,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  KeyActionName,           // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  KeyActionItems,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  KEY_ACTION_EMPTY                           
};



/*************************************
  Параметра ТАЙМЕР ПОСТА (выдача не по количеству импульсов, а по длине заданного уровня сигнала)
*************************************/
TRangeValueULONG const PostTimerRange = {0, 60};
CPU_INT08U const PostTimerName[] = "Таймер";
CPU_INT08U const PostTimer_str00[] = "откл.";
CPU_INT08U const PostTimer_str01[] = "1 сек."; CPU_INT08U const PostTimer_str02[] = "2 сек."; CPU_INT08U const PostTimer_str03[] = "3 сек."; CPU_INT08U const PostTimer_str04[] = "4 сек.";
CPU_INT08U const PostTimer_str05[] = "5 сек."; CPU_INT08U const PostTimer_str06[] = "6 сек."; CPU_INT08U const PostTimer_str07[] = "7 сек."; CPU_INT08U const PostTimer_str08[] = "8 сек.";
CPU_INT08U const PostTimer_str09[] = "9 сек."; CPU_INT08U const PostTimer_str10[] = "10 сек."; CPU_INT08U const PostTimer_str11[] = "11 сек."; CPU_INT08U const PostTimer_str12[] = "12 сек.";
CPU_INT08U const PostTimer_str13[] = "13 сек."; CPU_INT08U const PostTimer_str14[] = "14 сек."; CPU_INT08U const PostTimer_str15[] = "15 сек."; CPU_INT08U const PostTimer_str16[] = "16 сек.";
CPU_INT08U const PostTimer_str17[] = "17 сек."; CPU_INT08U const PostTimer_str18[] = "18 сек."; CPU_INT08U const PostTimer_str19[] = "19 сек."; CPU_INT08U const PostTimer_str20[] = "20 сек.";
CPU_INT08U const PostTimer_str21[] = "21 сек."; CPU_INT08U const PostTimer_str22[] = "22 сек."; CPU_INT08U const PostTimer_str23[] = "23 сек."; CPU_INT08U const PostTimer_str24[] = "24 сек.";
CPU_INT08U const PostTimer_str25[] = "25 сек."; CPU_INT08U const PostTimer_str26[] = "26 сек."; CPU_INT08U const PostTimer_str27[] = "27 сек."; CPU_INT08U const PostTimer_str28[] = "28 сек.";
CPU_INT08U const PostTimer_str29[] = "29 сек."; CPU_INT08U const PostTimer_str30[] = "30 сек."; CPU_INT08U const PostTimer_str31[] = "31 сек."; CPU_INT08U const PostTimer_str32[] = "32 сек.";
CPU_INT08U const PostTimer_str33[] = "33 сек."; CPU_INT08U const PostTimer_str34[] = "34 сек."; CPU_INT08U const PostTimer_str35[] = "35 сек."; CPU_INT08U const PostTimer_str36[] = "36 сек.";
CPU_INT08U const PostTimer_str37[] = "37 сек."; CPU_INT08U const PostTimer_str38[] = "38 сек."; CPU_INT08U const PostTimer_str39[] = "39 сек."; CPU_INT08U const PostTimer_str40[] = "40 сек.";
CPU_INT08U const PostTimer_str41[] = "41 сек."; CPU_INT08U const PostTimer_str42[] = "42 сек."; CPU_INT08U const PostTimer_str43[] = "43 сек."; CPU_INT08U const PostTimer_str44[] = "44 сек.";
CPU_INT08U const PostTimer_str45[] = "45 сек."; CPU_INT08U const PostTimer_str46[] = "46 сек."; CPU_INT08U const PostTimer_str47[] = "47 сек."; CPU_INT08U const PostTimer_str48[] = "48 сек.";
CPU_INT08U const PostTimer_str49[] = "49 сек."; CPU_INT08U const PostTimer_str50[] = "50 сек."; CPU_INT08U const PostTimer_str51[] = "51 сек."; CPU_INT08U const PostTimer_str52[] = "52 сек.";
CPU_INT08U const PostTimer_str53[] = "53 сек."; CPU_INT08U const PostTimer_str54[] = "54 сек."; CPU_INT08U const PostTimer_str55[] = "55 сек."; CPU_INT08U const PostTimer_str56[] = "56 сек.";
CPU_INT08U const PostTimer_str57[] = "57 сек."; CPU_INT08U const PostTimer_str58[] = "58 сек."; CPU_INT08U const PostTimer_str59[] = "59 сек."; CPU_INT08U const PostTimer_str60[] = "60 сек.";

CPU_INT08U const *PostTimerList[61] = {PostTimer_str00,
                                       PostTimer_str01, PostTimer_str02, PostTimer_str03, PostTimer_str04, PostTimer_str05, PostTimer_str06, PostTimer_str07, PostTimer_str08, PostTimer_str09, PostTimer_str10,
                                       PostTimer_str11, PostTimer_str12, PostTimer_str13, PostTimer_str14, PostTimer_str15, PostTimer_str16, PostTimer_str17, PostTimer_str18, PostTimer_str19, PostTimer_str20,
                                       PostTimer_str21, PostTimer_str22, PostTimer_str23, PostTimer_str24, PostTimer_str25, PostTimer_str26, PostTimer_str27, PostTimer_str28, PostTimer_str29, PostTimer_str30,
                                       PostTimer_str31, PostTimer_str30, PostTimer_str33, PostTimer_str34, PostTimer_str35, PostTimer_str36, PostTimer_str37, PostTimer_str38, PostTimer_str39, PostTimer_str40,
                                       PostTimer_str41, PostTimer_str42, PostTimer_str43, PostTimer_str44, PostTimer_str45, PostTimer_str46, PostTimer_str47, PostTimer_str48, PostTimer_str49, PostTimer_str50,
                                       PostTimer_str51, PostTimer_str52, PostTimer_str53, PostTimer_str54, PostTimer_str55, PostTimer_str56, PostTimer_str57, PostTimer_str58, PostTimer_str59, PostTimer_str60
};


void OnChangePostTimerDesc()
{
#if defined(BOARD_CENTRAL_CARWASH)
    PostUserEvent(EVENT_REREAD_SIGNAL_LEVEL);
#endif
}

TDataDescStruct const PostTimerDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.timer),            // указатель на переменную или адрес FRAM
  (void*)&PostTimerRange,     // указатель на границы параметра
  OnChangePostTimerDesc,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostTimerName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  PostTimerList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           // значение по умолчанию
};



/*************************************
  Параметра СИГНАЛ ПОСТА (уровень активного сигнала)
*************************************/
TRangeValueULONG const PostSignalRange = {0, 1};
CPU_INT08U const PostSignalName[] = "Сигнал";
CPU_INT08U const PostSignal_str00[] = "LOW";
CPU_INT08U const PostSignal_str01[] = "HIGH";
CPU_INT08U const *PostSignalList[2] = {PostSignal_str00, PostSignal_str01};

void OnChangePostSignalDesc()
{
    CPU_INT32U en, timer;
    GetData(&EnableChannelDesc, &en, ChannelIndex, DATA_FLAG_DIRECT_INDEX);
    GetData(&PostTimerDesc, &timer, ChannelIndex, DATA_FLAG_DIRECT_INDEX);
    if (en && timer)
    {
        CPU_INT32U ip;
        CPU_INT32U signal;
        char str[8];
        GetData(&PostIpAddrDesc, &ip, ChannelIndex, DATA_FLAG_DIRECT_INDEX);  
        GetData(&PostSignalDesc, &signal, ChannelIndex, DATA_FLAG_DIRECT_INDEX);  
        sprintf(str, "%d", signal);
        HostWriteParam(ip, CONSOLE_TCP_DEFAULT_PORT, "SIGNAL", str, HOST_SOCKET_DEFAULT_TIMEOUT);
    }
}

TDataDescStruct const PostSignalDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  &ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ChannelConfig.signal),            // указатель на переменную или адрес FRAM
  (void*)&PostSignalRange,     // указатель на границы параметра
  OnChangePostSignalDesc,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  PostSignalName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  PostSignalList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  1                           // значение по умолчанию
};

#if defined(BOARD_SOLARIUM_WEB)
/*************************************
  Параметр ТИП СОЛЯРИЯ
*************************************/
TRangeValueULONG const SolariumTypeRange = {0, 1};
CPU_INT08U const SolariumTypeName[] = "ТИП";
CPU_INT08U const SolariumType_str00[] = "1 РЕЛЕ";
CPU_INT08U const SolariumType_str01[] = "2 РЕЛЕ";
CPU_INT08U const *SolariumTypeList[2] = {SolariumType_str00, SolariumType_str01};

TDataDescStruct const SolariumTypeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumType),            // указатель на переменную или адрес FRAM
  (void*)&SolariumTypeRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  SolariumTypeName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  SolariumTypeList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           // значение по умолчанию
};

/*************************************
  Параметр ТАЙМАУТ ВОЗВРАТА НА ГЛАВНЫЙ ЭКРАН
*************************************/
TRangeValueULONG const SolariumTimeoutRange = {0, 99};
CPU_INT08U const SolariumTimeoutName[] = "ТАйМАУТ,С";

TDataDescStruct const SolariumTimeoutDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumTimeout),            // указатель на переменную или адрес FRAM
  (void*)&SolariumTimeoutRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  SolariumTimeoutName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  60                           // значение по умолчанию
};

/*************************************
  Параметр ПАУЗА ПЕРЕД СЕАНСОМ
*************************************/
TRangeValueULONG const SolariumPauseRange = {0, 999};
CPU_INT08U const SolariumPauseName[] = "ПАУЗА,С";

TDataDescStruct const SolariumPauseDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumPause),            // указатель на переменную или адрес FRAM
  (void*)&SolariumPauseRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  SolariumPauseName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           // значение по умолчанию
};

/*************************************
  Параметр ВРЕМЯ ВЕНТИЛЯЦИИ
*************************************/
TRangeValueULONG const SolariumVentilationTimeRange = {60, 10*60};
CPU_INT08U const SolariumVentilationTimeName[] = "ВЕНТ.,С";

TDataDescStruct const SolariumVentilationTimeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumVentilationTime),            // указатель на переменную или адрес FRAM
  (void*)&SolariumVentilationTimeRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  SolariumVentilationTimeName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  180                           // значение по умолчанию
};

/*************************************
  Параметр СТОИМОСТЬ МИНУТЫ
*************************************/
TRangeValueULONG const SolariumPricePerMinRange = {1, 1000};
CPU_INT08U const SolariumPricePerMinName[] = "РУБ/1МИН";

TDataDescStruct const SolariumPricePerMinDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumPricePerMin),            // указатель на переменную или адрес FRAM
  (void*)&SolariumPricePerMinRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  SolariumPricePerMinName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  10                          // значение по умолчанию
};

/*************************************
  Параметр МИНИМАЛЬНОЕ ВРЕМЯ ЗАГАРА
*************************************/
TRangeValueULONG const SolariumMinTimeRange = {1, 99};
CPU_INT08U const SolariumMinTimeName[] = "МИН.ВР.,МИН";

TDataDescStruct const SolariumMinTimeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumMinTime),            // указатель на переменную или адрес FRAM
  (void*)&SolariumMinTimeRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  SolariumMinTimeName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  2                          // значение по умолчанию
};

/*************************************
  Параметр МАКСИМАЛЬНОЕ ВРЕМЯ ЗАГАРА
*************************************/
TRangeValueULONG const SolariumMaxTimeRange = {1, 99};
CPU_INT08U const SolariumMaxTimeName[] = "МАКС.ВР.,МИН";

TDataDescStruct const SolariumMaxTimeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumMaxTime),            // указатель на переменную или адрес FRAM
  (void*)&SolariumMaxTimeRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  SolariumMaxTimeName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  19                          // значение по умолчанию
};

/*************************************
  Настройка зуммера
*************************************/
TRangeValueULONG const ZummerEnableRange = {0, 1};
CPU_INT08U const ZummerEnableName[] = "Зуммер";
CPU_INT08U const ZummerEnable_str0[] = "откл";
CPU_INT08U const ZummerEnable_str1[] = "вкл";
CPU_INT08U const *ZummerEnableList[] = {ZummerEnable_str0, ZummerEnable_str1, NULL};

extern CPU_INT08U zummer_enabled;

void OnZummerEnabledChange(void)
{
    CPU_INT32U en = 0;
    GetData(&ZummerEnableDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX);
    if (en) zummer_enabled = 1;
    else zummer_enabled = 0;
}

TDataDescStruct const ZummerEnableDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ZummerEnable),            // указатель на переменную или адрес FRAM
  (void*)&ZummerEnableRange,     // указатель на границы параметра
  OnZummerEnabledChange,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  ZummerEnableName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  ZummerEnableList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

#endif


#if defined(CONFIG_MUSIC_ENABLE)

/*************************************
  Включение звука
*************************************/
TRangeValueULONG const SoundEnableRange = {0, 2};
CPU_INT08U const SoundEnableName[] = "Звук  ";
CPU_INT08U const SoundEnable_str0[] = "откл";
CPU_INT08U const SoundEnable_str1[] = "SD-card";
CPU_INT08U const SoundEnable_str2[] = "Ethernet";
CPU_INT08U const *SoundEnableList[] = {SoundEnable_str0, SoundEnable_str1, SoundEnable_str2, NULL};

void OnChangeMusicIp(void)
{
    CPU_INT32U sound_type;
    GetData(&SoundTypeDesc, &sound_type, 0, DATA_FLAG_SYSTEM_INDEX);
    if (sound_type == 2)
    {
        PostUserEvent(EVENT_STOP_SOUND_FILE);
    }
}

TDataDescStruct const SoundTypeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SoundEnable),            // указатель на переменную или адрес FRAM
  (void*)&SoundEnableRange,     // указатель на границы параметра
  OnChangeMusicIp,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  SoundEnableName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  SoundEnableList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const SoundTypeDescId[] = "SoundTypeDesc";

/*************************************
  IP-адрес ethernet плеера 
*************************************/
CPU_INT08U const MusicIpAddrName[] = "IP";

TDataDescStruct const SoundIpAddrDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  1,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SoundIpAddr),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  OnChangeMusicIp,                     // функция по изменению
  0,       // смещение между элементами в массиве
  MusicIpAddrName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0xC0A800FA
};
char const SoundIpAddrDescId[] = "SoundIpAddrDesc";

/*************************************
  Громкость звука
*************************************/
TRangeValueULONG const SoundVolumeRange = {0, 100};
CPU_INT08U const SoundVolumeName[] = "Громкость";

void OnChangeSoundVolume(void)
{
    CPU_INT32U sound_type;
    GetData(&SoundTypeDesc, &sound_type, 0, DATA_FLAG_SYSTEM_INDEX);
    if (sound_type == 2)
    {
        PostUserEvent(EVENT_UPDATE_MUSIC_VOLUME);
    }
}

TDataDescStruct const SoundVolumeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SoundVolume),            // указатель на переменную или адрес FRAM
  (void*)&SoundVolumeRange,     // указатель на границы параметра
  OnChangeSoundVolume,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  SoundVolumeName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  100
};
char const SoundVolumeDescId[] = "SoundVolumeDesc";

/*************************************
  Статус подключения плеера 
*************************************/
CPU_INT08U const PlayerStatusName[] = "Плеер ";
CPU_INT08U const PlayerStatus_str0[] = "не подключен";
CPU_INT08U const PlayerStatus_str1[] = "ОК";
CPU_INT08U const *PlayerStatusList[] = {PlayerStatus_str0, PlayerStatus_str1};

TDataDescStruct const PlayerStatusDesc = {
  DATA_DESC_VIEW,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &player_conn,            // указатель на переменную или адрес FRAM
  NULL,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  PlayerStatusName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  PlayerStatusList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const PlayerStatusDescId[] = "PlayerStatusDesc";

/*************************************
  Команда проиграть файл из меню
*************************************/
TRangeValueULONG const SoundFileIndexRange = {0, 999};
CPU_INT08U const SoundFileIndexName[] = "Воспр.файл";

CPU_INT32U file_menu_cmd;

void OnChangeSoundFileIndex(void)
{
    if (file_menu_cmd != 0)
    {
        CPU_INT32U sound_type;
        GetData(&SoundTypeDesc, &sound_type, 0, DATA_FLAG_SYSTEM_INDEX);
        if (sound_type == 1)
        {
            PlayMusicFile(file_menu_cmd);
        }
        else if (sound_type == 2)
        {
            PostUserEvent(EVENT_PLAY_SOUND_FILE);
        }
    }
}

TDataDescStruct const SoundFileIndexDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)&file_menu_cmd,            // указатель на переменную или адрес FRAM
  (void*)&SoundFileIndexRange,     // указатель на границы параметра
  OnChangeSoundFileIndex,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  SoundFileIndexName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0
};
char const SoundFileIndexDescId[] = "SoundFileIndexDesc";

#endif

#if defined(CONFIG_SDCARD_ENABLE)
/*************************************
  Статус подключения SD-карты
*************************************/
CPU_INT08U const SdCardStatusName[] = "SD-карта ";
CPU_INT08U const SdCardStatus_str0[] = "не подключена";
CPU_INT08U const SdCardStatus_str1[] = "нет";
CPU_INT08U const SdCardStatus_str2[] = "ошибка";
CPU_INT08U const SdCardStatus_str3[] = "ОК";
CPU_INT08U const *SdCardStatusList[] = {SdCardStatus_str0, SdCardStatus_str1, SdCardStatus_str2, SdCardStatus_str3};

extern CPU_INT32U fat_status;

TDataDescStruct const SdCardStatusDesc = {
  DATA_DESC_VIEW,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &fat_status,            // указатель на переменную или адрес FRAM
  NULL,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  SdCardStatusName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  SdCardStatusList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const SdCardStatusDescId[] = "SdCardStatusDesc";

#endif

#if defined(BOARD_SOLARIUM_VLAD)


void CheckVladPasswords(void)
{
  CPU_INT32U pass[3],crc,crc_fram;
  GetData(&PassDescCleaning, &pass[0], 0, DATA_FLAG_SYSTEM_INDEX);      
  GetData(&PassDescService, &pass[1], 0, DATA_FLAG_SYSTEM_INDEX);      
  GetData(&PassDescTest, &pass[2], 0, DATA_FLAG_SYSTEM_INDEX);      
  crc = crc16((unsigned char*)pass, sizeof(CPU_INT32U) * 3);
  GetData(&PassVladCrc, &crc_fram, 0, DATA_FLAG_SYSTEM_INDEX);
  if (crc != crc_fram)
  {
      pass[0] = 2222;
      pass[1] = 3333;
      pass[2] = 4444;
      crc = crc16((unsigned char*)pass, sizeof(CPU_INT32U) * 3);
      SetData(&PassDescCleaning, &pass[0], 0, DATA_FLAG_SYSTEM_INDEX);      
      SetData(&PassDescService, &pass[1], 0, DATA_FLAG_SYSTEM_INDEX);      
      SetData(&PassDescTest, &pass[2], 0, DATA_FLAG_SYSTEM_INDEX);      
      SetData(&PassVladCrc, &crc, 0, DATA_FLAG_SYSTEM_INDEX);
  }
}

void OnChangePassModes(void)
{
  CPU_INT32U pass[3],crc;
  GetData(&PassDescCleaning, &pass[0], 0, DATA_FLAG_SYSTEM_INDEX);      
  GetData(&PassDescService, &pass[1], 0, DATA_FLAG_SYSTEM_INDEX);      
  GetData(&PassDescTest, &pass[2], 0, DATA_FLAG_SYSTEM_INDEX);      
  crc = crc16((unsigned char*)pass, sizeof(CPU_INT32U) * 3);
  SetData(&PassVladCrc, &crc, 0, DATA_FLAG_SYSTEM_INDEX);
}

CPU_INT08U const PassNameCleaning[] = "УБОРКА";

TDataDescStruct const PassDescCleaning = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, PassCleaning),            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangePassModes,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&PassNameCleaning,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  2222                           
};

CPU_INT08U const PassNameService[] = "СЕРВИС";

TDataDescStruct const PassDescService = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, PassService),            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangePassModes,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&PassNameService,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  3333                           
};

CPU_INT08U const PassNameTest[] = "ТЕСТ";

TDataDescStruct const PassDescTest = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, PassTestMode),            // указатель на переменную или адрес FRAM
  (void*)&PassRange,                     // указатель на границы параметра
  OnChangePassModes,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  (void*)&PassNameTest,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  4444                           
};

char const PassDescCleaningId[] = "PassDescCleaning";
char const PassDescServiceId[] = "PassDescService";
char const PassDescTestId[] = "PassDescTest";


TDataDescStruct const PassVladCrc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, PassModesCrc),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

/*************************************
  Индекс меню режимы
*************************************/
CPU_INT08U const SolariumModesName[] = "";
TRangeValueULONG const SolariumModesRange = {0, CHANNELS_NUM * SOLAR_MODES_COUNT - 1};
CPU_INT08U const SolariumModes_str0[] = "СОЛ.1 КОЛЛАТЭН";
CPU_INT08U const SolariumModes_str1[] = "СОЛ.1 УЛbТРАФ.";
CPU_INT08U const SolariumModes_str2[] = "СОЛ.1 МАКСИМ.";
CPU_INT08U const SolariumModes_str3[] = "СОЛ.2 КОЛЛАТЭН";
CPU_INT08U const SolariumModes_str4[] = "СОЛ.2 УЛbТРАФ.";
CPU_INT08U const SolariumModes_str5[] = "СОЛ.2 МАКСИМ.";
CPU_INT08U const SolariumModes_str6[] = "СОЛ.3 КОЛЛАТЭН";
CPU_INT08U const SolariumModes_str7[] = "СОЛ.3 УЛbТРАФ.";
CPU_INT08U const SolariumModes_str8[] = "СОЛ.3 МАКСИМ.";
CPU_INT08U const *SolariumModesList[] = {SolariumModes_str0, SolariumModes_str1, SolariumModes_str2, SolariumModes_str3, SolariumModes_str4, SolariumModes_str5, SolariumModes_str6, SolariumModes_str7, SolariumModes_str8};

CPU_INT32U solar_modes_index;

TDataDescStruct const SolariumModesDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &solar_modes_index,            // указатель на переменную или адрес FRAM
  (void*)&SolariumModesRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  SolariumModesName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  SolariumModesList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const SolariumModesDescId[] = "SolariumModesDesc";

/*************************************
  Индекс меню режимы
*************************************/
CPU_INT08U const SolariumModeIndexName[] = "";
TRangeValueULONG const SolariumModeIndexRange = {0, SOLAR_MODES_COUNT - 1};
CPU_INT08U const SolariumModeIndex_str0[] = "   КОЛЛАТЭН";
CPU_INT08U const SolariumModeIndex_str1[] = "  УЛbТРАФИОЛЕТ";
CPU_INT08U const SolariumModeIndex_str2[] = "  МАКСИМАЛbНЫй";
CPU_INT08U const *SolariumModeIndexList[] = {SolariumModeIndex_str0, SolariumModeIndex_str1, SolariumModeIndex_str2};

TDataDescStruct const SolariumModeIndexDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &solar_modes_index,            // указатель на переменную или адрес FRAM
  (void*)&SolariumModeIndexRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  SolariumModeIndexName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  SolariumModeIndexList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const SolariumModeIndexDescId[] = "SolariumModeIndexDesc";

/*************************************
  Количество ламп
*************************************/
TRangeValueULONG const SolarLampsCountRange = {15, 60};
CPU_INT08U const SolarLampsCountName[] = "Кол-во ламп";

TDataDescStruct const SolarLampsCountDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,             // размер массива
  (void*)&SolariumModesDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarLampsCount),            // указатель на переменную или адрес FRAM
  (void*)&SolarLampsCountRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarLampsCountName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  18
};
char const SolarLampsCountDescId[] = "SolarLampsCountDesc";

/*************************************
  Цена минуты по режимам
*************************************/
TRangeValueULONG const SolarPricePerMinuteRange = {5*100, 9999};
CPU_INT08U const SolarPricePerMinuteName[] = "Ст.мин.,руб.";

void OnChangeSolarPricePerMinuteDesc(void)
{
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1 + solar_modes_index / SOLAR_MODES_COUNT);
}

TDataDescStruct const SolarPricePerMinuteDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,             // размер массива
  (void*)&SolariumModesDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarPricePerMinute),            // указатель на переменную или адрес FRAM
  (void*)&SolarPricePerMinuteRange,     // указатель на границы параметра
  OnChangeSolarPricePerMinuteDesc,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarPricePerMinuteName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1800
};
char const SolarPricePerMinuteDescId[] = "SolarPricePerMinuteDesc";


/*************************************
  Текущая цена минуты по режимам с учетом скидки (во fram для экономии RAM)
*************************************/
CPU_INT08U const SolarCurrentPricePerMinuteName[] = "Со скидкой,руб.";

TDataDescStruct const SolarCurrentPricePerMinuteDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,             // размер массива
  (void*)&SolariumModesDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarCurrentPricePerMinute),            // указатель на переменную или адрес FRAM
  (void*)&SolarPricePerMinuteRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarCurrentPricePerMinuteName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0
};
char const SolarCurrentPricePerMinuteDescId[] = "SolarCurrentPricePerMinuteDesc";

/*************************************
  Текущая цена минуты по режимам с учетом скидки (во fram для экономии RAM)
*************************************/
TDataDescStruct const SolarCurrentPricePerMinuteForViewDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,             // размер массива
  (void*)&SolariumModesDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarCurrentPricePerMinute),            // указатель на переменную или адрес FRAM
  (void*)&SolarPricePerMinuteRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarCurrentPricePerMinuteName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0
};

/*************************************
  Максимальное время работы по режимам
*************************************/
TRangeValueULONG const SolarMaximumTimeMinutesRange = {10, 60};
CPU_INT08U const SolarMaximumTimeMinutesName[] = "Макс.время,мин.";

TDataDescStruct const SolarMaximumTimeMinutesDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,             // размер массива
  (void*)&SolariumModesDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarMaximumTimeMinutes),            // указатель на переменную или адрес FRAM
  (void*)&SolarMaximumTimeMinutesRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarMaximumTimeMinutesName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  18
};
char const SolarMaximumTimeMinutesDescId[] = "SolarMaximumTimeMinutesDesc";

/*************************************
  Минимальное время работы для солярия
*************************************/
TRangeValueULONG const SolarMinimumTimeMinutesRange = {1, 10};
CPU_INT08U const SolarMinimumTimeMinutesName[] = "Мин.время,мин.";

TDataDescStruct const SolarMinimumTimeMinutesDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  (void*)&ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarMinimumTimeMinutes),            // указатель на переменную или адрес FRAM
  (void*)&SolarMinimumTimeMinutesRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarMinimumTimeMinutesName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  2
};
char const SolarMinimumTimeMinutesDescId[] = "SolarMinimumTimeMinutesDesc";

/*************************************
  Время вентиляции для солярия
*************************************/
TRangeValueULONG const SolarVentilationTimeMinutesRange = {2, 9};
CPU_INT08U const SolarVentilationTimeMinutesName[] = "Вентил.,мин.";

TDataDescStruct const SolarVentilationTimeMinutesDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  (void*)&ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarVentilationTimeMinutes),            // указатель на переменную или адрес FRAM
  (void*)&SolarVentilationTimeMinutesRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarVentilationTimeMinutesName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  3
};
char const SolarVentilationTimeMinutesDescId[] = "SolarVentilationTimeMinutesDesc";

/*************************************
  Таймаут до начала сеанса
*************************************/
TRangeValueULONG const SolarTimeoutBeforeMinutesRange = {0, 20};
CPU_INT08U const SolarTimeoutBeforeMinutesName[] = "Пауза до,мин.";

TDataDescStruct const SolarTimeoutBeforeMinutesDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  (void*)&ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarTimeoutBeforeMinutes),            // указатель на переменную или адрес FRAM
  (void*)&SolarTimeoutBeforeMinutesRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarTimeoutBeforeMinutesName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1
};
char const SolarTimeoutBeforeMinutesDescId[] = "SolarTimeoutBeforeMinutesDesc";

/*************************************
  Таймаут после окончания сеанса (время на одевание)
*************************************/
TRangeValueULONG const SolarTimeoutAfterMinutesRange = {0, 10};
CPU_INT08U const SolarTimeoutAfterMinutesName[] = "Пауза после,мин.";

TDataDescStruct const SolarTimeoutAfterMinutesDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  (void*)&ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarTimeoutAfterMinutes),            // указатель на переменную или адрес FRAM
  (void*)&SolarTimeoutAfterMinutesRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarTimeoutAfterMinutesName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  5
};
char const SolarTimeoutAfterMinutesDescId[] = "SolarTimeoutAfterMinutesDesc";

/*************************************
  Канал управления для канала
*************************************/
TRangeValueULONG const SolarControlChannelRange = {0, 2};
CPU_INT08U const SolarControlChannelName[] = "Управление";
CPU_INT08U const SolarControlChannel_str0[] = "ПОРТ 1";
CPU_INT08U const SolarControlChannel_str1[] = "ПОРТ 2";
CPU_INT08U const SolarControlChannel_str2[] = "ПОРТ 3";
CPU_INT08U const *SolarControlChannelList[] = {SolarControlChannel_str0, SolarControlChannel_str1, SolarControlChannel_str2};

extern void LoadControlChannels(void);

void OnChangeControlChannels()
{
    LoadControlChannels();
}

TDataDescStruct const SolarControlChannelDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  (void*)&ChannelIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarControlChannels),            // указатель на переменную или адрес FRAM
  (void*)&SolarControlChannelRange,     // указатель на границы параметра
  OnChangeControlChannels,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarControlChannelName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  SolarControlChannelList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0
};
char const SolarControlChannelDescId[] = "SolarControlChannelDesc";

/*************************************
  Таймаут уборки (один на все солярии)
*************************************/
TRangeValueULONG const SolarCleaningTimeoutMinutesRange = {0, 60};
CPU_INT08U const SolarCleaningTimeoutMinutesName[] = "Таймаут уб.мин.";

TDataDescStruct const SolarCleaningTimeoutMinutesDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolarCleaningTimeout),            // указатель на переменную или адрес FRAM
  (void*)&SolarCleaningTimeoutMinutesRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  SolarCleaningTimeoutMinutesName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  30
};
char const SolarCleaningTimeoutMinutesDescId[] = "SolarCleaningTimeoutMinutesDesc";

/*************************************
  Индекс абонемента
*************************************/
CPU_INT08U const AbonementIndexName[] = "";
TRangeValueULONG const AbonementIndexHourRange = {0, 3};
CPU_INT08U const AbonementIndexHour_str0[] = "СЕРЕБРЯННЫй";
CPU_INT08U const AbonementIndexHour_str1[] = "ЗОЛОТОй";
CPU_INT08U const AbonementIndexHour_str2[] = "ПЛАТИНОВЫй";
CPU_INT08U const AbonementIndexHour_str3[] = "АЛМАЗНЫй";
CPU_INT08U const *AbonementIndexHourList[] = {AbonementIndexHour_str0, AbonementIndexHour_str1, AbonementIndexHour_str2, AbonementIndexHour_str3};

CPU_INT32U abonement_index;

TDataDescStruct const AbonementIndexDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &abonement_index,            // указатель на переменную или адрес FRAM
  (void*)&AbonementIndexHourRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  AbonementIndexName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  AbonementIndexHourList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const AbonementIndexDescId[] = "AbonementIndexDesc";


/*************************************
  Деньги
*************************************/
TRangeValueULONG const AbonementMoneyRange = {0, 99999};
CPU_INT08U const AbonementMoneyName[] = "Деньги";

TDataDescStruct const AbonementMoneyDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  4,             // размер массива
  &AbonementIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, AbonementMoney),                // указатель на переменную или адрес FRAM
  (void*)&AbonementMoneyRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  AbonementMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  3000
};

/*************************************
  Индекс абонемента
*************************************/

TRangeValueULONG const AbonementIndexRange = {0, 4};
CPU_INT08U const AbonementIndex_str0[] = "СЕРЕБРЯННЫй";
CPU_INT08U const AbonementIndex_str1[] = "ЗОЛОТОй";
CPU_INT08U const AbonementIndex_str2[] = "ПЛАТИНОВЫй";
CPU_INT08U const AbonementIndex_str3[] = "АЛМАЗНЫй";
CPU_INT08U const AbonementIndex_str4[] = "ИТОГО";
CPU_INT08U const *AbonementIndexList[] = {AbonementIndex_str0, AbonementIndex_str1, AbonementIndex_str2, AbonementIndex_str3, AbonementIndex_str4};

TDataDescStruct const AbonementCounterIndexDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &abonement_index,            // указатель на переменную или адрес FRAM
  (void*)&AbonementIndexRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  AbonementIndexName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  AbonementIndexList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const AbonementCounterIndexDescId[] = "AbonementCounterIndexDesc";

/*************************************
  Деньги
*************************************/

CPU_INT08U const AbonementMoneyAbonementName[] = "Оплачено,руб";

TDataDescStruct const CounterMoneyAbonementDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  5,                        // размер массива
  &AbonementCounterIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.abonement[0].card_money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(AbonentCountersRecord),                        // смещение между элементами в массиве
  AbonementMoneyAbonementName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterMoneyAbonementDescId[] = "CounterMoneyAbonementDesc";

/*************************************
  Бонусы
*************************************/

CPU_INT08U const AbonementBonusName[] = "Бонусы";

TDataDescStruct const CounterBonusAbonementDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  5,                        // размер массива
  &AbonementCounterIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.abonement[0].card_bonus),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(AbonentCountersRecord),                        // смещение между элементами в массиве
  AbonementBonusName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterBonusAbonementDescId[] = "CounterBonusAbonementDesc";

/*************************************
  Количество запусков
*************************************/

CPU_INT08U const AbonementRunsName[] = "Кол-во";

TDataDescStruct const CounterRunsAbonementDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  5,                        // размер массива
  &AbonementCounterIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.abonement[0].runs),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(AbonentCountersRecord),                        // смещение между элементами в массиве
  AbonementRunsName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterRunsAbonementDescId[] = "CounterRunsAbonementDesc";

/*************************************
  Бонусы
*************************************/
TRangeValueULONG const AbonementBonusRange = {0, 99999};

TDataDescStruct const AbonementBonusDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,             // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  4,             // размер массива
  &AbonementIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, AbonementBonus),                // указатель на переменную или адрес FRAM
  (void*)&AbonementBonusRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  AbonementBonusName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  600
};

/*************************************
  Срок действия
*************************************/
TRangeValueULONG const AbonementBestBeforeRange = {0, 1000};
CPU_INT08U const AbonementBestBeforeName[] = "Срок дейст,дн.";

TDataDescStruct const AbonementBestBeforeDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  4,                        // размер массива
  &AbonementIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, AbonementBestBefore),                // указатель на переменную или адрес FRAM
  (void*)&AbonementBestBeforeRange,           // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  AbonementBestBeforeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  180
};

/*************************************
  Индекс скидки по часам
*************************************/
CPU_INT08U const DiscountIndexHourName[] = "  СКИДКА";
TRangeValueULONG const DiscountIndexHourRange = {0, 3};
CPU_INT08U const DiscountIndexHour_str0[] = "НОЧb";
CPU_INT08U const DiscountIndexHour_str1[] = "УТРО";
CPU_INT08U const DiscountIndexHour_str2[] = "ДЕНb";
CPU_INT08U const DiscountIndexHour_str3[] = "ВЕЧЕР";
CPU_INT08U const *DiscountIndexHourList[] = {DiscountIndexHour_str0, DiscountIndexHour_str1, DiscountIndexHour_str2, DiscountIndexHour_str3};

CPU_INT32U discount_index;

TDataDescStruct const DiscountIndexHourDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &discount_index,            // указатель на переменную или адрес FRAM
  (void*)&DiscountIndexHourRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  DiscountIndexHourName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  DiscountIndexHourList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const DiscountIndexHourDescId[] = "DiscountIndexHourDesc";

/*************************************
  Начало интервала скидки по часам
*************************************/
CPU_INT08U const DiscountBeginHourName[] = "Начало";
TRangeValueULONG const DiscountBeginHourRange = {0, 23};
CPU_INT08U const DiscountBeginHour_str0[] = "00:00";
CPU_INT08U const DiscountBeginHour_str1[] = "01:00";
CPU_INT08U const DiscountBeginHour_str2[] = "02:00";
CPU_INT08U const DiscountBeginHour_str3[] = "03:00";
CPU_INT08U const DiscountBeginHour_str4[] = "04:00";
CPU_INT08U const DiscountBeginHour_str5[] = "05:00";
CPU_INT08U const DiscountBeginHour_str6[] = "06:00";
CPU_INT08U const DiscountBeginHour_str7[] = "07:00";
CPU_INT08U const DiscountBeginHour_str8[] = "08:00";
CPU_INT08U const DiscountBeginHour_str9[] = "09:00";
CPU_INT08U const DiscountBeginHour_str10[] = "10:00";
CPU_INT08U const DiscountBeginHour_str11[] = "11:00";
CPU_INT08U const DiscountBeginHour_str12[] = "12:00";
CPU_INT08U const DiscountBeginHour_str13[] = "13:00";
CPU_INT08U const DiscountBeginHour_str14[] = "14:00";
CPU_INT08U const DiscountBeginHour_str15[] = "15:00";
CPU_INT08U const DiscountBeginHour_str16[] = "16:00";
CPU_INT08U const DiscountBeginHour_str17[] = "17:00";
CPU_INT08U const DiscountBeginHour_str18[] = "18:00";
CPU_INT08U const DiscountBeginHour_str19[] = "19:00";
CPU_INT08U const DiscountBeginHour_str20[] = "20:00";
CPU_INT08U const DiscountBeginHour_str21[] = "21:00";
CPU_INT08U const DiscountBeginHour_str22[] = "22:00";
CPU_INT08U const DiscountBeginHour_str23[] = "23:00";
CPU_INT08U const *DiscountBeginHourList[] = {DiscountBeginHour_str0, DiscountBeginHour_str1, DiscountBeginHour_str2, DiscountBeginHour_str3,
                                            DiscountBeginHour_str4, DiscountBeginHour_str5, DiscountBeginHour_str6, DiscountBeginHour_str7,
                                            DiscountBeginHour_str8, DiscountBeginHour_str9, DiscountBeginHour_str10, DiscountBeginHour_str11,
                                            DiscountBeginHour_str12, DiscountBeginHour_str13, DiscountBeginHour_str14, DiscountBeginHour_str15,
                                            DiscountBeginHour_str16, DiscountBeginHour_str17, DiscountBeginHour_str18, DiscountBeginHour_str19,
                                            DiscountBeginHour_str20, DiscountBeginHour_str21, DiscountBeginHour_str22, DiscountBeginHour_str23};

void OnChangeDiscountBegin(void)
{
    CPU_INT32U begin_val, end_val;
    GetData(&DiscountBeginHourDesc, &begin_val, discount_index, DATA_FLAG_DIRECT_INDEX);
    GetData(&DiscountEndHourDesc, &end_val, discount_index, DATA_FLAG_DIRECT_INDEX);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
    if (end_val < begin_val)
    {
        end_val = begin_val;
        SetData(&DiscountEndHourDesc, &end_val, discount_index, DATA_FLAG_DIRECT_INDEX);
    }
}

TDataDescStruct const DiscountBeginHourDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  4,                       // размер массива
  (void*)&DiscountIndexHourDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountHourBegin),            // указатель на переменную или адрес FRAM
  (void*)&DiscountBeginHourRange,                    // указатель на границы параметра
  OnChangeDiscountBegin,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  DiscountBeginHourName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  DiscountBeginHourList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const DiscountBeginHourDescId[] = "DiscountBeginHourDesc";

/*************************************
  Конец интервала скидки по часам
*************************************/
CPU_INT08U const DiscountEndHourName[] = "Окончание";
TRangeValueULONG const DiscountEndHourRange = {0, 23};
CPU_INT08U const DiscountEndHour_str0[] = "00:59";
CPU_INT08U const DiscountEndHour_str1[] = "01:59";
CPU_INT08U const DiscountEndHour_str2[] = "02:59";
CPU_INT08U const DiscountEndHour_str3[] = "03:59";
CPU_INT08U const DiscountEndHour_str4[] = "04:59";
CPU_INT08U const DiscountEndHour_str5[] = "05:59";
CPU_INT08U const DiscountEndHour_str6[] = "06:59";
CPU_INT08U const DiscountEndHour_str7[] = "07:59";
CPU_INT08U const DiscountEndHour_str8[] = "08:59";
CPU_INT08U const DiscountEndHour_str9[] = "09:59";
CPU_INT08U const DiscountEndHour_str10[] = "10:59";
CPU_INT08U const DiscountEndHour_str11[] = "11:59";
CPU_INT08U const DiscountEndHour_str12[] = "12:59";
CPU_INT08U const DiscountEndHour_str13[] = "13:59";
CPU_INT08U const DiscountEndHour_str14[] = "14:59";
CPU_INT08U const DiscountEndHour_str15[] = "15:59";
CPU_INT08U const DiscountEndHour_str16[] = "16:59";
CPU_INT08U const DiscountEndHour_str17[] = "17:59";
CPU_INT08U const DiscountEndHour_str18[] = "18:59";
CPU_INT08U const DiscountEndHour_str19[] = "19:59";
CPU_INT08U const DiscountEndHour_str20[] = "20:59";
CPU_INT08U const DiscountEndHour_str21[] = "21:59";
CPU_INT08U const DiscountEndHour_str22[] = "22:59";
CPU_INT08U const DiscountEndHour_str23[] = "23:59";
CPU_INT08U const *DiscountEndHourList[] = {DiscountEndHour_str0, DiscountEndHour_str1, DiscountEndHour_str2, DiscountEndHour_str3,
                                            DiscountEndHour_str4, DiscountEndHour_str5, DiscountEndHour_str6, DiscountEndHour_str7,
                                            DiscountEndHour_str8, DiscountEndHour_str9, DiscountEndHour_str10, DiscountEndHour_str11,
                                            DiscountEndHour_str12, DiscountEndHour_str13, DiscountEndHour_str14, DiscountEndHour_str15,
                                            DiscountEndHour_str16, DiscountEndHour_str17, DiscountEndHour_str18, DiscountEndHour_str19,
                                            DiscountEndHour_str20, DiscountEndHour_str21, DiscountEndHour_str22, DiscountEndHour_str23};

void OnChangeDiscountEnd(void)
{
    CPU_INT32U begin_val, end_val;
    GetData(&DiscountBeginHourDesc, &begin_val, discount_index, DATA_FLAG_DIRECT_INDEX);
    GetData(&DiscountEndHourDesc, &end_val, discount_index, DATA_FLAG_DIRECT_INDEX);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
    if (begin_val >= end_val)
    {
        begin_val = end_val;
        SetData(&DiscountBeginHourDesc, &begin_val, discount_index, DATA_FLAG_DIRECT_INDEX);
    }
}

TDataDescStruct const DiscountEndHourDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  4,                       // размер массива
  (void*)&DiscountIndexHourDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountHourEnd),            // указатель на переменную или адрес FRAM
  (void*)&DiscountEndHourRange,                    // указатель на границы параметра
  OnChangeDiscountEnd,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  DiscountEndHourName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  DiscountEndHourList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const DiscountEndHourDescId[] = "DiscountEndHourDesc";

/*************************************
  Значение скидки по часам в процентах
*************************************/
CPU_INT08U const DiscountValueHourName[] = "Скидка,%";
TRangeValueULONG const DiscountValueHourRange = {0, 99};

void OnChangeDiscountValueHour(void)
{
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
}
        
TDataDescStruct const DiscountValueHourDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  4,                       // размер массива
  (void*)&DiscountIndexHourDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountHourValue),            // указатель на переменную или адрес FRAM
  (void*)&DiscountValueHourRange,                    // указатель на границы параметра
  OnChangeDiscountValueHour,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  DiscountValueHourName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const DiscountValueHourDescId[] = "DiscountValueHourDesc";

/*************************************
  Индекс скидки по дням недели
*************************************/
CPU_INT08U const DiscountIndexDayName[] = "  СКИДКА";
TRangeValueULONG const DiscountIndexDayRange = {0, 6};
CPU_INT08U const DiscountIndexDay_str0[] = "ВС";
CPU_INT08U const DiscountIndexDay_str1[] = "ПН";
CPU_INT08U const DiscountIndexDay_str2[] = "ВТ";
CPU_INT08U const DiscountIndexDay_str3[] = "СР";
CPU_INT08U const DiscountIndexDay_str4[] = "ЧТ";
CPU_INT08U const DiscountIndexDay_str5[] = "ПТ";
CPU_INT08U const DiscountIndexDay_str6[] = "СБ";
CPU_INT08U const *DiscountIndexDayList[] = {DiscountIndexDay_str0, DiscountIndexDay_str1, DiscountIndexDay_str2, DiscountIndexDay_str3, DiscountIndexDay_str4, DiscountIndexDay_str5, DiscountIndexDay_str6};

TDataDescStruct const DiscountIndexDayDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &discount_index,            // указатель на переменную или адрес FRAM
  (void*)&DiscountIndexDayRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  DiscountIndexDayName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  DiscountIndexDayList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const DiscountIndexDayDescId[] = "DiscountIndexDayDesc";

/*************************************
  Значение скидки по дням недели в процентах
*************************************/
CPU_INT08U const DiscountValueDayName[] = "Скидка,%";
TRangeValueULONG const DiscountValueDayRange = {0, 99};

void OnChangeDiscountValueDay(void)
{
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
}

TDataDescStruct const DiscountValueDayDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  7,                       // размер массива
  (void*)&DiscountIndexDayDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountDayValue),            // указатель на переменную или адрес FRAM
  (void*)&DiscountValueDayRange,                    // указатель на границы параметра
  OnChangeDiscountValueDay,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  DiscountValueDayName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const DiscountValueDayDescId[] = "DiscountValueDayDesc";

/*************************************
  Индекс скидки по месяцам
*************************************/
CPU_INT08U const DiscountIndexMonthName[] = "СКИДКА";
TRangeValueULONG const DiscountIndexMonthRange = {0, 11};
CPU_INT08U const DiscountIndexMonth_str0[] = "ЯНВАРb";
CPU_INT08U const DiscountIndexMonth_str1[] = "ФЕВРАЛb";
CPU_INT08U const DiscountIndexMonth_str2[] = "МАРТ";
CPU_INT08U const DiscountIndexMonth_str3[] = "АПРЕЛb";
CPU_INT08U const DiscountIndexMonth_str4[] = "МАй";
CPU_INT08U const DiscountIndexMonth_str5[] = "ИЮНb";
CPU_INT08U const DiscountIndexMonth_str6[] = "ИЮЛb";
CPU_INT08U const DiscountIndexMonth_str7[] = "АВГУСТ";
CPU_INT08U const DiscountIndexMonth_str8[] = "СЕНТЯБРb";
CPU_INT08U const DiscountIndexMonth_str9[] = "ОКТЯБРb";
CPU_INT08U const DiscountIndexMonth_str10[] = "НОЯБРb";
CPU_INT08U const DiscountIndexMonth_str11[] = "ДЕКАБРb";
CPU_INT08U const *DiscountIndexMonthList[] = {DiscountIndexMonth_str0, DiscountIndexMonth_str1, DiscountIndexMonth_str2, 
                                              DiscountIndexMonth_str3, DiscountIndexMonth_str4, DiscountIndexMonth_str5, 
                                              DiscountIndexMonth_str6, DiscountIndexMonth_str7, DiscountIndexMonth_str8, 
                                              DiscountIndexMonth_str9, DiscountIndexMonth_str10, DiscountIndexMonth_str11};

TDataDescStruct const DiscountIndexMonthDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &discount_index,            // указатель на переменную или адрес FRAM
  (void*)&DiscountIndexMonthRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  DiscountIndexMonthName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  DiscountIndexMonthList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const DiscountIndexMonthDescId[] = "DiscountIndexMonthDesc";

/*************************************
  Значение скидки по месяцам в процентах
*************************************/
CPU_INT08U const DiscountValueMonthName[] = "Скидка,%";
TRangeValueULONG const DiscountValueMonthRange = {0, 99};

void OnChangeDiscountValueMonth(void)
{
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
}

TDataDescStruct const DiscountValueMonthDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  12,                       // размер массива
  (void*)&DiscountIndexMonthDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountMonthValue),            // указатель на переменную или адрес FRAM
  (void*)&DiscountValueMonthRange,                    // указатель на границы параметра
  OnChangeDiscountValueMonth,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  DiscountValueMonthName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const DiscountValueMonthDescId[] = "DiscountValueMonthDesc";

/*************************************
  Индекс скидки разовой
*************************************/
CPU_INT08U const DiscountIndexCustomName[] = "  СКИДКА";
TRangeValueULONG const DiscountIndexCustomRange = {0, 2};
CPU_INT08U const DiscountIndexCustom_str0[] = "1";
CPU_INT08U const DiscountIndexCustom_str1[] = "2";
CPU_INT08U const DiscountIndexCustom_str2[] = "3";
CPU_INT08U const *DiscountIndexCustomList[] = {DiscountIndexCustom_str0, DiscountIndexCustom_str1, DiscountIndexCustom_str2};

TDataDescStruct const DiscountIndexCustomDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &discount_index,            // указатель на переменную или адрес FRAM
  (void*)&DiscountIndexCustomRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  DiscountIndexCustomName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  DiscountIndexCustomList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const DiscountIndexCustomDescId[] = "DiscountIndexCustomDesc";

/*************************************
  Значение скидки разовой
*************************************/
CPU_INT08U const DiscountValueCustomName[] = "Скидка,%";
TRangeValueULONG const DiscountValueCustomRange = {0, 99};

void OnChangeDiscountValueCustom(void)
{
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
}

TDataDescStruct const DiscountValueCustomDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  3,                       // размер массива
  (void*)&DiscountIndexCustomDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountCustomValue),            // указатель на переменную или адрес FRAM
  (void*)&DiscountValueCustomRange,                    // указатель на границы параметра
  OnChangeDiscountValueCustom,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  DiscountValueCustomName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const DiscountValueCustomDescId[] = "DiscountValueCustomDesc";

/*************************************
  Дата начала разовой скидки
*************************************/
CPU_INT08U const DiscountDateBeginCustomName[] = "От";

void OnChangeDiscountDateBeginCustomDesc(void)
{
    CPU_INT32U begin, end;
    GetData(&DiscountDateBeginCustomDesc, &begin, 0, DATA_FLAG_SYSTEM_INDEX);
    GetData(&DiscountDateEndCustomDesc, &end, 0, DATA_FLAG_SYSTEM_INDEX);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
    if (begin > end)
    {
        end = begin;
        SetData(&DiscountDateEndCustomDesc, &end, 0, DATA_FLAG_SYSTEM_INDEX);
    }
}

TDataDescStruct const DiscountDateBeginCustomDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_DATE,    // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  3,             // размер массива
  (void*)&DiscountIndexCustomDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountBeginDateValue),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  DiscountDateBeginCustomName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0
};
char const DiscountDateBeginCustomDescId[] = "DiscountDateBeginCustomDesc";

/*************************************
  Дата конца разовой скидки
*************************************/
CPU_INT08U const DiscountDateEndCustomName[] = "До";

void OnChangeDiscountDateEndCustomDesc(void)
{
    CPU_INT32U begin, end;
    GetData(&DiscountDateBeginCustomDesc, &begin, 0, DATA_FLAG_SYSTEM_INDEX);
    GetData(&DiscountDateEndCustomDesc, &end, 0, DATA_FLAG_SYSTEM_INDEX);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE1);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE2);
    PostScoreEvent(SCORE_EVENT_UPDATE_PRICE3);
    if (end < begin)
    {
        begin = end;
        SetData(&DiscountDateBeginCustomDesc, &begin, 0, DATA_FLAG_SYSTEM_INDEX);
    }
}

TDataDescStruct const DiscountDateEndCustomDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_DATE,    // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  3,             // размер массива
  (void*)&DiscountIndexCustomDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, DiscountEndDateValue),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  DiscountDateEndCustomName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0
};
char const DiscountDateEndCustomDescId[] = "DiscountDateEndCustomDesc";

/*************************************
  Значение текущей скидки
*************************************/
CPU_INT08U const DiscountValueCurrentName[] = "Текущая,%";

CPU_INT32U current_discount;

TDataDescStruct const DiscountValueCurrentDesc = {
  DATA_DESC_VIEW,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  NULL,                       // указатель на дескриптор индекса массива
  (void*)&current_discount,            // указатель на переменную или адрес FRAM
  NULL,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  DiscountValueCurrentName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const DiscountValueCurrentDescId[] = "DiscountValueCurrentDesc";

/*************************************
  Индекс табло
*************************************/
CPU_INT08U const ScoreIndexName[] = "ТАБЛО";
TRangeValueULONG const ScoreIndexRange = {0, SCORE_COUNT - 1};
CPU_INT08U const ScoreIndex_str0[] = "ВРЕМЕНИ 1";
CPU_INT08U const ScoreIndex_str1[] = "ВРЕМЕНИ 2";
CPU_INT08U const ScoreIndex_str2[] = "ВРЕМЕНИ 3";
CPU_INT08U const ScoreIndex_str3[] = "ЦЕН 1";
CPU_INT08U const ScoreIndex_str4[] = "ЦЕН 2";
CPU_INT08U const ScoreIndex_str5[] = "ЦЕН 3";
CPU_INT08U const *ScoreIndexList[] = {ScoreIndex_str0, ScoreIndex_str1, ScoreIndex_str2, ScoreIndex_str3, ScoreIndex_str4, ScoreIndex_str5};

CPU_INT32U score_index;

TDataDescStruct const ScoreIndexDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &score_index,            // указатель на переменную или адрес FRAM
  (void*)&ScoreIndexRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  ScoreIndexName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ScoreIndexList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const ScoreIndexDescId[] = "ScoreIndexDesc";

/*************************************
  Включение табло
*************************************/
CPU_INT08U const ScoreEnableName[] = "Включить";
TRangeValueULONG const ScoreEnableRange = {0, 1};
CPU_INT08U const ScoreEnable_str0[] = "нет";
CPU_INT08U const ScoreEnable_str1[] = "да";
CPU_INT08U const *ScoreEnableList[] = {ScoreEnable_str0, ScoreEnable_str1};

TDataDescStruct const ScoreEnableDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  SCORE_COUNT,                       // размер массива
  &ScoreIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ScoreEnable),            // указатель на переменную или адрес FRAM
  (void*)&ScoreEnableRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  ScoreEnableName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ScoreEnableList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const ScoreEnableDescId[] = "ScoreEnableDesc";

/*************************************
  Скорость связи (общая для табло)
*************************************/
CPU_INT08U const ScoreRs485SpeedName[] = "Скорость,бод";
TRangeValueULONG const ScoreRs485SpeedRange = {0, 7};
CPU_INT08U const ScoreRs485Speed_str0[] = "1200";
CPU_INT08U const ScoreRs485Speed_str1[] = "2400";
CPU_INT08U const ScoreRs485Speed_str2[] = "4800";
CPU_INT08U const ScoreRs485Speed_str3[] = "9600";
CPU_INT08U const ScoreRs485Speed_str4[] = "19200";
CPU_INT08U const ScoreRs485Speed_str5[] = "38400";
CPU_INT08U const ScoreRs485Speed_str6[] = "57600";
CPU_INT08U const ScoreRs485Speed_str7[] = "115200";
CPU_INT08U const *ScoreRs485SpeedList[] = {ScoreRs485Speed_str0, ScoreRs485Speed_str1, ScoreRs485Speed_str2, ScoreRs485Speed_str3,
                                           ScoreRs485Speed_str4, ScoreRs485Speed_str5, ScoreRs485Speed_str6, ScoreRs485Speed_str7};


void OnChangeScoreRs485SpeedDesc(void)
{
    PostScoreEvent(SCORE_EVENT_CHANGE_SPEED);
}

TDataDescStruct const ScoreRs485SpeedDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ScoreRs485Speed),            // указатель на переменную или адрес FRAM
  (void*)&ScoreRs485SpeedRange,                    // указатель на границы параметра
  OnChangeScoreRs485SpeedDesc,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  ScoreRs485SpeedName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ScoreRs485SpeedList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  3                           
};
char const ScoreRs485SpeedDescId[] = "ScoreRs485SpeedDesc";

/*************************************
  Адрес табло
*************************************/
CPU_INT08U const ScoreRs485AddressName[] = "Адрес";
TRangeValueULONG const ScoreRs485AddressRange = {1, 254};

TDataDescStruct const ScoreRs485AddressDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  SCORE_COUNT,             // размер массива
  &ScoreIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ScoreRs485Address),            // указатель на переменную или адрес FRAM
  (void*)&ScoreRs485AddressRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  ScoreRs485AddressName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  1                           
};
char const ScoreRs485AddressDescId[] = "ScoreRs485AddressDesc";

/*************************************
  Разделитель для табло точка или двоеточие
*************************************/
CPU_INT08U const ScoreColumnName[] = "Разделитель";
TRangeValueULONG const ScoreColumnRange = {0, 1};
CPU_INT08U const ScoreColumn_str0[] = ":";
CPU_INT08U const ScoreColumn_str1[] = ".";
CPU_INT08U const *ScoreColumnList[] = {ScoreColumn_str0, ScoreColumn_str1};

TDataDescStruct const ScoreColumnDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  SCORE_COUNT,             // размер массива
  &ScoreIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, ScoreColumn),            // указатель на переменную или адрес FRAM
  (void*)&ScoreColumnRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  ScoreColumnName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ScoreColumnList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const ScoreColumnDescId[] = "ScoreColumnDesc";

/*************************************
  Команда настройки табло
*************************************/
CPU_INT08U const ScoreCommandName[] = "Настроить";
TRangeValueULONG const ScoreCommandRange = {0, 1};
CPU_INT08U const ScoreCommand_str0[] = "нет";
CPU_INT08U const ScoreCommand_str1[] = "да";
CPU_INT08U const *ScoreCommandList[] = {ScoreCommand_str0, ScoreCommand_str1};

CPU_INT32U score_cmd;

void OnchangeScoreCommand(void)
{
    if (score_cmd)
    {
        PostScoreEvent(SCORE_EVENT_SETUP1 + score_index);
    }
}

TDataDescStruct const ScoreCommandDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &score_cmd,            // указатель на переменную или адрес FRAM
  (void*)&ScoreCommandRange,                    // указатель на границы параметра
  OnchangeScoreCommand,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  ScoreCommandName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ScoreCommandList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const ScoreCommandDescId[] = "ScoreCommandDesc";

/*************************************
  Статус подключения табло
*************************************/
CPU_INT08U const ScoreStateName[] = "Состояние";
TRangeValueULONG const ScoreStateRange = {0, 3};
CPU_INT08U const ScoreState_str0[] = "откл";
CPU_INT08U const ScoreState_str1[] = "подкл";
CPU_INT08U const ScoreState_str2[] = "ошибка";
CPU_INT08U const ScoreState_str3[] = "настройка";
CPU_INT08U const *ScoreStateList[] = {ScoreState_str0, ScoreState_str1, ScoreState_str2, ScoreState_str3};

TDataDescStruct const ScoreStateDesc = {
  DATA_DESC_VIEW,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  SCORE_COUNT,                       // размер массива
  &ScoreIndexDesc,                       // указатель на дескриптор индекса массива
  &score_state,            // указатель на переменную или адрес FRAM
  (void*)&ScoreStateRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  ScoreStateName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ScoreStateList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const ScoreStateDescId[] = "ScoreStateDesc";

/*************************************
  Индекс типов кожи
*************************************/
CPU_INT08U const SkinTypeIndexName[] = "ТИП КОЖИ";
TRangeValueULONG const SkinTypeIndexRange = {0, 3};
CPU_INT08U const SkinTypeIndex_str0[] = "1";
CPU_INT08U const SkinTypeIndex_str1[] = "2";
CPU_INT08U const SkinTypeIndex_str2[] = "3";
CPU_INT08U const SkinTypeIndex_str3[] = "4";
CPU_INT08U const *SkinTypeIndexList[] = {SkinTypeIndex_str0, SkinTypeIndex_str1, SkinTypeIndex_str2, SkinTypeIndex_str3};

CPU_INT32U skin_index;

TDataDescStruct const SkinTypeIndexDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &skin_index,            // указатель на переменную или адрес FRAM
  (void*)&SkinTypeIndexRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  SkinTypeIndexName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  SkinTypeIndexList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const SkinTypeIndexDescId[] = "SkinTypeIndexDesc";

/*************************************
  Максимальное время КОЛЛАТЭНА по типу кожи
*************************************/
CPU_INT08U const SkinCollatenMaxTimeName[] = "КОЛЛАТЭН,мин.";
TRangeValueULONG const SkinCollatenMaxTimeRange = {0, 999};

TDataDescStruct const SkinCollatenMaxTimeDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  4,             // размер массива
  &SkinTypeIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SkinCollatenMaxTime),            // указатель на переменную или адрес FRAM
  (void*)&SkinCollatenMaxTimeRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  SkinCollatenMaxTimeName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const SkinCollatenMaxTimeDescId[] = "SkinCollatenMaxTimeDesc";

/*************************************
  Максимальное время УЛЬТРАФИОЛЕТА по типу кожи
*************************************/
CPU_INT08U const SkinUFMaxTimeName[] = "УЛbТРАФ.,мин.";
TRangeValueULONG const SkinUFMaxTimeRange = {0, 999};

TDataDescStruct const SkinUFMaxTimeDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  4,             // размер массива
  &SkinTypeIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SkinUFMaxTime),            // указатель на переменную или адрес FRAM
  (void*)&SkinUFMaxTimeRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  SkinUFMaxTimeName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0
};
char const SkinUFMaxTimeDescId[] = "SkinUFMaxTimeDesc";

/*************************************
  Максимальное время МАКСИМАЛЬНЫЙ по типу кожи
*************************************/
CPU_INT08U const SkinMaximalMaxTimeName[] = "МАКС.,мин.";
TRangeValueULONG const SkinMaximalMaxTimeRange = {0, 999};

TDataDescStruct const SkinMaximalMaxTimeDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  4,             // размер массива
  &SkinTypeIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SkinMaximalMaxTime),            // указатель на переменную или адрес FRAM
  (void*)&SkinMaximalMaxTimeRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  SkinMaximalMaxTimeName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const SkinMaximalMaxTimeDescId[] = "SkinMaximalMaxTimeDesc";

/*************************************
  Дескриптор для энергонезависимого сохранения оплаченного времени для солярия
*************************************/
TDataDescStruct const SolariumTimePayedDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumTimePayed),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const SolariumTimePayedDescId[] = "SolariumTimePayedDesc";

/*************************************
  Дескриптор для энергонезависимого сохранения оплаченных денег для солярия
*************************************/
TDataDescStruct const SolariumMoneyPayedDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,             // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumMoneyPayed),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const SolariumMoneyPayedDescId[] = "SolariumMoneyPayedDesc";

/*************************************
  Дескриптор Crc16 энергонезависимого сохранения оплаченного времени для солярия
*************************************/
TDataDescStruct const SolariumTimePayedCrc16Desc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, SolariumTimePayedCrc16),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  NULL,           // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const SolariumTimePayedCrc16DescId[] = "SolariumTimePayedCrc16Desc";

/*************************************
  Сумма денег раздельно по соляриям и режимам 
*************************************/
CPU_INT08U const CounterSolarMoneyName[] = "Деньги,руб.";

TDataDescStruct const CounterSolarMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModesDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_chm[0].money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterSolarMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterSolarMoneyDescId[] = "CounterSolarMoneyDesc";

/*************************************
  Сумма с карт абонентов денег раздельно по соляриям и режимам 
*************************************/
CPU_INT08U const CounterSolarCardMoneyName[] = "К_Деньги,руб.";

TDataDescStruct const CounterSolarCardMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModesDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_chm[0].card_money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterSolarCardMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterSolarCardMoneyDescId[] = "CounterSolarCardMoneyDesc";

/*************************************
  Сумма с карт абонентов бонусов раздельно по соляриям и режимам 
*************************************/
CPU_INT08U const CounterSolarCardBonusName[] = "К_Бонусы,руб.";

TDataDescStruct const CounterSolarCardBonusDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModesDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_chm[0].card_bonus),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterSolarCardBonusName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterSolarCardBonusDescId[] = "CounterSolarCardBonusDesc";

/*************************************
  Количество запусков раздельно по соляриям и режимам 
*************************************/
CPU_INT08U const CounterSolarRunsName[] = "Запусков";

TDataDescStruct const CounterSolarRunsDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModesDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_chm[0].runs),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterSolarRunsName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterSolarRunsDescId[] = "CounterSolarRunsDesc";

/*************************************
  Количество запусков раздельно по соляриям и режимам в тестовом режиме
*************************************/
CPU_INT08U const CounterSolarTestRunsName[] = "Тестов";

TDataDescStruct const CounterSolarTestRunsDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModesDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_chm_test[0].runs),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterSolarTestRunsName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterSolarTestRunsDescId[] = "CounterSolarTestRunsDesc";

/*************************************
  Время работы раздельно по соляриям и режимам 
*************************************/
CPU_INT08U const CounterSolarWorkTimeName[] = "Нараб.,мин.";

TDataDescStruct const CounterSolarWorkTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModesDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_chm[0].worktime),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterSolarWorkTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterSolarWorkTimeDescId[] = "CounterSolarWorkTimeDesc";

/*************************************
  Время работы раздельно по соляриям и режимам в тестовом режиме
*************************************/
CPU_INT08U const CounterSolarTestWorkTimeName[] = "Тест,мин.";

TDataDescStruct const CounterSolarTestWorkTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM * SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModesDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_chm_test[0].worktime),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterSolarTestWorkTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterSolarTestWorkTimeDescId[] = "CounterSolarTestWorkTimeDesc";

/*************************************
  Сумма денег по режимам 
*************************************/
CPU_INT08U const CounterModeMoneyName[] = "Деньги,руб.";

TDataDescStruct const CounterModeMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModeIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_m[0].money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterModeMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterModeMoneyDescId[] = "CounterModeMoneyDesc";

/*************************************
  Сумма денег по режимам по абонементам
*************************************/
CPU_INT08U const CounterModeCardMoneyName[] = "К_Деньги,руб.";

TDataDescStruct const CounterModeCardMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModeIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_m[0].card_money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterModeCardMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterModeCardMoneyDescId[] = "CounterModeCardMoneyDesc";

/*************************************
  Сумма бонусов по режимам по абонементам
*************************************/
CPU_INT08U const CounterModeCardBonusName[] = "К_Бонусы,руб.";

TDataDescStruct const CounterModeCardBonusDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModeIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_m[0].card_bonus),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterModeCardBonusName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterModeCardBonusDescId[] = "CounterModeCardBonusDesc";

/*************************************
  Количество запусков по режимам 
*************************************/
CPU_INT08U const CounterModeRunsName[] = "Запусков";

TDataDescStruct const CounterModeRunsDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModeIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_m[0].runs),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterModeRunsName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterModeRunsDescId[] = "CounterModeRunsDesc";

/*************************************
  Количество запусков по режимам в тестовом режиме
*************************************/
CPU_INT08U const CounterModeTestRunsName[] = "Тестов";

TDataDescStruct const CounterModeTestRunsDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModeIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_m_test[0].runs),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterModeTestRunsName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterModeTestRunsDescId[] = "CounterModeTestRunsDesc";

/*************************************
  Время работы по режимам 
*************************************/
CPU_INT08U const CounterModeWorkTimeName[] = "Нараб.мин.";

TDataDescStruct const CounterModeWorkTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModeIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_m[0].worktime),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterModeWorkTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterModeWorkTimeDescId[] = "CounterModeWorkTimeDesc";

/*************************************
  Время работы по режимам в тестовом режиме
*************************************/
CPU_INT08U const CounterModeWorkTestTimeName[] = "Тест,мин.";

TDataDescStruct const CounterModeWorkTestTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  SOLAR_MODES_COUNT,                        // размер массива
  &SolariumModeIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.solar_m_test[0].worktime),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(SolarCountersRecord),                        // смещение между элементами в массиве
  CounterModeWorkTestTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterModeWorkTestTimeDescId[] = "CounterModeWorkTestTimeDesc";

/*************************************
  Счетчик наработки ламп коллатен + макси
*************************************/
CPU_INT08U const CounterCollatenTimeName[] = "Колл.ч:мм";

TDataDescStruct const CounterCollatenTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_H_MM,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.collaten_time),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterCollatenTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterCollatenTimeDescId[] = "CounterCollatenTimeDesc";

/*************************************
  Счетчик наработки ламп ультрафиолет + макси
*************************************/
CPU_INT08U const CounterUFTimeName[] = "УФ ч:мм";

TDataDescStruct const CounterUFTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_H_MM,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.uf_time),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterUFTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterUFTimeDescId[] = "CounterUFTimeDesc";

/*************************************
  Общее количество тестовых запусков по соляриям
*************************************/
CPU_INT08U const CounterAllTestCountName[] = "Кол.тестов";

TDataDescStruct const CounterAllTestCountDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.test_count),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterAllTestCountName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterAllTestCountDescId[] = "CounterAllTestCountDesc";

/*************************************
  Общее время тестовых запусков по соляриям
*************************************/
CPU_INT08U const CounterAllTestTimeName[] = "Тесты,мин.";

TDataDescStruct const CounterAllTestTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.test_time),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterAllTestTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterAllTestTimeDescId[] = "CounterAllTestTimeDesc";


/*************************************
  Счетчик длительности уборок
*************************************/
CPU_INT08U const CounterCleaningTimeName[] = "Уборка,мин.";

TDataDescStruct const CounterCleaningTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.cleaning_time),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterCleaningTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterCleaningTimeDescId[] = "CounterCleaningTimeDesc";

/*************************************
  Счетчик количества уборок
*************************************/
CPU_INT08U const CounterCleaningCountName[] = "Кол.уборок";

TDataDescStruct const CounterCleaningCountDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.cleaning_count),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterCleaningCountName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterCleaningCountDescId[] = "CounterCleaningCountDesc";

/*************************************
  Средняя длительность уборки
*************************************/
CPU_INT08U const CounterCleaningMeanTimeName[] = "Ср.дл.уб.";

TDataDescStruct const CounterCleaningMeanTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M_SS,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.cleaning_mean_time),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterCleaningMeanTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterCleaningMeanTimeDescId[] = "CounterCleaningMeanTimeDesc";

/*************************************
  Средняя длительность теста
*************************************/
CPU_INT08U const CounterTestMeanTimeName[] = "Ср.дл.тестов";

TDataDescStruct const CounterTestMeanTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME_SEC_M_SS,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  CHANNELS_NUM,                        // размер массива
  &ChannelIndexDesc,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.test_mean_time),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  CounterTestMeanTimeName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterTestMeanTimeDescId[] = "CounterTestMeanTimeDesc";

/*************************************
  Общий счетчик денег
*************************************/
CPU_INT08U const CounterCommonMoneyName[] = "ВСЕГО,руб.";

TDataDescStruct const CounterCommonMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.common_money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterCommonMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterCommonMoneyDescId[] = "CounterCommonMoneyDesc";

/*************************************
  Cчетчик наличных денег
*************************************/
CPU_INT08U const CounterCashMoneyName[] = "НАЛ.,руб.";

TDataDescStruct const CounterCashMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.cash_money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterCashMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterCashMoneyDescId[] = "CounterCashMoneyDesc";

/*************************************
  Cчетчик безналичных денег
*************************************/
CPU_INT08U const CounterCardMoneyName[] = "БАНК.,руб.";

TDataDescStruct const CounterCardMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_RUB_CENT,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.card_money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterCardMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterCardMoneyDescId[] = "CounterCardMoneyDesc";

/*************************************
  Cчетчик денег по абонементам
*************************************/
CPU_INT08U const CounterAbonementMoneyName[] = "АБОНЕМ.,руб.";

TDataDescStruct const CounterAbonementMoneyDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, solar_counters.abonement_money),            // указатель на переменную или адрес FRAM
  NULL,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  CounterAbonementMoneyName,             // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const CounterAbonementMoneyDescId[] = "CounterAbonementMoneyDesc";

/*************************************
  Включение общего доступа по паролю
*************************************/
CPU_INT08U const EnableGlobalPassName[] = "Доступ по пар.";
TRangeValueULONG const EnableGlobalPassRange = {0, 1};
CPU_INT08U const EnableGlobalPass_str0[] = "нет";
CPU_INT08U const EnableGlobalPass_str1[] = "да";
CPU_INT08U const *EnableGlobalPassList[] = {EnableGlobalPass_str0, EnableGlobalPass_str1};

TDataDescStruct const EnableGlobalPassDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,                        // размер массива
  NULL,                     // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, EnableGlobalPass),            // указатель на переменную или адрес FRAM
  (void*)&EnableGlobalPassRange,                     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),                        // смещение между элементами в массиве
  EnableGlobalPassName,           // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableGlobalPassList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const EnableGlobalPassDescId[] = "EnableGlobalPassDesc";

#endif

#if defined(CONFIG_RELAY_ENABLE)
/*************************************
  Индекс реле
*************************************/
CPU_INT08U const RelayIndexName[] = " РЕЛЕ";
TRangeValueULONG const RelayIndexRange = {0, RELAY_COUNT - 1};
CPU_INT08U const RelayIndex_str0[] = "1";
CPU_INT08U const RelayIndex_str1[] = "2";
CPU_INT08U const RelayIndex_str2[] = "3";
CPU_INT08U const *RelayIndexList[] = {RelayIndex_str0, RelayIndex_str1, RelayIndex_str2};

CPU_INT32U relay_index;

TDataDescStruct const RelayIndexDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &relay_index,            // указатель на переменную или адрес FRAM
  (void*)&RelayIndexRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  RelayIndexName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  RelayIndexList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const RelayIndexDescId[] = "RelayIndexDesc";

/*************************************
  Включение реле
*************************************/
TDataDescStruct const RelayEnableDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  RELAY_COUNT,                       // размер массива
  &RelayIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, RelayEnable),            // указатель на переменную или адрес FRAM
  (void*)&ScoreEnableRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  ScoreEnableName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  ScoreEnableList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const RelayEnableDescId[] = "RelayEnableDesc";

/*************************************
  IP-адрес ethernet-реле
*************************************/
CPU_INT08U const RelayIpAddrName[] = "IP";

TDataDescStruct const RelayIpAddrDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,            // признак массива
  RELAY_COUNT,             // размер массива
  &RelayIndexDesc,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, RelayIpAddr),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  RelayIpAddrName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0xC0A800A0
};
char const RelayIpAddrDescId[] = "RelayIpAddrDesc";

/*************************************
  Канал реле
*************************************/
CPU_INT08U const RelayChannelName[] = "Канал";
TRangeValueULONG const RelayChannelRange = {0, 9};
CPU_INT08U const RelayChannel_str0[] = "1";
CPU_INT08U const RelayChannel_str1[] = "2";
CPU_INT08U const RelayChannel_str2[] = "3";
CPU_INT08U const RelayChannel_str3[] = "4";
CPU_INT08U const RelayChannel_str4[] = "1+2";
CPU_INT08U const RelayChannel_str5[] = "1+3";
CPU_INT08U const RelayChannel_str6[] = "1+4";
CPU_INT08U const RelayChannel_str7[] = "2+3";
CPU_INT08U const RelayChannel_str8[] = "2+4";
CPU_INT08U const RelayChannel_str9[] = "3+4";
CPU_INT08U const *RelayChannelList[] = {RelayChannel_str0, RelayChannel_str1, RelayChannel_str2, RelayChannel_str3, RelayChannel_str4, RelayChannel_str5, RelayChannel_str6, RelayChannel_str7, RelayChannel_str8, RelayChannel_str9};

TDataDescStruct const RelayChannelDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  RELAY_COUNT,                       // размер массива
  &RelayIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, RelayChannel),            // указатель на переменную или адрес FRAM
  (void*)&RelayChannelRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  RelayChannelName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  RelayChannelList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const RelayChannelDescId[] = "RelayChannelDesc";

/*************************************
  Время открытия двери
*************************************/
CPU_INT08U const RelayOpenTimeName[] = "Время откр,с";
TRangeValueULONG const RelayOpenTimeRange = {1, 3600};

TDataDescStruct const RelayOpenTimeDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_IS_ARRAY,           // признак массива
  RELAY_COUNT,                       // размер массива
  &RelayIndexDesc,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, RelayOpenTime),            // указатель на переменную или адрес FRAM
  (void*)&RelayOpenTimeRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  RelayOpenTimeName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  30                           
};
char const RelayOpenTimeDescId[] = "RelayOpenTimeDesc";

/*************************************
  Команда провеки реле
*************************************/
CPU_INT08U const RelayCommandName[] = "Команда";
TRangeValueULONG const RelayCommandRange = {0, 2};
CPU_INT08U const RelayCommand_str0[] = "нет";
CPU_INT08U const RelayCommand_str1[] = "открыть";
CPU_INT08U const RelayCommand_str2[] = "закрыть";
CPU_INT08U const *RelayCommandList[] = {RelayCommand_str0, RelayCommand_str1, RelayCommand_str2};

CPU_INT32U relay_cmd;

void OnchangeRelayCommand(void)
{
    if (relay_cmd == 1)
    {
        PostUserEvent(EVENT_OPEN_RELAY1 + relay_index);
    }
    else if (relay_cmd == 2)
    {
        PostUserEvent(EVENT_CLOSE_RELAY1 + relay_index);
    }
}

TDataDescStruct const RelayCommandDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  0,                       // указатель на дескриптор индекса массива
  &relay_cmd,            // указатель на переменную или адрес FRAM
  (void*)&RelayCommandRange,                    // указатель на границы параметра
  OnchangeRelayCommand,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  RelayCommandName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  RelayCommandList,        // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0                           
};
char const RelayCommandDescId[] = "RelayCommandDesc";


#endif

#ifdef CONFIG_FTP_CLIENT_ENABLE

/*************************************
  Включение FTP
*************************************/
TDataDescStruct const FtpEnableDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpEnable),            // указатель на переменную или адрес FRAM
  (void*)&EnableChannelRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  EnableChannelName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableChannelList,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};

char const FtpEnableDescId[] = "FtpEnableDesc";

/*************************************
  IP-адрес FTP-сервера 
*************************************/
CPU_INT08U const FtpServerIpAddrName[] = "FTP";

TDataDescStruct const FtpServerIpAddrDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_IP_ADDR,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpServerIpAddr),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  sizeof(CPU_INT32U),       // смещение между элементами в массиве
  FtpServerIpAddrName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0x5C356065 // "92.53.96.101"
};
char const FtpServerIpAddrDescId[] = "FtpServerIpAddrDesc";

/*************************************
  Логин FTP-сервера 
*************************************/
CPU_INT08U const FtpServerLoginName[] = "Логин";
CPU_INT08U const FtpServerLoginDefault[] = "xmiker_morozov";

TDataDescStruct const FtpServerLoginDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_CHAR_STRING,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  15,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpLogin),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  FtpServerLoginName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  (CPU_INT32U)&FtpServerLoginDefault[0]
};
char const FtpServerLoginDescId[] = "FtpServerLoginDesc";

/*************************************
  Пароль FTP-сервера 
*************************************/
CPU_INT08U const FtpServerPassName[] = "Пароль";
CPU_INT08U const FtpServerPassDefault[] = "Qwerty11";

TDataDescStruct const FtpServerPassDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_CHAR_STRING,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  15,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpPass),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  FtpServerPassName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  (CPU_INT32U)&FtpServerPassDefault[0]
};
char const FtpServerPassDescId[] = "FtpServerPassDesc";

/*************************************
  FTP идентификатор устройства
*************************************/
CPU_INT08U const FtpDeviceNumberName[] = "ID устр.";
TRangeValueULONG const FtpDeviceNumberRange = {0, 99999999};

TDataDescStruct const FtpDeviceNumberDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  NULL,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpDeviceNumber),            // указатель на переменную или адрес FRAM
  (void*)&FtpDeviceNumberRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  sizeof(CPU_INT32U),                       // смещение между элементами в массиве
  FtpDeviceNumberName,        // указатель на строку названия параметра
  DATA_NO_INDEX,           // признак индексного параметра (список строк)
  NULL,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const FtpDeviceNumberDescId[] = "FtpDeviceNumberDesc";

/*************************************
Время отправки статистики на FTP, час : мин
*************************************/
CPU_INT08U const FtpSendHourMinName[] = "Вр.отпр.";

TDataDescStruct const FtpSendHourMinDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_HOUR_MIN,    // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  0,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpSendHourMin),            // указатель на переменную или адрес FRAM
  (void*)&StatSendHourRange,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  FtpSendHourMinName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  60 * 1
};
char const FtpSendHourMinDescId[] = "FtpSendHourMinDesc";

/*************************************
  Интервал отправки на FTP
*************************************/
CPU_INT08U const FtpSendIntervalName[] = "Интервал";
TRangeValueULONG const FtpSendIntervalRange = {0, 7};
CPU_INT08U const FtpSendInterval_str0[] = "1ч";
CPU_INT08U const FtpSendInterval_str1[] = "2ч";
CPU_INT08U const FtpSendInterval_str2[] = "3ч";
CPU_INT08U const FtpSendInterval_str3[] = "4ч";
CPU_INT08U const FtpSendInterval_str4[] = "6ч";
CPU_INT08U const FtpSendInterval_str5[] = "8ч";
CPU_INT08U const FtpSendInterval_str6[] = "12ч";
CPU_INT08U const FtpSendInterval_str7[] = "24ч";
CPU_INT08U const *FtpSendIntervalList[] = {FtpSendInterval_str0, FtpSendInterval_str1, FtpSendInterval_str2, FtpSendInterval_str3,
                                           FtpSendInterval_str4, FtpSendInterval_str5, FtpSendInterval_str6, FtpSendInterval_str7};

TDataDescStruct const FtpSendIntervalDesc = {
  DATA_DESC_EDIT,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  NULL,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpSendIntervalIndex),            // указатель на переменную или адрес FRAM
  (void*)&FtpSendIntervalRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  FtpSendIntervalName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  FtpSendIntervalList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  7                           
};
char const FtpSendIntervalDescId[] = "FtpSendIntervalDesc";

/*************************************
  Последнее время отправки на ftp
*************************************/
CPU_INT08U const FtpLastSendTimeName[] = "Посл.вр.";

TDataDescStruct const FtpLastSendTimeDesc = {
  DATA_DESC_VIEW,           // тип дескриптора
  DATA_TYPE_TIME,          // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpLastTime),            // указатель на переменную или адрес FRAM
  NULL,     // указатель на границы параметра
  NULL,                     // функция по изменению
  0,       // смещение между элементами в массиве
  FtpLastSendTimeName,       // указатель на строку названия параметра
  DATA_NO_INDEX,            // признак индексного параметра (список строк)
  NULL,                     // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  0                           
};
char const FtpLastSendTimeDescId[] = "FtpLastSendTimeDesc";

/*************************************
  Последний результат отправки на FTP
*************************************/
CPU_INT08U const FtpLastSendResultName[] = "Посл.статус";
TRangeValueULONG const FtpLastSendResultRange = {0, 1};
CPU_INT08U const FtpLastSendResult_str0[] = "ОШИБКА";
CPU_INT08U const FtpLastSendResult_str1[] = "ОК";
CPU_INT08U const FtpLastSendResult_str2[] = "НЕИЗВЕСТНО";
CPU_INT08U const *FtpLastSendResultList[] = {FtpLastSendResult_str0, FtpLastSendResult_str1, FtpLastSendResult_str2};

TDataDescStruct const FtpLastSendResultDesc = {
  DATA_DESC_VIEW,          // тип дескриптора
  DATA_TYPE_ULONG,         // тип параметра
  DATA_LOC_FRAM,            // расположение параметра
  DATA_NO_ARRAY,           // признак массива
  0,                       // размер массива
  NULL,                       // указатель на дескриптор индекса массива
  (void*)offsetof(TFramMap, FtpLastResult),            // указатель на переменную или адрес FRAM
  (void*)&FtpLastSendResultRange,                    // указатель на границы параметра
  NULL,                    // функция по изменению
  0,                       // смещение между элементами в массиве
  FtpLastSendResultName,        // указатель на строку названия параметра
  DATA_IS_INDEX,           // признак индексного параметра (список строк)
  FtpLastSendResultList,        // указатель на список строк для индексного параметра
  DATA_INIT_DISABLE,
  2
};
char const FtpLastSendResultDescId[] = "FtpLastSendResultDesc";

/*************************************
  Команда отправить данные на ftp сейчас 
*************************************/
CPU_INT08U const FtpSendNowCmdName[] = "Отправить";

CPU_INT32U ftp_send_cmd;
extern CPU_INT08U time_to_ftp;

void OnChangeFtpSendNowCmd(void)
{
    if (ftp_send_cmd != 0)
    {
        time_to_ftp = FTP_FLAG_SEND_COUNTERS | FTP_FLAG_SEND_LOGS;
    }
}

TDataDescStruct const FtpSendNowCmdDesc = {
  DATA_DESC_EDIT,           // тип дескриптора
  DATA_TYPE_ULONG,          // тип параметра
  DATA_LOC_RAM,            // расположение параметра
  DATA_NO_ARRAY,            // признак массива
  0,             // размер массива
  NULL,        // указатель на дескриптор индекса массива
  (void*)&ftp_send_cmd,            // указатель на переменную или адрес FRAM
  (void*)&EnableChannelRange,     // указатель на границы параметра
  OnChangeFtpSendNowCmd,                     // функция по изменению
  0,                        // смещение между элементами в массиве
  FtpSendNowCmdName,       // указатель на строку названия параметра
  DATA_IS_INDEX,            // признак индексного параметра (список строк)
  EnableChannelList,                     // указатель на список строк для индексного параметра
  DATA_INIT_ENABLE,
  0
};
char const FtpSendNowCmdDescId[] = "FtpSendNowCmdDesc";

#endif // #ifdef CONFIG_FTP_CLIENT_ENABLE


char const WorkTimeDescArrId[] = "WorkTimeDesc";
char const ChannelIndexDescArrId[] = "ChannelIndexDesc";
char const EnableChannelDescArrId[] = "EnableChannelDesc";
char const EnableValidatorDescArrId[] = "EnableValidatorDesc";
char const EnableModemDescArrId[] = "EnableModemDesc";
char const EnableFiscalDescArrId[] = "EnableFiscalDesc";
char const EnableCoinDescArrId[] = "EnableCoinDesc";
char const TimeOutBeforeDescArrId[] = "TimeOutBeforeDesc";
char const TimeOutAfterDescArrId[] = "TimeOutAfterDesc";
char const MaxWorkTimeDescArrId[] = "MaxWorkTimeDesc";
char const MinWorkTimeDescArrId[] = "MinWorkTimeDesc";
char const WeekEndDescArrId[] = "WeekEndDesc";
char const PeriodWeekendIndexDescArrId[] = "PeriodWeekendIndexDesc";
char const PeriodWeekdaysIndexDescArrId[] = "PeriodWeekdaysIndexDesc";
char const PriceWeekendDescArrId[] = "PriceWeekendDesc";
char const PriceWeekdaysDescArrId[] = "PriceWeekdaysDesc";
char const PriceTimeWeekendDescArrId[] = "PriceTimeWeekendDesc";
char const PriceTimeWeekdaysDescArrId[] = "PriceTimeWeekdaysDesc";
char const T_Start_WeekdaysDescArrId[] = "T_Start_WeekdaysDesc";
char const T_End_WeekdaysDescArrId[] = "T_End_WeekdaysDesc";
char const T_Start_WeekendDescArrId[] = "T_Start_WeekendDesc";
char const T_End_WeekendDescArrId[] = "T_End_WeekendDesc";
char const PrintZReportDescArrId[] = "PrintZReportDesc";
char const PrintXReportDescArrId[] = "PrintXReportDesc";
char const SystemTimeDescArrId[] = "SystemTimeDesc";
char const SystemTimeEditDescArrId[] = "SystemTimeEditDesc";
char const CoinPerPulseDescArrId[] = "CoinPerPulseDesc";
char const  BillFormatDescArrId[] = "BillFormatDesc";
char const NameChannelDescArrId[] = "NameChannelDesc";
char const PassDescArrId[] = "PassDesc";
char const DeviceIDDescArrId[] = "DeviceIDDesc";
char const EnableEmailErrorSendDescArrId[] = "EnableEmailErrorSendDesc";
char const EnableEmailJournalSendDescArrId[] = "EnableEmailJournalSendDesc";
char const ClearJournalAfterSendDescArrId[] = "ClearJournalAfterSendDesc";
char const StatSendHourMinDescArrId[] = "StatSendHourMinDesc";
char const SendTestEmailDescArrId[] = "SendTestEmailDesc";
char const BillnomIndexDescArrId[] = "BillnomIndexDesc";
char const DeferredStartDescArrId[] = "DeferredStartDesc";
char const StartButtonNameDescArrId[] = "StartButtonNameDesc";
char const GatewayDescArrId[] = "GatewayDesc";
char const NetMaskDescArrId[] = "NetMaskDesc";
char const IpAddrDescArrId[] = "IpAddrDesc";
char const SelectProtectDescArrId[] = "SelectProtectDesc";
char const PostIpAddrDescArrId[] = "PostIpAddrDesc";
char const PostImpCostDescArrId[] = "PostImpCostDesc";
char const PostLenCostDescArrId[] = "PostLenCostDesc";
char const PostMinutePriceDescArrId[] = "PostMinutePriceDesc";
char const PostPauseDescArrId[] = "PostPauseDesc";
char const EnablePrintReportsDescArrId[] = "EnablePrintReportsDesc";
char const TerminalIpAddrDescArrId[] = "PosTerminalIpAddrDesctPauseDesc";
char const TerminalPortDescArrId[] = "TerminalPortDesc";
char const EnableTerminalDescArrId[] = "EnableTerminalDesc";
char const SelectedMoneyDescArrId[] = "SelectedMoneyDesc";
char const KeyMoneyDescArrId[] = "KeyMoneyDesc";
char const KeyActionDescArrId[] = "KeyActionDesc";
char const MakeSverkaDescArrId[] = "MakeSverkaDesc";
char const MakeSyncDescArrId[] = "MakeSyncDesc";
char const CounterChannelCardDescArrId[] = "CounterChannelCardDesc";
char const CounterChannelAbonementDescArrId[] = "CounterChannelAbonementDesc";
char const CounterCardDescArrId[] = "CounterCardDesc";
char const CounterChannelCardLongDescArrId[] = "CounterChannelCardLongDesc";
char const CounterChannelAbonementLongDescArrId[] = "CounterChannelAbonementLongDesc";
char const CounterLongCardDescArrId[] = "CounterLongCardDesc";
char const CounterLongAbonementDescArrId[] = "CounterLongAbonementDesc";
char const PostTimerDescArrId[] = "PostTimerDesc";
char const PostSignalDescArrId[] = "PostSignalDesc";
char const PostPauseLenCostDescId[] = "PostPauseLenCostDesc";
char const AbonementMoneyDescId[] = "AbonementMoneyDesc";
char const AbonementBonusDescId[] = "AbonementBonusDesc";
char const AbonementBestBeforeDescId[] = "AbonementBestBeforeDesc";
char const CountUseAbonementDescId[] = "CountUseAbonementDesc";

#if defined(BOARD_SOLARIUM_WEB)
char const SolariumTypeDescId[] = "SolariumTypeDescId";
char const SolariumTimeoutDescId[] = "SolariumTimeoutDescId";
char const SolariumPauseDescId[] = "SolariumPauseDescId";
char const SolariumVentilationTimeDescId[] = "SolariumVentilationTimeDescId";
char const SolariumPricePerMinDescId[] = "SolariumPricePerMinDesc";
char const SolariumMinTimeDescId[] = "SolariumMinTimeDesc";
char const SolariumMaxTimeDescId[] = "SolariumMaxTimeDesc";
char const ZummerEnableDescId[] = "ZummerEnableDesc";
#endif
char const JournalErrorNumberDescCodeId[] = "JournalErrorNumberDescCode";
char const JournalErrorNumberDescTimeId[] = "JournalErrorNumberDescTime";


//**************************************************
//**************************************************
//**************************************************
const TDataDescArrayStruct AllDataArray[] = 
{
    {&WorkTimeDesc, WorkTimeDescArrId},
    {&ChannelIndexDesc,  ChannelIndexDescArrId},
    {&EnableChannelDesc, EnableChannelDescArrId},
    {&EnableValidatorDesc,   EnableValidatorDescArrId},
    {&EnableModemDesc,   EnableModemDescArrId},
    {&EnableFiscalDesc,   EnableFiscalDescArrId},
    {&EnableCoinDesc,  EnableCoinDescArrId},
    {&TimeOutBeforeDesc,  TimeOutBeforeDescArrId},
    {&TimeOutAfterDesc,  TimeOutAfterDescArrId},
    {&MaxWorkTimeDesc,  MaxWorkTimeDescArrId},
    {&MinWorkTimeDesc,  MinWorkTimeDescArrId},
    {&WeekEndDesc,  WeekEndDescArrId},
    {&PeriodWeekendIndexDesc,  PeriodWeekendIndexDescArrId},
    {&PeriodWeekdaysIndexDesc,  PeriodWeekdaysIndexDescArrId},
    
    {&PriceWeekendDesc,  PriceWeekendDescArrId},
    {&PriceWeekdaysDesc,  PriceWeekdaysDescArrId},
    
    {&PriceTimeWeekendDesc,  PriceTimeWeekendDescArrId},
    {&PriceTimeWeekdaysDesc,  PriceTimeWeekdaysDescArrId},
    {&T_Start_WeekdaysDesc,  T_Start_WeekdaysDescArrId},
    {&T_End_WeekdaysDesc,  T_End_WeekdaysDescArrId},
    {&T_Start_WeekendDesc,  T_Start_WeekendDescArrId},
    {&T_End_WeekendDesc,  T_End_WeekendDescArrId},
    
    {&PrintZReportDesc,  PrintZReportDescArrId},
    {&PrintXReportDesc,  PrintXReportDescArrId},
    {&SystemTimeDesc,  SystemTimeDescArrId},
    {&SystemTimeEditDesc,  SystemTimeEditDescArrId},
    {&CoinPerPulseDesc,  CoinPerPulseDescArrId},
    
    {&BillFormatDesc,  BillFormatDescArrId},
    {&NameChannelDesc,  NameChannelDescArrId},
    
    {&PassDesc,  PassDescArrId},
    {&DeviceIDDesc,  DeviceIDDescArrId},
    
    {&EnableEmailErrorSendDesc,  EnableEmailErrorSendDescArrId},
    {&EnableEmailJournalSendDesc,  EnableEmailJournalSendDescArrId},
    {&ClearJournalAfterSendDesc,  ClearJournalAfterSendDescArrId},
    {&StatSendHourMinDesc,  StatSendHourMinDescArrId},
    {&SendTestEmailDesc,  SendTestEmailDescArrId},
    {&BillnomIndexDesc,  BillnomIndexDescArrId},
    
    {&DeferredStartDesc,  DeferredStartDescArrId},
    {&StartButtonNameDesc,  StartButtonNameDescArrId},
    
    {&GatewayDesc,  GatewayDescArrId},
    {&NetMaskDesc,  NetMaskDescArrId},
    {&IpAddrDesc,  IpAddrDescArrId},
    
    {&SelectProtectDesc,  SelectProtectDescArrId},
    {&PostIpAddrDesc,  PostIpAddrDescArrId},
    
    {&PostImpCostDesc,  PostImpCostDescArrId},
    {&PostLenCostDesc,  PostLenCostDescArrId},
    {&PostMinutePriceDesc,  PostMinutePriceDescArrId},
    {&PostPauseDesc,  PostPauseDescArrId},
    {&PostTimerDesc,  PostTimerDescArrId},
    {&PostSignalDesc,  PostSignalDescArrId},
    {&PostPauseLenCostDesc,  PostPauseLenCostDescId},

    {&EnablePrintReportsDesc,  EnablePrintReportsDescArrId},
    {&TerminalIpAddrDesc,  TerminalIpAddrDescArrId},
    {&TerminalPortDesc,  TerminalPortDescArrId},
    {&EnableTerminalDesc,  EnableTerminalDescArrId},
    {&SelectedMoneyDesc,  SelectedMoneyDescArrId},
    {&KeyMoneyDesc,  KeyMoneyDescArrId},
    {&KeyActionDesc,  KeyActionDescArrId},

    {&MakeSverkaDesc,  MakeSverkaDescArrId},
    {&MakeSyncDesc,  MakeSyncDescArrId},

    {&CounterChannelCardDesc,  CounterChannelCardDescArrId},
    {&CounterCardDesc,  CounterCardDescArrId},
    {&CounterChannelCardLongDesc,  CounterChannelCardLongDescArrId},
    {&CounterChannelAbonementLongDesc,  CounterChannelAbonementLongDescArrId},
    {&CounterLongCardDesc,  CounterLongCardDescArrId},
    {&CounterChannelAbonementDesc,  CounterChannelAbonementDescArrId},
    {&CounterLongAbonementDesc,  CounterLongAbonementDescArrId},

#if defined(BOARD_SOLARIUM_WEB)
    {&SolariumTypeDesc,  SolariumTypeDescId},
    {&SolariumTimeoutDesc,  SolariumTimeoutDescId},
    {&SolariumPauseDesc,  SolariumPauseDescId},
    {&SolariumVentilationTimeDesc,  SolariumVentilationTimeDescId},
    {&SolariumPricePerMinDesc,  SolariumPricePerMinDescId},
    {&SolariumMinTimeDesc,  SolariumMinTimeDescId},
    {&SolariumMaxTimeDesc,  SolariumMaxTimeDescId},
    {&ZummerEnableDesc,  ZummerEnableDescId},
#endif

    {&JournalErrorNumberDescCode,  JournalErrorNumberDescCodeId},
    {&JournalErrorNumberDescTime,  JournalErrorNumberDescTimeId},

#if defined(CONFIG_MUSIC_ENABLE)
    {&SoundTypeDesc,  SoundTypeDescId},
    {&PlayerStatusDesc,  PlayerStatusDescId},
    {&SoundVolumeDesc,  SoundVolumeDescId},
    {&SoundFileIndexDesc, SoundFileIndexDescId},
    {&SoundIpAddrDesc, SoundIpAddrDescId},
#endif

#if defined(BOARD_SOLARIUM_VLAD)
    {&SolariumModesDesc, SolariumModesDescId},
    {&SolarLampsCountDesc, SolarLampsCountDescId},
    {&SolarPricePerMinuteDesc, SolarPricePerMinuteDescId},
    {&SolarMaximumTimeMinutesDesc, SolarMaximumTimeMinutesDescId},
    {&SolarMinimumTimeMinutesDesc, SolarMinimumTimeMinutesDescId},
    {&SolarVentilationTimeMinutesDesc, SolarVentilationTimeMinutesDescId},
    {&SolarTimeoutBeforeMinutesDesc, SolarTimeoutBeforeMinutesDescId},
    {&SolarCurrentPricePerMinuteDesc, SolarCurrentPricePerMinuteDescId},

    {&DiscountIndexHourDesc, DiscountIndexHourDescId},
    {&DiscountBeginHourDesc, DiscountBeginHourDescId},
    {&DiscountEndHourDesc, DiscountEndHourDescId},
    {&DiscountValueHourDesc, DiscountValueHourDescId},
    {&DiscountIndexDayDesc, DiscountIndexDayDescId},
    {&DiscountValueDayDesc, DiscountValueDayDescId},
    {&DiscountIndexMonthDesc, DiscountIndexMonthDescId},
    {&DiscountValueMonthDesc, DiscountValueMonthDescId},
    {&DiscountIndexCustomDesc, DiscountIndexCustomDescId},
    {&DiscountValueCustomDesc, DiscountValueCustomDescId},
    {&DiscountDateBeginCustomDesc, DiscountDateBeginCustomDescId},
    {&DiscountDateEndCustomDesc, DiscountDateEndCustomDescId},
    {&DiscountValueCurrentDesc, DiscountValueCurrentDescId},

    {&ScoreIndexDesc, ScoreIndexDescId},
    {&ScoreRs485SpeedDesc, ScoreRs485SpeedDescId},
    {&ScoreEnableDesc, ScoreEnableDescId},
    {&ScoreRs485AddressDesc, ScoreRs485AddressDescId},
    {&ScoreCommandDesc, ScoreCommandDescId},
    {&ScoreStateDesc, ScoreStateDescId},
    {&ScoreColumnDesc, ScoreColumnDescId},

    {&SolariumTimePayedDesc, SolariumTimePayedDescId},
    {&SolariumTimePayedCrc16Desc, SolariumTimePayedCrc16DescId},
    {&SolariumMoneyPayedDesc, SolariumMoneyPayedDescId},
    {&SolarTimeoutAfterMinutesDesc, SolarTimeoutAfterMinutesDescId},
    {&SolarControlChannelDesc, SolarControlChannelDescId},

    {&CounterSolarMoneyDesc, CounterSolarMoneyDescId},
    {&CounterSolarRunsDesc, CounterSolarRunsDescId},
    {&CounterSolarWorkTimeDesc, CounterSolarWorkTimeDescId},
    {&CounterSolarTestWorkTimeDesc, CounterSolarTestWorkTimeDescId},

    {&CounterSolarTestRunsDesc, CounterSolarTestRunsDescId},

    {&SolariumModeIndexDesc, SolariumModeIndexDescId},
    {&CounterModeMoneyDesc, CounterModeMoneyDescId},
    {&CounterModeRunsDesc, CounterModeRunsDescId},
    {&CounterModeWorkTimeDesc, CounterModeWorkTimeDescId},
    {&CounterModeTestRunsDesc, CounterModeTestRunsDescId},
    {&CounterModeWorkTestTimeDesc, CounterModeWorkTestTimeDescId},

    {&CounterCollatenTimeDesc, CounterCollatenTimeDescId},
    {&CounterUFTimeDesc, CounterUFTimeDescId},
    {&CounterAllTestCountDesc, CounterAllTestCountDescId},
    {&CounterAllTestTimeDesc, CounterAllTestTimeDescId},

    {&CounterCommonMoneyDesc, CounterCommonMoneyDescId},
    {&CounterCashMoneyDesc, CounterCashMoneyDescId},
    {&CounterCardMoneyDesc, CounterCardMoneyDescId},

    {&SkinTypeIndexDesc, SkinTypeIndexDescId},
    {&SkinCollatenMaxTimeDesc, SkinCollatenMaxTimeDescId},
    {&SkinUFMaxTimeDesc, SkinUFMaxTimeDescId},
    {&SkinMaximalMaxTimeDesc, SkinMaximalMaxTimeDescId},
    {&EnableGlobalPassDesc, EnableGlobalPassDescId},

    {&PassDescCleaning, PassDescCleaningId},
    {&PassDescService, PassDescServiceId},
    {&PassDescTest, PassDescTestId},

    {&CounterCleaningTimeDesc, CounterCleaningTimeDescId},
    {&CounterCleaningCountDesc, CounterCleaningCountDescId},
    {&CounterCleaningMeanTimeDesc, CounterCleaningMeanTimeDescId},
    {&CounterTestMeanTimeDesc, CounterTestMeanTimeDescId},
    {&SolarCleaningTimeoutMinutesDesc, SolarCleaningTimeoutMinutesDescId},

#endif

#if defined(CONFIG_RELAY_ENABLE)
    {&RelayIndexDesc, RelayIndexDescId},
    {&RelayEnableDesc, RelayEnableDescId},
    {&RelayIpAddrDesc, RelayIpAddrDescId},
    {&RelayChannelDesc, RelayChannelDescId},
    {&RelayOpenTimeDesc, RelayOpenTimeDescId},
    {&RelayCommandDesc, RelayCommandDescId},

#endif

#if defined(CONFIG_SDCARD_ENABLE)
    {&SdCardStatusDesc,  SdCardStatusDescId},
#endif

#if defined(CONFIG_TERMINAL_ENABLE)
    {&TerminalProtocolDesc,  TerminalProtocolDescId},
#endif

#ifdef CONFIG_FTP_CLIENT_ENABLE
    {&FtpEnableDesc,  FtpEnableDescId},
    {&FtpServerIpAddrDesc,  FtpServerIpAddrDescId},
    {&FtpSendHourMinDesc,  FtpSendHourMinDescId},
    {&FtpSendIntervalDesc,  FtpSendIntervalDescId},
    {&FtpLastSendTimeDesc,  FtpLastSendTimeDescId},
    {&FtpLastSendResultDesc,  FtpLastSendResultDescId},
    {&FtpSendNowCmdDesc,  FtpSendNowCmdDescId},
    {&FtpDeviceNumberDesc,  FtpDeviceNumberDescId},
    {&FtpServerLoginDesc,  FtpServerLoginDescId},
    {&FtpServerPassDesc,  FtpServerPassDescId},
#endif

    {&CoinPulseLenDesc,  CoinPulseLenDescId},
    {&CoinPauseLenDesc,  CoinPauseLenDescId},
    {&CoinPulseDeltaDesc,  CoinPulseDeltaDescId},

    {&AbonementMoneyDesc,  AbonementMoneyDescId},
    {&AbonementBonusDesc,  AbonementBonusDescId},
    {&AbonementBestBeforeDesc,  AbonementBestBeforeDescId},
    {&CountUseAbonementDesc,  CountUseAbonementDescId},

    {NULL, NULL}
};


