Merge pull request #2 from dimoniche/develop

Develop
This commit is contained in:
Dmitriy 2026-04-17 10:11:15 +03:00 committed by GitHub
commit ccce9cd94d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
33 changed files with 6663 additions and 2399 deletions

12
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"files.associations": {
"array": "c",
"string": "c",
"string_view": "c",
"ranges": "c",
"span": "c",
"fram_map.h": "c",
"service_name.h": "c",
"variant": "c"
}
}

View File

@ -13,7 +13,7 @@
#include "keyboard.h"
#include "app_serv.h"
#include "lpc23xx-iap.h"
#include "rfid-spi.h"
extern const TFramMap config_params;
extern TFramMap *config_ram;
@ -94,6 +94,12 @@ static void AppTaskStart (void *p_arg)
SpiInit();
#endif
OSTimeDly(50);
#ifdef CONFIG_SPI_ENABLE
pcd_initialization();
#endif
#ifdef CONFIG_SPI1_ENABLE
spi1_init();
#endif

View File

@ -42,6 +42,7 @@
#if defined(BOARD_SOLARIUM_VLAD)
#include "app_vlad.h"
#endif
#include "rfid-spi.h"
#if defined(BOARD_SOLARIUM_WEB)
ApplicationState app_state;
@ -676,6 +677,7 @@ void UserAppTask(void *p_arg)
{
PrintSolariumPassMenu();
}
break;
case EVENT_KEY_STAR:
@ -2303,6 +2305,19 @@ void UserPrintPaymentErrorMenu(void)
PrintUserMenuStr(buf, 3);
}
void UserPrintAbonementPaymentErrorMenu(void)
{
char buf[32];
sprintf(buf, " Ïî ıòîé ÊÀĞÒÅ ÇÀÃÀĞÀ");
PrintUserMenuStr(buf, 0);
sprintf(buf, " ñåãîäíÿ ïîñåùåíèÿ");
PrintUserMenuStr(buf, 1);
sprintf(buf, " èñ÷åğïàíû");
PrintUserMenuStr(buf, 2);
sprintf(buf, " ");
PrintUserMenuStr(buf, 3);
}
int ChannelBusy(CPU_INT08U ch)
{
CPU_INT32U ch_en = 0;

View File

@ -57,6 +57,27 @@ typedef struct
#define USER_MENU_SKIN_ATTENTION_4 20
///
#define USER_MENU_SELECT_SERVICE_TIME 21
// ìåíþ äëÿ êàðòî÷íîé ñèñòåìû
#define USER_MENU_WAIT_CARD 30
#define USER_MENU_BALANCE_CARD 31
#define USER_MENU_START_INSERT_CARD_MONEY 32
#define USER_MENU_ALL_PRICE 33
#define USER_MENU_SILVER_BONUS 34
#define USER_MENU_GOLD_BONUS 35
#define USER_MENU_PLATINUM_BONUS 36
#define USER_MENU_BRILLANCE_BONUS 37
#define USER_MENU_START_PAY_CARD 38
#define USER_MENU_INSERT_BANK_CARD 39
#define USER_MENU_ERROR_BANK_CARD 40
#define USER_MENU_INSERT_BONUS_CARD 41
#define USER_MENU_FINISH_PAY_BONUS_CARD 42
#define USER_MENU_ABONENT_PROCESSING 43
#define USER_MENU_ABONENT_WRONG 44
#define USER_MENU_ABONEMENT_FAIL 45
///
#define USER_MENU_ERROR 255
@ -65,13 +86,15 @@ typedef struct
CPU_INT08U menu_timeout;
#define MENU_THANKS_TIMEOUT 5
#define MENU_CARD_FAIL_TIMEOUT 3
#define MENU_CARD_ABONEMENT_FAIL_TIMEOUT 6
#define MENU_ATTENTION_TIMEOUT 5
CPU_INT08U ch_index;
CPU_INT08U mode_index;
CPU_INT08U pay_index;
#define PAY_TYPE_CASH 0
#define PAY_TYPE_CARD_ABONEMENT 0
#define PAY_TYPE_CARD 1
#define PAY_TYPE_CASH 2
CPU_INT08U solar_state[CHANNELS_NUM];
#define SOLAR_STATE_FREE 0
@ -106,6 +129,19 @@ typedef struct
#define SOLAR_IN_SERVICE 1
#define SOLAR_IN_TEST 2
CPU_INT32U last_card_manipulation_time;
#define MENU_CARD_MANIPULATION_TIMEOUT_MS 10000
#define MENU_CARD_WRONG_TIMEOUT_MS 3000
#define MENU_WAIT_CARD_ABONEMENT_TIMEOUT_MS 20000
CPU_INT08U current_abonement;
#define SILVER_ABONEMENT 0
#define GOLD_ABONEMENT 1
#define PLATINUM_ABONEMENT 2
#define DIAMOND_ABONEMENT 3
CPU_INT32U abonementtopay;
} ApplicationState;
extern ApplicationState app_state;
#endif
@ -265,6 +301,11 @@ enum{
#elif defined(BOARD_CENTRAL_CARWASH)
EVENT_REREAD_SIGNAL_LEVEL,
#endif
#if defined(BOARD_SOLARIUM_VLAD)
EVENT_FINISH_PAYMENT_ABONEMENT,
EVENT_FINISH_PAYMENT_ABONEMENT_SOLARIUM,
#endif
};
#define EVENT_KEY_LEFT EVENT_KEY_POST2
@ -288,6 +329,7 @@ extern void SetAcceptedMoney(CPU_INT32U money);
extern void PrintCardBill(void);
extern void UserPrintTerminalRequestMenu();
extern void UserPrintPaymentErrorMenu(void);
extern void UserPrintAbonementPaymentErrorMenu(void);
extern void UserPrintResultMenu(void);
#endif //#ifndef _APP_SERV_H_

File diff suppressed because it is too large Load Diff

View File

