Moyka/PROJECT/app/app_serv.c
2019-06-19 01:29:26 +03:00

694 lines
19 KiB
C

#include <includes.h>
#include "app_serv.h"
#include "coin.h"
#include "time.h"
#include "fiscal.h"
#include "menu.h"
#include "data.h"
#include "mode.h"
#include "menudesc.h"
#include "datadesc.h"
#include "menu.h"
#include "journal.h"
#include "fr.h"
#include "CRC16.h"
#include "host_app.h"
#include "console.h"
#include "keyboard.h"
// åñëè îïðåäåëèòü ýòîò ìàêðîñ, áóäóò âíîñèòüñÿ äåíüãè ïî êíîïêå F1
//#define _DEBUG_MONEY
CPU_INT32U SystemTime;
CPU_INT32U money_timestamp[COUNT_POST + COUNT_VACUUM];
CPU_INT08U ChannelsState[COUNT_POST + COUNT_VACUUM];
#define CHANNEL_STATE_FREE 0
#define CHANNEL_STATE_BUSY 1
#define CHANNEL_STATE_DISABLED 2
CPU_INT32U ChannelsCounters[COUNT_POST + COUNT_VACUUM];
CPU_INT32U ChannelsPayedTime[COUNT_POST + COUNT_VACUUM];
CPU_INT32U incas_bill_nom_counter[24];
CPU_INT32U incas_common_bill_counter;
#define USER_QUERY_LEN 64
OS_STK UserTaskStk[USER_TASK_STK_SIZE];
OS_EVENT *UserQuery = NULL;
void *UserTbl[USER_QUERY_LEN];
int GetUserEvent(int* event);
void UserPrintMoneyMenu(int post);
void WorkServer(void);
void UserPrintThanksMenu(int post);
void UserPrintFirstMenu(void);
void UserPrintErrorMenu(void);
CPU_INT32U GetChannelsTimeForFree(CPU_INT08U ch);
void LoadAcceptedMoney(void);
void SetAcceptedMoney(CPU_INT32U money,int post);
void ClearAcceptedMoney(int post);
CPU_INT32U GetAcceptedMoney(int post);
void InitPass(void);
int CheckChannelEnabled(CPU_INT08U channel);
int ChannelBusy(CPU_INT08U ch);
void UserPrintIpDeviceErrMenu(CPU_INT08U post);
void UserPrintPrintBillMenu(int post);
#ifdef BOARD_CENTRAL_CFG
static char incassation;
static char was_critical_error;
#endif
#ifdef BOARD_POST_CFG
static int out_pulse_count = 0;
static int out_pulse_len = 0;
void AddOutPulses(int count, int len_ms)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
out_pulse_count += count;
out_pulse_len = len_ms;
OS_EXIT_CRITICAL();
}
#endif
int drawPostInfo[COUNT_POST + COUNT_VACUUM] = {0,0,0,0,0,0,0,0};
int currentPosition = 0;
void DrawMenu(void)
{
if((SystemTime%2))
{
UserPrintMoneyMenu(currentPosition++);
RefreshMenu();
if(currentPosition >= COUNT_POST + COUNT_VACUUM) currentPosition = 0;
}
}
/*
Ñåðâåð îáðàáîòêè ñîáûòèé ïîëüçîâàòåëÿ
*/
void UserAppTask(void *p_arg)
{
CPU_INT32U print_timeout;
CPU_INT32U accmoney;
int event;
#ifdef BOARD_CENTRAL_CFG
static CPU_INT08U fr_conn_ctr = 0;
incassation = 0;
was_critical_error = 0;
#endif
while (1)
{
if (GetUserEvent(&event))
{
switch (event){
#ifdef BOARD_CENTRAL_CFG
case EVENT_UPATE_RTC:
{
// ïðî÷èòàåì òåêóùåå âðåìÿ
CPU_INT32U time = GetTimeSec();
if(SystemTime != time)
{
SystemTime = time;
PostUserEvent(EVENT_SEC);
}
// ïðîâåðêà ðåæèìà
CheckMode();
}
break;
case EVENT_SEC:
// ðàáî÷èé ñåðâåð - ñ÷åò÷èêè, ñîñòîÿíèÿ è ò.ï.
WorkServer();
// ïðîâåðèì ôèñêàëüíèê, åñëè îí îòâàëèëñÿ
if ((++fr_conn_ctr % 10) == 0)
{
if ((FiscalConnState == FISCAL_NOCONN) || (TstCriticalFiscalError()))
{
if (ConnectFiscalFast() == 0)
{
CheckFiscalStatus();
}
}
}
// ñåðâåð îøèáîê
ErrorServer();
// äàëüøå òîëüêî â ðàáî÷åì ðåæèìå
if (GetMode() != MODE_WORK)
{
break;
}
// åñëè åñòü îøèáêè, íå ðàáîòàåì
if (TstCriticalErrors())
{
UserPrintErrorMenu();
RefreshMenu();
// âûêëþ÷èì ïðèåì äåíåã
if (was_critical_error == 0)
{
CoinDisable();
was_critical_error = 1;
}
break;
}
// âêëþ÷èì çàíîâî ïðèåì äåíåã, åñëè áûëà îøèáêà
if (was_critical_error)
{
was_critical_error = 0;
break;
}
for(int post = 0; post < COUNT_POST + COUNT_VACUUM; post++)
{
accmoney = GetAcceptedMoney(post);
if (accmoney > 0)
{
drawPostInfo[post] = 1;
// ïå÷àòü ïî âíåøíåìó ñèãíàëó, æäåì òàéìàóò îòìåíû
GetData(&PrintTimeoutAfterDesc, &print_timeout, 0, DATA_FLAG_SYSTEM_INDEX);
if(print_timeout)
{
// åñëè óêàçàí òàéìàóò îáíóëåíèÿ äåíåã - ïðîñòî èõ îáíóëÿåì
if (labs(OSTimeGet() - money_timestamp[post]) > 1000UL * print_timeout)
{
SetAcceptedMoney(0, post);
}
}
}
else
{
drawPostInfo[post] = 0;
}
}
// ïðèíèìàåì äåíüãè
DrawMenu();
break;
case EVENT_MODE_CHANGE:
ReInitMenu();
SaveEventRecord(0, JOURNAL_EVENT_CHANGE_MODE, GetMode());
break;
case EVENT_COIN_INSERTED_POST1:
case EVENT_COIN_INSERTED_POST2:
case EVENT_COIN_INSERTED_POST3:
case EVENT_COIN_INSERTED_POST4:
case EVENT_COIN_INSERTED_POST5:
case EVENT_COIN_INSERTED_POST6:
case EVENT_COIN_INSERTED_VACUUM1:
case EVENT_COIN_INSERTED_VACUUM2:
{
CPU_INT32U cpp = 1;
CPU_INT32U money, accmoney;
int number_post = event - EVENT_COIN_INSERTED_POST1;
GetData(&CoinPerPulseDesc, &cpp, number_post, DATA_FLAG_DIRECT_INDEX);
money = cpp*GetResetCoinCount(number_post);
accmoney = GetAcceptedMoney(number_post);
accmoney += money;
SetAcceptedMoney(accmoney, number_post);
money_timestamp[number_post] = OSTimeGet();
if (money) SaveEventRecord(number_post, JOURNAL_EVENT_MONEY_COIN_POST1 + number_post, money);
}
break;
case EVENT_CASH_INSERTED_POST1:
case EVENT_CASH_INSERTED_POST2:
case EVENT_CASH_INSERTED_POST3:
case EVENT_CASH_INSERTED_POST4:
case EVENT_CASH_INSERTED_POST5:
case EVENT_CASH_INSERTED_POST6:
{
CPU_INT32U cpp = 1;
CPU_INT32U money, accmoney;
int number_post = event - EVENT_CASH_INSERTED_POST1;
GetData(&CashPerPulseDesc, &cpp, number_post, DATA_FLAG_DIRECT_INDEX);
money = cpp * GetResetCashCount(number_post);
accmoney = GetAcceptedMoney(number_post);
accmoney += money;
SetAcceptedMoney(accmoney, number_post);
money_timestamp[number_post] = OSTimeGet();
if (money) SaveEventRecord(number_post, JOURNAL_EVENT_MONEY_NOTE_POST1 + number_post, money);
}
break;
case EVENT_KEY_CANSEL:
break;
case EVENT_KEY_START:
case EVENT_KEY_USER_START:
if (incassation) break;
if (GetMode() != MODE_WORK)
{
if (!FlagForPrintReport) break;
if (GetCurrentMenu() == xReportMenuPanel)
{ // ïå÷àòàåì X-îò÷åò
CPU_INT08U err;
if (IsFiscalConnected())
{
FPend();
FiscPrintDayReportNoClear(30, &err);
FPost();
if (err) {SetFiscalErrorByCode(err);}
SaveEventRecord(0, JOURNAL_EVENT_PRINT_X, GetTimeSec());
GoToPreviousMenu();
}
}
else if (GetCurrentMenu() == zReportMenuPanel)
{ // ïå÷àòàåì Z-îò÷åò
CPU_INT08U err;
if (IsFiscalConnected())
{
FPend();
FiscPrintDayReportClear(30, &err);
FPost();
if (err) {SetFiscalErrorByCode(err);}
SaveEventRecord(0, JOURNAL_EVENT_PRINT_Z, GetTimeSec());
GoToPreviousMenu();
ClrFiscalErrorByCode(FR_ERROR_CODE_4E);
}
}
else if (GetCurrentMenu() == bufReportMenuPanel)
{ // ïå÷àòàåì Z-îò÷åòû èç áóôåðà
CPU_INT08U err;
if (IsFiscalConnected())
{
FPend();
FiscPrintDayReportsFromBuf(30, &err);
FPost();
if (err) {SetFiscalErrorByCode(err);}
SaveEventRecord(0, JOURNAL_EVENT_PRINT_BUF, GetTimeSec());
GoToPreviousMenu();
}
}
break;
}
if (TstCriticalErrors())
{
UserPrintErrorMenu();
RefreshMenu();
break;
}
break;
case EVENT_STOP_MONEY_POST1:
case EVENT_STOP_MONEY_POST2:
case EVENT_STOP_MONEY_POST3:
case EVENT_STOP_MONEY_POST4:
case EVENT_STOP_MONEY_POST5:
case EVENT_STOP_MONEY_POST6:
case EVENT_STOP_MONEY_VACUUM1:
case EVENT_STOP_MONEY_VACUUM2:
if (GetMode() == MODE_WORK) //
{
}
break;
case EVENT_CASH_PRINT_CHECK_POST1:
case EVENT_CASH_PRINT_CHECK_POST2:
case EVENT_CASH_PRINT_CHECK_POST3:
case EVENT_CASH_PRINT_CHECK_POST4:
case EVENT_CASH_PRINT_CHECK_POST5:
case EVENT_CASH_PRINT_CHECK_POST6:
case EVENT_CASH_PRINT_CHECK_VACUUM1:
case EVENT_CASH_PRINT_CHECK_VACUUM2:
if (GetMode() == MODE_WORK) // ïå÷àòàåì òîëüêî â ðàáî÷åì ðåæèìå
{
int number_post = event - EVENT_CASH_PRINT_CHECK_POST1;
// çäåñü ñîáûòèå ñòàðòà ïå÷àòè ÷åêà - âêëþ÷èëè íàñîñ èëè ïûëåñîñ
CPU_INT32U accmoney = GetAcceptedMoney(number_post);
if (accmoney > 0)
{
UserPrintPrintBillMenu(number_post);
RefreshMenu();
// íàïå÷àòàåì ÷åê
if (IsFiscalConnected())
{
if (PrintFiscalBill(accmoney,number_post) == 0) // çäåñü äîáàâèòü ñ êàêîãî ïîñòà ÷åê
{
SaveEventRecord(number_post, JOURNAL_EVENT_PRINT_BILL_POST1 + number_post, GetTimeSec());
}
}
IncCounter(number_post, ChannelsPayedTime[number_post], accmoney);
SetAcceptedMoney(0, number_post);
OSTimeDly(1000);
// ïîâåñèì ìåíþ "ÑÏÀÑÈÁÎ"
if (IsFiscalConnected())
{
UserPrintThanksMenu(number_post);
RefreshMenu();
}
OSTimeDly(1000);
LED_OK_OFF();
}
}
break;
case EVENT_KEY_F1:
FIO4SET_bit.P4_28 = 1;
OSTimeDly(50);
FIO4CLR_bit.P4_28 = 1;
OSTimeDly(50);
FIO4SET_bit.P4_28 = 1;
OSTimeDly(50);
FIO4CLR_bit.P4_28 = 1;
OSTimeDly(50);
FIO4SET_bit.P4_28 = 1;
OSTimeDly(50);
FIO4CLR_bit.P4_28 = 1;
OSTimeDly(50);
FIO4SET_bit.P4_28 = 1;
OSTimeDly(50);
FIO4CLR_bit.P4_28 = 1;
OSTimeDly(50);
FIO4SET_bit.P4_28 = 1;
OSTimeDly(50);
FIO4CLR_bit.P4_28 = 1;
break;
/*case EVENT_KEY_F2:
PostUserEvent(EVENT_CASH_INSERTED_POST2);
break;
case EVENT_KEY_F3:
PostUserEvent(EVENT_CASH_PRINT_CHECK_POST1);
break;*/
#endif
default:
break;
}
}
else
{
OSTimeDly(1);
}
}
}
/*!
Ïîëüçîâàòåëüñêàÿ èíèöèàëèçàöèÿ
*/
void UserStartupFunc(void)
{
#ifdef BOARD_CENTRAL_CFG
// èíèöèàëèçàöèÿ ðåæèìà ðàáîòû
InitMode();
// èíèöèàëèçàöèÿ äàííûõ
CheckAllData();
OnChangeInitByDefault();
// ïðîâåðèì äëèííûå ñ÷åò÷èêè
CheckLongCounters();
// âîññòàíîâèì äåíüãè
LoadAcceptedMoney();
// ïðîâåðèì ïàðîëü
InitPass();
// èíèöèàëèçàöèÿ ìåíþ
InitMenu();
OSTimeDly(1000);
InitFiscal();
// ïðîèíèöèàëèçèðóåì ÷àñû
InitRTC();
// ñäåëàåì çàïèñü î âêëþ÷åíèè
SaveEventRecord(0, JOURNAL_EVENT_DEVICE_ON, GetTimeSec());
// çàïóñòèì ìîíåòíèê
InitCoin();
#endif
// ñîçäàäèì î÷åðåäü è çàäà÷ó
if (UserQuery == NULL)
{
UserQuery = OSQCreate(&UserTbl[0], USER_QUERY_LEN);
OSTaskCreate(UserAppTask, (void *)0, (OS_STK *)&UserTaskStk[USER_TASK_STK_SIZE-1], USER_TASK_PRIO);
}
InitConsole();
#ifdef BOARD_CENTRAL_CFG
InitHostApp();
#endif
SystemTime = GetTimeSec();
#ifdef BOARD_CENTRAL_CFG
// ïåðåéäåì â ñòàðòîâîå ìåíþ, åñëè ðàáîòà
if (GetMode() == MODE_WORK) {SetMenu(WORK_MENU);}
else SetMenu(SERVICE_MENU);
#endif
}
int GetUserEvent(int* event)
{
CPU_INT08U err = 0;
int evt = (int)OSQPend(UserQuery, 1, &err);
if (err != 0) return 0;
*event = evt;
return 1;
}
void PostUserEvent(int event)
{
OSQPost(UserQuery, (void *)event);
}
void InitUserMenu(void)
{
}
void UserPrintMoneyMenu(int post)
{
char buf[32];
CPU_INT32U accmoney;
strcpy(buf, " ");
PrintUserMenuStr(buf, 0);
sprintf(buf, " Âíåñèòå äåíüãè");
PrintUserMenuStr(buf, 1);
accmoney = GetAcceptedMoney(post);
sprintf(buf, "Ïðèíÿòî %d ðóá.", accmoney);
PrintUserMenuStr(buf, 2);
if(post < COUNT_POST)
sprintf(buf, " Ïîñò %d", post + 1);
else if(post < COUNT_POST + COUNT_VACUUM)
sprintf(buf, "Ïûëåñîñ %d", post + 1 - COUNT_POST);
else
sprintf(buf, " ");
PrintUserMenuStr(buf, 3);
}
// âûâîä ìåíþ î íåâîçìîæîñòè ðàáîòû
void UserPrintErrorMenu(void)
{
char buf[32];
if (TstErrorFlag(ERROR_FR_CONN))
{
sprintf(buf, "ÎØÈÁÊÀ");
PrintUserMenuStr(buf, 0);
sprintf(buf, "ÍÅÒ ÑÂßÇÈ Ñ ÔÐ");
PrintUserMenuStr(buf, 1);
sprintf(buf, "");
PrintUserMenuStr(buf, 2);
PrintUserMenuStr(buf, 3);
}
else if (TstCriticalFiscalError())
{
sprintf(buf, "ÎØÈÁÊÀ");
PrintUserMenuStr(buf, 0);
CPU_INT08U errcode = 0;
sprintf(buf, "ÎØÈÁÊÀ ÔÐ");
PrintUserMenuStr(buf, 1);
GetFirstCriticalFiscalError(&errcode);
GetDataItem(&JournalErrorNumberDesc0, (CPU_INT08U*)buf, errcode);
PrintUserMenuStr(buf, 2);
GetDataItem(&JournalErrorNumberDesc1, (CPU_INT08U*)buf, errcode);
PrintUserMenuStr(buf, 3);
}
}
void WorkServer(void)
{
}
void UserPrintPrintBillMenu(int post)
{
char buf[32];
sprintf(buf, " ");
PrintUserMenuStr(buf, 0);
sprintf(buf, "Èäeò ïå÷àòü");
PrintUserMenuStr(buf, 1);
sprintf(buf, " ÷åêà");
PrintUserMenuStr(buf, 2);
if(post < COUNT_POST)
sprintf(buf, " Ïîñò %d", post + 1);
else
sprintf(buf, "Ïûëåñîñ %d", post + 1 - COUNT_POST);
PrintUserMenuStr(buf, 3);
}
void UserPrintThanksMenu(int post)
{
char buf[32];
sprintf(buf, " ");
PrintUserMenuStr(buf, 0);
sprintf(buf, " ÑÏÀÑÈÁÎ");
PrintUserMenuStr(buf, 1);
sprintf(buf, " ");
PrintUserMenuStr(buf, 2);
if(post < COUNT_POST)
sprintf(buf, " Ïîñò %d", post + 1);
else
sprintf(buf, "Ïûëåñîñ %d", post + 1 - COUNT_POST);
PrintUserMenuStr(buf, 3);
}
int ChannelBusy(CPU_INT08U ch)
{
return 0;
}
void UserPrintFirstMenu(void)
{
char buf[32];
sprintf(buf, " ");
PrintUserMenuStr(buf, 0);
sprintf(buf, " ÂÍÅÑÈÒÅ");
PrintUserMenuStr(buf, 1);
sprintf(buf, " ÄÅÍÜÃÈ");
PrintUserMenuStr(buf, 2);
sprintf(buf, " ");
PrintUserMenuStr(buf, 3);
}
// ïðîâåðêà, áûëè ëè ñîõðàíåíû äåíüãè äî âûêëþ÷åíèÿ ïèòàíèÿ
void LoadAcceptedMoney(void)
{
CPU_INT32U m,crc,crct;
for(int i = 0; i < COUNT_POST + COUNT_VACUUM; i++)
{
// ñ÷èòàåì cîõðàíåííûå äåíüãè èç FRAM
GetData(&AcceptedMoneyDesc, &m, i, DATA_FLAG_DIRECT_INDEX);
// ñ÷èòàåì crc16 ýòèõ äåíåã èç FRAM
GetData(&AcceptedMoneyCRC16Desc, &crc, i, DATA_FLAG_DIRECT_INDEX);
crct = crc16((unsigned char*)&m, sizeof(CPU_INT32U));
if (crct != crc)
{ // îáíóëÿåì, åñëè crc íå ñîøëàñü
m = 0;
crc = crc16((unsigned char*)&m, sizeof(CPU_INT32U));
SetData(&AcceptedMoneyDesc, &m, i, DATA_FLAG_DIRECT_INDEX);
SetData(&AcceptedMoneyCRC16Desc, &crc, i, DATA_FLAG_DIRECT_INDEX);
}
}
}
// äîáàâèòü äåíåã
void SetAcceptedMoney(CPU_INT32U money, int post)
{
CPU_INT32U m,crc;
m=money;
crc = crc16((unsigned char*)&m, sizeof(CPU_INT32U));
SetData(&AcceptedMoneyDesc, &m, post, DATA_FLAG_DIRECT_INDEX);
SetData(&AcceptedMoneyCRC16Desc, &crc, post, DATA_FLAG_DIRECT_INDEX);
}
// î÷èñòèòü ñ÷åò÷èê äåíåã
void ClearAcceptedMoney(int post)
{
CPU_INT32U m,crc;
m=0;
crc = crc16((unsigned char*)&m, sizeof(CPU_INT32U));
SetData(&AcceptedMoneyDesc, &m, post, DATA_FLAG_DIRECT_INDEX);
SetData(&AcceptedMoneyCRC16Desc, &crc, post, DATA_FLAG_DIRECT_INDEX);
}
// î÷èñòèòü ñ÷åò÷èê äåíåã
CPU_INT32U GetAcceptedMoney(int post)
{
CPU_INT32U m;
GetData(&AcceptedMoneyDesc, &m, post, DATA_FLAG_DIRECT_INDEX);
return m;
}
// èíèöèàëèçàöèÿ ïàðîëÿ
void InitPass(void)
{
CPU_INT32U pass,crc,crct;
GetData(&PassDesc, &pass, 0, DATA_FLAG_SYSTEM_INDEX);
GetData(&PassCRCDesc, &crc, 0, DATA_FLAG_SYSTEM_INDEX);
crct = crc16((unsigned char*)&pass, sizeof(CPU_INT32U));
if (crct != crc)
{ // îáíóëÿåì, åñëè crc íå ñîøëàñü
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);
}
}