mirror of
https://github.com/dimoniche/changer.git
synced 2026-01-30 01:03:30 +03:00
Устройство "Разменный автомат" версия ПО 0.30, использовался купюроприемник cashcode в протоколе CCNET. Затем для купюроприемника некая контора сделала неофициальную прошивку с приемом новых желтых 100 руб. Купюроприемник cashcode с этой прошивкой нормально работает с симулятором протокола CCNET на ПК. И работает с нашим устройством "Солярий", версия ПО 3.45. Другие версии пока не пробовали. ПО для Разменного автомата (Туалета) изменяли после применения плат с китайским процессором NXP. Получились рабочие версии 0.33/1.33. Но купюроприемник cashcode с прошивкой под 100р. не заработал ни на версия ПО 0.30, ни на 0.33/1.33. Купюроприемник горит красным - как будто не получает команду на прием купюр или вообще нет обмена данными.
374 lines
11 KiB
C
374 lines
11 KiB
C
#include <includes.h>
|
|
#include "validator.h"
|
|
#include "CCRSProtocol.h"
|
|
#include "uart1.h"
|
|
#include "app_serv.h"
|
|
#include "journal.h"
|
|
#include "data.h"
|
|
#include "datadesc.h"
|
|
|
|
|
|
OS_STK ValidatorTaskStk[VALIDATOR_TASK_STK_SIZE];
|
|
OS_EVENT *VLock = NULL;
|
|
|
|
void CC_BusReset(void);
|
|
int ValidatorConnect(void);
|
|
|
|
// ñòàòóñ ïîäêëþ÷åíèÿ êóïþðíèêà
|
|
unsigned char VConnStat = VCONN_STATUS_NOCONN;
|
|
|
|
TBillRecord VBillTable[24];
|
|
/// òàáëèöà ñ öåëî÷èñëåííûìè çíà÷åíèÿìè íîìèíàëîâ - äëÿ GUI
|
|
CPU_INT32U BillNominals[24];
|
|
|
|
TBillStatus VBillStatus;
|
|
/// ñ÷åò÷èê äåíåã
|
|
CPU_INT32U VBillCount = 0;
|
|
/// èíäåêñ íîìèíàëà ïîñëåäíåé ïðèÿíòîé êóïþðû
|
|
CPU_INT32U VLastBillIndex = V_BILLS_NUMBER;
|
|
|
|
void ValidatorTask(void *p_arg)
|
|
{
|
|
char incas = 0;
|
|
// 1. åñëè íåò ñâÿçè, ïðîáóåì êîííåêòèòüñÿ êîìàíäîé RESET
|
|
// 2. BUS RESET - min 100 ms
|
|
// 3. POLL íàäî äåëàòü êàæäûå 100-200 ìñ, ðåêîìåíäóåòñÿ áîëüøå 200
|
|
|
|
VBillCount = 0;
|
|
VConnStat = VCONN_STATUS_NOCONN;
|
|
ClrErrorFlag(ERROR_VALIDATOR_CONN);
|
|
ClrErrorFlag(ERROR_VALIDATOR_FAILURE);
|
|
|
|
while(1)
|
|
{
|
|
TPollResults polldata;
|
|
OSTimeDly(CC_POLL_TIME_OUT);
|
|
|
|
CPU_INT32U enable, cash_mode;
|
|
GetData(&EnableValidatorDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX);
|
|
GetData(&CashModeDesc, &cash_mode, 0, DATA_FLAG_SYSTEM_INDEX);
|
|
|
|
// îáðàáîòêà ñòàòóñà ñâÿçè
|
|
if (VConnStat == VCONN_STATUS_NOCONN)
|
|
{ // íåò ïîäêëþ÷åíèÿ
|
|
if ((!enable) || (cash_mode != 0))
|
|
{ // íå âêëþ÷åí
|
|
VConnStat = VCONN_STATUS_NOCONN;
|
|
ClrErrorFlag(ERROR_VALIDATOR_CONN);
|
|
ClrErrorFlag(ERROR_VALIDATOR_FAILURE);
|
|
continue;
|
|
}
|
|
// íàäî ïðîèíèöèàëèçèðîâàòüñÿ
|
|
if (ValidatorConnect() != 0) {SetErrorFlag(ERROR_VALIDATOR_CONN); continue;}
|
|
// óñïåøíî
|
|
ClrErrorFlag(ERROR_VALIDATOR_CONN);
|
|
ClrErrorFlag(ERROR_VALIDATOR_FAILURE);
|
|
VConnStat = VCONN_STATUS_CONN;
|
|
}
|
|
else
|
|
{ // ïîäêëþ÷åíèå åñòü
|
|
if (!enable)
|
|
{ // íå âêëþ÷åí
|
|
VConnStat = VCONN_STATUS_NOCONN;
|
|
ClrErrorFlag(ERROR_VALIDATOR_CONN);
|
|
ClrErrorFlag(ERROR_VALIDATOR_FAILURE);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// çàïðîñ ñòàòóñà óâàëèäàòîðà
|
|
if (CC_CmdPoll(ADDR_FL, &polldata))
|
|
{// ðàçáèðàåì îòâåò íà poll
|
|
|
|
if ((incas) && (polldata.Z1 != ST_BOX))
|
|
{
|
|
incas = 0;
|
|
PostUserEvent(EVENT_INCASSATION_FINISH);
|
|
}
|
|
|
|
switch (polldata.Z1){
|
|
// States CCNET states and events
|
|
case ST_POWER_UP:
|
|
case ST_POWER_BILL_ESCROW:
|
|
case ST_POWER_BILL_STACKER:
|
|
case ST_INITIALIZE:
|
|
case ST_IDLING:
|
|
case ST_ACCEPTING:
|
|
case ST_PACKING:
|
|
case ST_RETURNING:
|
|
case ST_DISABLED:
|
|
case ST_HOLDING:
|
|
case ST_BUSY:
|
|
ClrValidatorErrors();
|
|
break;
|
|
case ST_REJECTING:
|
|
ClrErrorFlag(ERROR_VALIDATOR_FAILURE);
|
|
switch (polldata.Z2){
|
|
case RJ_INSERTION: //!< Rejection because of insertion problem
|
|
case RJ_REMAINING: //!< Rejection because of other bill remaining in the device
|
|
SetErrorFlag(ERROR_VALIDATOR_INSERTION);
|
|
break;
|
|
case RJ_MAGNETIC: //!< Rejection because of invalid magnetic pattern
|
|
SetErrorFlag(ERROR_VALIDATOR_MAGNETIC);
|
|
break;
|
|
case RJ_CONVEYING: //!< Rejection because of conveying
|
|
SetErrorFlag(ERROR_VALIDATOR_CONVEYING);
|
|
break;
|
|
case RJ_IDENT: //!< Rejection because of identification failure
|
|
SetErrorFlag(ERROR_VALIDATOR_IDENT);
|
|
break;
|
|
case RJ_VRFY: //!< Rejection because of verification failure
|
|
SetErrorFlag(ERROR_VALIDATOR_VRFY);
|
|
break;
|
|
case RJ_OPT: //!< Rejection because of optical pattern mismatch
|
|
SetErrorFlag(ERROR_VALIDATOR_OPT);
|
|
break;
|
|
case RJ_INHIBIT: //!< Rejection because the denomination is inhibited
|
|
SetErrorFlag(ERROR_VALIDATOR_INHIBIT);
|
|
break;
|
|
case RJ_CAP: //!< Rejection because of capacity sensor pattern mismatch
|
|
SetErrorFlag(ERROR_VALIDATOR_CAP);
|
|
break;
|
|
case RJ_LNG: //!< Rejection because of invalid bill length
|
|
SetErrorFlag(ERROR_VALIDATOR_LNG);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
case ST_ST_FULL: //!< DROP CASSETTE IS FULL state
|
|
SetErrorFlag(ERROR_STACKER_FULL);
|
|
break;
|
|
case ST_BOX: //!< DROP CASSETTE REMOVED state
|
|
//SetErrorFlag(ERROR_STACKER_REMOVED);
|
|
if (incas == 0)
|
|
{
|
|
PostUserEvent(EVENT_INCASSATION);
|
|
ClrValidatorErrors();
|
|
incas = 1;
|
|
}
|
|
break;
|
|
case ST_BV_JAMMED: //!< JAM IN VALIDATOR state
|
|
SetErrorFlag(ERROR_BV_JAMMED);
|
|
break;
|
|
case ST_ST_JAMMED: //!< JAM IN STACKER state
|
|
SetErrorFlag(ERROR_ST_JAMMED);
|
|
break;
|
|
case ST_CHEATED: //!< CHEATED event
|
|
SetErrorFlag(ERROR_CHEATED);
|
|
break;
|
|
case ST_FAILURE:
|
|
switch (polldata.Z2){
|
|
case FLR_STACKER: //!< Stacking mechanism failure
|
|
SetErrorFlag(ERROR_FLR_STACKER);
|
|
break;
|
|
case FLR_TR_SPEED: //!< Invalid speed of transport mechanism
|
|
SetErrorFlag(ERROR_TR_SPEED);
|
|
break;
|
|
case FLR_TRANSPORT: //!< Transport mechanism failure
|
|
SetErrorFlag(ERROR_FLR_TRANSPORT);
|
|
break;
|
|
case FLR_ALIGNING: //!< Aligning mechanism failure
|
|
SetErrorFlag(ERROR_FLR_ALIGNIN);
|
|
break;
|
|
case FLR_INIT_CAS: //!< Initial cassette status failure
|
|
SetErrorFlag(ERROR_FLR_INIT_CAS);
|
|
break;
|
|
case FLR_OPT: //!< Optical channel failure
|
|
SetErrorFlag(ERROR_FLR_OPT);
|
|
break;
|
|
case FLR_MAG: //!< Inductive channel failure
|
|
SetErrorFlag(ERROR_FLR_MAG);
|
|
break;
|
|
case FLR_CAP: //!< Capacity sensor failure
|
|
SetErrorFlag(ERROR_FLR_CAP);
|
|
break;
|
|
}
|
|
// íàäî ïåðåïîäêëþ÷èòüñÿ ê ìîäåìó, à òî òàê è áóäåò âèñåòü
|
|
SetErrorFlag(ERROR_VALIDATOR_CONN);
|
|
VConnStat = VCONN_STATUS_NOCONN;
|
|
break;
|
|
// Failure codes
|
|
case FLR_STACKER:
|
|
case FLR_TR_SPEED:
|
|
case FLR_TRANSPORT:
|
|
case FLR_ALIGNING:
|
|
case FLR_INIT_CAS:
|
|
case FLR_OPT:
|
|
case FLR_MAG:
|
|
case FLR_CAP:
|
|
SetErrorFlag(ERROR_VALIDATOR_FAILURE);
|
|
break;
|
|
// Credit events
|
|
case ST_PACKED:
|
|
// áàíêíîòà óïàêîâàíà
|
|
// çàïðåòèì ïðèåì
|
|
if (!CC_CmdBillType(0x000000, 0x000000, ADDR_FL)){SetErrorFlag(ERROR_VALIDATOR_CONN);}
|
|
// çàïîñòèì ñîáûòèå ïîëüçîâàòåëüñêîìó ñåðâåðó
|
|
if (polldata.Z2 < V_BILLS_NUMBER)
|
|
{
|
|
VBillCount += VBillTable[polldata.Z2].Denomination;
|
|
// ñîõðàíÿåì èíäåêñ êóïþðû
|
|
VLastBillIndex = polldata.Z2;
|
|
}
|
|
else
|
|
{
|
|
VBillCount = 0;
|
|
// íåïðàâèëüíûé èíäåêñ
|
|
VLastBillIndex = V_BILLS_NUMBER;
|
|
}
|
|
PostUserEvent(EVENT_BILL_STACKED);
|
|
ClrValidatorErrors();
|
|
break;
|
|
case ESCROW:
|
|
if (polldata.Z2 < V_BILLS_NUMBER)
|
|
{
|
|
//VBillCount += VBillTable[polldata.Z2].Denomination;
|
|
// ñîõðàíÿåì èíäåêñ êóïþðû
|
|
//VLastBillIndex = polldata.Z2;
|
|
}
|
|
else
|
|
{
|
|
VBillCount = 0;
|
|
// íåïðàâèëüíûé èíäåêñ
|
|
VLastBillIndex = V_BILLS_NUMBER;
|
|
}
|
|
PostUserEvent(EVENT_BILL_ESCROW);
|
|
ClrValidatorErrors();
|
|
break;
|
|
case RETURNED:
|
|
ClrValidatorErrors();
|
|
break;
|
|
default:
|
|
ClrValidatorErrors();
|
|
break;
|
|
}// switch (polldata.Z1)
|
|
ClrErrorFlag(ERROR_VALIDATOR_CONN);
|
|
VConnStat = VCONN_STATUS_CONN;
|
|
}
|
|
else
|
|
{ // îøèáêà
|
|
SetErrorFlag(ERROR_VALIDATOR_CONN);
|
|
VConnStat = VCONN_STATUS_NOCONN;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
int ValidatorConnect(void)
|
|
{
|
|
int i;
|
|
OSTimeDly(200);
|
|
|
|
for (i = 0; i < 24; i++)
|
|
{
|
|
BillNominals[i] = 0;
|
|
}
|
|
|
|
CC_BusReset();
|
|
|
|
// ñáðîñèì âàëèäàòîð
|
|
if (!CC_CmdReset(ADDR_FL)) return -1;
|
|
|
|
// ïðî÷èòàåì òàáëèöó íîìèíàëîâ âàëþò
|
|
if (!CC_CmdGetBillTable(ADDR_FL, VBillTable)) return -2;
|
|
|
|
for (i = 0; i < 24; i++)
|
|
{
|
|
BillNominals[i] = (CPU_INT32U)VBillTable[i].Denomination;
|
|
}
|
|
|
|
// ðàçðåøèì ïðèåì
|
|
if (!CC_CmdBillType(0x00000000, 0x00000000, ADDR_FL)) return -3;
|
|
|
|
VConnStat = VCONN_STATUS_CONN;
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int IsValidatorConnected(void)
|
|
{
|
|
#if OS_CRITICAL_METHOD == 3
|
|
OS_CPU_SR cpu_sr = 0;
|
|
#endif
|
|
OS_ENTER_CRITICAL();
|
|
int retval;
|
|
if (VConnStat == VCONN_STATUS_CONN) retval=1;
|
|
else retval=0;
|
|
OS_EXIT_CRITICAL();
|
|
return retval;
|
|
}
|
|
|
|
|
|
// çàïóñê çàëà÷è âàëèäàòîðà
|
|
void StartUpValidator(void)
|
|
{
|
|
Uart1_Init(CC_VALIDATOR_SPEED);
|
|
|
|
#if OS_CRITICAL_METHOD == 3
|
|
OS_CPU_SR cpu_sr = 0;
|
|
#endif
|
|
|
|
OS_ENTER_CRITICAL();
|
|
|
|
// BUS RESET init
|
|
PINSEL4_bit.P2_4 = 0;
|
|
PINMODE4_bit.P2_4 = 0;
|
|
FIO2DIR_bit.P2_4 = 1;
|
|
FIO2MASK_bit.P2_4 = 0;
|
|
FIO2CLR_bit.P2_4 = 1;
|
|
|
|
OS_EXIT_CRITICAL();
|
|
|
|
if (!VLock)
|
|
{
|
|
VLock = OSSemCreate(1);
|
|
OSTaskCreate(ValidatorTask, (void *)0, (OS_STK *)&ValidatorTaskStk[VALIDATOR_TASK_STK_SIZE-1], VALIDATOR_TASK_PRIO);
|
|
}
|
|
}
|
|
|
|
|
|
void CC_BusReset(void)
|
|
{
|
|
VPend();
|
|
FIO2CLR_bit.P2_4 = 1;
|
|
OSTimeDly(CC_BUS_RESET_TIME_OUT);
|
|
FIO2SET_bit.P2_4 = 1;
|
|
VPost();
|
|
}
|
|
|
|
// çàíÿòü âàëèäàòîð
|
|
void VPend(void)
|
|
{
|
|
CPU_INT08U err;
|
|
do{
|
|
OSSemPend(VLock, 1, &err);
|
|
if (!err) break;
|
|
OSTimeDly(1);
|
|
}while (err);
|
|
}
|
|
|
|
// îñâîáîäèòü âàëèäàòîð
|
|
void VPost(void)
|
|
{
|
|
OSSemPost(VLock);
|
|
}
|
|
|
|
// ïðî÷èòàòü ñ÷åò÷èê äåíåã îò êóïþðíèêà è ñáðîñèòü
|
|
CPU_INT32U GetResetBillCount(CPU_INT32U *bill_index)
|
|
{
|
|
#if OS_CRITICAL_METHOD == 3
|
|
OS_CPU_SR cpu_sr = 0;
|
|
#endif
|
|
OS_ENTER_CRITICAL();
|
|
CPU_INT32U count = VBillCount;
|
|
VBillCount = 0;
|
|
*bill_index = VLastBillIndex;
|
|
OS_EXIT_CRITICAL();
|
|
return count;
|
|
}
|
|
|