@ -285,6 +285,8 @@ int ReadFtpCountersString(int index, char *buf)
}
// ÷òåíèå î÷åðåäíîé ñòðîêè äëÿ ñîçäàíèÿ ôàéëà csv æóðíàëîâ
TEventRecord record;
int ReadFtpLogString(int index, char *buf)
{
static const char header[] = "Íîìåð çàïèñè;Âðåìÿ;Ñîáûòèå;Äàííûå\r\n";
@ -295,7 +297,6 @@ int ReadFtpLogString(int index, char *buf)
}
else if ((index >= 1) && (index <= EVENT_RECORDS_COUNT))
{
TEventRecord record;
index -= 1;
GetEventRecord(&record, index);
sprintf(buf, "%d;", index);

View File

@ -119,6 +119,26 @@ int GetEventRecord(TEventRecord* record, CPU_INT32U index)
return 0;
}
void SaveEventAbonementRecord(TEventRecord * record)
{
journal_getSem();
record->time = GetTimeSec();
WriteArrayFram(offsetof(TFramMap, EventRecords[0])+journal_rec_index*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)record);
journal_rec_index = (journal_rec_index + 1) % EVENT_RECORDS_COUNT;
#ifdef CONFIG_FTP_CLIENT_ENABLE
if ((journal_rec_index == 0) || (journal_rec_index == EVENT_RECORDS_COUNT / 2))
{
time_to_ftp = FTP_FLAG_SEND_COUNTERS | FTP_FLAG_SEND_LOGS;
}
#endif
journal_freeSem();
}
// çàïèñü â æóðíàë çàïèñè î ñîáûòèè
void SaveEventRecord(CPU_INT08U channel, CPU_INT08U event, CPU_INT16U data)
{
@ -191,9 +211,33 @@ void GetEventStr(char* str, char event)
case JOURNAL_EVENT_CARD_ACCEPTED:
sprintf(str, "Áàíê.îïëàòà ");
break;
case JOURNAL_EVENT_CARD_ABONEMENT_ACCEPTED:
sprintf(str, "Áàíê.îïëàòà ïîïîëí.");
break;
case JOURNAL_EVENT_CARD_REJECTED:
sprintf(str, "Áàíê.îïëàòà ");
break;
case JOURNAL_EVENT_ABONEMENT_ACCEPTED:
sprintf(str, "ÁÊÇ.îïëàòà ");
break;
case JOURNAL_EVENT_ABONEMENT_REJECTED:
sprintf(str, "ÁÊÇ.îòêàç ");
break;
case JOURNAL_EVENT_ABONEMENT_PAY_ACCEPTED:
sprintf(str, "ÁÊÇ.ïîïîëí.");
break;
case JOURNAL_EVENT_CARD_ABONEMENT_REAPEATE:
sprintf(str, "ÁÊÇ.îòêàç.Ïîâòîð");
break;
case JOURNAL_EVENT_ABONEMENT_PAY_REJECTED:
sprintf(str, "ÁÊÇ.ïîïîëí.");
break;
case JOURNAL_EVENT_ABONEMENT_BALANCE:
sprintf(str, "ÁÊÇ.áàëàíñ ");
break;
case JOURNAL_EVENT_ABONEMENT_WRONG:
sprintf(str, "ÁÊÇ.êàðòà ");
break;
case JOURNAL_EVENT_START_SESSION:
#if defined(BOARD_CENTRAL_CARWASH)
sprintf(str, "Íà÷.ðàáîòû ");
@ -388,7 +432,13 @@ void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money, CPU_INT08U car
WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelRun)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&r);
WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelTime)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&t);
if (card)
if (card == 2)
{
ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelAbonement)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m);
m+=money;
WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelAbonement)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m);
}
else if (card)
{
ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelCard)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m);
m+=money;
@ -409,7 +459,13 @@ void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money, CPU_INT08U car
WriteArrayFram(offsetof(TFramMap, Counters.CounterRun), sizeof(CPU_INT32U), (unsigned char*)&r);
WriteArrayFram(offsetof(TFramMap, Counters.CounterTime), sizeof(CPU_INT32U), (unsigned char*)&t);
if (card)
if (card == 2)
{
ReadArrayFram(offsetof(TFramMap, Counters.CounterAbonement), sizeof(CPU_INT32U), (unsigned char*)&m);
m+=money;
WriteArrayFram(offsetof(TFramMap, Counters.CounterAbonement), sizeof(CPU_INT32U), (unsigned char*)&m);
}
else if (card)
{
ReadArrayFram(offsetof(TFramMap, Counters.CounterCard), sizeof(CPU_INT32U), (unsigned char*)&m);
m+=money;
@ -429,7 +485,12 @@ void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money, CPU_INT08U car
long_ctrs.CounterRunLong++;
long_ctrs.CounterTimeLong += time;
if (card)
if (card == 2)
{
long_ctrs.CounterChannelAbonementLong[ch] += money;
long_ctrs.CounterAbonementLong += money;
}
else if (card)
{
long_ctrs.CounterChannelCardLong[ch] += money;
long_ctrs.CounterCardLong += money;

View File

@ -4,7 +4,7 @@
#include "control.h"
#include "fiscal.h"
#define EVENT_RECORDS_COUNT 512 // число записей в журнале
#define EVENT_RECORDS_COUNT 150 // ÷èñëî çàïèñåé â æóðíàëå
#pragma pack(push, 1)
/// ñòðóêòóðà çàïèñè æóðíàëà ðàáî÷èõ ñîáûòèé
@ -99,18 +99,71 @@ typedef struct{
// îøèáêà ñâÿçè ñ ôèñêàëüíèêîì
#define ERROR_FR_CONN 52
#define JOURNAL_EVENT_ABONEMENT_ACCEPTED 53 // ïðèíÿò àáîíåìåíò, ñóììà áåçíàëà
#define JOURNAL_EVENT_ABONEMENT_REJECTED 54 // àáîíåìåíò îòêëîíåí
#define JOURNAL_EVENT_ABONEMENT_PAY_ACCEPTED 55 // êóïëåí àáîíåìåíò, ñóììà áåçíàëà
#define JOURNAL_EVENT_ABONEMENT_PAY_REJECTED 56 // ïîêóïêà àáîíåìåíòà îòêëîíåíà
#define JOURNAL_EVENT_ABONEMENT_BALANCE 57 // ÷òåíèå áàëàíñà
#define JOURNAL_EVENT_ABONEMENT_WRONG 58 // íå âåðíàÿ êàðòà
#define JOURNAL_EVENT_CARD_ABONEMENT_ACCEPTED 59 // ïðèíÿòà êàðòà, ñóììà áåçíàëà - îïëàòà àáîíåìåíòà
#define JOURNAL_EVENT_CARD_ABONEMENT_REAPEATE 60 // ïðåâûøåíî êîëè÷åñòâî ïîñåùåíèé â äåíü
// ÂÑÅ ÎØÈÁÊÈ ÔÐ ÔÀÒÀËÜÍÛÅ
#define ERROR_FR 53
#define ERROR_FR 61
#define JOURNAL_EVENTS_COUNT (ERROR_FR + FR_ERROR_NUMBER) // ÷èñëî ñîáûòèé
// êàíàë
union
{
CPU_INT08U channel;
CPU_INT08U type_abonement;
};
// данные: для получения денег - номинал купюры, для сеанса - длительность оплаченного времени, мин.
/// @brief äàííûå: äëÿ ïîëó÷åíèÿ äåíåã - íîìèíàë êóïþðû, äëÿ ñåàíñà - äëèòåëüíîñòü îïëà÷åííîãî âðåìåíè, ìèí., ïîòðà÷åííûå äåíüãè
union
{
CPU_INT16U data;
CPU_INT16U money;
};
}TEventRecord;
/// @brief Ïîòðà÷åííûå áîíóñû
union
{
CPU_INT16U bonus;
};
/// @brief Äàòà îêîí÷àíèÿ àáîíåìåíòà, ïàðîëü, ñóììà äëÿ áàíêà â êîïåéêàõ
union
{
CPU_INT32U time_before;
CPU_INT32U password;
CPU_INT32U money_bank;
};
/// @brief Íîìåð êàðòû
union
{
CPU_INT32U number_abonement;
};
/// @brief Äåíüãè íà êàðòå
union
{
CPU_INT16U money_sum;
};
/// @brief Áîíóñû íà êàðòå
union
{
CPU_INT16U bonus_sum;
};
}TEventRecord; // 22 áàéòà
#pragma pack(pop)
#if defined(BOARD_SOLARIUM_VLAD)
@ -123,8 +176,23 @@ typedef struct{
CPU_INT32U runs;
/// êîëè÷åñòâî ñåêóíä ðàáîòû
CPU_INT32U worktime;
// äåíüãè ñ êàðò
CPU_INT32U card_money;
// áîíóñà ñ êàðò
CPU_INT32U card_bonus;
}SolarCountersRecord;
/// ñòðóêòóðà çàïèñè ñ÷åò÷èêîâ î ñîëÿðèè â îäíîì ðåæèìå
typedef struct{
/// ÷èñëî çàïóñêîâ
CPU_INT32U runs;
// äåíüãè ñ êàðò
CPU_INT32U card_money;
// áîíóñà ñ êàðò
CPU_INT32U card_bonus;
}AbonentCountersRecord;
/// ñòðóêòóðà âñåõ ñ÷åò÷èêîâ äëÿ ñîëÿðèÿ
typedef struct{
/// ñ÷åò÷èêè ïî ñîëÿðèÿì è ðåæèìàì
@ -135,6 +203,10 @@ typedef struct{
SolarCountersRecord solar_m[SOLAR_MODES_COUNT];
/// ñ÷åò÷èêè òåñòà ïî ðåæèìàì
SolarCountersRecord solar_m_test[SOLAR_MODES_COUNT];
/// ñ÷åò÷èêè ïî àáîíåìåíòàì
AbonentCountersRecord abonement[5];
/// îòðàáîòàííîå âðåìÿ êîëëàòåí+ìàêñè ïî ñîëÿðèÿì
CPU_INT32U collaten_time[CHANNELS_NUM];
/// îòðàáîòàííîå âðåìÿ óëüòðàôèîëåò+ìàêñè ïî ñîëÿðèÿì
@ -145,6 +217,8 @@ typedef struct{
CPU_INT32U cash_money;
/// äåíåã ïî êàðòå
CPU_INT32U card_money;
/// äåíåã ïî àáîíåìåíòàì
CPU_INT32U abonement_money;
/// êîëè÷åñòâî êóïþð
CPU_INT32U bill_count;
/// êîëè÷åñòâî óáîðîê
@ -175,6 +249,8 @@ typedef struct{
CPU_INT32U CounterChannelMoney[CHANNELS_NUM];
// Ñóììà áåçíàëà ïîêàíàëüíî
CPU_INT32U CounterChannelCard[CHANNELS_NUM];
// Ñóììà ïî àáîíåìåíòó
CPU_INT32U CounterChannelAbonement[CHANNELS_NUM];
// îáùåå ÷èñëî çàïóñêîâ
CPU_INT32U CounterRun;
@ -184,6 +260,8 @@ typedef struct{
CPU_INT32U CounterMoney;
// îáùåå Ñóììà áåçíàëà
CPU_INT32U CounterCard;
// îáùåå Ñóììà ïî àáîíåìåíòó
CPU_INT32U CounterAbonement;
// ñ÷åò÷èêè êóïþð â êóïþðíèêå ïî íîìèíàëàì
CPU_INT32U CounterBillNominals[24];
@ -202,11 +280,15 @@ typedef struct{
CPU_INT32U CounterChannelMoneyLong[CHANNELS_NUM];
// Ñóììà áåçíàëà ïîêàíàëüíî
CPU_INT32U CounterChannelCardLong[CHANNELS_NUM];
// Ñóììà ïî àáîíåìåíòó
CPU_INT32U CounterChannelAbonementLong[CHANNELS_NUM];
CPU_INT32U CounterRunLong;
CPU_INT32U CounterTimeLong;
CPU_INT32U CounterMoneyLong;
CPU_INT32U CounterCardLong;
CPU_INT32U CounterAbonementLong;
CPU_INT16U crc;
}TCountersLong;
@ -214,6 +296,11 @@ typedef struct{
extern void IncBillnomCounter(CPU_INT32U index);
extern void CheckLongCounters(void);
extern void SaveEventRecord(CPU_INT08U channel, CPU_INT08U event, CPU_INT16U data);
/// @brief Ñîõðàíåíèå çàïèñè æóðíàëà
/// @param record çàïèñü æóðíàëà
extern void SaveEventAbonementRecord(TEventRecord * record);
extern void SetErrorFlag(CPU_INT08U error);
extern void ClrErrorFlag(CPU_INT08U error);
extern int TstErrorFlag(CPU_INT08U error);

View File

@ -0,0 +1,8 @@
#include "service_name.h"
char service_name[] = "Услуга загара в солярии";
char* get_service_name()
{
return service_name;
}

View File

@ -0,0 +1,13 @@
#ifndef _SERVICE_NAME_H_
#define _SERVICE_NAME_H_
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
/// @brief Возвращаем имя услуги
/// @return
extern char* get_service_name();
#endif

View File

@ -10,6 +10,7 @@
#include <string.h>
#include "time.h"
#include "ftp_app.h"
#include "service_name.h"
static OS_STK TermTaskStk[TERM_TASK_STK_SIZE];
@ -153,7 +154,7 @@ int TermReadPacket(NET_SOCK_ID sock, CPU_INT08U *packet, CPU_INT32U maxlen, CPU_
CPU_INT08U c;
CPU_INT16U packet_len = 0;
// длина
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!TermReadChar(sock, &packet[0], timeout)) return len;
len++;
if (!TermReadChar(sock, &packet[1], timeout)) return len;
@ -161,7 +162,7 @@ int TermReadPacket(NET_SOCK_ID sock, CPU_INT08U *packet, CPU_INT32U maxlen, CPU_
packet_len = (uint16_t)packet[0] * 256UL + (uint16_t)packet[1];
if (packet_len < 2) return 0;
// метка
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!TermReadChar(sock, &packet[2], timeout)) return len;
len++;
if (!TermReadChar(sock, &packet[3], timeout)) return len;
@ -175,7 +176,7 @@ int TermReadPacket(NET_SOCK_ID sock, CPU_INT08U *packet, CPU_INT32U maxlen, CPU_
if ((packet[2] != 0x97) || (packet[3] != 0xFB)) return 0;
}
// тэги
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (len < packet_len + 2)
{
CPU_INT16U tag;
@ -290,7 +291,7 @@ uint32_t SetTermCommand(uint32_t cmd, uint32_t* param)
return curr_cmd;
}
/// создать заголовок
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t ttk2_tag_header(char *buf)
{
buf[2] = '\x96';
@ -298,7 +299,7 @@ uint32_t ttk2_tag_header(char *buf)
return 4;
}
/// создать заголовок
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
uint32_t vtk_tag_header(char *buf)
{
buf[2] = '\x96';
@ -306,7 +307,7 @@ uint32_t vtk_tag_header(char *buf)
return 4;
}
/// задать длину
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
uint32_t ttk2_tag_setlen(char *buf, uint16_t len)
{
buf[0] = (len >> 8) & 0xFF;
@ -314,7 +315,7 @@ uint32_t ttk2_tag_setlen(char *buf, uint16_t len)
return 2;
}
/// записать тэг, возвращает длину
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
uint32_t ttk2_tag_add(char *buf, uint16_t id, char *value, uint8_t value_len)
{
buf[0] = (char)(id & 0xFF);
@ -376,7 +377,7 @@ int ttk2_get_field(CPU_INT08U *packet, uint32_t packet_len, uint16_t field, uint
return 0;
}
/// получение параметров из последнего удачного запроса (информация для чека)
/// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>)
int ttk2_get_field_string(uint16_t field, char* str, uint16_t maxlen)
{
int tag_size;
@ -448,6 +449,7 @@ void TermAppTask(void *p_arg)
if (time_to_ftp & FTP_FLAG_CLEAR_LOGS)
{
ClearEventJournal();
JournalInit();
}
}
else
@ -472,8 +474,8 @@ void TermAppTask(void *p_arg)
GetData(&TerminalProtocolDesc, &proto, 0, DATA_FLAG_SYSTEM_INDEX);
if (proto == TERMINAL_PROTOCOL_VTK)
{
// дальше протокол VTK
// периодический запрос IDL
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VTK
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> IDL
if (OSTimeGet() - idl_stamp > op_timeout * 1000UL / 2)
{
NET_ERR err;
@ -488,15 +490,15 @@ void TermAppTask(void *p_arg)
uint32_t packet_len;
char *content;
// заголовок
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
vtk_tag_header(term_buffer);
// содержимое
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "IDL", 3);
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
OSTimeDly(50);
@ -512,11 +514,11 @@ void TermAppTask(void *p_arg)
char opcode[16];
int tag_size;
memset(opcode, 0, 16);
// код сообщения
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
tag_size = ttk2_get_field((CPU_INT08U *)term_buffer, plen, 0x01, (uint8_t*)opcode, 15);
if ((tag_size == 3) && (strcmp(opcode, "IDL") == 0))
{
// таймаут операции
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int value;
memset(opcode, 0, 16);
tag_size = ttk2_get_field((CPU_INT08U *)term_buffer, plen, 0x06, (uint8_t*)opcode, 15);
@ -524,7 +526,7 @@ void TermAppTask(void *p_arg)
{
op_timeout = value;
}
// номер операции
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memset(opcode, 0, 16);
tag_size = ttk2_get_field((CPU_INT08U *)term_buffer, plen, 0x03, (uint8_t*)opcode, 15);
if (sscanf(opcode, "%d", &value) == 1)
@ -562,7 +564,7 @@ void TermAppTask(void *p_arg)
{
uint32_t packet_len;
char *content;
char str[16];
char str[32];
term_state = TERM_STATE_WAITING_PUR;
term_command_new &= ~TERM_COMMAND_ABORT_PUR;
@ -571,9 +573,9 @@ void TermAppTask(void *p_arg)
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "VRP", 3);
// номер операции
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
++op_number;
sprintf(str, "%d", op_number);
packet_len += ttk2_tag_add(&content[packet_len], 0x03, str, strlen(str));
@ -588,9 +590,13 @@ void TermAppTask(void *p_arg)
packet_len += ttk2_tag_add(&content[packet_len], 0x09, "1", 1);
// timeout
packet_len += ttk2_tag_add(&content[packet_len], 0x06, "60", 1);
// длина в пакете
// Product name
packet_len += ttk2_tag_add(&content[packet_len], 0x0F, get_service_name(), 43);
// <20><><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
OSTimeDly(50);
@ -629,14 +635,14 @@ void TermAppTask(void *p_arg)
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "ABR", 3);
// номер операции
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sprintf(str, "%d", op_number);
packet_len += ttk2_tag_add(&content[packet_len], 0x03, str, strlen(str));
// длина в пакете
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
int writed = HostWriteData(sock, term_buffer, packet_len);
@ -665,14 +671,14 @@ void TermAppTask(void *p_arg)
tag_size = ttk2_get_field((CPU_INT08U *)term_buffer, plen, 0x04, (uint8_t*)opcode, 15);
if ((tag_size > 0) && (strcmp(opcode, str) == 0))
{
// VRP OK, посылаем FIN
// VRP OK, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FIN
vtk_tag_header(term_buffer);
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "FIN", 3);
// номер операции
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
sprintf(str, "%d", op_number);
packet_len += ttk2_tag_add(&content[packet_len], 0x03, str, strlen(str));
// transaction amount (money * 100)
@ -680,9 +686,9 @@ void TermAppTask(void *p_arg)
packet_len += ttk2_tag_add(&content[packet_len], 0x04, str, strlen(str));
// product id
packet_len += ttk2_tag_add(&content[packet_len], 0x09, "1", 1);
// длина в пакете
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
OSTimeDly(50);
@ -781,7 +787,7 @@ void TermAppTask(void *p_arg)
continue;
}
// дальше протокол ТТК2
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>2
if (term_state == TERM_STATE_IDLE)
{
if (term_command_new & TERM_COMMAND_MAKE_SVERKA)
@ -806,18 +812,18 @@ void TermAppTask(void *p_arg)
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "SRV", 3);
// номер клиента
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x02, "1", 1);
// номер документа (ERN)
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ERN)
sprintf(str, "%d", terminal_info.ern);
packet_len += ttk2_tag_add(&content[packet_len], 0x03, str, strlen(str));
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x1A, "2", 1);
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
OSTimeDly(50);
@ -919,18 +925,18 @@ void TermAppTask(void *p_arg)
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "SRV", 3);
// номер клиента
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x02, "1", 1);
// номер документа (ERN)
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ERN)
sprintf(str, "%d", terminal_info.ern);
packet_len += ttk2_tag_add(&content[packet_len], 0x03, str, strlen(str));
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x1A, "8", 1);
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
OSTimeDly(50);
@ -1041,11 +1047,11 @@ void TermAppTask(void *p_arg)
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "PUR", 3);
// номер клиента
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x02, "1", 1);
// номер документа (ERN)
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ERN)
sprintf(str, "%d", terminal_info.ern);
packet_len += ttk2_tag_add(&content[packet_len], 0x03, str, strlen(str));
// transaction amount (money * 100)
@ -1059,10 +1065,10 @@ void TermAppTask(void *p_arg)
packet_len += ttk2_tag_add(&content[packet_len], 0x08, "\xC0", 1);
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
// сохраним признак операции
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
terminal_info.request_active = 1;
SaveTerminalInfo(&terminal_info);
@ -1072,7 +1078,7 @@ void TermAppTask(void *p_arg)
if (writed != packet_len)
{
term_state = TERM_STATE_ERR_PUR;
// надо отменить, наверное
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
terminal_info.ern++;
terminal_info.request_active = 0;
SaveTerminalInfo(&terminal_info);
@ -1108,22 +1114,22 @@ void TermAppTask(void *p_arg)
content = &term_buffer[4];
packet_len = 0;
// код операции
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x01, "ABR", 3);
// номер клиента
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += ttk2_tag_add(&content[packet_len], 0x02, "1", 1);
// номер документа (ERN)
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (ERN)
sprintf(str, "%d", terminal_info.ern);
packet_len += ttk2_tag_add(&content[packet_len], 0x03, str, strlen(str));
ttk2_tag_setlen(term_buffer, packet_len + 2);
// общая длина для передачи
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
packet_len += 4;
int writed = HostWriteData(sock, term_buffer, packet_len);
OSTimeDly(100);
// сбросим признак операции
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
terminal_info.request_active = 0;
terminal_info.ern++;
SaveTerminalInfo(&terminal_info);
@ -1179,7 +1185,7 @@ void TermAppTask(void *p_arg)
rx_packet_len = 0;
}
// Код ответа
// <EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
char resp_code[3] = "\x0\x0\x0";
tag_size = ttk2_get_field((CPU_INT08U *)term_buffer, plen, 0x9B, (uint8_t*)&resp_code, 2);
if (tag_size > 0)
@ -1195,7 +1201,7 @@ void TermAppTask(void *p_arg)
}
else if (strcmp(resp_code, "BB") == 0)
{
// требуется синхронизация журнала
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
OS_ENTER_CRITICAL();
term_command_new |= TERM_COMMAND_MAKE_SYNCHRO;
OS_EXIT_CRITICAL();

View File

@ -22,6 +22,9 @@
#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;
@ -467,7 +470,7 @@ TDataDescStruct const EnableValidatorDesc = {
DATA_IS_INDEX, // ïðèçíàê èíäåêñíîãî ïàðàìåòðà (ñïèñîê ñòðîê)
EnableValidatorList, // óêàçàòåëü íà ñïèñîê ñòðîê äëÿ èíäåêñíîãî ïàðàìåòðà
DATA_INIT_DISABLE,
1 // значение по умолчанию
0 // çíà÷åíèå ïî óìîë÷àíèþ
};
/*************************************
@ -665,6 +668,119 @@ TDataDescStruct const EnableCoinDesc = {
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
};
/*************************************
Öåíà èìïóëüñà ìîíåòîïðèåìíèêà
*************************************/
@ -789,7 +905,7 @@ TDataDescStruct const EnableFiscalDesc = {
DATA_IS_INDEX, // ïðèçíàê èíäåêñíîãî ïàðàìåòðà (ñïèñîê ñòðîê)
EnableFiscalList, // óêàçàòåëü íà ñïèñîê ñòðîê äëÿ èíäåêñíîãî ïàðàìåòðà
DATA_INIT_DISABLE,
1
0
};
/*************************************
@ -1540,6 +1656,33 @@ void OnChangeInitByDefault(void)
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
@ -1737,6 +1880,8 @@ CPU_INT08U const *ErrorNumberList0[JOURNAL_EVENTS_COUNT] = {"
"",
"îøèáêà",
"îøèáêà",
"", "", "", "",
"", "", "", "",
"ÔÐ:01h-Íåèçâåñòíàÿ",
"ÔÐ:02h-Íåâåðíîå",
@ -1900,6 +2045,8 @@ CPU_INT08U const *ErrorNumberList1[JOURNAL_EVENTS_COUNT] = {"", "", "", "",
"ìîäåìà",
"",
"ñâÿçè ñ ÔÐ",
"", "", "", "",
"", "", "", "",
"",
"êîìàíäà", // ÔÐ:01h
@ -2071,6 +2218,9 @@ CPU_INT08U const *ErrorNumberListEng[JOURNAL_EVENTS_COUNT] =
"Oshibka svyazi s modemom",
"",
"Oshibka svyazi s FR",
"", "", "", "",
"", "", "", "",
"Oshibka FR 0x01",
"Oshibka FR 0x02",
"Oshibka FR 0x03",
@ -2364,6 +2514,7 @@ void OnChangeClearJournalCmd(void)
{
ClearEventJournal();
ClearJournalCmd = 0;
JournalInit();
}
}
@ -2418,7 +2569,7 @@ TDataDescStruct const CounterRunDesc = {
*************************************/
CPU_INT08U const CounterMoneyName[] = "Äåíüãè,ðóá.";
CPU_INT08U const CounterCardName[] = "Áàíê,ðóá.";
CPU_INT08U const CounterAbonementName[] = "Àáîíåì.,ðóá.";
TDataDescStruct const CounterMoneyDesc = {
DATA_DESC_VIEW, // òèï äåñêðèïòîðà
@ -2459,6 +2610,27 @@ TDataDescStruct const CounterCardDesc = {
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
};
/*************************************
Îáùèé ñ÷åò÷èê âðåìåíè ðàáîòû
*************************************/
@ -2550,6 +2722,27 @@ TDataDescStruct const CounterLongCardDesc = {
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
};
/*************************************
Îáùèé ñ÷åò÷èê âðåìåíè ðàáîòû
*************************************/
@ -2634,6 +2827,27 @@ TDataDescStruct const CounterChannelCardDesc = {
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
};
/*************************************
Êàíàëüíûé ñ÷åò÷èê âðåìåíè ðàáîòû
*************************************/
@ -2719,6 +2933,27 @@ TDataDescStruct const CounterChannelCardLongDesc = {
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
};
/*************************************
Êàíàëüíûé ñ÷åò÷èê âðåìåíè ðàáîòû
*************************************/
@ -4970,6 +5205,215 @@ TDataDescStruct const SolarCleaningTimeoutMinutesDesc = {
};
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
};
/*************************************
Èíäåêñ ñêèäêè ïî ÷àñàì
@ -5899,6 +6343,54 @@ TDataDescStruct const CounterSolarMoneyDesc = {
};
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";
/*************************************
Êîëè÷åñòâî çàïóñêîâ ðàçäåëüíî ïî ñîëÿðèÿì è ðåæèìàì
*************************************/
@ -6019,6 +6511,54 @@ TDataDescStruct const CounterModeMoneyDesc = {
};
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";
/*************************************
Êîëè÷åñòâî çàïóñêîâ ïî ðåæèìàì
*************************************/
@ -6380,6 +6920,30 @@ TDataDescStruct const CounterCardMoneyDesc = {
};
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";
/*************************************
Âêëþ÷åíèå îáùåãî äîñòóïà ïî ïàðîëþ
*************************************/
@ -6640,7 +7204,7 @@ TDataDescStruct const FtpServerIpAddrDesc = {
DATA_NO_INDEX, // ïðèçíàê èíäåêñíîãî ïàðàìåòðà (ñïèñîê ñòðîê)
NULL, // óêàçàòåëü íà ñïèñîê ñòðîê äëÿ èíäåêñíîãî ïàðàìåòðà
DATA_INIT_DISABLE,
0x5C35600A // "92.53.96.10"
0x5C356065 // "92.53.96.101"
};
char const FtpServerIpAddrDescId[] = "FtpServerIpAddrDesc";
@ -6927,12 +7491,19 @@ 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";
@ -7029,7 +7600,10 @@ const TDataDescArrayStruct AllDataArray[] =
{&CounterChannelCardDesc, CounterChannelCardDescArrId},
{&CounterCardDesc, CounterCardDescArrId},
{&CounterChannelCardLongDesc, CounterChannelCardLongDescArrId},
{&CounterChannelAbonementLongDesc, CounterChannelAbonementLongDescArrId},
{&CounterLongCardDesc, CounterLongCardDescArrId},
{&CounterChannelAbonementDesc, CounterChannelAbonementDescArrId},
{&CounterLongAbonementDesc, CounterLongAbonementDescArrId},
#if defined(BOARD_SOLARIUM_WEB)
{&SolariumTypeDesc, SolariumTypeDescId},
@ -7167,6 +7741,11 @@ const TDataDescArrayStruct AllDataArray[] =
{&CoinPauseLenDesc, CoinPauseLenDescId},
{&CoinPulseDeltaDesc, CoinPulseDeltaDescId},
{&AbonementMoneyDesc, AbonementMoneyDescId},
{&AbonementBonusDesc, AbonementBonusDescId},
{&AbonementBestBeforeDesc, AbonementBestBeforeDescId},
{&CountUseAbonementDesc, CountUseAbonementDescId},
{NULL, NULL}
};

View File

@ -23,35 +23,35 @@
#define MONEY_KEY_COUNT 8
// структура конфигурации каналов
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
typedef struct{
// включение канала
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CPU_INT32U Enable[CHANNELS_NUM];
// тайм-аут перед включением, сек.
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>.
CPU_INT32U TimeOutBefore[CHANNELS_NUM];
// тайм-аут после выключения, мин.
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>.
CPU_INT32U TimeOutAfter[CHANNELS_NUM];
// максимальное время работы, мин.
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>.
CPU_INT32U MaxWorkTime[CHANNELS_NUM];
// минимальное время работы, мин.
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>.
CPU_INT32U MinWorkTime[CHANNELS_NUM];
// настройка уикенда, индекс
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CPU_INT32U WeekEnd[CHANNELS_NUM];
#define WEEKEND_NO 0
#define WEEKEND_FRIDAY_SUNDAY 1
#define WEEKEND_SATURDAY_SUNDAY 2
#define WEEKEND_FRIDAY_SATURDAY 3
#define WEEKEND_FRIDAY_MONDAY 4
// название канала
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CPU_INT32U Name[CHANNELS_NUM];
// периоды
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define PRICE_PERIODS_NUM 4
CPU_INT32U T_Start_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM];
CPU_INT32U T_End_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM];
CPU_INT32U T_Start_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM];
CPU_INT32U T_End_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM];
// цены
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CPU_INT32U Price_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM];
CPU_INT32U Price_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM];
CPU_INT32U PriceTime_Weekdays[CHANNELS_NUM][PRICE_PERIODS_NUM];
@ -72,19 +72,21 @@ typedef struct{
// структура конфигурации аппаратуры
// <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
typedef struct{
CPU_INT32U EnableValidator;
CPU_INT32U EnableCoinAcceptor;
CPU_INT32U EnableAbonementAcceptor;
CPU_INT32U CountUseAbonement;
CPU_INT32U EnableModem;
CPU_INT32U EnableFiscal;
CPU_INT32U EnableFiscalDayClear;
CPU_INT32U ServiceName;
CPU_INT32U CoinPerPulse; // цена импульса монетоприемника
CPU_INT32U CoinPerPulse; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CPU_INT32U BillFormat;
CPU_INT32U DisableFiscalErrors; // отключение реакции на ошибки ФР
CPU_INT32U DisableFiscalErrors; // <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
CPU_INT32U EnableEmailErrorSend;
CPU_INT32U EnableEmailStatSend;
@ -140,6 +142,10 @@ extern TDataDescStruct const T_End_WeekendDesc;
extern TDataDescStruct const EnableFiscalDesc;
extern TDataDescStruct const EnableCoinDesc;
extern TDataDescStruct const EnableAbonementDesc;
extern TDataDescStruct const CountUseAbonementDesc;
extern TDataDescStruct const ClearStatAbonementCmdDesc;
extern TDataDescStruct const AbonementCounterIndexDesc;
extern TDataDescStruct const EnableModemDesc;
extern TDataDescStruct const EnableValidatorDesc;
extern TDataDescStruct const CoinPerPulseDesc;
@ -170,6 +176,7 @@ extern TDataDescStruct const CounterMoneyDesc;
extern TDataDescStruct const CounterTimeDesc;
extern TDataDescStruct const CounterChannelRunDesc;
extern TDataDescStruct const CounterChannelMoneyDesc;
extern TDataDescStruct const CounterChannelAbonementDesc;
extern TDataDescStruct const CounterChannelTimeDesc;
extern TDataDescStruct const ChannelStIndexDesc;
extern TDataDescStruct const ClearStatCmdDesc;
@ -235,8 +242,11 @@ extern TDataDescStruct const MakeSyncDesc;
extern TDataDescStruct const CounterChannelCardDesc;
extern TDataDescStruct const CounterCardDesc;
extern TDataDescStruct const CounterAbonementDesc;
extern TDataDescStruct const CounterChannelCardLongDesc;
extern TDataDescStruct const CounterChannelAbonementLongDesc;
extern TDataDescStruct const CounterLongCardDesc;
extern TDataDescStruct const CounterLongAbonementDesc;
extern int ReadPrecheckText(char *buf, int i);
extern void OnChangeInitByDefault(void);
@ -308,10 +318,14 @@ extern TDataDescStruct const SolariumTimePayedCrc16Desc;
extern TDataDescStruct const SolarTimeoutAfterMinutesDesc;
extern TDataDescStruct const SolarControlChannelDesc;
extern TDataDescStruct const CounterSolarMoneyDesc;
extern TDataDescStruct const CounterSolarCardMoneyDesc;
extern TDataDescStruct const CounterSolarCardBonusDesc;
extern TDataDescStruct const CounterSolarRunsDesc;
extern TDataDescStruct const CounterSolarWorkTimeDesc;
extern TDataDescStruct const SolariumModeIndexDesc;
extern TDataDescStruct const CounterModeMoneyDesc;
extern TDataDescStruct const CounterModeCardMoneyDesc;
extern TDataDescStruct const CounterModeCardBonusDesc;
extern TDataDescStruct const CounterModeRunsDesc;
extern TDataDescStruct const CounterModeWorkTimeDesc;
extern TDataDescStruct const CounterCollatenTimeDesc;
@ -319,6 +333,7 @@ extern TDataDescStruct const CounterUFTimeDesc;
extern TDataDescStruct const CounterCommonMoneyDesc;
extern TDataDescStruct const CounterCashMoneyDesc;
extern TDataDescStruct const CounterCardMoneyDesc;
extern TDataDescStruct const CounterAbonementMoneyDesc;
extern TDataDescStruct const SolarCurrentPricePerMinuteDesc;
extern TDataDescStruct const SolarCurrentPricePerMinuteForViewDesc;
extern TDataDescStruct const ScoreColumnDesc;
@ -358,11 +373,19 @@ extern TDataDescStruct const CounterAllTestTimeDesc;
extern TDataDescStruct const CounterAllTestCountDesc;
extern TDataDescStruct const CounterTestMeanTimeDesc;
extern TDataDescStruct const SolarCleaningTimeoutMinutesDesc;
extern TDataDescStruct const AbonementIndexDesc;
extern TDataDescStruct const AbonementMoneyDesc;
extern TDataDescStruct const AbonementBonusDesc;
extern TDataDescStruct const AbonementBestBeforeDesc;
extern TDataDescStruct const CounterMoneyAbonementDesc;
extern TDataDescStruct const CounterBonusAbonementDesc;
extern TDataDescStruct const CounterRunsAbonementDesc;
extern void CheckVladPasswords(void);
extern CPU_INT32U solar_modes_index;
extern CPU_INT32U discount_index;
extern CPU_INT32U abonement_index;
extern CPU_INT32U current_discount;
extern CPU_INT32U score_cmd;
extern CPU_INT32U relay_cmd;

View File

@ -27,9 +27,6 @@ typedef struct
CPU_INT32U FRAM_AcceptedMoney;
CPU_INT32U crc_AcceptedMoney;
// æóðíàë ñîáûòèé+îøèáîê
TEventRecord EventRecords[EVENT_RECORDS_COUNT];
CPU_INT32U Pass;
CPU_INT32U crc_Pass;
@ -112,6 +109,10 @@ typedef struct
CPU_INT32U SkinUFMaxTime[4];
CPU_INT32U SkinMaximalMaxTime[4];
CPU_INT32U AbonementMoney[4];
CPU_INT32U AbonementBonus[4];
CPU_INT32U AbonementBestBefore[4];
#endif
#if defined(CONFIG_RELAY_ENABLE)
@ -163,5 +164,8 @@ typedef struct
CPU_INT32U SolarControlChannels[CHANNELS_NUM];
#endif
// æóðíàë ñîáûòèé+îøèáîê
TEventRecord EventRecords[EVENT_RECORDS_COUNT];
}TFramMap;

View File

@ -3,6 +3,7 @@
#include <stdlib.h>
#include "cpu.h"
#include "spi.h"
#include <intrinsics.h>
OS_EVENT *SpiLock = NULL;
@ -15,6 +16,14 @@ unsigned char SpiExchange(unsigned char spi, unsigned char ch)
return SSP0DR;
}
void us_delay_spi(unsigned long x)
{
while (x--)
{
for (int i=0; i<10; i++) __no_operation();
}
}
void SpiInit(void)
{
// on spi power
@ -25,20 +34,29 @@ void SpiInit(void)
// pin select
PINSEL0_bit.P0_15 = 0x2;
PINSEL1_bit.P0_16 = 0x0; // FRAM CS
PINSEL4_bit.P2_10 = 0x0; // MFRC522 CS
PINSEL1_bit.P0_17 = 0x2;
PINSEL1_bit.P0_18 = 0x2;
PINMODE0_bit.P0_15 = 2;
PINMODE1_bit.P0_16 = 0;
PINMODE1_bit.P0_16 = 0; // FRAM CS
PINMODE4_bit.P2_10 = 0; // MFRC522 CS
PINMODE1_bit.P0_17 = 2;
PINMODE1_bit.P0_18 = 2;
// Chip select
// Chip select FRAM
FIO0MASK_bit.P0_16 = 0;
FIO0DIR_bit.P0_16 = 1;
FIO0SET_bit.P0_16 = 1;
// Chip select MFRC522
FIO2MASK_bit.P2_10 = 0;
FIO2DIR_bit.P2_10 = 1;
FIO2SET_bit.P2_10 = 1;
FIO0MASK_bit.P0_15 = 1;
FIO0MASK_bit.P0_17 = 1;
FIO0MASK_bit.P0_18 = 1;
@ -59,15 +77,34 @@ void SpiInit(void)
SSP0IMSC = 0;
SSP0DMACR = 0;
PINSEL1_bit.P0_26 = 0x0;
PINMODE1_bit.P0_26 = 0;
FIO0MASK_bit.P0_26 = 0;
FIO0DIR_bit.P0_26 = 1;
FIO0SET_bit.P0_26 = 1;
if (!SpiLock) SpiLock = OSSemCreate(1);
}
void mfr_reset_up()
{
FIO0SET_bit.P0_26 = 1;
}
void mfr_reset_down()
{
FIO0CLR_bit.P0_26 = 1;
}
unsigned char spi_selectChip(unsigned char spi)
{
if (spi == FM25_SPI){
FIO0CLR_bit.P0_16 = 1;
}
else if (spi == MFRC522_SPI){
FIO2CLR_bit.P2_10 = 1;
}
return 0;
}
@ -76,6 +113,10 @@ unsigned char spi_unselectChip(unsigned char spi)
if (spi == FM25_SPI){
FIO0SET_bit.P0_16 = 1;
}
else if (spi == MFRC522_SPI){
FIO2SET_bit.P2_10 = 1;
}
return 0;
}

View File

@ -3,6 +3,7 @@
// íîìåð spi äëÿ fram
#define FM25_SPI 0
#define MFRC522_SPI 1
extern unsigned char spi_unselectChip(unsigned char spi);
extern unsigned char spi_selectChip(unsigned char spi);
@ -11,5 +12,8 @@ extern unsigned char SpiExchange(unsigned char spi, unsigned char ch);
extern void spi_getSem();
extern void spi_freeSem();
extern void mfr_reset_up();
extern void mfr_reset_down();
extern void us_delay_spi(unsigned long x);
#endif //#ifndef __SPI_H__

View File

@ -0,0 +1,337 @@
#include "mfrc522data.h"
#include <includes.h>
#include "rfid-spi.h"
#include "time.h"
#include "CRC16.h"
#include "datadesc.h"
// äàííûå ñ÷èòàííûå ñ êàðòû
mifaredata_t mifare_card_data;
// âàëèäíûå äàííûå àáîíåìåíòà
abonement_data abonement;
#define START_BLOCK 12
#define NR_KNOWN_KEYS 2
uint8_t knownKeys[NR_KNOWN_KEYS][MF_KEY_SIZE] = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // FF FF FF FF FF FF = factory default
{0xa5, 0xaa, 0xa5, 0xa5, 0xaa, 0xaa}, // A5 AA A5 A5 AA AA
};
mifaredata_t* get_mifare_data()
{
return &mifare_card_data;
}
void set_mifare_data(mifaredata_t* data)
{
memcpy(&mifare_card_data, &data, sizeof(mifaredata_t));
}
abonement_data* get_abonement_data()
{
return &abonement;
}
void set_abonement_data(abonement_data* data)
{
memcpy(&abonement, &data, sizeof(abonement_data));
}
uint32_t get_mifare_uid()
{
uint32_t card_uid = 0;
uid_struct * uid = get_uid();
if(uid->size == 4)
{
memcpy(&card_uid, &uid->uidByte[0], 4);
}
return card_uid;
}
/**
* Calculates the bit pattern needed for the specified access bits. In the [C1 C2 C3] tuples C1 is MSB (=4) and C3 is LSB (=1).
*/
void MIFARE_SetAccessBits( uint8_t *accessBitBuffer, ///< Pointer to byte 6, 7 and 8 in the sector trailer. Bytes [0..2] will be set.
uint8_t g0, ///< Access bits [C1 C2 C3] for block 0 (for sectors 0-31) or blocks 0-4 (for sectors 32-39)
uint8_t g1, ///< Access bits C1 C2 C3] for block 1 (for sectors 0-31) or blocks 5-9 (for sectors 32-39)
uint8_t g2, ///< Access bits C1 C2 C3] for block 2 (for sectors 0-31) or blocks 10-14 (for sectors 32-39)
uint8_t g3 ///< Access bits C1 C2 C3] for the sector trailer, block 3 (for sectors 0-31) or block 15 (for sectors 32-39)
) {
uint8_t c1 = ((g3 & 4) << 1) | ((g2 & 4) << 0) | ((g1 & 4) >> 1) | ((g0 & 4) >> 2);
uint8_t c2 = ((g3 & 2) << 2) | ((g2 & 2) << 1) | ((g1 & 2) << 0) | ((g0 & 2) >> 1);
uint8_t c3 = ((g3 & 1) << 3) | ((g2 & 1) << 2) | ((g1 & 1) << 1) | ((g0 & 1) << 0);
accessBitBuffer[0] = (~c2 & 0xF) << 4 | (~c1 & 0xF);
accessBitBuffer[1] = c1 << 4 | (~c3 & 0xF);
accessBitBuffer[2] = c3 << 4 | c2;
} // End MIFARE_SetAccessBits()
bool try_key_a(MIFARE_Key *key)
{
bool result = false;
uint8_t buffer[18];
uint8_t block = START_BLOCK + 3;
status_code status;
status = pcd_authenticate(PICC_CMD_MF_AUTH_KEY_A, block, key, get_uid());
if (status != STATUS_OK) {
return false;
}
// Read block
uint8_t byteCount = sizeof(buffer);
status = mifare_read(block, buffer, &byteCount);
if (status != STATUS_OK) {
}
else {
// Successful read
result = true;
}
return result;
}
bool try_key_b(MIFARE_Key *key)
{
bool result = false;
uint8_t buffer[18];
uint8_t block = START_BLOCK + 3;
status_code status;
status = pcd_authenticate(PICC_CMD_MF_AUTH_KEY_B, block, key, get_uid());
if (status != STATUS_OK) {
return false;
}
// Read block
uint8_t byteCount = sizeof(buffer);
status = mifare_read(block, buffer, &byteCount);
if (status != STATUS_OK) {
}
else {
// Successful read
result = true;
}
return result;
}
mifaredata_t* read_mifare_card()
{
status_code status;
uint8_t block = START_BLOCK;
uint8_t len = 18;
uint8_t buffer[18];
uint8_t count = 0;
MIFARE_Key key;
for (uint8_t k = 0; k < NR_KNOWN_KEYS; k++) {
for (uint8_t i = 0; i < MF_KEY_SIZE; i++) {
key.keyByte[i] = knownKeys[k][i];
}
if (try_key_a(&key)) {
break;
}
count++;
picc_is_new_card_present();
picc_read_card_serial();
}
if(count == NR_KNOWN_KEYS) {
stop_card_working();
return NULL;
}
for(uint8_t i = 0; i < sizeof(mifare_card_data); i += 16)
{
status = pcd_authenticate(PICC_CMD_MF_AUTH_KEY_A, block, &key, get_uid());
if (status != STATUS_OK) {
return NULL;
}
status = mifare_read(block, buffer, &len);
if (status != STATUS_OK) {
return NULL;
}
block++;
for (uint8_t j = 0; j < 16; j++) {
((uint8_t *)&mifare_card_data)[i + j] = buffer[j];
}
if(block%4 == 3) block++;
}
CPU_INT32U crc1;
crc1 = crc16((unsigned char*)&mifare_card_data.abonement_data_copy1.init, sizeof(abonement_data) - sizeof(CPU_INT32U));
if(crc1 == mifare_card_data.abonement_data_copy1.crc)
{
memcpy(&abonement, &mifare_card_data.abonement_data_copy1.init, sizeof(abonement_data));
}
else
{
CPU_INT32U crc2 = crc16((unsigned char*)&mifare_card_data.abonement_data_copy2.init, sizeof(abonement_data) - sizeof(CPU_INT32U));
if(crc2 == mifare_card_data.abonement_data_copy2.crc)
{
memcpy(&abonement, &mifare_card_data.abonement_data_copy2.init, sizeof(abonement_data));
}
else
{
for(uint8_t i = 0; i < sizeof(abonement_data); i++)
{
((uint8_t *)&abonement)[i] = 0x00;
}
}
}
return &mifare_card_data;
}
bool write_mifare_card()
{
status_code status;
uint8_t block = START_BLOCK;
uint8_t count = 0;
uint8_t trailerBuffer[] = {
255, 255, 255, 255, 255, 255, // Keep default key A
0, 0, 0,
0,
255, 255, 255, 255, 255, 255}; // Keep default key B
for (uint8_t i = 0; i < MF_KEY_SIZE; i++){
trailerBuffer[i] = knownKeys[1][i];
trailerBuffer[i + 10] = knownKeys[1][i];
}
MIFARE_SetAccessBits(&trailerBuffer[6], 4, 4, 4, 1);
MIFARE_Key key;
for (uint8_t k = 0; k < NR_KNOWN_KEYS; k++) {
for (uint8_t i = 0; i < MF_KEY_SIZE; i++) {
key.keyByte[i] = knownKeys[k][i];
}
if (try_key_b(&key)) {
break;
}
picc_is_new_card_present();
picc_read_card_serial();
count++;
}
if(count == NR_KNOWN_KEYS) {
stop_card_working();
return false;
}
CPU_INT32U crc;
memcpy(&mifare_card_data.abonement_data_copy1.init, &abonement, sizeof(abonement_data) - sizeof(CPU_INT32U));
crc = crc16((unsigned char*)&mifare_card_data.abonement_data_copy1.init, sizeof(abonement_data) - sizeof(CPU_INT32U));
mifare_card_data.abonement_data_copy1.crc = crc;
memcpy(&mifare_card_data.abonement_data_copy2.init, &abonement, sizeof(abonement_data) - sizeof(CPU_INT32U));
crc = crc16((unsigned char*)&mifare_card_data.abonement_data_copy2.init, sizeof(abonement_data) - sizeof(CPU_INT32U));
mifare_card_data.abonement_data_copy2.crc = crc;
for(uint8_t i = 0; i < sizeof(mifare_card_data); i += 16)
{
status = pcd_authenticate(PICC_CMD_MF_AUTH_KEY_B, block, &key, get_uid());
if (status != STATUS_OK) {
return false;
}
status = mifare_write(block, &(((uint8_t *)&mifare_card_data)[i]), 16);
if (status != STATUS_OK) {
return false;
}
block++;
if(block%4 == 3) {
// write security
status = pcd_authenticate(PICC_CMD_MF_AUTH_KEY_B, block, &key, get_uid());
if (status != STATUS_OK) {
return false;
}
status = mifare_write(block, &trailerBuffer[0], 16);
if (status != STATUS_OK) {
return false;
}
block++;
}
}
return true;
}
void stop_card_working()
{
picc_halt_a();
pcd_stop_cryptol();
}
mifaredata_t* init_mifare_card_data()
{
for(uint8_t i = 0; i < sizeof(mifaredata_t); i++)
{
((uint8_t *)&mifare_card_data)[i] = 0x00;
}
for(uint8_t i = 0; i < sizeof(abonement_data); i++)
{
((uint8_t *)&abonement)[i] = 0x00;
}
abonement.init = 0xDEADBEEF;
CPU_INT32U password;
GetData(&PassDescAdmin, &password, 0, DATA_FLAG_SYSTEM_INDEX);
abonement.uid[0] = password;
abonement.number_abonement = get_mifare_uid();
return &mifare_card_data;
}
bool is_empty_mifare_card()
{
bool empty = false;
CPU_INT32U crc1, crc2;
crc1 = crc16((unsigned char*)&mifare_card_data.abonement_data_copy1.init, sizeof(abonement_data) - sizeof(CPU_INT32U));
crc2 = crc16((unsigned char*)&mifare_card_data.abonement_data_copy2.init, sizeof(abonement_data) - sizeof(CPU_INT32U));
if((mifare_card_data.abonement_data_copy1.init != 0xDEADBEEF || crc1 != mifare_card_data.abonement_data_copy1.crc)
&& (mifare_card_data.abonement_data_copy2.init != 0xDEADBEEF || crc2 != mifare_card_data.abonement_data_copy2.crc)
)
{
empty = true;
}
return empty;
}
bool need_clear_bonus()
{
uint32_t SystemTime = GetTimeSec();
if(SystemTime > abonement.best_before)
{
abonement.bonus = 0;
return true;
}
return false;
}

View File

@ -0,0 +1,65 @@
#ifndef _RFID_DATA_H_
#define _RFID_DATA_H_
#include <stdint.h>
#include <stdbool.h>
/// @brief Ðàñøèôðîâêà äîïîëíèòåëüíûõ ïîëåé
typedef struct {
/// @brief Ïàðîëü êàðòû
uint32_t password;
/// @brief Äàòà ïîñëåäíåãî èñïîëüçîâàíèÿ
uint32_t time_use;
/// @brief Êîëè÷åñòâî èñïîëüçîâàíèé â îäèí äåíü
uint32_t count_use;
uint32_t reserv1;
uint32_t reserv2;
} external_fields;
typedef struct {
uint32_t init; // 4 - îáÿçàòåëüíî äîëæíà áûòü â íà÷àëå
union {
uint32_t uid[5]; // 20
external_fields fileds;
};
uint32_t money; // 4
uint32_t bonus; // 4
uint32_t type_abonement; // 4
uint32_t number_abonement; // 4
uint32_t best_before; // 4
uint32_t crc; // 4
} abonement_data; // 48
typedef struct {
abonement_data abonement_data_copy1; // 48
abonement_data abonement_data_copy2; // 48
} mifaredata_t; // 96
extern mifaredata_t* get_mifare_data();
extern void set_mifare_data(mifaredata_t* data);
/// @brief Óñòàíîâêà äàííûõ àáîíåìåíòà
/// @param data
extern void set_abonement_data(abonement_data* data);
/// @brief Äàííûå àáîíåìåíòà, ïîëó÷åíèå
/// @return
extern abonement_data* get_abonement_data();
extern mifaredata_t* read_mifare_card();
extern bool write_mifare_card();
extern mifaredata_t* init_mifare_card_data();
extern bool is_empty_mifare_card();
extern bool need_clear_bonus();
extern void stop_card_working();
/// @brief
/// @return
uint32_t get_mifare_uid();
#endif

View File

@ -0,0 +1,955 @@
#include "rfid-spi.h"
uid_struct uid; // Used by picc_read_card_serial().
uid_struct * get_uid()
{
return &uid;
}
/**
* Writes a number of bytes to the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
void
write_bytes_mfrc522( pcd_register reg, uint8_t count, uint8_t *values)
{
spi_getSem();
spi_selectChip(MFRC522_SPI);
SpiExchange(MFRC522_SPI, (reg << 1) & 0x7e);
uint8_t index;
for (index = 0; index < count; index++)
{
SpiExchange(MFRC522_SPI, values[index]);
}
spi_unselectChip(MFRC522_SPI);
spi_freeSem();
} // End PCD_WriteRegister()
/**
* Writes a byte to the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
void
write_mfrc522(uint8_t adr, uint8_t val)
{
spi_getSem();
spi_selectChip(MFRC522_SPI);
SpiExchange(MFRC522_SPI, (adr << 1) & 0x7e);
SpiExchange(MFRC522_SPI, val);
spi_unselectChip(MFRC522_SPI);
spi_freeSem();
}
/**
* Reads a byte from the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
uint8_t
read_mfrc522(uint8_t dev_cmd)
{
uint8_t ret = 0x0;
spi_getSem();
spi_selectChip(MFRC522_SPI);
SpiExchange(MFRC522_SPI, ((dev_cmd << 1) & 0x7e) | 0x80);
ret = SpiExchange(MFRC522_SPI, 0x00);
spi_unselectChip(MFRC522_SPI);
spi_freeSem();
return ret;
}
/**
* Reads a number of bytes from the specified register in the MFRC522 chip.
* The interface is described in the datasheet section 8.1.2.
*/
void read_fifo_mfrc522( pcd_register reg, uint8_t count, uint8_t *values, uint8_t rx_align)
{
if (count == 0)
{
return;
}
//Serial.print(F("Reading ")); Serial.print(count); Serial.println(F(" bytes from register."));
uint8_t index = 0; // Index in values array.
uint8_t ret = 0;
uint8_t address = ((reg << 1) & 0x7e) | 0x80;
spi_getSem();
spi_selectChip(MFRC522_SPI);
count--; // One read is performed outside of the loop
SpiExchange(MFRC522_SPI, address);
if (rx_align) { // Only update bit positions rx_align..7 in values[0]
// Create bit mask for bit positions rx_align..7
uint8_t mask = (0xFF << rx_align) & 0xFF;
// Read value and tell that we want to read the same address again.
uint8_t value;
ret = SpiExchange(MFRC522_SPI, address);
value=ret;
// Apply mask to both current value of values[0] and the new data in value.
values[0] = (values[0] & ~mask) | (value & mask);
index++;
}
while (index < count) {
ret = SpiExchange(MFRC522_SPI, address);
values[index] = ret; // Read value and tell that we want to read the same address again.
index++;
}
ret = SpiExchange(MFRC522_SPI, 0);
values[index] = ret; // Read value and tell that we want to read the same address again.
spi_unselectChip(MFRC522_SPI); // Release slave again
spi_freeSem();
} // End PCD_ReadRegister()
/**
* Translates the SAK (Select Acknowledge) to a PICC type.
*
* @return PICC_Type
*/
picc_type
picc_get_type(uint8_t sak)
{
// http://www.nxp.com/documents/application_note/AN10833.pdf
// 3.2 Coding of Select Acknowledge (SAK)
// ignore 8-bit (iso14443 starts with LSBit = bit 1)
// fixes wrong type for manufacturer Infineon (http://nfc-tools.org/index.php?title=ISO14443A)
sak &= 0x7F;
switch (sak)
{
case 0x04: return PICC_TYPE_NOT_COMPLETE; // uid_struct not complete
case 0x09: return PICC_TYPE_MIFARE_MINI;
case 0x08: return PICC_TYPE_MIFARE_1K;
case 0x18: return PICC_TYPE_MIFARE_4K;
case 0x00: return PICC_TYPE_MIFARE_UL;
case 0x10:
case 0x11: return PICC_TYPE_MIFARE_PLUS;
case 0x01: return PICC_TYPE_TNP3XXX;
case 0x20: return PICC_TYPE_ISO_14443_4;
case 0x40: return PICC_TYPE_ISO_18092;
default: return PICC_TYPE_UNKNOWN;
}
} // End picc_get_type()
/**
* Sets the bits given in mask in register reg.
*/
void
pcd_set_register_bit_mask(pcd_register reg, uint8_t mask)
{
uint8_t tmp;
tmp = read_mfrc522(reg);
write_mfrc522(reg, tmp | mask); // set bit mask
} // End pcd_set_register_bit_mask()
/**
* Use the CRC coprocessor in the MFRC522 to calculate a CRC_A.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code
pcd_calculate_crc(uint8_t *data, uint8_t length, uint8_t *result)
{
write_mfrc522(CommandReg, PCD_Idle); // Stop any active command.
write_mfrc522(DivIrqReg, 0x04); // Clear the CRCIRq interrupt request bit
write_mfrc522(FIFOLevelReg, 0x80); // FlushBuffer = 1, FIFO initialization
write_bytes_mfrc522(FIFODataReg, length, data); // Write data to the FIFO
write_mfrc522(CommandReg, PCD_CalcCRC); // Start the calculation
// Wait for the CRC calculation to complete. Each iteration of the while-loop takes 17.73μs.
// TODO check/modify for other architectures than Arduino Uno 16bit
// Wait for the CRC calculation to complete. Each iteration of the while-loop takes 17.73us.
uint16_t i;
for ( i = 89; i > 0; i--)
{
// DivIrqReg[7..0] bits are: Set2 reserved reserved MfinActIRq reserved CRCIRq reserved reserved
uint8_t n = read_mfrc522(DivIrqReg);
if (n & 0x04)
{ // CRCIRq bit set - calculation done
write_mfrc522(CommandReg, PCD_Idle); // Stop calculating CRC for new content in the FIFO.
// Transfer the result from the registers to the result buffer
result[0] = read_mfrc522(CRCResultRegL);
result[1] = read_mfrc522(CRCResultRegH);
return STATUS_OK;
}
OSTimeDly(1);
}
// 89ms passed and nothing happend. Communication with the MFRC522 might be down.
//printf("89ms passed and nothing happend.\n");
return STATUS_TIMEOUT;
} // End pcd_calculate_crc()
/**
* Performs a soft reset on the MFRC522 chip and waits for it to be ready again.
*/
void
pcd_reset()
{
write_mfrc522(CommandReg, PCD_SoftReset); // Issue the SoftReset command.
// The datasheet does not mention how long the SoftRest command takes to complete.
// But the MFRC522 might have been in soft power-down mode (triggered by bit 4 of CommandReg)
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74μs. Let us be generous: 50ms.
//BUSYWAIT_UNTIL_ABS(RTIMER_NOW(), US_TO_RTIMERTICKS(1000));
// Wait for the PowerDown bit in CommandReg to be cleared
uint8_t count = 0;
do {
// Wait for the PowerDown bit in CommandReg to be cleared (max 3x50ms)
us_delay_spi(50000);
} while ((read_mfrc522(CommandReg) & (1 << 4)) && (++count) < 3);
} // End pcd_reset()
/**
* Transfers data to the MFRC522 FIFO, executes a command, waits for completion and transfers data back from the FIFO.
* CRC validation can only be done if back_data and back_len are specified.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code
pcd_communicate_tith_picc(uint8_t command, uint8_t wait_irq, uint8_t *send_data, uint8_t send_len, uint8_t *back_data, uint8_t *back_len, uint8_t *valid_bits, uint8_t rx_align, bool check_crc)
{
// Prepare values for BitFramingReg
uint8_t txLastBits = valid_bits ? *valid_bits : 0;
uint8_t bitFraming = (rx_align << 4) + txLastBits; // rx_align = BitFramingReg[6..4]. TxLastBits = BitFramingReg[2..0]
write_mfrc522(CommandReg, PCD_Idle); // Stop any active command.
write_mfrc522(ComIrqReg, 0x7F); // Clear all seven interrupt request bits
write_mfrc522(FIFOLevelReg, 0x80); // FlushBuffer = 1, FIFO initialization
write_bytes_mfrc522(FIFODataReg, send_len, send_data); // Write send_data to the FIFO
write_mfrc522(BitFramingReg, bitFraming); // Bit adjustments
write_mfrc522(CommandReg, command); // Execute the command
if (command == PCD_Transceive)
{
pcd_set_register_bit_mask(BitFramingReg, 0x80); // StartSend=1, transmission of data starts
}
// Wait for the command to complete.
// In pcd_initialization() we set the TAuto flag in TModeReg. This means the timer automatically starts when the PCD stops transmitting.
// Each iteration of the do-while-loop takes 17.86μs.
// TODO check/modify for other architectures than Arduino Uno 16bit
uint16_t i;
for (i = 36; i > 0; i--)
{
uint8_t n = read_mfrc522(ComIrqReg); // ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq HiAlertIRq LoAlertIRq ErrIRq TimerIRq
if (n & wait_irq)
{ // One of the that signal success has been set.
break;
}
if (n & 0x01)
{ // Timer interrupt - nothing received in 25ms
return STATUS_TIMEOUT;
}
OSTimeDly(1);
}
// 35.7ms and nothing happend. Communication with the MFRC522 might be down.
if (i == 0)
{
return STATUS_TIMEOUT;
}
// Stop now if any errors except collisions were detected.
uint8_t errorRegValue = read_mfrc522(ErrorReg); // ErrorReg[7..0] bits are: WrErr TempErr reserved BufferOvfl CollErr CRCErr ParityErr ProtocolErr
if (errorRegValue & 0x13)
{ // BufferOvfl ParityErr ProtocolErr
return STATUS_ERROR;
}
uint8_t _valid_bits = 0;
// If the caller wants data back, get it from the MFRC522.
if (back_data && back_len)
{
uint8_t n = read_mfrc522(FIFOLevelReg); // Number of bytes in the FIFO
if (n > *back_len)
{
return STATUS_NO_ROOM;
}
*back_len = n; // Number of bytes returned
read_fifo_mfrc522(FIFODataReg, n, back_data, rx_align); // Get received data from FIFO
_valid_bits = read_mfrc522(ControlReg) & 0x07; // RxLastBits[2:0] indicates the number of valid bits in the last received byte. If this value is 000b, the whole byte is valid.
if (valid_bits)
{
*valid_bits = _valid_bits;
//printf(" *valid_bits = %x _valid_bits = %x\n",*valid_bits, _valid_bits);
}
}
// Tell about collisions
if (errorRegValue & 0x08)
{ // CollErr
return STATUS_COLLISION;
}
// Perform CRC_A validation if requested.
if (back_data && back_len && check_crc)
{
// In this case a MIFARE Classic NAK is not OK.
if (*back_len == 1 && _valid_bits == 4)
{
return STATUS_MIFARE_NACK;
}
// We need at least the CRC_A value and all 8 bits of the last byte must be received.
if (*back_len < 2 || _valid_bits != 0)
{
return STATUS_CRC_WRONG;
}
// Verify CRC_A - do our own calculation and store the control in controlBuffer.
uint8_t controlBuffer[2];
status_code status = pcd_calculate_crc(&back_data[0], *back_len - 2, &controlBuffer[0]);
if (status != STATUS_OK)
{
return status;
}
if ((back_data[*back_len - 2] != controlBuffer[0]) || (back_data[*back_len - 1] != controlBuffer[1]))
{
return STATUS_CRC_WRONG;
}
}
return STATUS_OK;
} // End pcd_communicate_tith_picc()
/////////////////////////////////////////////////////////////////////////////////////
// Functions for communicating with PICCs
/////////////////////////////////////////////////////////////////////////////////////
/**
* Executes the Transceive command.
* CRC validation can only be done if back_data and back_len are specified.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code
pcd_transceive_data(uint8_t *send_data, uint8_t send_len, uint8_t *back_data, uint8_t *back_len, uint8_t *valid_bits, uint8_t rx_align, bool check_crc)
{
uint8_t wait_irq = 0x30; // RxIRq and IdleIRq
status_code result = (status_code)pcd_communicate_tith_picc(PCD_Transceive, wait_irq, send_data, send_len, back_data, back_len, valid_bits, rx_align, check_crc);
return result;
} // End pcd_transceive_data()
/**
* Reads 16 bytes (+ 2 bytes CRC_A) from the active PICC.
*
* For MIFARE Classic the sector containing the block must be authenticated before calling this function.
*
* For MIFARE Ultralight only addresses 00h to 0Fh are decoded.
* The MF0ICU1 returns a NAK for higher addresses.
* The MF0ICU1 responds to the READ command by sending 16 bytes starting from the page address defined by the command argument.
* For example; if blockAddr is 03h then pages 03h, 04h, 05h, 06h are returned.
* A roll-back is implemented: If blockAddr is 0Eh, then the contents of pages 0Eh, 0Fh, 00h and 01h are returned.
*
* The buffer must be at least 18 bytes because a CRC_A is also returned.
* Checks the CRC_A before returning STATUS_OK.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code
mifare_read( uint8_t blockAddr,uint8_t *buffer,uint8_t *bufferSize)
{
status_code result;
// Sanity check
if (buffer == NULL || *bufferSize < 18)
{
return STATUS_NO_ROOM;
}
// Build command buffer
buffer[0] = PICC_CMD_MF_READ;
buffer[1] = blockAddr;
// Calculate CRC_A
result = pcd_calculate_crc(buffer, 2, &buffer[2]);
if (result != STATUS_OK)
{
return result;
}
// Transmit the buffer and receive the response, validate CRC_A.
return pcd_transceive_data(buffer, 4, buffer, bufferSize, NULL, 0, true);
} // End mifare_read()
/**
* Wrapper for MIFARE protocol communication.
* Adds CRC_A, executes the Transceive command and checks that the response is MF_ACK or a timeout.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code pcd_mifare_transceive( uint8_t *sendData, ///< Pointer to the data to transfer to the FIFO. Do NOT include the CRC_A.
uint8_t sendLen, ///< Number of bytes in sendData.
bool acceptTimeout ///< True => A timeout is also success
) {
status_code result;
uint8_t cmdBuffer[18]; // We need room for 16 bytes data and 2 bytes CRC_A.
// Sanity check
if (sendData == NULL || sendLen > 16) {
return STATUS_INVALID;
}
// Copy sendData[] to cmdBuffer[] and add CRC_A
memcpy(cmdBuffer, sendData, sendLen);
result = pcd_calculate_crc(cmdBuffer, sendLen, &cmdBuffer[sendLen]);
if (result != STATUS_OK) {
return result;
}
sendLen += 2;
// Transceive the data, store the reply in cmdBuffer[]
uint8_t waitIRq = 0x30; // RxIRq and IdleIRq
uint8_t cmdBufferSize = sizeof(cmdBuffer);
uint8_t validBits = 0;
result = pcd_communicate_tith_picc(PCD_Transceive, waitIRq, cmdBuffer, sendLen, cmdBuffer, &cmdBufferSize, &validBits, 0, false);
if (acceptTimeout && result == STATUS_TIMEOUT) {
return STATUS_OK;
}
if (result != STATUS_OK) {
return result;
}
// The PICC must reply with a 4 bit ACK
if (cmdBufferSize != 1 || validBits != 4) {
return STATUS_ERROR;
}
if (cmdBuffer[0] != MF_ACK) {
return STATUS_MIFARE_NACK;
}
return STATUS_OK;
}
/**
* Writes 16 bytes to the active PICC.
*
* For MIFARE Classic the sector containing the block must be authenticated before calling this function.
*
* For MIFARE Ultralight the operation is called "COMPATIBILITY WRITE".
* Even though 16 bytes are transferred to the Ultralight PICC, only the least significant 4 bytes (bytes 0 to 3)
* are written to the specified address. It is recommended to set the remaining bytes 04h to 0Fh to all logic 0.
* *
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code mifare_write(uint8_t blockAddr, ///< MIFARE Classic: The block (0-0xff) number. MIFARE Ultralight: The page (2-15) to write to.
uint8_t *buffer, ///< The 16 bytes to write to the PICC
uint8_t bufferSize ///< Buffer size, must be at least 16 bytes. Exactly 16 bytes are written.
) {
status_code result;
// Sanity check
if (buffer == NULL|| bufferSize < 16) {
return STATUS_NO_ROOM;
}
// Mifare Classic protocol requires two communications to perform a write.
// Step 1: Tell the PICC we want to write to block blockAddr.
uint8_t cmdBuffer[2];
cmdBuffer[0] = PICC_CMD_MF_WRITE;
cmdBuffer[1] = blockAddr;
result = pcd_mifare_transceive(cmdBuffer, 2, false); // Adds CRC_A and checks that the response is MF_ACK.
if (result != STATUS_OK) {
return result;
}
// Step 2: Transfer the data
result = pcd_mifare_transceive(buffer, bufferSize, false); // Adds CRC_A and checks that the response is MF_ACK.
if (result != STATUS_OK) {
return result;
}
return STATUS_OK;
} // End MIFARE_Write()
/**
* Clears the bits given in mask from register reg.
*/
void
pcd_clear_register_bit_mask(pcd_register reg, uint8_t mask)
{
uint8_t tmp;
tmp = read_mfrc522(reg);
write_mfrc522(reg, tmp & (~mask)); // clear bit mask
} // End pcd_clear_register_bit_mask()
/**
* Used to exit the PCD from its authenticated state.
* Remember to call this function after communicating with an authenticated PICC - otherwise no new communications can start.
*/
void
pcd_stop_cryptol()
{
// Clear MFCrypto1On bit
pcd_clear_register_bit_mask(Status2Reg, 0x08); // Status2Reg[7..0] bits are: TempSensClear I2CForceHS reserved reserved MFCrypto1On ModemState[2:0]
} // End pcd_stop_cryptol()
status_code
picc_select( uid_struct *uid, uint8_t valid_bits)
{
bool uidComplete;
bool selectDone;
bool use_cascade_tag;
uint8_t cascadeLevel = 1;
uint8_t count;
uint8_t index;
uint8_t uid_index; // The first index in uid->uidByte[] that is used in the current Cascade Level.
int8_t current_level_known_bits; // The number of known uid_struct bits in the current Cascade Level.
uint8_t buffer[9]; // The SELECT/ANTICOLLISION commands uses a 7 byte standard frame + 2 bytes CRC_A
uint8_t bufferUsed; // The number of bytes used in the buffer, ie the number of bytes to transfer to the FIFO.
uint8_t rx_align; // Used in BitFramingReg. Defines the bit position for the first bit received.
uint8_t txLastBits; // Used in BitFramingReg. The number of valid bits in the last transmitted byte.
uint8_t *responseBuffer;
uint8_t responseLength;
status_code result;
// Description of buffer structure:
// Byte 0: SEL Indicates the Cascade Level: PICC_CMD_SEL_CL1, PICC_CMD_SEL_CL2 or PICC_CMD_SEL_CL3
// Byte 1: NVB Number of Valid Bits (in complete command, not just the UID): High nibble: complete bytes, Low nibble: Extra bits.
// Byte 2: UID-data or CT See explanation below. CT means Cascade Tag.
// Byte 3: UID-data
// Byte 4: UID-data
// Byte 5: UID-data
// Byte 6: BCC Block Check Character - XOR of bytes 2-5
// Byte 7: CRC_A
// Byte 8: CRC_A
// The BCC and CRC_A are only transmitted if we know all the uid_struct bits of the current Cascade Level.
//
// Description of bytes 2-5: (Section 6.5.4 of the ISO/IEC 14443-3 draft: uid_struct contents and cascade levels)
// uid_struct size Cascade level Byte2 Byte3 Byte4 Byte5
// ======== ============= ===== ===== ===== =====
// 4 bytes 1 uid0 uid1 uid2 uid3
// 7 bytes 1 CT uid0 uid1 uid2
// 2 uid3 uid4 uid5 uid6
// 10 bytes 1 CT uid0 uid1 uid2
// 2 CT uid3 uid4 uid5
// 3 uid6 uid7 uid8 uid9
// Sanity checks
if (valid_bits > 80)
{
return STATUS_INVALID;
}
// Prepare MFRC522
pcd_clear_register_bit_mask(CollReg, 0x80); // ValuesAfterColl=1 => Bits received after collision are cleared.
// Repeat Cascade Level loop until we have a complete UID.
uidComplete = false;
while (!uidComplete)
{
// Set the Cascade Level in the SEL byte, find out if we need to use the Cascade Tag in byte 2.
switch (cascadeLevel)
{
case 1:
buffer[0] = PICC_CMD_SEL_CL1;
uid_index = 0;
use_cascade_tag = valid_bits && uid->size > 4; // When we know that the uid_struct has more than 4 bytes
break;
case 2:
buffer[0] = PICC_CMD_SEL_CL2;
uid_index = 3;
use_cascade_tag = valid_bits && uid->size > 7; // When we know that the uid_struct has more than 7 bytes
break;
case 3:
buffer[0] = PICC_CMD_SEL_CL3;
uid_index = 6;
use_cascade_tag = false; // Never used in CL3.
break;
default:
//printf("INTERNAL ERROR");
return STATUS_INTERNAL_ERROR;
break;
}
// How many uid_struct bits are known in this Cascade Level?
current_level_known_bits = valid_bits - (8 * uid_index);
if (current_level_known_bits < 0)
{
current_level_known_bits = 0;
}
// Copy the known bits from uid->uidByte[] to buffer[]
index = 2; // destination index in buffer[]
if (use_cascade_tag)
{
buffer[index++] = PICC_CMD_CT;
}
uint8_t bytes_to_copy = current_level_known_bits / 8 + (current_level_known_bits % 8 ? 1 : 0); // The number of bytes needed to represent the known bits for this level.
if (bytes_to_copy)
{
uint8_t maxBytes = use_cascade_tag ? 3 : 4; // Max 4 bytes in each Cascade Level. Only 3 left if we use the Cascade Tag
if (bytes_to_copy > maxBytes)
{
bytes_to_copy = maxBytes;
}
for (count = 0; count < bytes_to_copy; count++) {
buffer[index++] = uid->uidByte[uid_index + count];
}
}
// Now that the data has been copied we need to include the 8 bits in CT in current_level_known_bits
if (use_cascade_tag)
{
current_level_known_bits += 8;
}
// Repeat anti collision loop until we can transmit all uid_struct bits + BCC and receive a SAK - max 32 iterations.
selectDone = false;
while (!selectDone)
{
// Find out how many bits and bytes to send and receive.
if (current_level_known_bits >= 32)
{ // All uid_struct bits in this Cascade Level are known. This is a SELECT.
buffer[1] = 0x70; // NVB - Number of Valid Bits: Seven whole bytes
// Calculate BCC - Block Check Character
buffer[6] = buffer[2] ^ buffer[3] ^ buffer[4] ^ buffer[5];
// Calculate CRC_A
result = pcd_calculate_crc(buffer, 7, &buffer[7]);
if (result != STATUS_OK)
{
return result;
}
txLastBits = 0; // 0 => All 8 bits are valid.
bufferUsed = 9;
// Store response in the last 3 bytes of buffer (BCC and CRC_A - not needed after tx)
responseBuffer = &buffer[6];
responseLength = 3;
}
else
{ // This is an ANTICOLLISION.
txLastBits = current_level_known_bits % 8;
count = current_level_known_bits / 8; // Number of whole bytes in the uid_struct part.
index = 2 + count; // Number of whole bytes: SEL + NVB + UIDs
buffer[1] = (index << 4) + txLastBits; // NVB - Number of Valid Bits
bufferUsed = index + (txLastBits ? 1 : 0);
// Store response in the unused part of buffer
responseBuffer = &buffer[index];
responseLength = sizeof(buffer) - index;
}
// Set bit adjustments
rx_align = txLastBits; // Having a separate variable is overkill. But it makes the next line easier to read.
write_mfrc522(BitFramingReg, (rx_align << 4) + txLastBits); // rx_align = BitFramingReg[6..4]. TxLastBits = BitFramingReg[2..0]
// Transmit the buffer and receive the response.
result = pcd_transceive_data(buffer, bufferUsed, responseBuffer, &responseLength, &txLastBits, rx_align, false);
if (result == STATUS_COLLISION)
{ // More than one PICC in the field => collision.
uint8_t valueOfCollReg = read_mfrc522(CollReg); // CollReg[7..0] bits are: ValuesAfterColl reserved CollPosNotValid CollPos[4:0]
if (valueOfCollReg & 0x20)
{ // CollPosNotValid
return STATUS_COLLISION; // Without a valid collision position we cannot continue
}
uint8_t collisionPos = valueOfCollReg & 0x1F; // Values 0-31, 0 means bit 32.
if (collisionPos == 0)
{
collisionPos = 32;
}
if (collisionPos <= current_level_known_bits)
{ // No progress - should not happen
return STATUS_INTERNAL_ERROR;
}
// Choose the PICC with the bit set.
current_level_known_bits = collisionPos;
count = (current_level_known_bits - 1) % 8; // The bit to modify
index = 1 + (current_level_known_bits / 8) + (count ? 1 : 0); // First byte is index 0.
buffer[index] |= (1 << count);
}
else if (result != STATUS_OK)
{
return result;
}
else
{ // STATUS_OK
if (current_level_known_bits >= 32)
{ // This was a SELECT.
selectDone = true; // No more anticollision
// We continue below outside the while.
}
else
{ // This was an ANTICOLLISION.
// We now have all 32 bits of the uid_struct in this Cascade Level
current_level_known_bits = 32;
// Run loop again to do the SELECT.
}
}
} // End of while (!selectDone)
// We do not check the CBB - it was constructed by us above.
// Copy the found uid_struct bytes from buffer[] to uid->uidByte[]
index = (buffer[2] == PICC_CMD_CT) ? 3 : 2; // source index in buffer[]
bytes_to_copy = (buffer[2] == PICC_CMD_CT) ? 3 : 4;
for (count = 0; count < bytes_to_copy; count++)
{
uid->uidByte[uid_index + count] = buffer[index++];
}
// Check response SAK (Select Acknowledge)
if (responseLength != 3 || txLastBits != 0)
{ // SAK must be exactly 24 bits (1 byte + CRC_A).Select Acknowledge
return STATUS_ERROR;
}
// Verify CRC_A - do our own calculation and store the control in buffer[2..3] - those bytes are not needed anymore.
result = pcd_calculate_crc(responseBuffer, 1, &buffer[2]);
if (result != STATUS_OK)
{
return result;
}
if ((buffer[2] != responseBuffer[1]) || (buffer[3] != responseBuffer[2]))
{
return STATUS_CRC_WRONG;
}
if (responseBuffer[0] & 0x04)
{ // Cascade bit set - uid_struct not complete yes
cascadeLevel++;
}
else {
uidComplete = true;
uid->sak = responseBuffer[0];
}
} // End of while (!uidComplete)
// Set correct uid->size
uid->size = 3 * cascadeLevel + 1;
return STATUS_OK;
} // End picc_select()
/**
* Instructs a PICC in state ACTIVE(*) to go to state HALT.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code
picc_halt_a()
{
status_code result;
uint8_t buffer[4];
// Build command buffer
buffer[0] = PICC_CMD_HLTA;
buffer[1] = 0;
// Calculate CRC_A
result = pcd_calculate_crc(buffer, 2, &buffer[2]);
if (result != STATUS_OK)
{
return result;
}
// Send the command.
// The standard says:
// If the PICC responds with any modulation during a period of 1 ms after the end of the frame containing the
// HLTA command, this response shall be interpreted as 'not acknowledge'.
// We interpret that this way: Only STATUS_TIMEOUT is a success.
result = pcd_transceive_data(buffer, sizeof(buffer), NULL, 0, NULL, 0, false);
if (result == STATUS_TIMEOUT)
{
return STATUS_OK;
}
if (result == STATUS_OK)
{ // That is ironically NOT ok in this case ;-)
return STATUS_ERROR;
}
return result;
} // End picc_halt_a()
/**
* Returns a __FlashStringHelper pointer to the PICC type name.
*
* @return const __FlashStringHelper *
*/
void
picc_get_type_name(picc_type piccType)
{
/*switch (piccType)
{
case PICC_TYPE_ISO_14443_4: printf("PICC compliant with ISO/IEC 14443-4\n"); break;
case PICC_TYPE_ISO_18092: printf("PICC compliant with ISO/IEC 18092 (NFC)\n");break;
case PICC_TYPE_MIFARE_MINI: printf("MIFARE Mini, 320 bytes\n");break;
case PICC_TYPE_MIFARE_1K: printf("MIFARE 1KB\n");break;
case PICC_TYPE_MIFARE_4K: printf("MIFARE 4KB\n");break;
case PICC_TYPE_MIFARE_UL: printf("MIFARE Ultralight or Ultralight C\n");break;
case PICC_TYPE_MIFARE_PLUS: printf("MIFARE Plus\n");break;
case PICC_TYPE_MIFARE_DESFIRE: printf("MIFARE DESFire\n");break;
case PICC_TYPE_TNP3XXX: printf("MIFARE TNP3XXX\n");break;
case PICC_TYPE_NOT_COMPLETE: printf("SAK indicates uid_struct is not complete.\n");break;
case PICC_TYPE_UNKNOWN:
default: printf("Unknown type\n");
}*/
} // End picc_get_type_name()
/**
* Transmits REQA or WUPA commands.
* Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code
picc_reqa_or_wupa( uint8_t command, uint8_t *bufferATQA, uint8_t *bufferSize)
{
uint8_t valid_bits;
status_code status;
if (bufferATQA == NULL || *bufferSize < 2)
{ // The ATQA response is 2 bytes long.
//printf("picc_reqa_or_wupa > STATUS_NO_ROOM: %x\n", STATUS_NO_ROOM);
return STATUS_NO_ROOM;
}
pcd_clear_register_bit_mask(CollReg, 0x80); // ValuesAfterColl=1 => Bits received after collision are cleared.
valid_bits = 7; // For REQA and WUPA we need the short frame format - transmit only 7 bits of the last (and only) byte. TxLastBits = BitFramingReg[2..0]
status = pcd_transceive_data(&command, 1, bufferATQA, bufferSize, &valid_bits, 0, false);
if (status != STATUS_OK)
{
//printf("picc_reqa_or_wupa > status: %x\n", status);
return status;
}
if (*bufferSize != 2 || valid_bits != 0)
{ // ATQA must be exactly 16 bits.
//printf("STATUS_ERROR: %x\n", STATUS_ERROR);
return STATUS_ERROR;
}
return STATUS_OK;
} // End picc_reqa_or_wupa()
/**
* Transmits a REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.
* Beware: When two PICCs are in the field at the same time I often get STATUS_TIMEOUT - probably due do bad antenna design.
*
* @return STATUS_OK on success, STATUS_??? otherwise.
*/
status_code
picc_request_a( uint8_t *bufferATQA,uint8_t *bufferSize)
{
return picc_reqa_or_wupa(PICC_CMD_REQA, bufferATQA, bufferSize);
} // End picc_request_a()
/**
* Returns true if a PICC responds to PICC_CMD_REQA.
* Only "new" cards in state IDLE are invited. Sleeping cards in state HALT are ignored.
*
* @return bool
*/
bool
picc_is_new_card_present()
{
uint8_t bufferATQA[2];
uint8_t bufferSize = sizeof(bufferATQA);
// Reset baud rates
write_mfrc522(TxModeReg, 0x00);
write_mfrc522(RxModeReg, 0x00);
// Reset ModWidthReg
write_mfrc522(ModWidthReg, 0x26);
status_code result = picc_request_a(bufferATQA, &bufferSize);
return (result == STATUS_OK || result == STATUS_COLLISION);
} // End picc_is_new_card_present()
/**
* Simple wrapper around picc_select.
* Returns true if a uid_struct could be read.
* Remember to call picc_is_new_card_present(), picc_request_a() or PICC_WakeupA() first.
* The read uid_struct is available in the class variable uid.
*
* @return bool
*/
bool
picc_read_card_serial()
{
status_code result = picc_select(&uid,0);
return (result == STATUS_OK);
} // End
status_code
pcd_authenticate (uint8_t command, uint8_t blockAddr, MIFARE_Key *key, uid_struct *uid)
{
uint8_t wait_irq = 0x10; // IdleIRq
uint8_t i;
// Build command buffer
uint8_t send_data[12];
send_data[0] = command;
send_data[1] = blockAddr;
for ( i = 0; i < MF_KEY_SIZE; i++)
{ // 6 key bytes
send_data[2+i] = key->keyByte[i];
}
// Use the last uid_struct bytes as specified in http://cache.nxp.com/documents/application_note/AN10927.pdf
// section 3.2.5 "MIFARE Classic Authentication".
// The only missed case is the MF1Sxxxx shortcut activation,
// but it requires cascade tag (CT) byte, that is not part of uid.
for ( i = 0; i < 4; i++)
{ // The last 4 bytes of the UID
send_data[8+i] = uid->uidByte[i+uid->size-4];
}
// Start the authentication.
return pcd_communicate_tith_picc(pcd_mf_authent, wait_irq, &send_data[0], sizeof(send_data), NULL, NULL, NULL, 0, false);
} // End pcd_authenticate()
void
antenna_on()
{
uint8_t value ;
value = read_mfrc522(TxControlReg);
if ((value & 0x03) != 0x03) {
write_mfrc522(TxControlReg, value | 0x03);
}
value = read_mfrc522(TxControlReg);
}
/*
* Initializes the MFRC522 chip.
*/
bool
pcd_initialization()
{
//printf("pcd_initialization()\n");
mfr_reset_down();
us_delay_spi(2);
mfr_reset_up();
us_delay_spi(50000);
pcd_reset();
// Reset baud rates
write_mfrc522(TxModeReg, 0x00);
write_mfrc522(RxModeReg, 0xb0);
//Reset ModWidthReg
write_mfrc522(ModWidthReg, 0x26);
// When communicating with a PICC we need a timeout if something goes wrong.
// f_timer = 13.56 MHz / (2*TPreScaler+1) where TPreScaler = [TPrescaler_Hi:TPrescaler_Lo].
// TPrescaler_Hi are the four low bits in TModeReg. TPrescaler_Lo is TPrescalerReg.
write_mfrc522(TModeReg, 0x80); // TAuto=1; timer starts automatically at the end of the transmission in all communication modes at all speeds
write_mfrc522(TPrescalerReg, 0xA9); // TPreScaler = TModeReg[3..0]:TPrescalerReg, ie 0x0A9 = 169 => f_timer=40kHz, ie a timer period of 25μs.
write_mfrc522(TReloadRegH, 0x03); // Reload timer with 0x3E8 = 1000, ie 25ms before timeout.
write_mfrc522(TReloadRegL, 0xE8);
write_mfrc522(TxASKReg, 0x40); // Default 0x00. Force a 100 % ASK modulation independent of the ModGsPReg register setting
write_mfrc522(ModeReg, 0x3D); // Default 0x3F. Set the preset value for the CRC coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4)
write_mfrc522(RFCfgReg,0x70);
write_mfrc522(ComIEnReg,0x80);
write_mfrc522(FIFOLevelReg,0x00);
antenna_on(); // Enable the antenna driver pins TX1 and TX2 (they were disabled by the reset)
//printf("initialization Done()\n");
return 1;
} // End pcd_initialization() */

View File

@ -0,0 +1,237 @@
#ifndef _RFID_SPI_H_
#define _RFID_SPI_H_
#include <includes.h>
#include "spi.h"
#include <stdint.h>
#include <stdbool.h>
#define SPI_CS 0x01 //PC0
#define SPI_MOSI 0x10 //PA4
#define SPI_MISO 0x02 //PB1
#define SPI_Ck 0x04 //PA2
#define GPIO_PIN_6 0x40 //SDA (SLAVE SELECT)
#define MAX_LEN 16 // Maximum length of the array
#define MI_OK 0
#define MI_NOTAGERR 1
#define MI_ERR 2
#define PICC_REQIDL 0x26 // Area of the antenna is not trying to get into the idle state
#define Reserved00 0x00
#define CommIEnReg 0x02
#define DivlEnReg 0x03
#define CommIrqReg 0x04
#define PCD_IDLE 0x00 // No action; And cancel the command
#define PCD_AUTHENT 0x0E // authentication key
#define PCD_RECEIVE 0x08 // receiving data
#define PCD_TRANSMIT 0x04 // Send data
#define PCD_TRANSCEIVE 0x0C // Send and receive data
#define PCD_RESETPHASE 0x0F // reset
#define PCD_CALCCRC 0x03 // calculate CRC
#define Reserved01 0x0F
//Page 1:Command
#define Reserved10 0x10
#define Reserved11 0x1A
#define Reserved12 0x1B
#define MifareReg 0x1C
#define Reserved13 0x1D
#define Reserved14 0x1E
//Page 2:CFG
#define Reserved20 0x20
#define Reserved21 0x23
#define CRCResultRegM 0x21 // shows the MSB and LSB values of the CRC calculation
// MFRC522 commands. Described in chapter 10 of the datasheet.
#define PCD_Idle 0x00 // no action, cancels current command execution
#define PCD_Mem 0x01 // stores 25 bytes into the internal buffer
#define PCD_GenerateRandomID 0x02 // generates a 10-byte random ID number
#define PCD_CalcCRC 0x03 // activates the CRC coprocessor or performs a self test
#define PCD_Transmit 0x04 // transmits data from the FIFO buffer
#define PCD_NoCmdChange 0x07 // no command change, can be used to modify the CommandReg register bits without affecting the command, for example, the PowerDown bit
#define PCD_Receive 0x08 // activates the receiver circuits
#define PCD_Transceive 0x0C // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission
#define pcd_mf_authent 0x0E // performs the MIFARE standard authentication as a reader
#define PCD_SoftReset 0x0F // resets the MFRC522
#define TxAutoReg 0x15
#define delay_ms(i) (ti_lib_cpu_delay(8000 * (i)))
typedef enum {
// Page 0: Command and status
// 0x00 // reserved for future use
CommandReg = 0x01 , // starts and stops command execution
ComIEnReg = 0x02 , // enable and disable interrupt request control bits
DivIEnReg = 0x03 , // enable and disable interrupt request control bits
ComIrqReg = 0x04 , // interrupt request bits
DivIrqReg = 0x05 , // interrupt request bits
ErrorReg = 0x06 , // error bits showing the error status of the last command executed
Status1Reg = 0x07 , // communication status bits
Status2Reg = 0x08 , // receiver and transmitter status bits
FIFODataReg = 0x09 , // input and output of 64 byte FIFO buffer
FIFOLevelReg = 0x0A , // number of bytes stored in the FIFO buffer
WaterLevelReg = 0x0B , // level for FIFO underflow and overflow warning
ControlReg = 0x0C , // miscellaneous control registers
BitFramingReg = 0x0D , // adjustments for bit-oriented frames
CollReg = 0x0E , // bit position of the first bit-collision detected on the RF interface
// 0x0F // reserved for future use
// Page 1: Command
// 0x10 // reserved for future use
ModeReg = 0x11 , // defines general modes for transmitting and receiving
TxModeReg = 0x12 , // defines transmission data rate and framing
RxModeReg = 0x13 , // defines reception data rate and framing
TxControlReg = 0x14 , // controls the logical behavior of the antenna driver pins TX1 and TX2
TxASKReg = 0x15 , // controls the setting of the transmission modulation
TxSelReg = 0x16 , // selects the internal sources for the antenna driver
RxSelReg = 0x17 , // selects internal receiver settings
RxThresholdReg = 0x18 , // selects thresholds for the bit decoder
DemodReg = 0x19 , // defines demodulator settings
// 0x1A // reserved for future use
// 0x1B // reserved for future use
MfTxReg = 0x1C , // controls some MIFARE communication transmit parameters
MfRxReg = 0x1D , // controls some MIFARE communication receive parameters
// 0x1E // reserved for future use
SerialSpeedReg = 0x1F , // selects the speed of the serial UART interface
// Page 2: Configuration
// 0x20 // reserved for future use
CRCResultRegH = 0x21 , // shows the MSB and LSB values of the CRC calculation
CRCResultRegL = 0x22 ,
// 0x23 // reserved for future use
ModWidthReg = 0x24 , // controls the ModWidth setting?
// 0x25 // reserved for future use
RFCfgReg = 0x26 , // configures the receiver gain
GsNReg = 0x27 , // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
CWGsPReg = 0x28 , // defines the conductance of the p-driver output during periods of no modulation
ModGsPReg = 0x29 , // defines the conductance of the p-driver output during periods of modulation
TModeReg = 0x2A , // defines settings for the internal timer
TPrescalerReg = 0x2B , // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
TReloadRegH = 0x2C , // defines the 16-bit timer reload value
TReloadRegL = 0x2D ,
TCounterValueRegH = 0x2E , // shows the 16-bit timer value
TCounterValueRegL = 0x2F ,
// Page 3: Test Registers
// 0x30 // reserved for future use
TestSel1Reg = 0x31 , // general test signal configuration
TestSel2Reg = 0x32 , // general test signal configuration
TestPinEnReg = 0x33 , // enables pin output driver on pins D1 to D7
TestPinValueReg = 0x34 , // defines the values for D1 to D7 when it is used as an I/O bus
TestBusReg = 0x35 , // shows the status of the internal test bus
AutoTestReg = 0x36 , // controls the digital self-test
VersionReg = 0x37 , // shows the software version
AnalogTestReg = 0x38 , // controls the pins AUX1 and AUX2
TestDAC1Reg = 0x39 , // defines the test value for TestDAC1
TestDAC2Reg = 0x3A , // defines the test value for TestDAC2
TestADCReg = 0x3B // shows the value of ADC I and Q channels
// 0x3C // reserved for production tests
// 0x3D // reserved for production tests
// 0x3E // reserved for production tests
// 0x3F // reserved for production tests
}pcd_register;
// Commands sent to the PICC.
typedef enum {
// The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)
PICC_CMD_REQA = 0x26, // REQuest command, Type A. Invites PICCs in state IDLE to go to READY and prepare for anticollision or selection. 7 bit frame.
PICC_CMD_WUPA = 0x52, // Wake-UP command, Type A. Invites PICCs in state IDLE and HALT to go to READY(*) and prepare for anticollision or selection. 7 bit frame.
PICC_CMD_CT = 0x88, // Cascade Tag. Not really a command, but used during anti collision.
PICC_CMD_SEL_CL1 = 0x93, // Anti collision/Select, Cascade Level 1
PICC_CMD_SEL_CL2 = 0x95, // Anti collision/Select, Cascade Level 2
PICC_CMD_SEL_CL3 = 0x97, // Anti collision/Select, Cascade Level 3
PICC_CMD_HLTA = 0x50, // HaLT command, Type A. Instructs an ACTIVE PICC to go to state HALT.
PICC_CMD_RATS = 0xE0, // Request command for Answer To Reset.
// The commands used for MIFARE Classic (from http://www.mouser.com/ds/2/302/MF1S503x-89574.pdf, Section 9)
// Use pcd_mf_authent to authenticate access to a sector, then use these commands to read/write/modify the blocks on the sector.
// The read/write commands can also be used for MIFARE Ultralight.
PICC_CMD_MF_AUTH_KEY_A = 0x60, // Perform authentication with Key A
PICC_CMD_MF_AUTH_KEY_B = 0x61, // Perform authentication with Key B
PICC_CMD_MF_READ = 0x30, // Reads one 16 byte block from the authenticated sector of the PICC. Also used for MIFARE Ultralight.
PICC_CMD_MF_WRITE = 0xA0, // Writes one 16 byte block to the authenticated sector of the PICC. Called "COMPATIBILITY WRITE" for MIFARE Ultralight.
PICC_CMD_MF_DECREMENT = 0xC0, // Decrements the contents of a block and stores the result in the internal data register.
PICC_CMD_MF_INCREMENT = 0xC1, // Increments the contents of a block and stores the result in the internal data register.
PICC_CMD_MF_RESTORE = 0xC2, // Reads the contents of a block into the internal data register.
PICC_CMD_MF_TRANSFER = 0xB0, // Writes the contents of the internal data register to a block.
// The commands used for MIFARE Ultralight (from http://www.nxp.com/documents/data_sheet/MF0ICU1.pdf, Section 8.6)
// The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight.
PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC.
}PICC_Command;
typedef enum {
PICC_TYPE_UNKNOWN ,
PICC_TYPE_ISO_14443_4 , // PICC compliant with ISO/IEC 14443-4
PICC_TYPE_ISO_18092 , // PICC compliant with ISO/IEC 18092 (NFC)
PICC_TYPE_MIFARE_MINI , // MIFARE Classic protocol, 320 bytes
PICC_TYPE_MIFARE_1K , // MIFARE Classic protocol, 1KB
PICC_TYPE_MIFARE_4K , // MIFARE Classic protocol, 4KB
PICC_TYPE_MIFARE_UL , // MIFARE Ultralight or Ultralight C
PICC_TYPE_MIFARE_PLUS , // MIFARE Plus
PICC_TYPE_MIFARE_DESFIRE, // MIFARE DESFire
PICC_TYPE_TNP3XXX , // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure
PICC_TYPE_NOT_COMPLETE = 0xff // SAK indicates uid_struct is not complete.
}picc_type;
// Return codes from the functions in this class. Remember to update Getstatus_codeName() if you add more.
// last value set to 0xff, then compiler uses less ram, it seems some optimisations are triggered
typedef enum {
STATUS_OK , // Success
STATUS_ERROR , // Error in communication
STATUS_COLLISION , // Collission detected
STATUS_TIMEOUT , // Timeout in communication.
STATUS_NO_ROOM , // A buffer is not big enough.
STATUS_INTERNAL_ERROR , // Internal error in the code. Should not happen ;-)
STATUS_INVALID , // Invalid argument.
STATUS_CRC_WRONG , // The CRC_A does not match
STATUS_MIFARE_NACK = 0xff // A MIFARE PICC responded with NAK.
}status_code;
typedef enum {
MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK.
MF_KEY_SIZE = 6 // A Mifare Crypto1 key is 6 bytes.
}MIFARE_Misc;
// A struct used for passing a MIFARE Crypto1 key
typedef struct {
uint8_t keyByte[MF_KEY_SIZE];
} MIFARE_Key;
// A struct used for passing the uid_struct of a PICC.
typedef struct {
uint8_t size; // Number of bytes in the UID. 4, 7 or 10.
uint8_t uidByte[10];
uint8_t sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
} uid_struct;
void write_bytes_mfrc522( pcd_register reg, uint8_t count, uint8_t *values);
void write_mfrc522(uint8_t adr, uint8_t val);
uint8_t read_mfrc522(uint8_t dev_cmd);
void read_fifo_mfrc522( pcd_register reg, uint8_t count, uint8_t *values, uint8_t rx_align);
picc_type picc_get_type(uint8_t sak);
void pcd_set_register_bit_mask(pcd_register reg, uint8_t mask);
status_code pcd_calculate_crc(uint8_t *data, uint8_t length, uint8_t *result);
void pcd_reset();
status_code pcd_communicate_tith_picc(uint8_t command, uint8_t wait_irq, uint8_t *send_data, uint8_t send_len, uint8_t *back_data, uint8_t *back_len, uint8_t *valid_bits, uint8_t rx_align, bool check_crc);
status_code pcd_transceive_data(uint8_t *send_data, uint8_t send_len, uint8_t *back_data, uint8_t *back_len, uint8_t *valid_bits, uint8_t rx_align, bool check_crc);
status_code mifare_read( uint8_t blockAddr, uint8_t *buffer, uint8_t *bufferSize);
status_code mifare_write(uint8_t blockAddr, uint8_t *buffer, uint8_t bufferSize);
void pcd_clear_register_bit_mask(pcd_register reg, uint8_t mask);
void pcd_stop_cryptol();
status_code picc_select( uid_struct *uid, uint8_t valid_bits);
status_code picc_halt_a();
void picc_get_type_name(picc_type piccType);
status_code picc_reqa_or_wupa( uint8_t command, uint8_t *bufferATQA, uint8_t *bufferSize);
status_code picc_request_a( uint8_t *bufferATQA,uint8_t *bufferSize);
bool picc_is_new_card_present();
bool picc_read_card_serial();
status_code pcd_authenticate (uint8_t command, uint8_t blockAddr, MIFARE_Key *key, uid_struct *uid);
void get_status_code_name (status_code code);
void antenna_on();
bool pcd_initialization();
uid_struct * get_uid();
#endif

View File

@ -443,16 +443,15 @@ const TMenuLine line_ChannelCountersMenu_3 = {
NULL // ïàíåëü äëÿ ïåðåõîäà
};
/*
const TMenuLine line_ChannelCountersMenu_4 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterChannelTimeDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
(void*)&CounterChannelAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
*/
const TMenuLineArray arr_ChannelCountersArray[] = {&line_ChannelCountersMenu_0, &line_ChannelCountersMenu_1, &line_ChannelCountersMenu_2, &line_ChannelCountersMenu_3, NULL};
const TMenuPanel ChannelCountersPanel[] = {arr_ChannelCountersArray, NULL, 4, MENU_PANEL_STATIC};
const TMenuLineArray arr_ChannelCountersArray[] = {&line_ChannelCountersMenu_0, &line_ChannelCountersMenu_1, &line_ChannelCountersMenu_2, &line_ChannelCountersMenu_3, &line_ChannelCountersMenu_4, NULL};
const TMenuPanel ChannelCountersPanel[] = {arr_ChannelCountersArray, NULL, 5, MENU_PANEL_STATIC};
/***********************************
@ -526,6 +525,13 @@ const TMenuLine line_CommonCountersMenu_2 = {
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_CommonCountersMenu_3 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
#elif defined(BOARD_SOLARIUM_WEB)
const TMenuLine line_CommonCountersMenu_1 = {
@ -545,8 +551,8 @@ const TMenuLine line_CommonCountersMenu_2 = {
#endif
const TMenuLineArray arr_CommonCountersArray[] = {&line_CommonCountersMenu_0, &line_CommonCountersMenu_1, &line_CommonCountersMenu_2, NULL};
const TMenuPanel CommonCountersPanel[] = {arr_CommonCountersArray, NULL, 3, MENU_PANEL_STANDARD};
const TMenuLineArray arr_CommonCountersArray[] = {&line_CommonCountersMenu_0, &line_CommonCountersMenu_1, &line_CommonCountersMenu_2, &line_CommonCountersMenu_3, NULL};
const TMenuPanel CommonCountersPanel[] = {arr_CommonCountersArray, NULL, 4, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ÎÁÙÀß ÑÒÀÒÈÑÒÈÊÀ ÄËÈÍÍÛÅ Ñ×ÅÒ×ÈÊÈ
@ -576,6 +582,13 @@ const TMenuLine line_CommonCountersLongMenu_2 = {
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_CommonCountersLongMenu_3 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterLongAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
#elif defined(BOARD_SOLARIUM_WEB)
const TMenuLine line_CommonCountersLongMenu_1 = {
@ -595,8 +608,8 @@ const TMenuLine line_CommonCountersLongMenu_2 = {
#endif
const TMenuLineArray arr_CommonCountersLongArray[] = {&line_CommonCountersLongMenu_0, &line_CommonCountersLongMenu_1, &line_CommonCountersLongMenu_2, NULL};
const TMenuPanel CommonCountersLongPanel[] = {arr_CommonCountersLongArray, NULL, 3, MENU_PANEL_STANDARD};
const TMenuLineArray arr_CommonCountersLongArray[] = {&line_CommonCountersLongMenu_0, &line_CommonCountersLongMenu_1, &line_CommonCountersLongMenu_2, &line_CommonCountersLongMenu_3, NULL};
const TMenuPanel CommonCountersLongPanel[] = {arr_CommonCountersLongArray, NULL, 4, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ÍÀÑÒÐÎÉÊÈ
@ -612,6 +625,7 @@ const CPU_INT08U str_SettingsMenu_7[] = "
#if defined(BOARD_SOLARIUM_VLAD)
const CPU_INT08U str_SettingsMenu_1[] = "Ñîëÿðèè";
const CPU_INT08U str_SettingsMenu_7[] = "Ñêèäêè";
const CPU_INT08U str_SettingsMenu_10[] = "Àáîíåìåíòû";
const CPU_INT08U str_SettingsMenu_8[] = "Òèïû êîæè";
#else
const CPU_INT08U str_SettingsMenu_1[] = "Ïîñòû";
@ -676,6 +690,13 @@ const TMenuLine line_SettingsMenu_10 = {
(void*)str_SettingsMenu_8, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
(void*)&SkinTypeSettingsMenuPanel // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_SettingsMenu_12 = {
MENU_LINE_GOTO_MENU, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)str_SettingsMenu_10, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
(void*)&AbonementMenuPanel // ïàíåëü äëÿ ïåðåõîäà
};
#endif
const TMenuLine line_SettingsMenu_8 = {
@ -730,6 +751,7 @@ const TMenuLineArray arr_SettingsMenuArray[] = {&line_SettingsMenu_0,
#endif
#if defined(BOARD_SOLARIUM_VLAD)
&line_SettingsMenu_10,
&line_SettingsMenu_12,
&line_SettingsMenu_9,
#endif
#if defined(BOARD_CENTRAL_CARWASH) || defined(BOARD_SOLARIUM_VLAD)
@ -757,7 +779,7 @@ const TMenuPanel SettingsMenuPanel[] = {arr_SettingsMenuArray, NULL,
#if defined(BOARD_CENTRAL_CARWASH)
7
#elif defined(BOARD_SOLARIUM_VLAD)
9
10
#else
6
#endif
@ -1190,6 +1212,7 @@ const CPU_INT08U str_DeviceMenu_6[] = "
#endif
#if defined(BOARD_SOLARIUM_VLAD)
const CPU_INT08U str_DeviceMenu_7[] = "Òàáëî";
const CPU_INT08U str_DeviceMenu_9[] = "Àáîíåìåíò";
#endif
#if defined(CONFIG_RELAY_ENABLE)
const CPU_INT08U str_DeviceMenu_8[] = "Ðåëå";
@ -1253,6 +1276,13 @@ const TMenuLine line_DeviceMenu_7 = {
(void*)str_DeviceMenu_7, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
(void*)&ScoreSettingsPanel // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_DeviceMenu_9 = {
MENU_LINE_GOTO_MENU, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)str_DeviceMenu_9, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
(void*)&AbonementSetupPanel // ïàíåëü äëÿ ïåðåõîäà
};
#endif
#if defined(CONFIG_RELAY_ENABLE)
@ -1264,7 +1294,7 @@ const TMenuLine line_DeviceMenu_8 = {
};
#endif
const TMenuLineArray arr_DeviceMenuArray[] = {&line_DeviceMenu_0, &line_DeviceMenu_1, &line_DeviceMenu_2, &line_DeviceMenu_3,
const TMenuLineArray arr_DeviceMenuArray[] = {&line_DeviceMenu_0, /*&line_DeviceMenu_1, &line_DeviceMenu_2, &line_DeviceMenu_3,*/
#if defined(CONFIG_MODEM_ENABLE)
&line_DeviceMenu_4,
#endif
@ -1274,13 +1304,14 @@ const TMenuLineArray arr_DeviceMenuArray[] = {&line_DeviceMenu_0, &line_DeviceMe
#endif
#if defined(BOARD_SOLARIUM_VLAD)
&line_DeviceMenu_7,
&line_DeviceMenu_9,
#endif
#if defined(CONFIG_RELAY_ENABLE)
&line_DeviceMenu_8,
#endif
NULL};
const TMenuPanel DeviceMenuPanel[] = {arr_DeviceMenuArray, NULL,
5
2
#if defined(CONFIG_MUSIC_ENABLE)
+ 1
#endif
@ -1288,7 +1319,7 @@ const TMenuPanel DeviceMenuPanel[] = {arr_DeviceMenuArray, NULL,
+ 1
#endif
#if defined(BOARD_SOLARIUM_VLAD)
+ 1
+ 2
#endif
#if defined(CONFIG_RELAY_ENABLE)
+ 1
@ -1526,6 +1557,42 @@ const TMenuLine line_CoinMenu_5 = {
const TMenuLineArray arr_CoinMenuArray[] = {&line_CoinMenu_0, &line_CoinMenu_1, &line_CoinMenu_2, &line_CoinMenu_3, &line_CoinMenu_4, &line_CoinMenu_5, NULL};
const TMenuPanel CoinSetupPanel[] = {arr_CoinMenuArray, NULL, 6, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ÍÀÑÒÐÎÉÊÀ ÀÁÎÍÅÌÅÍÒÀ
***********************************/
const CPU_INT08U str_AbonementMenuSet_0[] = "ÍÀÑÒÐÎéÊÈ ÀÁÎÍÅÌÅÍ.";
const TMenuLine line_AbonementMenuSet_0 = {
MENU_LINE_STRING, // òèï ïóíêòà ìåíþ
MENU_FIXED_LINE, // äîï. ôëàãè
(void*)str_AbonementMenuSet_0, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementMenuSet_1 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&EnableAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementMenuSet_2 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CountUseAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementMenuSet_3 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&ClearStatAbonementCmdDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLineArray arr_AbonementMenuArray[] = {&line_AbonementMenuSet_0, &line_AbonementMenuSet_1, &line_AbonementMenuSet_2, &line_AbonementMenuSet_3, NULL};
const TMenuPanel AbonementSetupPanel[] = {arr_AbonementMenuArray, NULL, 4, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ÍÀÑÒÐÎÉÊÀ ÌÎÄÅÌÀ
***********************************/
@ -2212,8 +2279,8 @@ const TMenuPanel FrIsOffMenuPanel[] = {arr_FrIsOffMenuArray, NULL, 3, MENU_PANEL
/***********************************
ÌÅÍÞ ÏÐÎÑÌÎÒÐ ÆÓÐÍÀËÀ ÑÎÁÛÒÈÉ
***********************************/
char str_EventNumber[24];
char str_EventData[24];
char str_EventNumber[40];
char str_EventData[40];
const TMenuLine line_EventJournalMenu_0 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
@ -2297,6 +2364,68 @@ void PrintEventJournalRecord(TEventRecord *record, char *str_event, char *str_da
sprintf(str_data, "%d ðóá.", record->data);
#endif
}
else if (record->event == JOURNAL_EVENT_CARD_ABONEMENT_ACCEPTED)
{
sprintf(str_data, "%dðóá.%02dêîï.", record->money_bank / 100, record->money_bank % 100);
}
else if (record->event == JOURNAL_EVENT_ABONEMENT_ACCEPTED)
{
sprintf(&str_event[strlen(str_event)], " %dð %d", record->money, record->bonus);
char str[32];
PrintDateString(str, record->time_before);
sprintf(str_data, "%x %dð %dÁ %s", record->number_abonement, record->money_sum, record->bonus_sum, str);
// äîáàâèì â str_event ïðîáåëîâ äî äëèíû str_data ÷òîáû îíè îäíîâðåìåííî ïðîêðó÷èâàëèñü
CPU_INT08U len_event = strlen(str_event);
CPU_INT08U len_data = strlen(str_data);
if(len_data > len_event)
{
CPU_INT08U i = 0;
for(i = 0; i < len_data - len_event; i++)
{
str_event[len_event + i] = 0x20;
}
str_event[len_event + i] = 0x00;
}
}
else if (record->event == JOURNAL_EVENT_ABONEMENT_PAY_ACCEPTED)
{
sprintf(&str_event[strlen(str_event)], " %dð %d", record->money, record->type_abonement + 1);
char str[32];
PrintDateString(str, record->time_before);
sprintf(str_data, "%x %dð %dÁ %s", record->number_abonement, record->money_sum, record->bonus_sum, str);
}
else if (record->event == JOURNAL_EVENT_ABONEMENT_REJECTED)
{
sprintf(str_data, "%x %dðóá %dÁ", record->number_abonement, record->money_sum, record->bonus_sum);
}
else if (record->event == JOURNAL_EVENT_CARD_ABONEMENT_REAPEATE)
{
sprintf(str_data, "%x %dðóá %dÁ", record->number_abonement, record->money_sum, record->bonus_sum);
}
else if (record->event == JOURNAL_EVENT_ABONEMENT_PAY_REJECTED)
{
sprintf(&str_event[strlen(str_event)], "Ïîñò %d", record->channel+1);
strcpy(str_data, "Îòêàç");
}
else if (record->event == JOURNAL_EVENT_ABONEMENT_BALANCE)
{
char str[32];
PrintDateString(str, record->time_before);
sprintf(str_data, "%x %dð %dÁ %s", record->number_abonement, record->money_sum, record->bonus_sum, str);
}
else if (record->event == JOURNAL_EVENT_ABONEMENT_WRONG)
{
sprintf(str_data, "%x. Êîä îøèáêè %ld", record->number_abonement, record->password);
}
else if (record->event == JOURNAL_EVENT_CARD_REJECTED)
{
sprintf(&str_event[strlen(str_event)], "Ïîñò %d", record->channel+1);
@ -2544,8 +2673,15 @@ const TMenuLine line_ChannelCountersLongMenu_3 = {
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLineArray arr_ChannelCountersLongArray[] = {&line_ChannelCountersLongMenu_0, &line_ChannelCountersLongMenu_1, &line_ChannelCountersLongMenu_2, &line_ChannelCountersLongMenu_3, NULL};
const TMenuPanel ChannelCountersLongPanel[] = {arr_ChannelCountersLongArray, NULL, 4, MENU_PANEL_STANDARD};
const TMenuLine line_ChannelCountersLongMenu_4 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterChannelAbonementLongDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLineArray arr_ChannelCountersLongArray[] = {&line_ChannelCountersLongMenu_0, &line_ChannelCountersLongMenu_1, &line_ChannelCountersLongMenu_2, &line_ChannelCountersLongMenu_3, &line_ChannelCountersLongMenu_4, NULL};
const TMenuPanel ChannelCountersLongPanel[] = {arr_ChannelCountersLongArray, NULL, 5, MENU_PANEL_STANDARD};
#if defined(BOARD_SOLARIUM_WEB)
@ -2857,6 +2993,45 @@ const TMenuLine line_DiscountMainMenu_5 = {
const TMenuLineArray arr_DiscountMainArray[] = {&line_DiscountMainMenu_0, &line_DiscountMainMenu_1, &line_DiscountMainMenu_2, &line_DiscountMainMenu_3, &line_DiscountMainMenu_4, &line_DiscountMainMenu_5, NULL};
const TMenuPanel DiscountMainMenuPanel[] = {arr_DiscountMainArray, NULL, 6, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ÀÁÎÍÅÌÅÍÒÛ
***********************************/
const TMenuLine line_AbonementMenu_0 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
MENU_FIXED_LINE|MENU_INDEX_LINE, // äîï. ôëàãè
(void*)&AbonementIndexDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementMenu_1 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&AbonementMoneyDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementMenu_2 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&AbonementBonusDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementMenu_3 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&AbonementBestBeforeDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
void OnEnterAbonementMenu(void)
{
abonement_index = 0;
}
const TMenuLineArray arr_AbonementArray[] = {&line_AbonementMenu_0, &line_AbonementMenu_1, &line_AbonementMenu_2, &line_AbonementMenu_3, NULL};
const TMenuPanel AbonementMenuPanel[] = {arr_AbonementArray, OnEnterAbonementMenu, 4, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ÑÊÈÄÊÈ ÏÎ ×ÀÑÀÌ
***********************************/
@ -3111,6 +3286,20 @@ const TMenuLine line_SolarModesCountersMenu_1 = {
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_SolarModesCountersMenu_6 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterModeCardMoneyDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_SolarModesCountersMenu_7 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterModeCardBonusDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_SolarModesCountersMenu_2 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
@ -3144,8 +3333,8 @@ void OnEnterSolarModesCountersMenu(void)
solar_modes_index = 0;
}
const TMenuLineArray arr_SolarModesCountersArray[] = {&line_SolarModesCountersMenu_0, &line_SolarModesCountersMenu_1, &line_SolarModesCountersMenu_2, &line_SolarModesCountersMenu_3, &line_SolarModesCountersMenu_4, &line_SolarModesCountersMenu_5, NULL};
const TMenuPanel SolarModesCountersPanel[] = {arr_SolarModesCountersArray, OnEnterSolarModesCountersMenu, 6, MENU_PANEL_STANDARD};
const TMenuLineArray arr_SolarModesCountersArray[] = {&line_SolarModesCountersMenu_0, &line_SolarModesCountersMenu_1, &line_SolarModesCountersMenu_6, &line_SolarModesCountersMenu_7, &line_SolarModesCountersMenu_2, &line_SolarModesCountersMenu_3, &line_SolarModesCountersMenu_4, &line_SolarModesCountersMenu_5, NULL};
const TMenuPanel SolarModesCountersPanel[] = {arr_SolarModesCountersArray, OnEnterSolarModesCountersMenu, 8, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ Ñ×ÅÒ×ÈÊΠÏÎ ÑÎËßÐÈßÌ È ÐÅÆÈÌÀÌ
@ -3164,6 +3353,20 @@ const TMenuLine line_SolarChannelsCountersMenu_1 = {
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_SolarChannelsCountersMenu_6 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterSolarCardMoneyDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_SolarChannelsCountersMenu_7 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterSolarCardBonusDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_SolarChannelsCountersMenu_2 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
@ -3198,8 +3401,47 @@ void OnEnterSolarChannelsCountersMenu(void)
solar_modes_index = 0;
}
const TMenuLineArray arr_SolarChannelsCountersArray[] = {&line_SolarChannelsCountersMenu_0, &line_SolarChannelsCountersMenu_1, &line_SolarChannelsCountersMenu_2, &line_SolarChannelsCountersMenu_3, &line_SolarChannelsCountersMenu_4, &line_SolarChannelsCountersMenu_5, NULL};
const TMenuPanel SolarChannelsCountersPanel[] = {arr_SolarChannelsCountersArray, OnEnterSolarChannelsCountersMenu, 6, MENU_PANEL_STANDARD};
const TMenuLineArray arr_SolarChannelsCountersArray[] = {&line_SolarChannelsCountersMenu_0, &line_SolarChannelsCountersMenu_1, &line_SolarChannelsCountersMenu_6, &line_SolarChannelsCountersMenu_7, &line_SolarChannelsCountersMenu_2, &line_SolarChannelsCountersMenu_3, &line_SolarChannelsCountersMenu_4, &line_SolarChannelsCountersMenu_5, NULL};
const TMenuPanel SolarChannelsCountersPanel[] = {arr_SolarChannelsCountersArray, OnEnterSolarChannelsCountersMenu, 8, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ñ÷åò÷èêîâ ïî àáîíåìåíòàì
***********************************/
const TMenuLine line_AbonementsCountersMenu_0 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
MENU_FIXED_LINE|MENU_INDEX_LINE, // äîï. ôëàãè
(void*)&AbonementCounterIndexDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementsCountersMenu_1 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterMoneyAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementsCountersMenu_2 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterRunsAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLine line_AbonementsCountersMenu_3 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterBonusAbonementDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
void OnEnterAbonementCountersMenu(void)
{
// abonement_index = 0;
}
const TMenuLineArray arr_AbonementCountersArray[] = {&line_AbonementsCountersMenu_0, &line_AbonementsCountersMenu_1, &line_AbonementsCountersMenu_2, &line_AbonementsCountersMenu_3, NULL};
const TMenuPanel AbonementCountersPanel[] = {arr_AbonementCountersArray, OnEnterAbonementCountersMenu, 4, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ Ñ×ÅÒ×ÈÊΠÏÎ ÂÐÅÌÅÍÈ ÍÀÐÀÁÎÒÊÈ ËÀÌÏ
@ -3317,8 +3559,15 @@ const TMenuLine line_SolarCommonCountersMenu_3 = {
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLineArray arr_SolarCommonCountersArray[] = {&line_SolarCommonCountersMenu_0, &line_SolarCommonCountersMenu_1, &line_SolarCommonCountersMenu_2, &line_SolarCommonCountersMenu_3, NULL};
const TMenuPanel SolarCommonCountersPanel[] = {arr_SolarCommonCountersArray, NULL, 4, MENU_PANEL_STANDARD};
const TMenuLine line_SolarCommonCountersMenu_4 = {
MENU_LINE_SHOW_DESC, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)&CounterAbonementMoneyDesc, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
NULL // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLineArray arr_SolarCommonCountersArray[] = {&line_SolarCommonCountersMenu_0, &line_SolarCommonCountersMenu_1, &line_SolarCommonCountersMenu_2, &line_SolarCommonCountersMenu_3, &line_SolarCommonCountersMenu_4, NULL};
const TMenuPanel SolarCommonCountersPanel[] = {arr_SolarCommonCountersArray, NULL, 5, MENU_PANEL_STANDARD};
/***********************************
ÌÅÍÞ ÏÐÎÑÌÎÒÐ ÑÒÀÒÈÑÒÈÊÈ
@ -3328,6 +3577,7 @@ const CPU_INT08U str_CommonStatMenu_1[] = "
const CPU_INT08U str_CommonStatMenu_2[] = "Ïî ðåæèìàì";
const CPU_INT08U str_CommonStatMenu_3[] = "Íàðàáîòêà";
const CPU_INT08U str_CommonStatMenu_4[] = "Äåíüãè";
const CPU_INT08U str_CommonStatMenu_5[] = "Àáîìåìåíòû";
const TMenuLine line_StatMenu_0 = {
MENU_LINE_STRING, // òèï ïóíêòà ìåíþ
@ -3364,8 +3614,15 @@ const TMenuLine line_StatMenu_4 = {
(void*)SolarCommonCountersPanel // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLineArray arr_StatMenuArray[] = {&line_StatMenu_0, &line_StatMenu_1, &line_StatMenu_2, &line_StatMenu_3, &line_StatMenu_4, NULL};
const TMenuPanel CommStatMenuPanel[] = {arr_StatMenuArray, NULL, 5, MENU_PANEL_STANDARD};
const TMenuLine line_StatMenu_5 = {
MENU_LINE_GOTO_MENU, // òèï ïóíêòà ìåíþ
0, // äîï. ôëàãè
(void*)str_CommonStatMenu_5, // óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
(void*)AbonementCountersPanel // ïàíåëü äëÿ ïåðåõîäà
};
const TMenuLineArray arr_StatMenuArray[] = {&line_StatMenu_0, &line_StatMenu_1, &line_StatMenu_2, &line_StatMenu_3, &line_StatMenu_4, &line_StatMenu_5, NULL};
const TMenuPanel CommStatMenuPanel[] = {arr_StatMenuArray, NULL, 6, MENU_PANEL_STANDARD};
/***********************************

View File

@ -20,6 +20,7 @@ extern const TMenuPanel CommonCountersLongPanel[];
extern const TMenuPanel BillCountersPanel[];
extern const TMenuPanel ModemSetupPanel[];
extern const TMenuPanel CoinSetupPanel[];
extern const TMenuPanel AbonementSetupPanel[];
extern const TMenuPanel JournalIsReset[];
extern const TMenuPanel ClearJournalMenuPanel[];
extern const TMenuPanel StatIsReset[];
@ -78,13 +79,14 @@ extern const TMenuPanel FtpUploadInProgressMenu[];
extern const TMenuPanel FtpOKMenu[];
extern const TMenuPanel FtpFAILMenu[];
extern const TMenuPanel CanselCheckMenuPanel[];
extern const TMenuPanel AbonementMenuPanel[];
extern int PrintUserMenuStr(char* str, CPU_INT08U n);
extern int PrintUserMenuStrUnalign(char* str, CPU_INT08U n);
extern void PrintEventJournalRecord(TEventRecord *record, char *str_event, char *str_data);
extern char str_EventNumber[24];
extern char str_EventData[24];
extern char str_EventNumber[40];
extern char str_EventData[40];
extern char str_UserMenu_0[22];
extern char str_UserMenu_1[22];

View File

@ -4,7 +4,7 @@
#if defined(BOARD_SOLARIUM_WEB)
#define DEVICE_FW_VERSION "7.09"
#elif defined(BOARD_SOLARIUM_VLAD)
#define DEVICE_FW_VERSION "8.46"
#define DEVICE_FW_VERSION "8.56"
#elif defined(BOARD_CENTRAL_CARWASH) || defined(BOARD_POST_CARWASH)
#define DEVICE_FW_VERSION "5.55"
#endif

View File

@ -12,7 +12,11 @@
"--device=LPC2368"
"--multicore_nr_of_cores=1"
"--drv_communication=USB0"
"--drv_interface_speed=auto"
"--jlink_initial_speed=1000"

View File

@ -1,6 +1,6 @@
"C:\Program Files\IAR Systems\Embedded Workbench 9.0\arm\bin\armPROC.dll"
"C:\Program Files\IAR Systems\Embedded Workbench 9.0\arm\bin\armSIM2.dll"
"C:\Program Files\IAR Systems\Embedded Workbench 9.0\arm\bin\armJLINK.dll"
"C:\git_work\solarium.vlad\Solarium Vlad\Exe\sk_mlpc2368.out"
@ -8,6 +8,8 @@
--device_macro="C:\Program Files\IAR Systems\Embedded Workbench 9.0\arm\config\debugger\NXP\LPC23xx.dmac"
--flash_loader="C:\Program Files\IAR Systems\Embedded Workbench 9.0\arm\config\flashloader\NXP\FlashNXPLPC512K2.board"

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,20 @@
<?xml version="1.0"?>
<settings>
<Stack>
<FillEnabled>0</FillEnabled>
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
<WarningThreshold>90</WarningThreshold>
<SpWarningsEnabled>1</SpWarningsEnabled>
<WarnLogOnly>1</WarnLogOnly>
<UseTrigger>1</UseTrigger>
<TriggerName>main</TriggerName>
<LimitSize>0</LimitSize>
<ByteLimit>50</ByteLimit>
</Stack>
<Trace1>
<Enabled>0</Enabled>
<ShowSource>1</ShowSource>
</Trace1>
<InterruptLog>
<LogEnabled>0</LogEnabled>
<GraphEnabled>0</GraphEnabled>
@ -15,23 +30,6 @@
<SumEnabled>0</SumEnabled>
<ShowTimeSum>1</ShowTimeSum>
</DataLog>
<Stack>
<FillEnabled>0</FillEnabled>
<OverflowWarningsEnabled>1</OverflowWarningsEnabled>
<WarningThreshold>90</WarningThreshold>
<SpWarningsEnabled>1</SpWarningsEnabled>
<WarnLogOnly>1</WarnLogOnly>
<UseTrigger>1</UseTrigger>
<TriggerName>main</TriggerName>
<LimitSize>0</LimitSize>
<ByteLimit>50</ByteLimit>
</Stack>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Count>0</Count>
</Breakpoints2>
<Interrupts>
<Enabled>1</Enabled>
</Interrupts>
@ -42,17 +40,86 @@
<TypeViol>0</TypeViol>
<Stop>1</Stop>
</MemConfig>
<Trace1>
<Enabled>0</Enabled>
<ShowSource>1</ShowSource>
</Trace1>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
<Simulator>
<Freq>10000000</Freq>
<FreqHi>0</FreqHi>
<MultiCoreRunAll>1</MultiCoreRunAll>
</Simulator>
<PlDriver>
<FirstRun>0</FirstRun>
<MemConfigValue>C:\Program Files\IAR Systems\Embedded Workbench 9.0\arm\CONFIG\debugger\NXP\LPC2368.ddf</MemConfigValue>
</PlDriver>
<DebugChecksum>
<Checksum>2586745689</Checksum>
</DebugChecksum>
<Exceptions>
<StopOnUncaught>_ 0</StopOnUncaught>
<StopOnThrow>_ 0</StopOnThrow>
</Exceptions>
<Disassembly>
<MixedMode>1</MixedMode>
<InstrCount>0</InstrCount>
</Disassembly>
<CallStack>
<ShowArgs>0</ShowArgs>
</CallStack>
<JLinkDriver>
<WatchCond>_ 0</WatchCond>
<Watch0>_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0</Watch0>
<Watch1>_ 0 "" 0 "" 0 "" 0 "" 0 0 0 0</Watch1>
<jlinkResetStyle>12</jlinkResetStyle>
<jlinkResetStrategy>0</jlinkResetStrategy>
<LeaveTargetRunning>_ 0</LeaveTargetRunning>
<CStepIntDis>_ 0</CStepIntDis>
</JLinkDriver>
<ArmDriver>
<EnableCache>0</EnableCache>
</ArmDriver>
<struct_types>
<Fmt0>mifaredata_t-bonus 4 0</Fmt0>
<Fmt1>mifaredata_t-init 4 0</Fmt1>
</struct_types>
<array_types>
<Fmt0>uint32_t[10] 4 0</Fmt0>
</array_types>
<watch_formats>
<Fmt0>{W}1:app_state.user_menu 3 0</Fmt0>
</watch_formats>
<DriverProfiling>
<Enabled>0</Enabled>
<Mode>1</Mode>
<Graph>0</Graph>
<Symbiont>0</Symbiont>
</DriverProfiling>
<CallStackLog>
<Enabled>0</Enabled>
</CallStackLog>
<CallStackStripe>
<ShowTiming>1</ShowTiming>
</CallStackStripe>
<TermIOLog>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
</TermIOLog>
<Trace2>
<Enabled>0</Enabled>
<ShowSource>0</ShowSource>
</Trace2>
<LogFile>
<LoggingEnabled>_ 0</LoggingEnabled>
<LogFile>_ ""</LogFile>
<Category>_ 0</Category>
</LogFile>
<DisassembleMode>
<mode>0</mode>
</DisassembleMode>
<Breakpoints2>
<Bp0>_ 1 "EMUL_CODE" "{$PROJ_DIR$\PROJECT\drivers\mfrc522\rfid-spi.c}.321.7" 0 0 1 "" 0 "" 0</Bp0>
<Bp1>_ 1 "EMUL_CODE" "{$PROJ_DIR$\PROJECT\drivers\mfrc522\rfid-spi.c}.190.3" 0 0 1 "" 0 "" 0</Bp1>
<Count>2</Count>
</Breakpoints2>
<Aliases>
<Count>0</Count>
<SuppressDialog>0</SuppressDialog>
</Aliases>
</settings>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,40 @@
[BREAKPOINTS]
ForceImpTypeAny = 0
ShowInfoWin = 1
EnableFlashBP = 2
BPDuringExecution = 0
[CFI]
CFISize = 0x00
CFIAddr = 0x00
[CPU]
MonModeVTableAddr = 0xFFFFFFFF
MonModeDebug = 0
MaxNumAPs = 0
LowPowerHandlingMode = 0
OverrideMemMap = 0
AllowSimulation = 1
ScriptFile=""
[FLASH]
EraseType = 0x00
CacheExcludeSize = 0x00
CacheExcludeAddr = 0x00
MinNumBytesFlashDL = 0
SkipProgOnCRCMatch = 1
VerifyDownload = 1
AllowCaching = 1
EnableFlashDL = 2
Override = 0
Device="ARM7"
[GENERAL]
WorkRAMSize = 0x00
WorkRAMAddr = 0x00
RAMUsageLimit = 0x00
[SWO]
SWOLogFile=""
[MEM]
RdOverrideOrMask = 0x00
RdOverrideAndMask = 0xFFFFFFFF
RdOverrideAddr = 0xFFFFFFFF
WrOverrideOrMask = 0x00
WrOverrideAndMask = 0xFFFFFFFF
WrOverrideAddr = 0xFFFFFFFF

File diff suppressed because it is too large Load Diff

View File

@ -6136,7 +6136,7 @@
</option>
<option>
<name>OCDynDriverList</name>
<state>ARMSIM_ID</state>
<state>JLINK_ID</state>
</option>
<option>
<name>OCLastSavedByProductVersion</name>
@ -6934,7 +6934,7 @@
</option>
<option>
<name>CCJLinkInterfaceRadio</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CCJLinkResetList</name>

View File

@ -4701,6 +4701,7 @@
<state>$PROJ_DIR$\PROJECT\drivers\lcd</state>
<state>$PROJ_DIR$\PROJECT\drivers\modem</state>
<state>$PROJ_DIR$\PROJECT\drivers\player1053</state>
<state>$PROJ_DIR$\PROJECT\drivers\mfrc522</state>
<state>$PROJ_DIR$\PROJECT\services</state>
<state>$PROJ_DIR$\PROJECT\libs</state>
<state>$PROJ_DIR$\PROJECT\libs\FatFs</state>
@ -4720,7 +4721,7 @@
</option>
<option>
<name>CCOptLevel</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CCOptStrategy</name>
@ -4729,7 +4730,7 @@
</option>
<option>
<name>CCOptLevelSlave</name>
<state>1</state>
<state>0</state>
</option>
<option>
<name>CCPosIndRopi</name>
@ -5002,7 +5003,7 @@
</option>
<option>
<name>OOCOutputFile</name>
<state>sk_mlpc2368.hex</state>
<state>solarium_vlad_8_56.hex</state>
</option>
<option>
<name>OOCCommandLineProducer</name>
@ -5020,7 +5021,7 @@
<data>
<extensions></extensions>
<cmdline></cmdline>
<hasPrio>0</hasPrio>
<hasPrio>112</hasPrio>
<buildSequence>inputOutputBased</buildSequence>
</data>
</settings>
@ -5346,7 +5347,7 @@
</option>
<option>
<name>IlinkTrustzoneImportLibraryOut</name>
<state>###Unitialized###</state>
<state>sk-mlpc2368_import_lib.o</state>
</option>
<option>
<name>OILinkExtraOption</name>
@ -5834,6 +5835,12 @@
<file>
<name>$PROJ_DIR$\PROJECT\app\modem_task.h</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\app\service_name.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\app\service_name.h</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\app\term_tsk.c</name>
<excluded>
@ -5942,6 +5949,21 @@
<name>$PROJ_DIR$\PROJECT\drivers\lcd\symtab.h</name>
</file>
</group>
<group>
<name>mfrc522</name>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\mfrc522data.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\mfrc522data.h</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\rfid-spi.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\rfid-spi.h</name>
</file>
</group>
<group>
<name>modem</name>
<file>

View File

@ -7498,6 +7498,12 @@
<file>
<name>$PROJ_DIR$\PROJECT\app\modem_task.h</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\app\service_name.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\app\service_name.h</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\app\term_tsk.c</name>
</file>
@ -7594,6 +7600,21 @@
<name>$PROJ_DIR$\PROJECT\drivers\lcd\symtab.h</name>
</file>
</group>
<group>
<name>mfrc522</name>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\mfrc522data.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\mfrc522data.h</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\rfid-spi.c</name>
</file>
<file>
<name>$PROJ_DIR$\PROJECT\drivers\mfrc522\rfid-spi.h</name>
</file>
</group>
<group>
<name>modem</name>
<file>