начало

This commit is contained in:
Dmitriy 2021-04-15 21:07:13 +03:00
commit 9fd4c2f933
301 changed files with 112182 additions and 0 deletions

1
.svn/entries Normal file
View File

@ -0,0 +1 @@
12

1
.svn/format Normal file
View File

@ -0,0 +1 @@
12

View File

@ -0,0 +1,523 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
*
* (c) Copyright 1992-2007, Micrium, Weston, FL
* All Rights Reserved
*
* Generic ARM Port
*
* File : OS_CPU_C.C
* Version : V1.82
* By : Jean J. Labrosse
* Jean-Denis Hatier
*
* For : ARM7 or ARM9
* Mode : ARM or Thumb
* Toolchain : IAR's EWARM V4.11a and higher
*********************************************************************************************************
*/
#define OS_CPU_GLOBALS
#include <ucos_ii.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*
* Note(s) : 1) ARM_MODE_ARM is the CPSR bit mask for ARM Mode
* 2) ARM_MODE_THUMB is the CPSR bit mask for THUMB Mode
* 3) ARM_SVC_MODE_THUMB is the CPSR bit mask for SVC MODE + THUMB Mode
* 4) ARM_SVC_MODE_ARM is the CPSR bit mask for SVC MODE + ARM Mode
5) OS_NTASKS_FP establishes the number of tasks capable of supporting floating-point. One
* task is removed for the idle task because it doesn't do floating-point at all.
* 6) OS_FP_STORAGE_SIZE currently allocates 1024 bytes of storage in order to accomodate
* thirty-two, single precision 32 bit, or sixteen double precision 64 bit VFP registers.
*********************************************************************************************************
*/
#define ARM_MODE_ARM 0x00000000
#define ARM_MODE_THUMB 0x00000020
#define ARM_SVC_MODE_THUMB (0x00000013L + ARM_MODE_THUMB)
#define ARM_SVC_MODE_ARM (0x00000013L + ARM_MODE_ARM)
#define OS_NTASKS_FP (OS_MAX_TASKS + OS_N_SYS_TASKS - 1)
#define OS_FP_STORAGE_SIZE 128L
/*
*********************************************************************************************************
* LOCAL VARIABLES
*********************************************************************************************************
*/
#if OS_TMR_EN > 0
static INT16U OSTmrCtr;
#endif
#if OS_CPU_FPU_EN > 0
static OS_MEM *OSFPPartPtr; /* Pointer to memory partition for storing FPU registers */
static INT32U OSFPPart[OS_NTASKS_FP][OS_FP_STORAGE_SIZE / sizeof(INT32U)];
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE FP SUPPORT
*
* Description: This function initializes the memory partition used to save FPU registers
* during a context switch. This function MUST be called AFTER calling
* OSInit(). OS_CPU_FPU_EN must be defined > 0 in order to compile FPU support into the
* build.
*
* Arguments : none
*
* Returns : none
*
* Note(s) : 1) Tasks that are to use FP support MUST be created with OSTaskCreateExt().
* 2) For the ARM VFP, 1024 bytes are required to save the VFP context.
* The INT32U data type is used to ensure that storage is aligned on a 32-bit boundary.
* 3) If you need to perform floating point operations from within the OSStatTaskHook(),
* then you must change the 'Options' attribute for OSTaskCreatExt() when creating
* the statistics task. This only applies if OS_TaskStat() was created with OSTaskCreateExt().
*********************************************************************************************************
*/
#if OS_CPU_FPU_EN > 0
void OS_CPU_FP_Init (void)
{
INT8U err;
#if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN
OS_TCB *ptcb;
void *pblk;
#endif
OSFPPartPtr = OSMemCreate(&OSFPPart[0][0], OS_NTASKS_FP, OS_FP_STORAGE_SIZE, &err);
#if OS_TASK_STAT_EN && OS_TASK_CREATE_EXT_EN /* CHANGE 'OPTIONS' for OS_TaskStat() */
ptcb = OSTCBPrioTbl[OS_TASK_STAT_PRIO];
ptcb->OSTCBOpt |= OS_TASK_OPT_SAVE_FP; /* Allow floating-point support for Statistic task */
pblk = OSMemGet(OSFPPartPtr, &err); /* Get storage for VFP registers */
if (pblk != (void *)0) { /* Did we get a memory block? */
ptcb->OSTCBExtPtr = pblk; /* Yes, Link to task's TCB */
OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */
}
#endif
}
#endif
/*
*********************************************************************************************************
* OS INITIALIZATION HOOK
* (BEGINNING)
*
* Description: This function is called by OSInit() at the beginning of OSInit().
*
* Arguments : none
*
* Note(s) : 1) Interrupts should be disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSInitHookBegin (void)
{
#if OS_TMR_EN > 0
OSTmrCtr = 0;
#endif
}
#endif
/*
*********************************************************************************************************
* OS INITIALIZATION HOOK
* (END)
*
* Description: This function is called by OSInit() at the end of OSInit().
*
* Arguments : none
*
* Note(s) : 1) Interrupts should be disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSInitHookEnd (void)
{
#if OS_CPU_INT_DIS_MEAS_EN > 0
OS_CPU_IntDisMeasInit();
#endif
#if OS_CPU_FPU_EN > 0
OS_CPU_FP_Init(); /* Initialize support for VFP register save / restore */
#endif
}
#endif
/*
*********************************************************************************************************
* TASK CREATION HOOK
*
* Description: This function is called when a task is created.
*
* Arguments : ptcb is a pointer to the task control block of the task being created.
*
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskCreateHook (OS_TCB *ptcb)
{
#if OS_CPU_FPU_EN > 0
INT8U err;
void *pblk;
#endif
#if OS_CPU_FPU_EN > 0
if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task needs FP support */
pblk = OSMemGet(OSFPPartPtr, &err); /* Yes, Get storage for VFP registers */
if (pblk != (void *)0) { /* Did we get a memory block? */
ptcb->OSTCBExtPtr = pblk; /* Yes, Link to task's TCB */
OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */
}
}
#endif
#if OS_APP_HOOKS_EN > 0
App_TaskCreateHook(ptcb);
#else
(void)ptcb; /* Prevent compiler warning */
#endif
}
#endif
/*
*********************************************************************************************************
* TASK DELETION HOOK
*
* Description: This function is called when a task is deleted.
*
* Arguments : ptcb is a pointer to the task control block of the task being deleted.
*
* Note(s) : 1) Interrupts are disabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskDelHook (OS_TCB *ptcb)
{
#if OS_CPU_FPU_EN > 0
if (ptcb->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task had FP support */
if (ptcb->OSTCBExtPtr != (void *)0) { /* Yes, OSTCBExtPtr must not be NULL */
OSMemPut(OSFPPartPtr, ptcb->OSTCBExtPtr); /* Return memory block to free pool */
}
}
#endif
#if OS_APP_HOOKS_EN > 0
App_TaskDelHook(ptcb);
#else
(void)ptcb; /* Prevent compiler warning */
#endif
}
#endif
/*
*********************************************************************************************************
* IDLE TASK HOOK
*
* Description: This function is called by the idle task. This hook has been added to allow you to do
* such things as STOP the CPU to conserve power.
*
* Arguments : none
*
* Note(s) : 1) Interrupts are enabled during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION >= 251
void OSTaskIdleHook (void)
{
#if OS_CPU_ARM_DCC_EN > 0
OSDCC_Handler();
#endif
#if OS_APP_HOOKS_EN > 0
App_TaskIdleHook();
#endif
}
#endif
/*
*********************************************************************************************************
* STATISTIC TASK HOOK
*
* Description: This function is called every second by uC/OS-II's statistics task. This allows your
* application to add functionality to the statistics task.
*
* Arguments : none
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskStatHook (void)
{
#if OS_APP_HOOKS_EN > 0
App_TaskStatHook();
#endif
}
#endif
/*
*********************************************************************************************************
* INITIALIZE A TASK'S STACK
*
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
* stack frame of the task being created. This function is highly processor specific.
*
* Arguments : task is a pointer to the task code
*
* p_arg is a pointer to a user supplied data area that will be passed to the task
* when the task first executes.
*
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
* of the stack.
*
* opt specifies options that can be used to alter the behavior of OSTaskStkInit().
* (see uCOS_II.H for OS_TASK_OPT_xxx).
*
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
*
* Note(s) : 1) Interrupts are enabled when your task starts executing.
* 2) All tasks run in SVC mode.
*********************************************************************************************************
*/
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
{
OS_STK *stk;
INT32U task_addr;
opt = opt; /* 'opt' is not used, prevent warning */
stk = ptos; /* Load stack pointer */
task_addr = (INT32U)task & ~1; /* Mask off lower bit in case task is thumb mode */
*(stk) = (INT32U)task_addr; /* Entry Point */
*(--stk) = (INT32U)0x14141414L; /* R14 (LR) */
*(--stk) = (INT32U)0x12121212L; /* R12 */
*(--stk) = (INT32U)0x11111111L; /* R11 */
*(--stk) = (INT32U)0x10101010L; /* R10 */
*(--stk) = (INT32U)0x09090909L; /* R9 */
*(--stk) = (INT32U)0x08080808L; /* R8 */
*(--stk) = (INT32U)0x07070707L; /* R7 */
*(--stk) = (INT32U)0x06060606L; /* R6 */
*(--stk) = (INT32U)0x05050505L; /* R5 */
*(--stk) = (INT32U)0x04040404L; /* R4 */
*(--stk) = (INT32U)0x03030303L; /* R3 */
*(--stk) = (INT32U)0x02020202L; /* R2 */
*(--stk) = (INT32U)0x01010101L; /* R1 */
*(--stk) = (INT32U)p_arg; /* R0 : argument */
if ((INT32U)task & 0x01) { /* See if task runs in Thumb or ARM mode */
*(--stk) = (INT32U)ARM_SVC_MODE_THUMB; /* CPSR (Enable both IRQ and FIQ interrupts, THUMB-mode) */
} else {
*(--stk) = (INT32U)ARM_SVC_MODE_ARM; /* CPSR (Enable both IRQ and FIQ interrupts, ARM-mode) */
}
return (stk);
}
/*
*********************************************************************************************************
* TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.
*
* Arguments : none
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
* task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
#if (OS_CPU_HOOKS_EN > 0) && (OS_TASK_SW_HOOK_EN > 0)
void OSTaskSwHook (void)
{
#if OS_CPU_FPU_EN > 0
void *pblk;
#endif
#if OS_CPU_FPU_EN > 0 /* Save VFP context of preempted task */
if (OSRunning == OS_TRUE) { /* Don't save on OSStart()! */
if (OSTCBCur->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if task used FP */
pblk = OSTCBCur->OSTCBExtPtr; /* Yes, Get pointer to FP storage area */
if (pblk != (void *)0) { /* Make sure we have storage */
OS_CPU_FP_Save(pblk); /* Save the VFP registers in block */
}
}
}
/* Restore VFP context of new task */
if (OSTCBHighRdy->OSTCBOpt & OS_TASK_OPT_SAVE_FP) { /* See if new task uses FP */
pblk = OSTCBHighRdy->OSTCBExtPtr; /* Yes, Get pointer to FP storage area */
if (pblk != (void *)0) { /* Make sure we have storage */
OS_CPU_FP_Restore(pblk); /* Get contents of VFP registers */
}
}
#endif
#if OS_APP_HOOKS_EN > 0
App_TaskSwHook();
#endif
}
#endif
/*
*********************************************************************************************************
* OS_TCBInit() HOOK
*
* Description: This function is called by OS_TCBInit() after setting up most of the TCB.
*
* Arguments : ptcb is a pointer to the TCB of the task being created.
*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSTCBInitHook (OS_TCB *ptcb)
{
#if OS_APP_HOOKS_EN > 0
App_TCBInitHook(ptcb);
#else
(void)ptcb; /* Prevent compiler warning */
#endif
}
#endif
/*
*********************************************************************************************************
* TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments : none
*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if (OS_CPU_HOOKS_EN > 0) && (OS_TIME_TICK_HOOK_EN > 0)
void OSTimeTickHook (void)
{
#if OS_APP_HOOKS_EN > 0
App_TimeTickHook();
#endif
#if OS_TMR_EN > 0
OSTmrCtr++;
if (OSTmrCtr >= (OS_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)) {
OSTmrCtr = 0;
OSTmrSignal();
}
#endif
#if OS_CPU_ARM_DCC_EN > 0
OSDCC_Handler();
#endif
}
#endif
/*
*********************************************************************************************************
* INTERRUPT DISABLE TIME MEASUREMENT, START
*********************************************************************************************************
*/
#if OS_CPU_INT_DIS_MEAS_EN > 0
void OS_CPU_IntDisMeasInit (void)
{
OS_CPU_IntDisMeasNestingCtr = 0;
OS_CPU_IntDisMeasCntsEnter = 0;
OS_CPU_IntDisMeasCntsExit = 0;
OS_CPU_IntDisMeasCntsMax = 0;
OS_CPU_IntDisMeasCntsDelta = 0;
OS_CPU_IntDisMeasCntsOvrhd = 0;
OS_CPU_IntDisMeasStart(); /* Measure the overhead of the functions */
OS_CPU_IntDisMeasStop();
OS_CPU_IntDisMeasCntsOvrhd = OS_CPU_IntDisMeasCntsDelta;
}
void OS_CPU_IntDisMeasStart (void)
{
OS_CPU_IntDisMeasNestingCtr++;
if (OS_CPU_IntDisMeasNestingCtr == 1) { /* Only measure at the first nested level */
OS_CPU_IntDisMeasCntsEnter = OS_CPU_IntDisMeasTmrRd();
}
}
void OS_CPU_IntDisMeasStop (void)
{
OS_CPU_IntDisMeasNestingCtr--; /* Decrement nesting ctr */
if (OS_CPU_IntDisMeasNestingCtr == 0) {
OS_CPU_IntDisMeasCntsExit = OS_CPU_IntDisMeasTmrRd();
OS_CPU_IntDisMeasCntsDelta = OS_CPU_IntDisMeasCntsExit - OS_CPU_IntDisMeasCntsEnter;
if (OS_CPU_IntDisMeasCntsDelta > OS_CPU_IntDisMeasCntsOvrhd) { /* Ensure overhead < delta */
OS_CPU_IntDisMeasCntsDelta -= OS_CPU_IntDisMeasCntsOvrhd;
} else {
OS_CPU_IntDisMeasCntsDelta = OS_CPU_IntDisMeasCntsOvrhd;
}
if (OS_CPU_IntDisMeasCntsDelta > OS_CPU_IntDisMeasCntsMax) { /* Track MAXIMUM */
OS_CPU_IntDisMeasCntsMax = OS_CPU_IntDisMeasCntsDelta;
}
}
}
#endif
/*
*********************************************************************************************************
* INITIALIZE EXCEPTION VECTORS
*
* Description : This function initialize exception vectors to the default handlers.
*
* Arguments : None.
*********************************************************************************************************
*/
void OS_CPU_InitExceptVect (void)
{
/*
(*(INT32U *)OS_CPU_ARM_EXCEPT_RESET_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_RESET_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptResetHndlr;
*/
(*(INT32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptUndefInstrHndlr;
(*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_SWI_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptSwiHndlr;
(*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptPrefetchAbortHndlr;
(*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptDataAbortHndlr;
(*(INT32U *)OS_CPU_ARM_EXCEPT_ADDR_ABORT_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptAddrAbortHndlr;
(*(INT32U *)OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptIrqHndlr;
(*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_VECT_ADDR) = OS_CPU_ARM_INSTR_JUMP_TO_HANDLER;
(*(INT32U *)OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR) = (INT32U)OS_CPU_ARM_ExceptFiqHndlr;
}

View File

@ -0,0 +1,7 @@
#ifndef _VERSION_H_
#define _VERSION_H_
#define DEVICE_FW_VERSION "03.19"
#endif // #ifndef _VERSION_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,364 @@
#ifndef _CCRSPROTOCOL_H_
#define _CCRSPROTOCOL_H_
#define CC_TIME_OUT 300
#define SYNC 0x02 //!< synchronization byte
#define ACK 0x00 //!< ACK code
#define NAK 0xFF //!< NAK code
#define ST_INV_CMD 0x30 //!< INVALID COMMAND response
/** \defgroup Addr Device Addresses
* @{
*/
#define ADDR_BB 0x01 //!< Address for Bill-To-Bill units
#define ADDR_CHANGER 0x02 //!< Address for Coin Changer
#define ADDR_FL 0x03 //!< Address for Bill Validators
#define ADDR_CR 0x04 //!< Address for Smart Card Reader
/**@} */
/** \defgroup Cmds Interface commands
* @{
*/
#define RESET 0x30 //!<REST command code
#define GET_STATUS 0x31 //!<STATUS REQUEST command code
#define SET_SECURITY 0x32 //!<SET SECURITY command code
#define POLL 0x33 //!<POLL command code
#define BILL_TYPE 0x34 //!<BILL TYPE command code
#define PACK 0x35 //!<PACK command code
#define RETURN 0x36 //!<RETURN command code
#define IDENTIFICATION 0x37 //!<IDENTIFICATION command code
#define IDENT_EXT 0x3E //!<EXTENDED IDENTIFICATION command code
#define HOLD 0x38 //!<HOLD command code
#define C_STATUS 0x3B //!<RECYCLING CASSETTE STATUS REQUEST command code
#define DISPENSE 0x3C //!<DISPENSE command code
#define UNLOAD 0x3D //!<UNLOAD command code
#define SET_CASSETES 0x40 //!<SET RECYCLING CASSETTE TYPE command code
#define GET_BILL_TABLE 0x41 //!<BILL TABLE REQUEST command code
#define DOWNLOAD 0x50 //!<DOWNLOAD command code
#define CRC32 0x51 //!<CRC32 REQUEST command code
#define SET_TIME 0x62 //!<SET BB TIME command code
#define SET_BAR_PARAMS 0x39 //!<SET BARCODE PARAMETERS command code
#define EXTRACT_BAR_DATA 0x3A //!<EXTRACT BARCODE DATA command code
#define POWER_RECOVERY 0x66 //!<POWER RECOVERY command code
#define EMPTY_DISPENSER 0x67 //!<EMPTY DISPENSER command code
#define SET_OPTIONS 0x68 //!<SET OPTIONS command code
#define GET_OPTIONS 0x69 //!<GET OPTIONS command code
/**@} */
/** \defgroup Options Options
* Describes options supported by CCNET (as a bitmap)
* @{
*/
//Options (bitmap)
#define OPT_LED_INHIBIT 0x80000000L //!< Turn OFF LEDs of the bezel in the DISABLED state
#define OPT_KEEP_BILL 0x40000000L //!< Hold bill after ejection on the input roller
#define OPT_LOOK_TAPE 0x20000000L //!< Use improved algorithm for tape detection
#define OPT_TURN_SWITCH 0x10000000L //!< Turn switch after packing a bill
/**@} */
// States
/** \defgroup States CCNET states and events
*
* @{
*/
#define ST_POWER_UP 0x10//!< POWER UP state
#define ST_POWER_BILL_ESCROW 0x11//!< POWER UP WITH BILL IN ESCROW state
#define ST_POWER_BILL_STACKER 0x12//!< POWER UP WITH BILL IN STACKER state
#define ST_INITIALIZE 0x13//!< INITIALIZING state
#define ST_IDLING 0x14//!< IDLING state
#define ST_ACCEPTING 0x15//!< ACCEPTING state
#define ST_PACKING 0x17//!< STACKING/PACKING state
#define ST_RETURNING 0x18//!< RETURNING state
#define ST_DISABLED 0x19//!< UNIT DISABLED state
#define ST_HOLDING 0x1A//!< HOLDING state
#define ST_BUSY 0x1B//!< Device is busy
#define ST_REJECTING 0x1C//!< REJECTING state. Followed by a rejection code
//Rejection codes
/** \defgroup RCodes Rejection codes
*
* @{
*/
#define RJ_INSERTION 0x60 //!< Rejection because of insertion problem
#define RJ_MAGNETIC 0x61 //!< Rejection because of invalid magnetic pattern
#define RJ_REMAINING 0x62 //!< Rejection because of other bill remaining in the device
#define RJ_MULTIPLYING 0x63 //!< Rejection because of multiple check failures
#define RJ_CONVEYING 0x64 //!< Rejection because of conveying
#define RJ_IDENT 0x65 //!< Rejection because of identification failure
#define RJ_VRFY 0x66 //!< Rejection because of verification failure
#define RJ_OPT 0x67 //!< Rejection because of optical pattern mismatch
#define RJ_INHIBIT 0x68 //!< Rejection because the denomination is inhibited
#define RJ_CAP 0x69 //!< Rejection because of capacity sensor pattern mismatch
#define RJ_OPERATION 0x6A //!< Rejection because of operation error
#define RJ_LNG 0x6C //!< Rejection because of invalid bill length
#define RJ_UV 0x6D //!< Rejection because of invalid UV pattern
#define RJ_BAR 0x92 //!< Rejection because of unrecognized barcode
#define RJ_BAR_LNG 0x93 //!< Rejection because of invalid barcode length
#define RJ_BAR_START 0x94 //!< Rejection because of invalid barcode start sequence
#define RJ_BAR_STOP 0x95 //!< Rejection because of invalid barcode stop sequence
/**@} */
#define ST_DISPENSING 0x1D//!< DISPENSING state
#define ST_UNLOADING 0x1E//!< UNLOADING state
#define ST_SETTING_CS_TYPE 0x21//!< SETTING RECYCLING CASSETTE TYPE state
#define ST_DISPENSED 0x25//!< DISPENSED event
#define ST_UNLOADED 0x26//!< UNLOADED event
#define ST_BILL_NUMBER_ERR 0x28//!< INVALID BILL NUMBER event
#define ST_CS_TYPE_SET 0x29//!< RECYCLING CASSETTE TYPE SET event
#define ST_ST_FULL 0x41//!< DROP CASSETTE IS FULL state
#define ST_BOX 0x42//!< DROP CASSETTE REMOVED state
#define ST_BV_JAMMED 0x43//!< JAM IN VALIDATOR state
#define ST_ST_JAMMED 0x44//!< JAM IN STACKER state
#define ST_CHEATED 0x45//!< CHEATED event
#define ST_PAUSED 0x46//!< PAUSED state
#define ST_FAILURE 0x47//!< FAILURE state
//Failure codes
/** \defgroup FCodes Failure codes
*
* @{
*/
#define FLR_STACKER 0x50 //!< Stacking mechanism failure
#define FLR_TR_SPEED 0x51 //!< Invalid speed of transport mechanism
#define FLR_TRANSPORT 0x52 //!< Transport mechanism failure
#define FLR_ALIGNING 0x53 //!< Aligning mechanism failure
#define FLR_INIT_CAS 0x54 //!< Initial cassette status failure
#define FLR_OPT 0x65 //!< Optical channel failure
#define FLR_MAG 0x66 //!< Inductive channel failure
#define FLR_CAP 0x67 //!< Capacity sensor failure
/**@} */
// Credit events
#define ST_PACKED 0x81 /**< A bill has been packed. 2nd byte - 0xXY:
\n X-bill type
\n Y-Packed into:
\n 0-BOX, else - Cassette Y;
*/
#define ESCROW 0x80 //!< A bill is held in the escrow position
#define RETURNED 0x82 //!< A bill was returned
/**@} */
// Cassetes status
/** \defgroup CSStatus Possible cassette status codes
*
* @{
*/
#define CS_OK 0 //!< Cassette is present and operational
#define CS_FULL 1 //!< Cassette is full
#define CS_NU 0xFE //!< Cassette is not present
#define CS_MALFUNCTION 0xFF //!< Cassette is malfunctioning
#define CS_NA 0xFD //!< Cassette is not assigned to any denomination
#define CS_ESCROW 0xFC //!< Cassette is assigned to multi-escrow
/**@} */
/** \defgroup BTs Predefined bill type values
*
* @{
*/
#define BT_ESCROW 24 //!< Bill type associated with the escrow cassette
#define BT_NO_TYPE 0x1f //!< Invalid bill type
#define BT_BAR 23 //!< Bill type associated with barcode coupon
/**@} */
// Error codes
/** \defgroup ErrCode CCNET Interface error codes
*
* @{
*/
/** \defgroup CErrs Communication error codes
The codes related to phisical data transmission and frame integrity
@{
*/
#define RE_NONE 0//!< No error happened
#define RE_TIMEOUT -1//!< Communication timeout
#define RE_SYNC -2//!< Synchronization error (invalid synchro byte)
#define RE_DATA -3//!< Data reception error
/**@} */
#define RE_CRC -4//!< CRC error
/** \defgroup LErrs Logical error codes
The codes related to the interface logic
@{
*/
#define ER_NAK -5//!< NAK received
#define ER_INVALID_CMD -6//!< Invalid command response received
#define ER_EXECUTION -7//!< Execution error response received
#define ERR_INVALID_STATE -8//!< Invalid state received
/**@} */
/**@} */
// Class Declaration
/** \class CCCRSProtocol
\brief The CCCRSProtocol class providing low-level communication functions for the CCNET protocol
*/
/*
class CCCRSProtocol
{
CCommand cmdIn; //!< A variable to store current device responses
CCommand cmdOut;//!< A variable to store controller commands
CCOMPort COMPort; //!< A COM port to work with
private:
WORD CalculateCRC(unsigned char*);
CCommand Transmit(CCommand CMD, BYTE Addr=ADDR_BB);
unsigned short crc16_ccitt(unsigned char, unsigned short);
CCommand TransmitCMD(CCommand&, BYTE);
int SendCommand(LPBYTE BufOut, LPBYTE BufIn);
public:
int iCmdDelay; //!< Delay between two consequtive commands
int iTimeout; //!< Communication timeout value
int iLastError; //!< A variable storing error code generated during last serial I/O operation
public:
CCCRSProtocol();
virtual ~CCCRSProtocol();
// Protocol commands
bool CmdEmptyDispenser();
bool CmdPowerRecovery(BYTE&,LPBYTE,int&);
bool CmdGetCRC32(DWORD&,BYTE);
bool CmdGetOptions(DWORD&, BYTE);
bool CmdSetOptions(DWORD, BYTE);
bool CmdIdentExt(BYTE);
bool CmdExtractBarData(LPSTR sBar, BYTE Addr);
bool CmdSetBarParams(BYTE Format, BYTE Length, BYTE Addr);
bool CmdBBTime(time_t&, bool bSet=false);
bool CmdDispenseNew(LPBYTE, bool bTypes=true);
bool CmdGetBillTable(_BillRecord*,BYTE Addr=ADDR_BB);
bool CmdSetCasseteType(BYTE, BYTE,BYTE);
bool CmdReset(BYTE Addr=ADDR_BB);
bool CmdPoll(BYTE Addr=ADDR_BB);
bool CmdStatus(BYTE Addr=ADDR_BB);
bool CmdUnload(BYTE,BYTE);//Unload bills
bool CmdDispense(LPBYTE);//
bool CmdCsStatus();
bool CmdReturn(BYTE Addr=ADDR_BB);
bool CmdPack(BYTE Addr=ADDR_BB);
bool CmdBillType(DWORD,DWORD,BYTE Addr=ADDR_BB);
bool CmdSetSecurity(DWORD,BYTE Addr=ADDR_BB);
bool CmdHold(BYTE Addr=ADDR_BB);
bool CmdIdentification(BYTE Addr=ADDR_BB);
//////////////////////////
// COM port related functions
BOOL InitCOM(int, int);
DWORD PortState(int);
CCOMPort* GetCOMPort();
*/
//Protocol structures
/** \struct _BillStatus
\brief The _BillStatus struct describing response to the STATUS REQUEST command
*/
/*
struct _BillStatus
{
DWORD Enabled; //!< A bitmap describing which bill types are enabled
DWORD Security; //!< A bitmap describing which bill types are processed in High Security mode
DWORD Routing; //!< A bitmap describing which denominations are routed to a recycling cassette. Is a valid value only for BB units
}BillStatus;//!< Variable containing the most recent response to the STATUS REQUEST
*/
/** \struct _Identification
\brief The _Identification struct contains identification of the device
*/
/*
*/
/** \struct _PollResults
\brief The _PollResults struct containing 2 first bytes of the response to the POLL command
*/
/*
_Cassete Cassetes[16], //!< List of the cassettes
EscrCassete; //!< Escrow cassette
};
*/
// The _PollResults struct containing 2 first bytes of the response to the POLL command
typedef struct{
unsigned char Z1; //!< State
unsigned char Z2; //!< State extension or substate
}TPollResults; //!< A variable keeping last POLL result
typedef struct{
unsigned long Enabled; //!< A bitmap describing which bill types are enabled
unsigned long Security; //!< A bitmap describing which bill types are processed in High Security mode
unsigned long Routing; //!< A bitmap describing which denominations are routed to a recycling cassette. Is a valid value only for BB units
}TBillStatus;//!< Variable containing the most recent response to the STATUS REQUEST
typedef struct{
// Identification command fields
char PartNumber[16];//!< Firmware part number
char SN[13];//!< Device's serial number
unsigned long long DS1;//!< Device's asset number
// Extended identification command fiels
char BVBootVersion[7];//!< Boot version of the validating head (is reported in response to EXTENDED IDENTIFICATION command)
char BVVersion[21];//!< Firmware version of the validating head (is reported in response to EXTENDED IDENTIFICATION command)
char BCCPUBoot[7];//!< Boot version of the central controller (is reported in response to EXTENDED IDENTIFICATION command)
char BCCPUVersion[7];//!<Firmware version of the central controller (is reported in response to EXTENDED IDENTIFICATION command)
char BCDispenserBoot[7];//!< Boot version of the dispenser (is reported in response to EXTENDED IDENTIFICATION command)
char BCDispenserVersion[7];//!< Firmware version of the dispenser (is reported in response to EXTENDED IDENTIFICATION command)
char BCCS1Boot[7];//!< Boot version of the cassette 1 (is reported in response to EXTENDED IDENTIFICATION command)
char BCCS2Boot[7];//!< Boot version of the cassette 2 (is reported in response to EXTENDED IDENTIFICATION command)
char BCCS3Boot[7];//!< Boot version of the cassette 3 (is reported in response to EXTENDED IDENTIFICATION command)
char BCCSVersion[7];//!< Firmware version of the cassettes (is reported in response to EXTENDED IDENTIFICATION command)
}TIdent;//!< A variable containing current device identification
/** \struct _BillRecord
\brief The _BillRecord struct represents a record in the bill table.
The structure describes denomination of the bill, country or currency code and whether
the bill is forwarded to the cassette. The bill table usually is an array of _BillRecord
structures, where the position is representing a billtype.
*/
typedef struct{
float Denomination; //!< Denomination of the bill
char sCountryCode[4]; //!< Country or currency code
unsigned char bRouted; //!< A bool variable specifiying whether the bill is forwarded to a cassette
}TBillRecord;
extern int CC_CmdReset(unsigned char Addr);
extern int CC_CmdPoll(unsigned char Addr, TPollResults *PollResults);
extern int CC_CmdStatus(unsigned char Addr, TBillStatus* BillStatus);
extern int CC_CmdIdentification(unsigned char Addr, TIdent* Ident);
extern int CC_CmdHold(unsigned char Addr);
extern int CC_CmdSetSecurity(unsigned long wS, unsigned char Addr);
extern int CC_CmdBillType(unsigned long enBill, unsigned long escBill, unsigned char Addr);
extern int CC_CmdPack(unsigned char Addr);
extern int CC_CmdReturn(unsigned char Addr);
extern int CC_CmdGetBillTable(unsigned char Addr, TBillRecord *BillTable);
extern int CC_CmdSetOptions(unsigned long dwOpt, unsigned char Addr);
extern int CC_CmdGetCRC32(unsigned long *dwCRC, unsigned char Addr);
#define PurgeComm Uart1_Purge
#define COMPort_Send Uart1_Send
#define COMPort_Recieve(x,y) Uart1_Receive(x,y,CC_TIME_OUT)
#define Sleep(x) OSTimeDly(x)
#endif //#ifndef _CCRSPROTOCOL_H_

View File

@ -0,0 +1,22 @@
#ifndef __INCLUDES_H__
#define __INCLUDES_H__
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <iolpc2368.h>
#include <ucos_ii.h>
#include <cpu.h>
#include <lib_def.h>
#include <lib_mem.h>
#include <lib_str.h>
#include <app_cfg.h>
#include <bsp.h>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,851 @@
#define BSP_GLOBALS
#include <includes.h>
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
CPU_INT32U VIC_SpuriousInt;
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
static void PLL_Init (void);
static void MAM_Init (void);
static void GPIO_Init (void);
static void VIC_Init (void);
static void Tmr_TickInit (void);
static void VIC_Dummy (void); /* Prototypes for dummy interrupt handlers */
static void VIC_DummyWDT (void);
static void VIC_DummySW (void);
static void VIC_DummyDEBUGRX (void);
static void VIC_DummyDEBUGTX (void);
static void VIC_DummyTIMER0 (void);
static void VIC_DummyTIMER1 (void);
static void VIC_DummyUART0 (void);
static void VIC_DummyUART1 (void);
static void VIC_DummyPWM01 (void);
static void VIC_DummyI2C0 (void);
static void VIC_DummySPI (void);
static void VIC_DummySSP1 (void);
static void VIC_DummyPLL (void);
static void VIC_DummyRTC (void);
static void VIC_DummyEINT0 (void);
static void VIC_DummyEINT1 (void);
static void VIC_DummyEINT2 (void);
static void VIC_DummyEINT3 (void);
static void VIC_DummyAD0 (void);
static void VIC_DummyI2C1 (void);
static void VIC_DummyBOD (void);
static void VIC_DummyETHERNET(void);
static void VIC_DummyUSB (void);
static void VIC_DummyCAN01 (void);
static void VIC_DummyMMC (void);
static void VIC_DummyGP_DMA (void);
static void VIC_DummyTIMER2 (void);
static void VIC_DummyTIMER3 (void);
static void VIC_DummyUART2 (void);
static void VIC_DummyUART3 (void);
static void VIC_DummyI2C2 (void);
static void VIC_DummyI2S (void);
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*********************************************************************************************************
** GLOBAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* BSP_Init()
*
* Description : Initialize the Board Support Package (BSP).
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Note(s) : (1) This function SHOULD be called before any other BSP function is called.
*********************************************************************************************************
*/
void BSP_Init (void)
{
PLL_Init(); /* Initialize the PLL */
MAM_Init(); /* Initialize the Memory Acceleration Module */
GPIO_Init(); /* Initialize the board's I/Os */
VIC_Init(); /* Initialize the Vectored Interrupt Controller */
Tmr_TickInit(); /* Initialize the uC/OS-II tick interrupt */
}
/*
*********************************************************************************************************
* BSP_CPU_ClkFreq()
*
* Description : Get the CPU clock frequency.
*
* Argument(s) : none.
*
* Return(s) : The CPU clock frequency, in Hz.
*********************************************************************************************************
*/
CPU_INT32U BSP_CPU_ClkFreq (void)
{
CPU_INT32U msel;
CPU_INT32U nsel;
CPU_INT32U fin;
CPU_INT32U pll_clk_feq; /* When the PLL is enabled, this is Fcco */
CPU_INT32U clk_div;
CPU_INT32U clk_freq;
switch (CLKSRCSEL & 0x03) { /* Determine the current clock source */
case 0:
fin = IRC_OSC_FRQ;
break;
case 1:
fin = MAIN_OSC_FRQ;
break;
case 2:
fin = RTC_OSC_FRQ;
break;
default:
fin = IRC_OSC_FRQ;
break;
}
if ((PLLSTAT & (1 << 25)) > 0) { /* If the PLL is currently enabled and connected */
msel = (CPU_INT32U)(PLLSTAT & 0x3FFF) + 1; /* Obtain the PLL multiplier */
nsel = (CPU_INT32U)((PLLSTAT >> 16) & 0x0F) + 1; /* Obtain the PLL divider */
pll_clk_feq = (2 * msel * (fin / nsel)); /* Compute the PLL output frequency */
} else {
pll_clk_feq = (fin); /* The PLL is bypassed */
}
clk_div = (CPU_INT32U)(CCLKCFG & 0xFF) + 1; /* Obtain the CPU core clock divider */
clk_freq = (CPU_INT32U)(pll_clk_feq / clk_div); /* Compute the ARM Core clock frequency */
return (clk_freq);
}
/*
*********************************************************************************************************
* BSP_CPU_PclkFreq()
*
* Description : Get the peripheral clock frequency for a specific peripheral.
*
* Argument(s) : pclk The peripheral clock ID, one of PCLK_??? defined in bsp.h.
*
* Return(s) : The peripheral's clock in Hz
*********************************************************************************************************
*/
CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk)
{
CPU_INT32U clk_freq;
CPU_INT32U selection;
clk_freq = BSP_CPU_ClkFreq();
switch (pclk) {
case PCLK_WDT:
case PCLK_TIMER0:
case PCLK_TIMER1:
case PCLK_UART0:
case PCLK_UART1:
case PCLK_PWM0:
case PCLK_PWM1:
case PCLK_I2C0:
case PCLK_SPI:
case PCLK_RTC:
case PCLK_SSP1:
case PCLK_DAC:
case PCLK_ADC:
case PCLK_CAN1:
case PCLK_CAN2:
case PCLK_ACF:
selection = ((PCLKSEL0 >> (pclk * 2)) & 0x03);
if (selection == 0) {
return (clk_freq / 4);
} else if (selection == 1) {
return (clk_freq);
} else if (selection == 2) {
return (clk_freq / 2);
} else {
return (clk_freq / 8);
}
case PCLK_BAT_RAM:
case PCLK_GPIO:
case PCLK_PCB:
case PCLK_I2C1:
case PCLK_SSP0:
case PCLK_TIMER2:
case PCLK_TIMER3:
case PCLK_UART2:
case PCLK_UART3:
case PCLK_I2C2:
case PCLK_MCI:
case PCLK_SYSCON:
selection = ((PCLKSEL1 >> ((pclk - 16) * 2)) & 0x03);
if (selection == 0) {
return (clk_freq / 4);
} else if (selection == 1) {
return (clk_freq);
} else if (selection == 2) {
return (clk_freq / 2);
} else {
return (clk_freq / 8);
}
default:
return (0);
}
}
/*
*********************************************************************************************************
* OS_CPU_ExceptHndlr()
*
* Description : Handle any exceptions.
*
* Argument(s) : except_id ARM exception type:
*
* OS_CPU_ARM_EXCEPT_RESET 0x00
* OS_CPU_ARM_EXCEPT_UNDEF_INSTR 0x01
* OS_CPU_ARM_EXCEPT_SWI 0x02
* OS_CPU_ARM_EXCEPT_PREFETCH_ABORT 0x03
* OS_CPU_ARM_EXCEPT_DATA_ABORT 0x04
* OS_CPU_ARM_EXCEPT_ADDR_ABORT 0x05
* OS_CPU_ARM_EXCEPT_IRQ 0x06
* OS_CPU_ARM_EXCEPT_FIQ 0x07
*
* Return(s) : none.
*
* Caller(s) : OS_CPU_ARM_EXCEPT_HANDLER(), which is declared in os_cpu_a.s.
*********************************************************************************************************
*/
void OS_CPU_ExceptHndlr (CPU_DATA except_id)
{
CPU_FNCT_VOID pfnct;
CPU_INT32U *sp;
/* If this exception is either an IRQ or FIQ */
if ((except_id == OS_CPU_ARM_EXCEPT_IRQ) || (except_id == OS_CPU_ARM_EXCEPT_FIQ)) {
pfnct = (CPU_FNCT_VOID)VICADDRESS; /* Read the interrupt vector from the VIC */
if (pfnct != (CPU_FNCT_VOID)0) { /* Make sure we don't have a NULL pointer */
(*pfnct)(); /* Execute the ISR for the interrupting device */
VICADDRESS = 1; /* Acknowlege the VIC interrupt */
}
} else {
sp = (CPU_INT32U *)OSTCBCur->OSTCBStkPtr;
APP_TRACE_INFO(("\nCPU_ARM_EXCEPTION #%d trapped.\n", except_id));
APP_TRACE_INFO(("R0 : 0x%08x\n", *(sp + 0x01)));
APP_TRACE_INFO(("R1 : 0x%08x\n", *(sp + 0x02)));
APP_TRACE_INFO(("R2 : 0x%08x\n", *(sp + 0x03)));
APP_TRACE_INFO(("R3 : 0x%08x\n", *(sp + 0x04)));
APP_TRACE_INFO(("R4 : 0x%08x\n", *(sp + 0x05)));
APP_TRACE_INFO(("R5 : 0x%08x\n", *(sp + 0x06)));
APP_TRACE_INFO(("R6 : 0x%08x\n", *(sp + 0x07)));
APP_TRACE_INFO(("R7 : 0x%08x\n", *(sp + 0x08)));
APP_TRACE_INFO(("R8 : 0x%08x\n", *(sp + 0x09)));
APP_TRACE_INFO(("R9 : 0x%08x\n", *(sp + 0x0A)));
APP_TRACE_INFO(("R10 : 0x%08x\n", *(sp + 0x0B)));
APP_TRACE_INFO(("R11 : 0x%08x\n", *(sp + 0x0C)));
APP_TRACE_INFO(("R12 : 0x%08x\n", *(sp + 0x0D)));
APP_TRACE_INFO(("SP : 0x%08x\n", sp));
APP_TRACE_INFO(("LR : 0x%08x\n", *(sp + 0x0E)));
APP_TRACE_INFO(("PC : 0x%08x\n", *(sp + 0x0F)));
APP_TRACE_INFO(("CPSR: 0x%08x\n", *(sp + 0x00)));
/* Infinite loop on other exceptions. */
/* Should be replaced by other behavior (reboot, etc.) */
while (DEF_TRUE) {
;
}
}
}
/*
*********************************************************************************************************
* BSP_IntDisAll()
*
* Description : Disable ALL interrupts.
*
* Argument(s) : none.
*
* Return(s) : none.
*********************************************************************************************************
*/
void BSP_IntDisAll (void)
{
VICINTENCLEAR = 0xFFFFFFFFL; /* Disable ALL interrupts */
}
/*
*********************************************************************************************************
*********************************************************************************************************
** uC/OS-II TIMER FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* Tmr_TickInit()
*
* Description : Initialize uC/OS-II's tick source.
*
* Argument(s) : none.
*
* Return(s) : none.
*********************************************************************************************************
*/
static void Tmr_TickInit (void)
{
CPU_INT32U pclk_freq;
CPU_INT32U rld_cnts;
/* VIC timer #0 Initialization */
VICINTSELECT &= ~(1 << VIC_TIMER0); /* Configure the timer interrupt as an IRQ source */
VICVECTADDR4 = (CPU_INT32U)Tmr_TickISR_Handler; /* Set the vector address */
VICINTENABLE = (1 << VIC_TIMER0); /* Enable the timer interrupt source */
pclk_freq = BSP_CPU_PclkFreq(PCLK_TIMER0); /* Get the peripheral clock frequency */
rld_cnts = pclk_freq / OS_TICKS_PER_SEC; /* Calculate the # of counts necessary for the OS ticker */
T0TCR = (1 << 1); /* Disable and reset counter 0 and the prescale counter 0 */
T0TCR = 0; /* Clear the reset bit */
T0PC = 0; /* Prescaler is set to no division */
T0MR0 = rld_cnts-1;
T0MCR = 3; /* Interrupt on MR0 (reset TC), stop TC */
T0CCR = 0; /* Capture is disabled. */
T0EMR = 0; /* No external match output. */
T0TCR = 1; /* Enable timer 0 */
}
/*
*********************************************************************************************************
* Tmr_TickISR_Handler()
*
* Description : Handle the timer interrupt that is used to generate TICKs for uC/OS-II.
*
* Argument(s) : none.
*
* Return(s) : none.
*********************************************************************************************************
*/
void Tmr_TickISR_Handler (void)
{
T0IR = 0xFF; /* Clear timer #0 interrupt */
OSTimeTick(); /* Call uC/OS-II's OSTimeTick() */
}
/*
*********************************************************************************************************
*********************************************************************************************************
** LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* PLL_Init()
*
* Description : Set up and activate the PLL.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Note(s) : (1) The PLL output frequency is calculated by:
*
* Fcco = 2 * Fin * m / n
*
* where
*
* Fin is the PLL input clock (here, the main oscillator)
* M is the PLL clock multiplier. The value (M - 1) is programmed in PLLCFG.
* N is the PLL clock divider. The value (N - 1) is programmed in PLLCFG.
*
* (2) Fcco must be between 250 and 550 MHz. The ARM Core clock must never exceed 72 MHz.
* Set clk_div to divide Fcco accordingly.
*
* (3) When using the USB device, you must choose Fcco as a multiple of 96 MHz, and then
* set clk_div_usb to divide Fcco to exactly 48 MHz.
*
* (4) In this example
*
* Fin = 12MHz,
* M = 12,
* N = 1,
* clk_div = 6, and
* clk_div_usb = 6.
*
* Therefore, Fcco = 2 * Fin * M / N = (2 * 12 * 12 / 1) = 288MHz.
* The processor clock = (Fcco / clk_div) = (288MHz / 6) = 48MHz.
* Finally, the USB clock = (Fcco / clk_div_usb) = (288MHz / 6) = 48MHz.
*
* (5) A PLL errata on early revisions of the part prevent Fcco from being greater than 288MHz.
*
* (6) For later revisions, M = 20, clk_div = 8, and clk_div_usb = 10 will yield 60MHz for
* the processor clock and 48MHz for the USB clock.
*********************************************************************************************************
*/
static void PLL_Init (void)
{
#if CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL /* Allocate storage for CPU status register */
CPU_SR cpu_sr = 0;
#endif
CPU_INT32U m;
CPU_INT32U n;
CPU_INT32U clk_div;
CPU_INT32U clk_div_usb;
m = 11; /* PLL Multiplier = 20, MSEL bits = 12 - 1 = 11 */
n = 0; /* PLL Divider = 1, NSEL bits = 1 - 1 = 0 */
clk_div = 3; /* Configure the ARM Core clock div to 6. CCLKSEL = 6 - 1 */
clk_div_usb = 5; /* Configure the USB clock divider to 6, USBSEL = 6 - 1 */
if ((PLLSTAT & DEF_BIT_25) > 0) { /* If the PLL is already running */
CPU_CRITICAL_ENTER();
PLLCON &= ~DEF_BIT_01; /* Disconnect the PLL */
PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */
PLLFEED = 0x55;
CPU_CRITICAL_EXIT();
}
CPU_CRITICAL_ENTER();
PLLCON &= ~DEF_BIT_00; /* Disable the PLL */
PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */
PLLFEED = 0x55;
CPU_CRITICAL_EXIT();
SCS &= ~DEF_BIT_04; /* OSCRANGE = 0, Main OSC is between 1 and 20 Mhz */
SCS |= DEF_BIT_05; /* OSCEN = 1, Enable the main oscillator */
SCS |= DEF_BIT_00; /* access to all ports as fast io */
while ((SCS & DEF_BIT_06) == 0) { /* Wait until OSCSTAT is set (Main OSC ready to be used) */
;
}
CLKSRCSEL = DEF_BIT_00; /* Select main OSC, 12MHz, as the PLL clock source */
CPU_CRITICAL_ENTER();
PLLCFG = (m << 0) | (n << 16); /* Configure the PLL multiplier and divider */
PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */
PLLFEED = 0x55;
CPU_CRITICAL_EXIT();
CPU_CRITICAL_ENTER();
PLLCON |= DEF_BIT_00; /* Enable the PLL */
PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */
PLLFEED = 0x55;
CPU_CRITICAL_EXIT();
CCLKCFG = clk_div; /* Configure the ARM Core Processor clock divider */
USBCLKCFG = clk_div_usb; /* Configure the USB clock divider */
while ((PLLSTAT & DEF_BIT_26) == 0) { /* Wait for PLOCK to become set */
;
}
PCLKSEL0 = 0xAAAAAAAA; /* Set peripheral clocks to be half of main clock */
PCLKSEL1 = 0x22AAA8AA;
CPU_CRITICAL_ENTER();
PLLCON |= DEF_BIT_01; /* Connect the PLL. The PLL is now the active clock source */
PLLFEED = 0xAA; /* PLL register update sequence, 0xAA, 0x55 */
PLLFEED = 0x55;
CPU_CRITICAL_EXIT();
while ((PLLSTAT & DEF_BIT_25) == 0) { /* Wait PLLC, the PLL connect status bit to become set */
;
}
}
/*
*********************************************************************************************************
* MAM_Init()
*
* Description : Initialize the Memory Acceleration Module.
*
* Argument(s) : none.
*
* Return(s) : none.
*********************************************************************************************************
*/
static void MAM_Init (void)
{
CPU_INT32U clk_freq;
clk_freq = BSP_CPU_ClkFreq(); /* Get the current core clock frequency */
MAMCR = 0; /* Disable MAM functionality */
if (clk_freq < 20000000) { /* Compare current clock frequency with MAM modes */
MAMTIM = 1; /* Set MAM fetch cycles to 1 processor clock in duration */
}
if (clk_freq < 40000000) {
MAMTIM = 2; /* Set MAM fetch cycles to 2 processor clock in duration */
}
if (clk_freq >= 40000000) {
MAMTIM = 3; /* Set MAM fetch cycles to 3 processor clock in duration */
}
MAMCR = 2; /* Enable full MAM functionality */
}
/*
*********************************************************************************************************
* GPIO_Init()
*
* Description : Initializes the GPIO pins. All the I/O pins are initialized in this function
* so you don't have to look at multiple places for I/O initialization.
*
* Argument(s) : none.
*
* Return(s) : none.
*
* Note(s) : (1) Refer to the LPC2378 User Manual, Chapter 9 for a detailed Pin Assignment
*********************************************************************************************************
*/
static void GPIO_Init (void)
{
IO0DIR = 0;
IO1DIR = 0;
FIO0DIR = 0;
FIO1DIR = 0;
FIO2DIR = 0;
FIO3DIR = 0;
FIO4DIR = 0;
FIO0MASK = 0;
FIO1MASK = 0;
FIO2MASK = 0;
FIO3MASK = 0;
FIO4MASK = 0;
PINSEL0 = 0;
PINSEL1 = 0;
PINSEL2 = 0;
PINSEL3 = 0;
PINSEL4 = 0;
PINSEL5 = 0;
PINSEL6 = 0;
PINSEL7 = 0;
PINSEL8 = 0;
PINSEL9 = 0;
PINSEL10 = 0;
}
/*
*********************************************************************************************************
* VIC_Init()
*
* Description : Initialize the Vectored Interrupt Controller
*
* Argument(s) : none.
*
* Return(s) : none.
*********************************************************************************************************
*/
static void VIC_Init (void)
{
VICINTENCLEAR = 0xFFFFFFFF; /* Disable ALL interrupts */
VICADDRESS = 0; /* Acknowlege any pending VIC interrupt */
VICPROTECTION = 0; /* Allow VIC register access in User of Priviledged modes */
VICVECTADDR0 = (CPU_INT32U)VIC_DummyWDT; /* Set the vector address */
VICVECTADDR1 = (CPU_INT32U)VIC_DummySW;
VICVECTADDR2 = (CPU_INT32U)VIC_DummyDEBUGRX;
VICVECTADDR3 = (CPU_INT32U)VIC_DummyDEBUGTX;
VICVECTADDR4 = (CPU_INT32U)VIC_DummyTIMER0;
VICVECTADDR5 = (CPU_INT32U)VIC_DummyTIMER1;
VICVECTADDR6 = (CPU_INT32U)VIC_DummyUART0;
VICVECTADDR7 = (CPU_INT32U)VIC_DummyUART1;
VICVECTADDR8 = (CPU_INT32U)VIC_DummyPWM01;
VICVECTADDR9 = (CPU_INT32U)VIC_DummyI2C0;
VICVECTADDR10 = (CPU_INT32U)VIC_DummySPI;
VICVECTADDR11 = (CPU_INT32U)VIC_DummySSP1;
VICVECTADDR12 = (CPU_INT32U)VIC_DummyPLL;
VICVECTADDR13 = (CPU_INT32U)VIC_DummyRTC;
VICVECTADDR14 = (CPU_INT32U)VIC_DummyEINT0;
VICVECTADDR15 = (CPU_INT32U)VIC_DummyEINT1;
VICVECTADDR16 = (CPU_INT32U)VIC_DummyEINT2;
VICVECTADDR17 = (CPU_INT32U)VIC_DummyEINT3;
VICVECTADDR18 = (CPU_INT32U)VIC_DummyAD0;
VICVECTADDR19 = (CPU_INT32U)VIC_DummyI2C1;
VICVECTADDR20 = (CPU_INT32U)VIC_DummyBOD;
VICVECTADDR21 = (CPU_INT32U)VIC_DummyETHERNET;
VICVECTADDR22 = (CPU_INT32U)VIC_DummyUSB;
VICVECTADDR23 = (CPU_INT32U)VIC_DummyCAN01;
VICVECTADDR24 = (CPU_INT32U)VIC_DummyMMC;
VICVECTADDR25 = (CPU_INT32U)VIC_DummyGP_DMA;
VICVECTADDR26 = (CPU_INT32U)VIC_DummyTIMER2;
VICVECTADDR27 = (CPU_INT32U)VIC_DummyTIMER3;
VICVECTADDR28 = (CPU_INT32U)VIC_DummyUART2;
VICVECTADDR29 = (CPU_INT32U)VIC_DummyUART3;
VICVECTADDR30 = (CPU_INT32U)VIC_DummyI2C2;
VICVECTADDR31 = (CPU_INT32U)VIC_DummyI2S;
}
/*
*********************************************************************************************************
*********************************************************************************************************
** DUMMY INTERRUPT HANDLERS
*********************************************************************************************************
*********************************************************************************************************
*/
static void VIC_Dummy (void)
{
while (DEF_TRUE) {
;
}
}
static void VIC_DummyWDT (void)
{
VIC_SpuriousInt = VIC_WDT;
VIC_Dummy();
}
static void VIC_DummySW (void)
{
VIC_SpuriousInt = VIC_SW;
VIC_Dummy();
}
static void VIC_DummyDEBUGRX (void)
{
VIC_SpuriousInt = VIC_DEBUGRX;
VIC_Dummy();
}
static void VIC_DummyDEBUGTX (void)
{
VIC_SpuriousInt = VIC_DEBUGTX;
VIC_Dummy();
}
static void VIC_DummyTIMER0 (void)
{
VIC_SpuriousInt = VIC_TIMER0;
VIC_Dummy();
}
static void VIC_DummyTIMER1 (void)
{
VIC_SpuriousInt = VIC_TIMER1;
VIC_Dummy();
}
static void VIC_DummyUART0 (void)
{
VIC_SpuriousInt = VIC_UART0;
VIC_Dummy();
}
static void VIC_DummyUART1 (void)
{
VIC_SpuriousInt = VIC_UART1;
VIC_Dummy();
}
static void VIC_DummyPWM01 (void)
{
VIC_SpuriousInt = VIC_PWM1;
VIC_Dummy();
}
static void VIC_DummyI2C0 (void)
{
VIC_SpuriousInt = VIC_I2C0;
VIC_Dummy();
}
static void VIC_DummySPI (void)
{
VIC_SpuriousInt = VIC_SPI;
VIC_Dummy();
}
static void VIC_DummySSP1 (void)
{
VIC_SpuriousInt = VIC_SSP1;
VIC_Dummy();
}
static void VIC_DummyPLL (void)
{
VIC_SpuriousInt = VIC_PLL;
VIC_Dummy();
}
static void VIC_DummyRTC (void)
{
VIC_SpuriousInt = VIC_RTC;
VIC_Dummy();
}
static void VIC_DummyEINT0 (void)
{
VIC_SpuriousInt = VIC_EINT0;
VIC_Dummy();
}
static void VIC_DummyEINT1 (void)
{
VIC_SpuriousInt = VIC_EINT1;
VIC_Dummy();
}
static void VIC_DummyEINT2 (void)
{
VIC_SpuriousInt = VIC_EINT2;
VIC_Dummy();
}
static void VIC_DummyEINT3 (void)
{
VIC_SpuriousInt = VIC_EINT3;
VIC_Dummy();
}
static void VIC_DummyAD0 (void)
{
VIC_SpuriousInt = VIC_AD0;
VIC_Dummy();
}
static void VIC_DummyI2C1 (void)
{
VIC_SpuriousInt = VIC_I2C1;
VIC_Dummy();
}
static void VIC_DummyBOD (void)
{
VIC_SpuriousInt = VIC_BOD;
VIC_Dummy();
}
static void VIC_DummyETHERNET (void)
{
VIC_SpuriousInt = VIC_ETHERNET;
VIC_Dummy();
}
static void VIC_DummyUSB (void)
{
VIC_SpuriousInt = VIC_USB;
VIC_Dummy();
}
static void VIC_DummyCAN01 (void)
{
VIC_SpuriousInt = VIC_CAN12;
VIC_Dummy();
}
static void VIC_DummyMMC (void)
{
VIC_SpuriousInt = VIC_MMC;
VIC_Dummy();
}
static void VIC_DummyGP_DMA (void)
{
VIC_SpuriousInt = VIC_GP_DMA;
VIC_Dummy();
}
static void VIC_DummyTIMER2 (void)
{
VIC_SpuriousInt = VIC_TIMER2;
VIC_Dummy();
}
static void VIC_DummyTIMER3 (void)
{
VIC_SpuriousInt = VIC_TIMER3;
VIC_Dummy();
}
static void VIC_DummyUART2 (void)
{
VIC_SpuriousInt = VIC_UART2;
VIC_Dummy();
}
static void VIC_DummyUART3 (void)
{
VIC_SpuriousInt = VIC_UART3;
VIC_Dummy();
}
static void VIC_DummyI2C2 (void)
{
VIC_SpuriousInt = VIC_I2C2;
VIC_Dummy();
}
static void VIC_DummyI2S (void)
{
VIC_SpuriousInt = VIC_I2S;
VIC_Dummy();
}

View File

@ -0,0 +1,121 @@
;********************************************************************************************************
; uC/CPU
; CPU CONFIGURATION & PORT LAYER
;
; (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
;
; All rights reserved. Protected by international copyright laws.
;
; uC/CPU is provided in source form for FREE evaluation, for educational
; use or peaceful research. If you plan on using uC/CPU in a commercial
; product you need to contact Micrium to properly license its use in your
; product. We provide ALL the source code for your convenience and to
; help you experience uC/CPU. The fact that the source code is provided
; does NOT mean that you can use it without paying a licensing fee.
;
; Knowledge of the source code may NOT be used to develop a similar product.
;
; Please help us continue to provide the Embedded community with the finest
; software available. Your honesty is greatly appreciated.
;********************************************************************************************************
;********************************************************************************************************
;
; CPU PORT FILE
;
; ARM
; IAR C Compiler
;
; Filename : cpu_a.s
; Version : V1.17
; Programmer(s) : JJL
; JDH
; ITJ
;********************************************************************************************************
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
PUBLIC CPU_SR_Save
PUBLIC CPU_SR_Restore
;********************************************************************************************************
; EQUATES
;********************************************************************************************************
CPU_ARM_CTRL_INT_DIS EQU 0xC0 ; Disable both FIQ & IRQ
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
RSEG CODE:CODE:NOROOT(2)
CODE32
;$PAGE
;********************************************************************************************************
; CRITICAL SECTION FUNCTIONS
;
; Description : Disable/Enable interrupts by preserving the state of interrupts. Generally speaking, the
; state of the interrupt disable flag is stored in the local variable 'cpu_sr' & interrupts
; are then disabled ('cpu_sr' is allocated in all functions that need to disable interrupts).
; The previous interrupt state is restored by copying 'cpu_sr' into the CPU's status register.
;
; Prototypes : CPU_SR CPU_SR_Save (void);
; void CPU_SR_Restore(CPU_SR cpu_sr);
;
; Note(s) : (1) These functions are used in general like this :
;
; void Task (void *p_arg)
; {
; /* Allocate storage for CPU status register */
; #if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
; CPU_SR cpu_sr;
; #endif
;
; :
; :
; CPU_CRITICAL_ENTER(); /* cpu_sr = CPU_SR_Save(); */
; :
; :
; CPU_CRITICAL_EXIT(); /* CPU_SR_Restore(cpu_sr); */
; :
; :
; }
;
; (2) CPU_SR_Restore() is implemented as recommended by Atmel's application note :
;
; "Disabling Interrupts at Processor Level"
;********************************************************************************************************
CPU_SR_Save
MRS R0, CPSR
CPU_SR_Save_Loop
; Set IRQ & FIQ bits in CPSR to DISABLE all interrupts
ORR R1, R0, #CPU_ARM_CTRL_INT_DIS
MSR CPSR_c, R1
MRS R1, CPSR ; Confirm that CPSR contains the proper interrupt disable flags
AND R1, R1, #CPU_ARM_CTRL_INT_DIS
CMP R1, #CPU_ARM_CTRL_INT_DIS
BNE CPU_SR_Save_Loop ; NOT properly DISABLED (try again)
BX LR ; DISABLED, return the original CPSR contents in R0
CPU_SR_Restore ; See Note #2
MSR CPSR_c, R0
BX LR
;$PAGE
;********************************************************************************************************
; CPU ASSEMBLY PORT FILE END
;********************************************************************************************************
END

View File

@ -0,0 +1,141 @@
#ifndef _DATA_H_
#define _DATA_H_
/*!
Îïèñàíèå ñòðóêòóð è ñïîñîáà äîñòóïà ê äàííûì
ïîêà âñå ïàðàìåòðû - 32 - áèòíûå float èëè signed long
*/
#include "cpu.h"
typedef union{
CPU_INT32U Val32U;
CPU_INT32S Val32S;
CPU_FP32 ValFloat;
}TVariant32;
// ñòðóêòóðû ãðàíèö
typedef struct{
CPU_INT32U Min;
CPU_INT32U Max;
}TRangeValueULONG;
typedef struct{
CPU_INT32S Min;
CPU_INT32S Max;
}TRangeValueSLONG;
typedef struct{
CPU_FP32 Min;
CPU_FP32 Max;
}TRangeValueFLOAT;
// óíèâåðñàëüíûé äåñêðèïòîð äàííûõ
typedef struct{
// òèï äåñêðèïòîðà
CPU_INT08U Desc;
#define DATA_DESC_EDIT 0 // ðåäàêòèðóåìûé
#define DATA_DESC_VIEW 1 // äëÿ ïðîñìîòðà
// òèï ïàðàìåòðà
CPU_INT08U Type;
//#define DATA_TYPE_UCHAR 0
//#define DATA_TYPE_SCHAR 1
#define DATA_TYPE_ULONG 2
#define DATA_TYPE_SLONG 3
#define DATA_TYPE_FLOAT 4
#define DATA_TYPE_TIME 5
#define DATA_TYPE_TIME_COUNT 6
#define DATA_TYPE_HOUR_MIN 7
// ðàñïîëîæåíèå ïàðàìåòðà
CPU_INT08U Location;
#define DATA_LOC_RAM 0
#define DATA_LOC_FRAM 1
// ïðèçíàê ìàññèâà
CPU_INT08U IsArray;
#define DATA_NO_ARRAY 0
#define DATA_IS_ARRAY 1
// ðàçìåð ìàññèâà
CPU_INT32U ArraySize;
// óêàçàòåëü íà äåñðèïòîð èíäåêñà ìàññèâà
const void* ArrayIndex; //TDataDescStruct*
// óêàçàòåëü íà ïåðåìåííóþ èëè àäðåñ FRAM
void* Data;
// óêàçàòåëü íà ãðàíèöû ïàðàìåòðà
void* RangeValue;
// ôóíêöèÿ ïî èçìåíåíèþ
void (*OnchangeFunc)(void);
// ñìåùåíèå ìåæäó ýëåìåíòàìè â ìàññèâå
CPU_INT32U ArrayOffset;
// óêàçàòåëü íà ñòðîêó íàçâàíèÿ ïàðàìåòðà
const CPU_INT08U* Name;
// ïðèçíàê èíäåêñíîãî ïàðàìåòðà (ñïèñîê ñòðîê)
CPU_INT08U IsIndex;
#define DATA_NO_INDEX 0
#define DATA_IS_INDEX 1
// óêàçàòåëü íà ñïèñîê ñòðîê äëÿ èíäåêñíîãî ïàðàìåòðà
const CPU_INT08U** Items;
// ðàçðåøèòü èíèöèàëèçàöèþ çíà÷åíèåì ïî óìîë÷àíèþ ïðè ñòàðòå ñèñòåìû
CPU_INT08U EnableInit;
#define DATA_INIT_DISABLE 0
#define DATA_INIT_ENABLE 1
// çíà÷åíèå ïî óìîë÷àíèþ
TVariant32 DefaultValue;
}TDataDescStruct;
// ñòðóêòóðà äëÿ ìàññèâà âñåõ ïàðàìåòðîâ
typedef struct{
const TDataDescStruct* ptr;
}TDataDescArrayStruct;
// ôëàãè
#define DATA_FLAG_SYSTEM_INDEX 0
#define DATA_FLAG_DIRECT_INDEX 1
// âîçâðàùàåìûå çíà÷åíèÿ
#define DATA_OK 0
#define DATA_ERR -1
// íåîáõîäèìûå ôóíêöèè
// ïîëó÷åíèå äàííûõ
extern int GetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags);
// çàïèñü äàííûõ
extern int SetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags);
// ïîëó÷åíèå ñòðîêè ñ îòôîðìàòèðîâàííûì çíà÷åíèåì
extern int GetDataStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags);
// ïîëó÷åíèå ïîëíîé ñòðîêè ñ íàçâàíèåì è çíà÷åíèåì
extern int GetDataFullStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags);
// ïîëó÷åíèå ñòðîêè ñ èìåíåì
extern int GetDataNameStr(const TDataDescStruct* desc, CPU_INT08U* buf);
// èíèöèàëèçàöèÿ ïî óìîë÷àíèþ
extern int InitDataByDefault(const TDataDescStruct* desc, CPU_INT32U index);
// ïðîâåðêà âñåõ äåñòðèïòîðîâ
extern int CheckAllData(void);
// èíèöèàëèçàöèÿ
extern int InitData(const TDataDescStruct* desc);
extern int GetDataItem(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U itemindex);
extern int InitDescByDefault(const TDataDescStruct* desc);
extern int GetDataMin(const TDataDescStruct* desc, void* buf);
extern int GetDataMax(const TDataDescStruct* desc, void* buf);
#endif //#ifndef _DATA_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
[FLASH]
SkipProgOnCRCMatch = 1
VerifyDownload = 1
AllowCaching = 1
EnableFlashDL = 2
Override = 0
Device="ADUC7020X62"
[BREAKPOINTS]
ShowInfoWin = 1
EnableFlashBP = 2
[CPU]
AllowSimulation = 1

View File

@ -0,0 +1,63 @@
1. Настройки канала:
- Разрешение работы канала: вкл/выкл
- Тайм-аут перед включением 0-120 сек.
- Тайм-аут после окончания работы - 0-15 мин.
- Минимальное время работы, мин. 1-120
- Максимальное время работы, мин. 1-120
Настройка сценариев цен для каждого канала:
- Выходные: "пт-вс", "сб-вс", "чт-сб", "чт-вс"
- Временные интервалы для будних дней, Временные интервалы для выходных дней:
T1 - начало, конец, чч
T2 - начало, конец, чч
T3 - начало, конец, чч
T4 - начало, конец, чч
всего 4 интервала для двух вариантов для каждого канала
- Для каждого канала и интервала цен настраивается:
Цена, руб. 0-9999
Время за данную цену, мин.
2. Настройка периферии - включение и отключение всей периферии.
3. Статистика:
- Число запусков по каждому каналу, шт.
- Суммарное время работы по каждому каналу, мин.
- Сумма денег по каждому каналу, руб.
- Общее число запусков, шт.
- Общее время работы, мин.
- Общая сумма денег, руб.
Каждый счетчик в двух вариантах - обнуляемый по паролю и необнуляемый итоговый.
4. Журналы:
- Прием денег
Структура записи:
- время
- номинал купюры
- канал
- Запуски поканально
Структура записи:
- время
- канал
- оплаченное время
- Ошибки общие: купюрник, ФР.
Структура записи:
- время
- событие
- Системные события: включение, переходы между режимами.
Структура записи:
- время
- событие
* журналы 1 и 2, 3 и 4 можно объединить *

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,18 @@
#ifndef _UART_H_
#define _UART_H_
#define UART2_RX_BUFSIZE 128
#define UART2_TX_BUFSIZE 64
extern void Uart2_Init(CPU_INT32U uart_speed);
extern void Uart2_Flush(void);
extern int Uart2_Gotc(void);
extern int Uart2_Getc(void);
extern int Uart2_Ready(void);
extern int Uart2_Putc(CPU_INT08U ch);
#endif //#ifndef _UART_H_

View File

@ -0,0 +1,57 @@
#include <includes.h>
#include "mode.h"
#include "app_serv.h"
// òåêóùèé ðåæèì ðàáîòû
CPU_INT08U RecentMode;
void InitMode(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
PINSEL3_bit.P1_22 = 0x0;
PINMODE3_bit.P1_22 = 0;
FIO1DIR_bit.P1_22 = 0;
FIO1MASK_bit.P1_22 = 0;
OS_EXIT_CRITICAL();
OSTimeDly(1);
OS_ENTER_CRITICAL();
if (FIO1PIN_bit.P1_22) RecentMode = MODE_WORK;
else RecentMode = MODE_SERVICE;
OS_EXIT_CRITICAL();
}
CPU_INT08U GetMode(void)
{
CPU_INT08U mode;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
mode = RecentMode;
OS_EXIT_CRITICAL();
return mode;
}
CPU_INT08U CheckMode(void)
{
CPU_INT08U newmode;
if (FIO1PIN_bit.P1_22) newmode = MODE_WORK;
else newmode = MODE_SERVICE;
if (newmode != RecentMode)
{
RecentMode = newmode;
PostUserEvent(EVENT_MODE_CHANGE);
return 1;
}
return 0;
}

View File

@ -0,0 +1,225 @@
#include <includes.h>
#include "keyboard.h"
#include "app_serv.h"
#define KBRD_QUERY_LEN 4
OS_STK KbrdTaskStk[KBRD_TASK_STK_SIZE];
OS_EVENT *KbrdQuery = NULL;
void *KbrdTbl[KBRD_QUERY_LEN];
void KbrdTask(void *p_arg);
unsigned long kbrd_state;
void InitKbrd()
{
// ïðîèíèöèàëèçèðóåì ïîðòû
/*
P0.28 MK_P24 «1»
P0.27 MK_P25 «2»
P3.26 MK_P26 «3»
P3.25 MK_P27 «a»
P1.18 MK_P32 «b»
P1.19 MK_P33 «c»
*/
// ñêàíèðóþùèå ëèíèè
PINSEL1_bit.P0_28 = 0x0;
PINSEL1_bit.P0_27 = 0x0;
PINSEL7_bit.P3_26 = 0x0;
PINMODE1_bit.P0_28 = 0;
PINMODE1_bit.P0_27 = 0;
PINMODE7_bit.P3_26 = 0;
FIO0DIR_bit.P0_28 = 1;
FIO0DIR_bit.P0_27 = 1;
FIO3DIR_bit.P3_26 = 1;
FIO0MASK_bit.P0_28 = 0;
FIO0MASK_bit.P0_27 = 0;
FIO3MASK_bit.P3_26 = 0;
// âõîäíûå ëèíèè
PINSEL3_bit.P1_18 = 0x0;
PINSEL3_bit.P1_19 = 0x0;
PINSEL7_bit.P3_25 = 0x0;
PINMODE3_bit.P1_18 = 0;
PINMODE3_bit.P1_19 = 0;
PINMODE7_bit.P3_25 = 0;
FIO1DIR_bit.P1_18 = 0;
FIO1DIR_bit.P1_19 = 0;
FIO3DIR_bit.P3_25 = 0;
FIO1MASK_bit.P1_18 = 0;
FIO1MASK_bit.P1_19 = 0;
FIO3MASK_bit.P3_25 = 0;
// êíîïêà ïîëüçîâàòåëÿ
PINSEL3_bit.P1_20 = 0x0;
PINMODE3_bit.P1_20 = 0;
FIO1DIR_bit.P1_20= 0;
FIO1MASK_bit.P1_20 = 0;
// êíîïêè îòëîæåííîãî ñòàðòà
/*
P1.25 MK_P39
P1.23 MK_P37
P1.31 MK_P20
P0.25 MK_P7
P1.24 MK_P38
P0.26 MK_P6
P1.29 MK_P45
P0.1 MK_P47
P2.13 MK_P50
P2.11 MK_P52
*/
// 1
PINSEL3_bit.P1_25 = 0x0;
PINMODE3_bit.P1_25 = 0;
FIO1DIR_bit.P1_25 = 0;
FIO1MASK_bit.P1_25 = 0;
// 2
PINSEL3_bit.P1_23 = 0x0;
PINMODE3_bit.P1_23 = 0;
FIO1DIR_bit.P1_23 = 0;
FIO1MASK_bit.P1_23 = 0;
// 3
PINSEL3_bit.P1_31 = 0x0;
PINMODE3_bit.P1_31 = 0;
FIO1DIR_bit.P1_31 = 0;
FIO1MASK_bit.P1_31 = 0;
// 4
PINSEL1_bit.P0_25 = 0x0;
PINMODE1_bit.P0_25 = 0;
FIO0DIR_bit.P0_25 = 0;
FIO0MASK_bit.P0_25 = 0;
// 5
PINSEL3_bit.P1_24 = 0x0;
PINMODE3_bit.P1_24 = 0;
FIO1DIR_bit.P1_24 = 0;
FIO1MASK_bit.P1_24 = 0;
// 6
PINSEL1_bit.P0_26 = 0x0;
PINMODE1_bit.P0_26 = 0;
FIO0DIR_bit.P0_26 = 0;
FIO0MASK_bit.P0_26 = 0;
// 7
PINSEL3_bit.P1_29 = 0x0;
PINMODE3_bit.P1_29 = 0;
FIO1DIR_bit.P1_29 = 0;
FIO1MASK_bit.P1_29 = 0;
// 8
PINSEL0_bit.P0_1 = 0x0;
PINMODE0_bit.P0_1 = 0;
FIO0DIR_bit.P0_1 = 0;
FIO0MASK_bit.P0_1 = 0;
// 9
PINSEL4_bit.P2_13 = 0x0;
PINMODE4_bit.P2_13 = 0;
FIO2DIR_bit.P2_13 = 0;
FIO2MASK_bit.P2_13 = 0;
// 10
PINSEL4_bit.P2_11 = 0x0;
PINMODE4_bit.P2_11 = 0;
FIO2DIR_bit.P2_11 = 0;
FIO2MASK_bit.P2_11 = 0;
kbrd_state = 0;
// ñîçäàäèì î÷åðåäü ñîáûòèé êëàâèàòóðû è çàäà÷ó îïðîñà êëàâèàòóðû
if (KbrdQuery == NULL)
{
KbrdQuery = OSQCreate(&KbrdTbl[0], KBRD_QUERY_LEN);
OSTaskCreate(KbrdTask, (void *)0, (OS_STK *)&KbrdTaskStk[KBRD_TASK_STK_SIZE-1], KBRD_TASK_PRIO);
}
}
#define KBRD_SCAN_LINE1() {FIO0CLR_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;}
#define KBRD_SCAN_LINE2() {FIO0SET_bit.P0_28 = 1; FIO0CLR_bit.P0_27 = 1; FIO3SET_bit.P3_26 = 1;}
#define KBRD_SCAN_LINE3() {FIO0SET_bit.P0_28 = 1; FIO0SET_bit.P0_27 = 1; FIO3CLR_bit.P3_26 = 1;}
void KbrdTask(void *p_arg)
{
unsigned long prew_state = 0;
while (1)
{
unsigned long state;
OSTimeDly(17);
state = 0;
KBRD_SCAN_LINE1();
OSTimeDly(1);
if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_F1);
if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_F2);
if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_F3);
KBRD_SCAN_LINE2();
OSTimeDly(1);
if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_LEFT);
if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_UP);
if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_RIGHT);
KBRD_SCAN_LINE3();
OSTimeDly(1);
if (!FIO3PIN_bit.P3_25) state |= (1UL << KEY_STOP);
if (!FIO1PIN_bit.P1_18) state |= (1UL << KEY_DOWN);
if (!FIO1PIN_bit.P1_19) state |= (1UL << KEY_START);
if (!FIO1PIN_bit.P1_20) state |= (1UL << KEY_USER_START);
if (!FIO1PIN_bit.P1_25) state |= (1UL << KEY_DEFERRED_CH1);
if (!FIO1PIN_bit.P1_23) state |= (1UL << KEY_DEFERRED_CH2);
if (!FIO1PIN_bit.P1_31) state |= (1UL << KEY_DEFERRED_CH3);
if (!FIO0PIN_bit.P0_25) state |= (1UL << KEY_DEFERRED_CH4);
if (!FIO1PIN_bit.P1_24) state |= (1UL << KEY_DEFERRED_CH5);
if (!FIO0PIN_bit.P0_26) state |= (1UL << KEY_DEFERRED_CH6);
if (!FIO1PIN_bit.P1_29) state |= (1UL << KEY_DEFERRED_CH7);
if (!FIO0PIN_bit.P0_1) state |= (1UL << KEY_DEFERRED_CH8);
if (!FIO2PIN_bit.P2_13) state |= (1UL << KEY_DEFERRED_CH9);
if (!FIO2PIN_bit.P2_11) state |= (1UL << KEY_DEFERRED_CH10);
if (prew_state == state)
{ // óñòðàíèëè äðåáåçã
if (kbrd_state ^ state)
{ // åñòü èçìåíåíèÿ íàæàòèÿ
for (unsigned long i = 0; i < KEY_COUNT; i++)
{
// ëîâèì ïåðåäíèé ôðîíò ïðè íàæàòèè
if (!(kbrd_state & (1UL << i)) && (state & (1UL << i)))
{
OSQPost(KbrdQuery, (void *)i);
PostUserEvent(EVENT_KEY_EMPTY+i); // ïîëüçîâàòåëþ òîæå ïîñòèì
}
}
}
kbrd_state = state;
}
prew_state = state;
}
}
int GetKbrdEvent(int* event)
{
CPU_INT08U err = 0;
int evt = (int)OSQPend(KbrdQuery, 1, &err);
if (err != 0) return 0;
*event = evt;
return 1;
}

View File

@ -0,0 +1,54 @@
Доработки в ПО контроллера солярия.
+ 1. Добавление отправки e-mail сообщений по расписанию со статистикой, журналами по событиям (сообщений об ошибках) или по команде (например, по смс).
Настройки модема:
Модем вкл/выкл
Период отправки статистики: не отправлять, 1 час, 2 часа, 4 часа, 8 часов, 12 часов, 24 часа.
Отправлять журналы: нет/да
* при включенной данной настройке в сообщение со статистикой включаются и оба журнала.
Ошибки модема:
Добавить в журнал ошибок ошибку модема
Добавить в журнал ошибок ошибку отправки e-mail
+ 2. Короткие и длинные счетчики:
Для общих счетчиков денег/сеансов/времени наработки добавил длинное и короткое значение.
Длинное - никогда не обнуляется, защита по crc.
+ 3. Добавил подсчет количества купюр в кассете и раздельные счетчики по номиналам купюр.
+ 4. Добавление серийного номера устройства, номера версии прошивки.
Серийный номер наверное не нужен, т.к. у нас есть только 2 режима, его всегда можно будет изменить.
-> Добавить id устройства в меню модема. id включается в тему e-mail.
+ 5. Добавить режим инкассации:
Вход в инкассацию по снятию коробки купюрника.
После инкассации - сброс коротких счетчиков, количества купюр в кассете.
+ 6. + Добавить в журнал ошибок ошибку отправки e-mail
+ Добавить события "Смена режима", "Введен неверный пароль".
+ Добавление события инкассации в журнал событий.
+ 7. Добавление мастер-пароля для сброса основного пароля.
+ 8. Добавить новые счетчики в e-mail. Проверить всё.
------------------------------------------------------
+ 9. Добавить событие Введен неправильный пароль.
+ 10. Событие оправки сообщения в случае успеха и неуспеха - в журнал СОБЫТИЙ.
+ 11. В программе настройки писать - "Test message from modem."
+ 13. Длинные счетчики поканально, переделать меню.
+ 14. В режиме инкассации выводить на дисплей сумму из короткого счетчика.
------------------------------------------------------
* 12. Не работают русские папки.
------------------------------------------------------
+ 15. В e-mail отчете указывать количество купюр по номиналам для номиналов, у которых
число купюр > 0.
+ 16. Добавить длинные канальные счетчики в сообщение.
+ 16. Выровнять таблицы в письме.

View File

@ -0,0 +1,577 @@
;
;********************************************************************************************************
; uC/OS-II
; The Real-Time Kernel
;
;
; (c) Copyright 1992-2007, Micrium, Weston, FL
; All Rights Reserved
;
; Generic ARM Port
;
; File : OS_CPU_A.ASM
; Version : V1.82
; By : Jean J. Labrosse
; Jean-Denis Hatier
;
; For : ARM7 or ARM9
; Mode : ARM or Thumb
; Toolchain : IAR's EWARM V4.11a and higher
;********************************************************************************************************
;
;********************************************************************************************************
; PUBLIC FUNCTIONS
;********************************************************************************************************
; External references.
EXTERN OSRunning
EXTERN OSPrioCur
EXTERN OSPrioHighRdy
EXTERN OSTCBCur
EXTERN OSTCBHighRdy
EXTERN OSIntNesting
EXTERN OSIntExit
EXTERN OSTaskSwHook
; Functions declared in this file.
PUBLIC OS_CPU_SR_Save
PUBLIC OS_CPU_SR_Restore
PUBLIC OSStartHighRdy
PUBLIC OSCtxSw
PUBLIC OSIntCtxSw
; Functions related to exception handling.
PUBLIC OS_CPU_ARM_ExceptResetHndlr
PUBLIC OS_CPU_ARM_ExceptUndefInstrHndlr
PUBLIC OS_CPU_ARM_ExceptSwiHndlr
PUBLIC OS_CPU_ARM_ExceptPrefetchAbortHndlr
PUBLIC OS_CPU_ARM_ExceptDataAbortHndlr
PUBLIC OS_CPU_ARM_ExceptAddrAbortHndlr
PUBLIC OS_CPU_ARM_ExceptIrqHndlr
PUBLIC OS_CPU_ARM_ExceptFiqHndlr
EXTERN OS_CPU_ExceptHndlr
;********************************************************************************************************
; EQUATES
;********************************************************************************************************
OS_CPU_ARM_CONTROL_INT_DIS EQU 0xC0 ; Disable both FIQ and IRQ.
OS_CPU_ARM_CONTROL_FIQ_DIS EQU 0x40 ; Disable FIQ.
OS_CPU_ARM_CONTROL_IRQ_DIS EQU 0x80 ; Disable IRQ.
OS_CPU_ARM_CONTROL_THUMB EQU 0x20 ; Set THUMB mode.
OS_CPU_ARM_CONTROL_ARM EQU 0x00 ; Set ARM mode.
OS_CPU_ARM_MODE_MASK EQU 0x1F
OS_CPU_ARM_MODE_USR EQU 0x10
OS_CPU_ARM_MODE_FIQ EQU 0x11
OS_CPU_ARM_MODE_IRQ EQU 0x12
OS_CPU_ARM_MODE_SVC EQU 0x13
OS_CPU_ARM_MODE_ABT EQU 0x17
OS_CPU_ARM_MODE_UND EQU 0x1B
OS_CPU_ARM_MODE_SYS EQU 0x1F
OS_CPU_ARM_EXCEPT_RESET EQU 0x00
OS_CPU_ARM_EXCEPT_UNDEF_INSTR EQU 0x01
OS_CPU_ARM_EXCEPT_SWI EQU 0x02
OS_CPU_ARM_EXCEPT_PREFETCH_ABORT EQU 0x03
OS_CPU_ARM_EXCEPT_DATA_ABORT EQU 0x04
OS_CPU_ARM_EXCEPT_ADDR_ABORT EQU 0x05
OS_CPU_ARM_EXCEPT_IRQ EQU 0x06
OS_CPU_ARM_EXCEPT_FIQ EQU 0x07
;********************************************************************************************************
; CODE GENERATION DIRECTIVES
;********************************************************************************************************
RSEG CODE:CODE:NOROOT(2)
CODE32
;*********************************************************************************************************
; CRITICAL SECTION METHOD 3 FUNCTIONS
;
; Description: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
; would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
; disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
; disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
; into the CPU's status register.
;
; Prototypes : OS_CPU_SR OS_CPU_SR_Save (void);
; void OS_CPU_SR_Restore (OS_CPU_SR os_cpu_sr);
;
;
; Note(s) : (1) These functions are used in general like this:
;
; void Task (void *p_arg)
; {
; /* Allocate storage for CPU status register. */
; #if (OS_CRITICAL_METHOD == 3)
; OS_CPU_SR os_cpu_sr;
; #endif
;
; :
; :
; OS_ENTER_CRITICAL(); /* os_cpu_sr = OS_CPU_SR_Save(); */
; :
; :
; OS_EXIT_CRITICAL(); /* OS_CPU_SR_Restore(cpu_sr); */
; :
; :
; }
;*********************************************************************************************************
OS_CPU_SR_Save
MRS R0, CPSR
ORR R1, R0, #OS_CPU_ARM_CONTROL_INT_DIS ; Set IRQ and FIQ bits in CPSR to disable all interrupts.
MSR CPSR_c, R1
BX LR ; Disabled, return the original CPSR contents in R0.
OS_CPU_SR_Restore
MSR CPSR_c, R0
BX LR
;*********************************************************************************************************
; START MULTITASKING
; void OSStartHighRdy(void)
;
; Note(s) : 1) OSStartHighRdy() MUST:
; a) Call OSTaskSwHook() then,
; b) Set OSRunning to TRUE,
; c) Switch to the highest priority task.
;*********************************************************************************************************
OSStartHighRdy
; Change to SVC mode.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
LDR R0, ?OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, ?OS_Running ; OSRunning = TRUE;
MOV R1, #1
STRB R1, [R0]
; SWITCH TO HIGHEST PRIORITY TASK:
LDR R0, ?OS_TCBHighRdy ; Get highest priority task TCB address,
LDR R0, [R0] ; Get stack pointer,
LDR SP, [R0] ; Switch to the new stack,
LDR R0, [SP], #4 ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From task level) - OSCtxSw()
;
; Note(s) : 1) OSCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED.
;
; 2) The pseudo-code for OSCtxSw() is:
; a) Save the current task's context onto the current task's stack,
; b) OSTCBCur->OSTCBStkPtr = SP;
; c) OSTaskSwHook();
; d) OSPrioCur = OSPrioHighRdy;
; e) OSTCBCur = OSTCBHighRdy;
; f) SP = OSTCBHighRdy->OSTCBStkPtr;
; g) Restore the new task's context from the new task's stack,
; h) Return to new task's code.
;
; 3) Upon entry:
; OSTCBCur points to the OS_TCB of the task to suspend,
; OSTCBHighRdy points to the OS_TCB of the task to resume.
;*********************************************************************************************************
OSCtxSw
; SAVE CURRENT TASK'S CONTEXT:
STMFD SP!, {LR} ; Push return address,
STMFD SP!, {LR}
STMFD SP!, {R0-R12} ; Push registers,
MRS R0, CPSR ; Push current CPSR,
TST LR, #1 ; See if called from Thumb mode,
ORRNE R0, R0, #OS_CPU_ARM_CONTROL_THUMB ; If yes, set the T-bit.
STMFD SP!, {R0}
LDR R0, ?OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R1, [R0]
STR SP, [R1]
LDR R0, ?OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, ?OS_PrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, ?OS_PrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, ?OS_TCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;*********************************************************************************************************
; PERFORM A CONTEXT SWITCH (From interrupt level) - OSIntCtxSw()
;
; Note(s) : 1) OSIntCtxSw() is called in SVC mode with BOTH FIQ and IRQ interrupts DISABLED.
;
; 2) The pseudo-code for OSCtxSw() is:
; a) OSTaskSwHook();
; b) OSPrioCur = OSPrioHighRdy;
; c) OSTCBCur = OSTCBHighRdy;
; d) SP = OSTCBHighRdy->OSTCBStkPtr;
; e) Restore the new task's context from the new task's stack,
; f) Return to new task's code.
;
; 3) Upon entry:
; OSTCBCur points to the OS_TCB of the task to suspend,
; OSTCBHighRdy points to the OS_TCB of the task to resume.
;*********************************************************************************************************
OSIntCtxSw
LDR R0, ?OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, ?OS_PrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, ?OS_PrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, ?OS_TCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, ?OS_TCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;********************************************************************************************************
; RESET EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptResetHndlr
; LR offset to return from this exception: 0.
; (there is no way to return from a RESET exception).
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_RESET ; Set exception ID to OS_CPU_ARM_EXCEPT_RESET.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; UNDEFINED INSTRUCTION EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptUndefInstrHndlr
; LR offset to return from this exception: 0.
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_UNDEF_INSTR ; Set exception ID to OS_CPU_ARM_EXCEPT_UNDEF_INSTR.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; SOFTWARE INTERRUPT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptSwiHndlr
; LR offset to return from this exception: 0.
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_SWI ; Set exception ID to OS_CPU_ARM_EXCEPT_SWI.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; PREFETCH ABORT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptPrefetchAbortHndlr
SUB LR, LR, #4 ; LR offset to return from this exception: -4.
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_PREFETCH_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_PREFETCH_ABORT.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; DATA ABORT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptDataAbortHndlr
SUB LR, LR, #8 ; LR offset to return from this exception: -8.
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_DATA_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_DATA_ABORT.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; ADDRESS ABORT EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptAddrAbortHndlr
SUB LR, LR, #8 ; LR offset to return from this exception: -8.
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_ADDR_ABORT ; Set exception ID to OS_CPU_ARM_EXCEPT_ADDR_ABORT.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; INTERRUPT REQUEST EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptIrqHndlr
SUB LR, LR, #4 ; LR offset to return from this exception: -4.
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_IRQ ; Set exception ID to OS_CPU_ARM_EXCEPT_IRQ.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; FAST INTERRUPT REQUEST EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptFiqHndlr
SUB LR, LR, #4 ; LR offset to return from this exception: -4.
STMFD SP!, {R0-R12, LR} ; Push working registers.
MOV R3, LR ; Save link register.
MOV R0, #OS_CPU_ARM_EXCEPT_FIQ ; Set exception ID to OS_CPU_ARM_EXCEPT_FIQ.
B OS_CPU_ARM_ExceptHndlr ; Branch to global exception handler.
;********************************************************************************************************
; GLOBAL EXCEPTION HANDLER
;
; Register Usage: R0 Exception Type
; R1 Exception's SPSR
; R2 Old CPU mode
; R3 Return PC
;********************************************************************************************************
OS_CPU_ARM_ExceptHndlr
MRS R1, SPSR ; Save CPSR (i.e. exception's SPSR).
; DETERMINE IF WE INTERRUPTED A TASK OR ANOTHER LOWER PRIORITY EXCEPTION:
; SPSR.Mode = SVC : task,
; SPSR.Mode = FIQ, IRQ, ABT, UND : other exceptions,
; SPSR.Mode = USR : *unsupported state*.
AND R2, R1, #OS_CPU_ARM_MODE_MASK
CMP R2, #OS_CPU_ARM_MODE_SVC
BNE OS_CPU_ARM_ExceptHndlr_BreakExcept
;********************************************************************************************************
; EXCEPTION HANDLER: TASK INTERRUPTED
;
; Register Usage: R0 Exception Type
; R1 Exception's SPSR
; R2 Exception's CPSR
; R3 Return PC
; R4 Exception's SP
;********************************************************************************************************
OS_CPU_ARM_ExceptHndlr_BreakTask
MRS R2, CPSR ; Save exception's CPSR.
MOV R4, SP ; Save exception's stack pointer.
; Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
; SAVE TASK'S CONTEXT ONTO TASK'S STACK:
STMFD SP!, {R3} ; Push task's PC,
STMFD SP!, {LR} ; Push task's LR,
STMFD SP!, {R5-R12} ; Push task's R12-R5,
LDMFD R4!, {R5-R9} ; Move task's R4-R0 from exception stack to task's stack.
STMFD SP!, {R5-R9}
STMFD SP!, {R1} ; Push task's CPSR (i.e. exception SPSR).
; if (OSRunning == 1)
LDR R1, ?OS_Running
LDRB R1, [R1]
CMP R1, #1
BNE OS_CPU_ARM_ExceptHndlr_BreakTask_1
; HANDLE NESTING COUNTER:
LDR R3, ?OS_IntNesting ; OSIntNesting++;
LDRB R4, [R3]
ADD R4, R4, #1
STRB R4, [R3]
LDR R3, ?OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R4, [R3]
STR SP, [R4]
OS_CPU_ARM_ExceptHndlr_BreakTask_1
MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE.
; EXECUTE EXCEPTION HANDLER:
LDR R1, ?OS_CPU_ExceptHndlr ; OS_CPU_ExceptHndlr(except_type = R0);
MOV LR, PC
BX R1
; Adjust exception stack pointer. This is needed because
; exception stack is not used when restoring task context.
ADD SP, SP, #(14 * 4)
; Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
; Call OSIntExit(). This call MAY never return if a ready
; task with higher priority than the interrupted one is
; found.
LDR R0, ?OS_IntExit
MOV LR, PC
BX R0
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;********************************************************************************************************
; EXCEPTION HANDLER: EXCEPTION INTERRUPTED
;
; Register Usage: R0 Exception Type
; R1
; R2
; R3
;********************************************************************************************************
OS_CPU_ARM_ExceptHndlr_BreakExcept
MRS R2, CPSR ; Save exception's CPSR.
; Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
; HANDLE NESTING COUNTER:
LDR R3, ?OS_IntNesting ; OSIntNesting++;
LDRB R4, [R3]
ADD R4, R4, #1
STRB R4, [R3]
MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE.
; EXECUTE EXCEPTION HANDLER:
LDR R3, ?OS_CPU_ExceptHndlr ; OS_CPU_ExceptHndlr(except_type = R0);
MOV LR, PC
BX R3
; Change to SVC mode & disable interruptions.
MSR CPSR_c, #(OS_CPU_ARM_CONTROL_INT_DIS | OS_CPU_ARM_MODE_SVC)
; HANDLE NESTING COUNTER:
LDR R3, ?OS_IntNesting ; OSIntNesting--;
LDRB R4, [R3]
SUB R4, R4, #1
STRB R4, [R3]
MSR CPSR_cxsf, R2 ; RESTORE INTERRUPTED MODE.
; RESTORE OLD CONTEXT:
LDMFD SP!, {R0-R12, PC}^ ; Pull working registers and return from exception.
;*********************************************************************************************************
; POINTERS TO VARIABLES
;*********************************************************************************************************
DATA
?OS_Running:
DC32 OSRunning
?OS_PrioCur:
DC32 OSPrioCur
?OS_PrioHighRdy:
DC32 OSPrioHighRdy
?OS_TCBCur:
DC32 OSTCBCur
?OS_TCBHighRdy:
DC32 OSTCBHighRdy
?OS_IntNesting:
DC32 OSIntNesting
?OS_TaskSwHook:
DC32 OSTaskSwHook
?OS_IntExit:
DC32 OSIntExit
?OS_CPU_ExceptHndlr:
DC32 OS_CPU_ExceptHndlr
END

View File

@ -0,0 +1,20 @@
#ifndef __CRC16_H__
#define __CRC16_H__
#define CRC16_SMALL 0 // ðàñ÷åò áåç òàáëèöû
#define CRC16_LARGE 1 // òàáëè÷íûé ìåòîä (áîëüøå ïî ðàçìåðó êîäà)
#define CRC16_MODEL_TYPE CRC16_LARGE
#if (CRC16_MODEL_TYPE==CRC16_LARGE)
extern unsigned short CRC16_large( unsigned char *pBuf, unsigned char ucLength );
#define CRC16 CRC16_large
#else
extern unsigned short CRC16_small( unsigned char *pBuf, unsigned char ucLength );
#define CRC16 CRC16_small
#endif
#endif // #ifndef __CRC16_H__

View File

@ -0,0 +1,50 @@
#ifndef __LCD_H__
#define __LCD_H__
/*!
Äðàéâåð äèñïëåÿ
êîíòðîëëåð äèñïëåÿ ks066, 4 ñòðîêè
*/
#define LCD_HOME 0x02
#define LCD_CLEAR 0x01
#define LCD_GOTO_LINE_0 0x80
#define LCD_GOTO_LINE_1 0xC0
#define LCD_GOTO_LINE_2 0x94
#define LCD_GOTO_LINE_3 0xD4
#define LCD_1CYCLE 0
#define LCD_2CYCLE 1
#define LCD_PORT PORTB
#define D4_pin PB4
#define D5_pin PB5
#define D6_pin PB6
#define D7_pin PB7
#define LCD_SET_E_PIN() {FIO2SET_bit.P2_7 = 1;}
#define LCD_CLR_E_PIN() {FIO2CLR_bit.P2_7 = 1;}
#define LCD_SET_RW_PIN() {FIO2SET_bit.P2_6 = 1;}
#define LCD_CLR_RW_PIN() {FIO2CLR_bit.P2_6 = 1;}
#define LCD_SET_RS_PIN() {FIO2SET_bit.P2_8 = 1;}
#define LCD_CLR_RS_PIN() {FIO2CLR_bit.P2_8 = 1;}
#define LCD_OUT_DATA(x) {FIO0PIN &= ~(0x0fL << 19); FIO0PIN |= (((x) & 0xf) << 19);}
#define LCD_IN_DATA() ((FIO0PIN >> 19) & 0x0f)
#define LCD_SET_DATA_IN() {FIO0DIR &= ~(0x0fL << 19);}
#define LCD_SET_DATA_OUT() {FIO0PIN |= (0x0fL << 19);}
extern void InitLcd();
extern void LCD_puts(unsigned char *s, unsigned char n);
extern void LCD_putc(unsigned char c, unsigned char n, unsigned char m);
extern void LCD_clear(void);
extern void LCD_putc_embed(unsigned char c, unsigned char n, unsigned char m);
extern void LCD_cursor_on(void);
extern void LCD_cursor_off(void);
extern void LCD_goto(unsigned char n, unsigned char m);
#endif //#ifndef __LCD_H__

View File

@ -0,0 +1,654 @@
#include <includes.h>
#include "menu.h"
#include "menudesc.h"
#include "data.h"
#include "keyboard.h"
#include "lcd.h"
#include "mode.h"
#include "app_serv.h"
#include "time.h"
OS_STK MenuTaskStk[MENU_TASK_STK_SIZE];
#define STACKPANELSIZE 8
TMenuStack MenuStack[STACKPANELSIZE];
CPU_INT08U MenuStackPtr;
CPU_INT08U MenuActiveLine, MenuFirstLine, MenuEditStatus;
TMenuPanel* MenuCurrentPanel;
CPU_INT08U EditPos, EditStart, EditLen, EditLine;
TVariant32 EditVal, EditMax, EditMin;
TDataDescStruct* EditDesc;
TRTC_Data EditTime;
// ïîçèöèè äëÿ ðåäàêòèðîâàíèÿ âðåìåíè
const CPU_INT08U EditTimePos[12] =
{
0, 1,
3, 4,
6, 7,
9,10,
12,13,
15,16
};
CPU_INT08U EditBuf[32];
#define EDIT_TYPE_NUMBER 0
#define EDIT_TYPE_ITEMS 1
CPU_INT08U refresh_menu = 0;
void ShowMenuLine(TMenuLine* line_ptr, CPU_INT08U pos)
{
CPU_INT08U strbuf[32];
if (line_ptr->LineType == MENU_LINE_STRING)
{
sprintf((char*)strbuf, " %s", (CPU_INT08U*)line_ptr->Ptr);
LCD_puts(strbuf, pos);
}
else if (line_ptr->LineType == MENU_LINE_SHOW_DESC)
{
strbuf[0] = ' ';
if ((MenuEditStatus) && (pos == EditLine))
{
// âûâîäèì ðåäàêòèðóåìóþ ñòðîêó
if (EditDesc->IsIndex)
{
GetDataNameStr((const TDataDescStruct*)EditDesc, &strbuf[1]);
strcat((char*)strbuf, "<");
strcat((char*)strbuf, (char const*)EditBuf);
strcat((char*)strbuf, ">");
LCD_puts(strbuf, pos);
}
else
{
GetDataNameStr((const TDataDescStruct*)EditDesc, &strbuf[1]);
if (EditDesc->Name) strcat((char*)strbuf, "=");
strcat((char*)strbuf, (char const*)EditBuf);
LCD_puts(strbuf, pos);
}
}
else
{
GetDataFullStr((const TDataDescStruct*)line_ptr->Ptr, &strbuf[1], 0, DATA_FLAG_SYSTEM_INDEX);
LCD_puts(strbuf, pos);
}
}
else if (line_ptr->LineType == MENU_LINE_GOTO_MENU)
{
sprintf((char*)strbuf, " %s", (CPU_INT08U*)line_ptr->Ptr);
LCD_puts(strbuf, pos);
}
}
void ClearMenuLine(CPU_INT08U pos)
{
CPU_INT08U c = 0;
LCD_puts(&c, pos);
}
void ClearDisplay(void)
{
LCD_clear();
}
TMenuPanel* GetCurrentMenu(void)
{
return MenuCurrentPanel;
}
// âûâîä òåêóùåãî ìåíþ
void ShowCurrentMenu(void)
{
// ïîäñ÷èòàåì ÷èñëî ñòðîê â òåêóùåé ïàíåëè
CPU_INT08U i, j;
TMenuLine* pLine;
//MenuCurrentPanel->LineNum
// åñëè ïàíåëü ñòàòè÷åñêàÿ, ïðîñòî âûâîäèì ïåðâûå 4 ñòðîêè
if (MenuCurrentPanel->PanelType == MENU_PANEL_STATIC)
{
j=0;
LCD_cursor_off();
for (i=0; i<MENU_LINES_NUMBER; i++)
{
pLine = (TMenuLine*)MenuCurrentPanel->LineArray[i].pMenuLine;
if (pLine == NULL) break;
ShowMenuLine(pLine, j++);
}
while (j<MENU_LINES_NUMBER)
{
ClearMenuLine(j++);
}
if ((((TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine)->Flags) & MENU_INDEX_LINE)
{
LCD_putc_embed(SYMB_IND_MARK, MENU_SYMB_NUMBER-2, 0); LCD_putc_embed(SYMB_DESC_MARK, MENU_SYMB_NUMBER-1, 0);
}
return;
}
// â îáû÷íîì ìåíþ ïåðâàÿ ëèíèÿ âñåãäà ôèêñèðîâàííàÿ
pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine;
if (pLine == NULL) {ClearDisplay(); return;}
ShowMenuLine(pLine, 0);
// âûâîäèì 3 ñòðîêè ñ ïåðåìåùåíèåì ïî ìåíþ
// MenuFirstLine - âåðõíÿÿ ñòðîêà äëÿ îòîáðàæåíèÿ
if (MenuActiveLine == 0) MenuFirstLine = 0;
else
{
if (MenuCurrentPanel->LineNum < MENU_LINES_NUMBER) MenuFirstLine = MenuActiveLine-1;
else
{
if (MenuActiveLine < MenuCurrentPanel->LineNum-2) MenuFirstLine = MenuActiveLine-1;
else MenuFirstLine = MenuActiveLine-2;
}
}
i=MenuFirstLine+1;
j=1;
while((j<MENU_LINES_NUMBER) && (i<MenuCurrentPanel->LineNum))
{
TMenuLine* pline = (TMenuLine*)MenuCurrentPanel->LineArray[i].pMenuLine;
if (pline == NULL) ClearMenuLine(j);
else ShowMenuLine(pline, j);
i++;
j++;
}
while(j<MENU_LINES_NUMBER) ClearMenuLine(j++);
// ñòðåëî÷êà òåêóùåãî âûáðàííîãî ïóíêòà
CPU_INT08U linetype = (((TMenuLine*)MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->LineType);
if (linetype == MENU_LINE_STRING)
{
LCD_putc_embed(SYMB_POINT_MARK, 0, MenuActiveLine-MenuFirstLine+1);
}
else if (linetype == MENU_LINE_GOTO_MENU)
{
LCD_putc_embed(SYMB_RIGHT_ARROW, 0, MenuActiveLine-MenuFirstLine+1);
}
else if (linetype == MENU_LINE_SHOW_DESC)
{
TMenuLine* mline = ((TMenuLine*)MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine);
if (((const TDataDescStruct*)mline->Ptr)->Desc == DATA_DESC_EDIT)
LCD_putc_embed(SYMB_DESC_MARK, 0, MenuActiveLine-MenuFirstLine+1);
else
LCD_putc_embed(SYMB_POINT_MARK, 0, MenuActiveLine-MenuFirstLine+1);
}
// çíàê èíäåêñà
CPU_INT08U lineflags = (((TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine)->Flags);
if (lineflags & MENU_INDEX_LINE)
{
LCD_putc_embed(SYMB_IND_MARK, MENU_SYMB_NUMBER-2, 0); LCD_putc_embed(SYMB_DESC_MARK, MENU_SYMB_NUMBER-1, 0);
}
// êóðñîð (àïïàðàòíûé)
if ((MenuEditStatus) && (!EditDesc->IsIndex))
{
if (EditDesc->Type == DATA_TYPE_ULONG)
{
LCD_goto(EditStart+EditPos, MenuActiveLine-MenuFirstLine+1);
}
else if ((EditDesc->Type == DATA_TYPE_TIME) || (EditDesc->Type == DATA_TYPE_HOUR_MIN))
{
LCD_goto(EditStart+EditTimePos[EditPos], MenuActiveLine-MenuFirstLine+1);
}
LCD_cursor_on();
}
else
{
LCD_cursor_off();
}
}
void RefreshMenu(void)
{
refresh_menu = 1;
}
// ïîèñê ïåðâîé àêòèâíîé ñòðîêè â ïàíåëè ìåíþ
CPU_INT08U GetFirstActiveLine(TMenuPanel *menu)
{
CPU_INT08U line = 0;
CPU_INT08U i = 0;
while (i++ < menu->LineNum)
{
TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine;
if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC))
{
line = i;
break;
}
}
return line-1;
}
// ïîèñê ñëåäóþùåé àêòèâíîé ñòðîêè â ïàíåëè ìåíþ
CPU_INT08U GetNextActiveLine(TMenuPanel *menu, CPU_INT08U recent)
{
CPU_INT08U line = recent+1;
CPU_INT08U i = recent+1;
while (i++ < menu->LineNum)
{
TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine;
if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC))
{
line = i;
break;
}
}
return line-1;
}
// ïîèñê ïðåäûäóùåé àêòèâíîé ñòðîêè â ïàíåëè ìåíþ
CPU_INT08U GetPrevActiveLine(TMenuPanel *menu, CPU_INT08U recent)
{
CPU_INT08U line = recent+1;
CPU_INT08U i = recent+1;
if (recent == 0) return 0;
while (i--)
{
TMenuLine* mline = (TMenuLine*)menu->LineArray[i].pMenuLine;
if ((mline->LineType == MENU_LINE_GOTO_MENU) || (mline->LineType == MENU_LINE_SHOW_DESC))
{
line = i;
break;
}
}
return line-1;
}
void GoToMenu(const TMenuPanel* Menu)
{
if (MenuStackPtr >= STACKPANELSIZE) return;
MenuStack[MenuStackPtr].PrevMenu = MenuCurrentPanel;
MenuStack[MenuStackPtr].PrevActiveLine = MenuActiveLine;
MenuStackPtr++;
MenuCurrentPanel = (TMenuPanel*)Menu;
MenuActiveLine = GetFirstActiveLine(MenuCurrentPanel);
if (Menu->InitFunc) Menu->InitFunc();
refresh_menu = 1;
}
void SetMenu(const TMenuPanel* Menu)
{
MenuCurrentPanel = (TMenuPanel*)Menu;
MenuActiveLine = GetFirstActiveLine(MenuCurrentPanel);
if (Menu->InitFunc) Menu->InitFunc();
refresh_menu = 1;
}
void GoToPreviousMenu(void)
{
if (!MenuStackPtr) return;
--MenuStackPtr;
MenuCurrentPanel = (TMenuPanel*)MenuStack[MenuStackPtr].PrevMenu;
MenuActiveLine = MenuStack[MenuStackPtr].PrevActiveLine;
if (MenuCurrentPanel->InitFunc) MenuCurrentPanel->InitFunc();
refresh_menu = 1;
}
void GoToNextMenu(void)
{
if ((MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->GoToPtr)
GoToMenu((MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->GoToPtr);
}
void MenuSprintf(CPU_INT08U* str, CPU_INT08U len, CPU_INT32U Val)
{
if (EditDesc->Type == DATA_TYPE_ULONG)
{
CPU_INT08U format[6];
format[0]='%';
format[1]='0';
format[2]='0'+len/10;
format[3]='0'+len%10;
format[4]='u';
format[5]=0;
sprintf((char*)str, (char const*)format, Val);
}
else if ((EditDesc->Type == DATA_TYPE_TIME) || (EditDesc->Type == DATA_TYPE_HOUR_MIN))
{
GetDataStr(EditDesc, str, 0, DATA_FLAG_SYSTEM_INDEX);
}
}
// íà÷àëî ðåäàêòèðîâàíèÿ
void EnterEdit(void)
{
// ïîçèöèÿ ðåäàêòèðîâàíèÿ, 0 - ñàìîå ñòàðøåå äåñÿòè÷íîå ÷èñëî
EditPos = 0;
// óêàçàòåëü íà ðåäàêòèðóåìûé äåñêðèïòîð
EditDesc = (TDataDescStruct*)(MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine)->Ptr;
// íîìåð ñòðîêè ñ ðåäàêòèðóåìûì äåñêðèïòîðîì
EditLine = MenuActiveLine+1-MenuFirstLine;
// ðåäàêòèðóåìîå ÷èñëî
GetData(EditDesc, &EditVal, 0, DATA_FLAG_SYSTEM_INDEX);
// ãðàíèöû
TRangeValueULONG* RVal = EditDesc->RangeValue;
memcpy(&EditMin, &RVal->Min, sizeof(CPU_INT32U));
memcpy(&EditMax, &RVal->Max, sizeof(CPU_INT32U));
if (EditDesc->IsIndex)
{
GetDataStr((const TDataDescStruct*)EditDesc, EditBuf, 0, DATA_FLAG_SYSTEM_INDEX);
}
else
{
GetDataNameStr((const TDataDescStruct*)EditDesc, EditBuf);
if (EditDesc->Name) strcat((char*)EditBuf, "=");
EditStart = strlen((char const*)EditBuf)+1;
if (EditDesc->Type == DATA_TYPE_ULONG)
{
sprintf((char*)EditBuf, "%u", RVal->Max);
EditLen = strlen((char const*)EditBuf);
}
else if (EditDesc->Type == DATA_TYPE_TIME)
{
EditLen = 12;
}
else if (EditDesc->Type == DATA_TYPE_HOUR_MIN)
{
EditLen = 4;
}
else
{
EditLen = 0;
}
MenuSprintf(EditBuf, EditLen, EditVal.Val32U);
}
MenuEditStatus = 1;
}
// âûõîä èç ðåäàêòèðîâàíèÿ áåç ñîõðàíåíèÿ
void EscEdit(void)
{
MenuEditStatus = 0;
}
// ñîõðàíåíèå ïàðàìåòðà
void SaveEdit(void)
{
if (EditDesc->Type == DATA_TYPE_ULONG)
{
if (!EditDesc->IsIndex)
{
sscanf((char const*)EditBuf, "%d", &EditVal.Val32U);
}
SetData(EditDesc, &EditVal, 0, DATA_FLAG_SYSTEM_INDEX);
}
else if (EditDesc->Type == DATA_TYPE_TIME)
{
TRTC_Data rtc;
ScanRTCDateTimeStringRus((char*)EditBuf, &rtc);
if (RTCCheckTime(&rtc) == 0)
{ // îê
CPU_INT32U time;
time = GetSec(&rtc);
SetData(EditDesc, &time, 0, DATA_FLAG_SYSTEM_INDEX);
}
}
else if (EditDesc->Type == DATA_TYPE_HOUR_MIN)
{
int hour, min, hour_min;
sscanf((char*)EditBuf, "%02d:%02d", &hour, &min);
hour_min = hour * 60 + min;
SetData(EditDesc, &hour_min, 0, DATA_FLAG_SYSTEM_INDEX);
}
MenuEditStatus = 0;
}
void MenuTask(void *p_arg)
{
int pause = 0;
SetMenu(START_MENU);
while (1)
{
int key=0;
if (GetKbrdEvent(&key) || (++pause >= 1000) || ((pause >= 500) && (MenuEditStatus)) || (refresh_menu != 0))
{
if (refresh_menu) {refresh_menu = 0; ShowCurrentMenu();}
// îòðàáîòêà êëàâèàòóðû
if (!MenuEditStatus)
{ // îòîáðàæåíèå ìåíþ
pause = 0;
if (key)
{
switch (key){
case KEY_UP:
//if (MenuActiveLine) MenuActiveLine--;
MenuActiveLine = GetPrevActiveLine(MenuCurrentPanel, MenuActiveLine);
ShowCurrentMenu();
break;
case KEY_DOWN:
//MenuActiveLine++;
//if (MenuActiveLine+1 >= MenuCurrentPanel->LineNum) MenuActiveLine--;
MenuActiveLine = GetNextActiveLine(MenuCurrentPanel, MenuActiveLine);
ShowCurrentMenu();
break;
case KEY_LEFT:
{
TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine;
if (pLine->Flags & MENU_INDEX_LINE)
{// ñâåðõó èíäåêñíûé ïàðàìåòð - ïîïðîáóåì åãî ïåðåêëþ÷èòü
TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr;
if (desc->Type == DATA_TYPE_ULONG)
{
CPU_INT32U i, min, max;
GetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX);
GetDataMin(desc, &min);
GetDataMax(desc, &max);
i--;
if ((i < min) || (i > max)) i = max;
SetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX);
}
ShowCurrentMenu();
}
}
break;
case KEY_RIGHT:
{
TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[0].pMenuLine;
if (pLine->Flags & MENU_INDEX_LINE)
{// ñâåðõó èíäåêñíûé ïàðàìåòð - ïîïðîáóåì åãî ïåðåêëþ÷èòü
TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr;
if (desc->Type == DATA_TYPE_ULONG)
{
CPU_INT32U i, min, max;
GetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX);
GetDataMin(desc, &min);
GetDataMax(desc, &max);
i++;
if ((i < min) || (i > max)) i = min;
SetData(desc, &i, 0, DATA_FLAG_SYSTEM_INDEX);
}
ShowCurrentMenu();
}
}
break;
case KEY_STOP:
// ïðîáóåì âûéòè â ïðåäûäóùåå ìåíþ
GoToPreviousMenu();
break;
case KEY_START:
{
if (MenuCurrentPanel->PanelType == MENU_PANEL_STATIC) {ShowCurrentMenu();break;}
TMenuLine* pLine = (TMenuLine*)MenuCurrentPanel->LineArray[MenuActiveLine+1].pMenuLine;
if (pLine->LineType == MENU_LINE_SHOW_DESC)
{// âõîäèì â ðåäàêòèðîâàíèå, åñëè ìîæíî
TDataDescStruct* desc = (TDataDescStruct*)pLine->Ptr;
if (desc->Desc == DATA_DESC_EDIT) {EnterEdit(); pause=1000;}
}
else if (pLine->LineType == MENU_LINE_GOTO_MENU)
{// ïðîáóåì ïåðåéòè â ñëåäóþùåå ìåíþ
GoToNextMenu();
}
}
break;
}//switch (key)
}//if (key)
else
{
ShowCurrentMenu();
}
}
else//if (!MenuEditStatus)
{ // ðåäàêòèðîâàíèå ïàðàìåòðà
if (key)
{
switch (key){
case KEY_UP:
if (EditDesc->IsIndex)
{
CPU_INT32U min, max;
GetDataMin(EditDesc, &min);
GetDataMax(EditDesc, &max);
EditVal.Val32U++;
if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = min;
GetDataItem(EditDesc, EditBuf, EditVal.Val32U);
}
else
{
if (EditDesc->Type == DATA_TYPE_ULONG)
{
EditBuf[EditPos]++;
if (EditBuf[EditPos] > '9') EditBuf[EditPos] = '0';
}
else if (EditDesc->Type == DATA_TYPE_TIME)
{
EditBuf[EditTimePos[EditPos]]++;
if (EditBuf[EditTimePos[EditPos]] > '9') EditBuf[EditTimePos[EditPos]] = '0';
}
else if (EditDesc->Type == DATA_TYPE_HOUR_MIN)
{
EditBuf[EditTimePos[EditPos]]++;
if (EditBuf[EditTimePos[EditPos]] > '9') EditBuf[EditTimePos[EditPos]] = '0';
}
}
break;
case KEY_DOWN:
if (EditDesc->IsIndex)
{
CPU_INT32U min, max;
GetDataMin(EditDesc, &min);
GetDataMax(EditDesc, &max);
EditVal.Val32U--;
if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = max;
GetDataItem(EditDesc, EditBuf, EditVal.Val32U);
}
else
{
if (EditDesc->Type == DATA_TYPE_ULONG)
{
EditBuf[EditPos]--;
if (EditBuf[EditPos] < '0') EditBuf[EditPos] = '9';
}
else if (EditDesc->Type == DATA_TYPE_TIME)
{
EditBuf[EditTimePos[EditPos]]--;
if (EditBuf[EditTimePos[EditPos]] < '0') EditBuf[EditTimePos[EditPos]] = '9';
}
else if (EditDesc->Type == DATA_TYPE_HOUR_MIN)
{
EditBuf[EditTimePos[EditPos]]--;
if (EditBuf[EditTimePos[EditPos]] < '0') EditBuf[EditTimePos[EditPos]] = '9';
}
}
break;
case KEY_LEFT:
if (EditDesc->IsIndex)
{
CPU_INT32U min, max;
GetDataMin(EditDesc, &min);
GetDataMax(EditDesc, &max);
EditVal.Val32U--;
if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = max;
GetDataItem(EditDesc, EditBuf, EditVal.Val32U);
}
else
{
if (EditPos) EditPos--;
}
break;
case KEY_RIGHT:
if (EditDesc->IsIndex)
{
CPU_INT32U min, max;
GetDataMin(EditDesc, &min);
GetDataMax(EditDesc, &max);
EditVal.Val32U++;
if ((EditVal.Val32U < min) || (EditVal.Val32U > max)) EditVal.Val32U = min;
GetDataItem(EditDesc, EditBuf, EditVal.Val32U);
}
else
{
if (EditPos < EditLen-1) EditPos++;
}
break;
case KEY_STOP:
EscEdit();
break;
case KEY_START:
SaveEdit();
break;
}//switch (key)
ShowCurrentMenu();
}//if (key)
else
{
pause = 0;
ShowCurrentMenu();
}
}//if (!MenuEditStatus)
}
}
}
void InitMenu(void)
{
MenuStackPtr = 0;
MenuActiveLine = 0;
MenuFirstLine = 0;
MenuEditStatus = 0;
MenuCurrentPanel = NULL;
memset(&MenuStack, 0, sizeof(TMenuStack)*STACKPANELSIZE);
OSTaskCreate(MenuTask, (void *)0, (OS_STK *)&MenuTaskStk[MENU_TASK_STK_SIZE-1], MENU_TASK_PRIO);
}
void ReInitMenu(void)
{
OSTaskDel(MENU_TASK_PRIO);
ClearDisplay();
OSTimeDly(100);
InitMenu();
OSTimeDly(100);
if (GetMode() == MODE_WORK) SetMenu(WORK_MENU);
else SetMenu(SERVICE_MENU);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Project>
<Desktop>
<Static>
<Debug-Log>
<PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows><Window><Factory>Find-in-Files</Factory></Window><Window><Factory>Breakpoints</Factory></Window></Windows></PreferedWindows><ColumnWidth0>20</ColumnWidth0><ColumnWidth1>1222</ColumnWidth1></Debug-Log>
<Build>
<ColumnWidth0>20</ColumnWidth0><ColumnWidth1>916</ColumnWidth1><ColumnWidth2>244</ColumnWidth2><ColumnWidth3>61</ColumnWidth3><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows><Window><Factory>Debug-Log</Factory></Window><Window><Factory>Breakpoints</Factory></Window><Window><Factory>Find-in-Files</Factory></Window></Windows></PreferedWindows></Build>
<Workspace>
<ColumnWidths>
<Column0>372</Column0><Column1>27</Column1><Column2>27</Column2><Column3>27</Column3></ColumnWidths>
</Workspace>
<Disassembly>
<PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><MixedMode>1</MixedMode><CodeCovShow>0</CodeCovShow><InstrProfShow>0</InstrProfShow><col-names><item>Disassembly</item><item>_I0</item></col-names><col-widths><item>500</item><item>20</item></col-widths><DisasmHistory/><ShowCodeCoverage>0</ShowCodeCoverage><ShowInstrProfiling>0</ShowInstrProfiling></Disassembly>
<Watch>
<Format>
<struct_types><Fmt><Key>TRangeValueULONG-Max</Key><Value>3</Value></Fmt><Fmt><Key>TVariant32-Val32U</Key><Value>4</Value></Fmt></struct_types>
<watch_formats><Fmt><Key>{W}Watch-0:state</Key><Value>4</Value></Fmt><Fmt><Key>{W}Watch-0:ulIndex</Key><Value>3</Value></Fmt></watch_formats>
</Format>
<PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><Column0>139</Column0><Column1>313</Column1><Column2>100</Column2><Column3>100</Column3></Watch>
<QuickWatch><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><Column0>100</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3><col-names><item>Expression</item><item>Location</item><item>Type</item><item>Value</item></col-names><col-widths><item>233</item><item>150</item><item>100</item><item>237</item></col-widths><QWatchHistory><item>FiscFullStatus</item><item>FiscShortStatus</item></QWatchHistory></QuickWatch><Find-in-Files><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows><Window><Factory>Debug-Log</Factory></Window><Window><Factory>Breakpoints</Factory></Window></Windows></PreferedWindows><ColumnWidth0>350</ColumnWidth0><ColumnWidth1>50</ColumnWidth1><ColumnWidth2>601</ColumnWidth2></Find-in-Files><TerminalIO><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><InputSource>1</InputSource><InputMode>10</InputMode><Filename>$PROJ_DIR$\TermIOInput.txt</Filename><InputEcho>1</InputEcho><ShowReset>0</ShowReset></TerminalIO><Memory><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><FindDirection>1</FindDirection><FindAsHex>0</FindAsHex></Memory><Breakpoints><PreferedWindows><Position>3</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows><Window><Factory>Debug-Log</Factory></Window><Window><Factory>Find-in-Files</Factory></Window></Windows></PreferedWindows></Breakpoints><Statics><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows><Window><Factory>Locals</Factory></Window></Windows></PreferedWindows><Column0>100</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3></Statics><Locals><PreferedWindows><Position>2</Position><ScreenPosX>0</ScreenPosX><ScreenPosY>0</ScreenPosY><Windows/></PreferedWindows><Column0>100</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3><col-names><item>Location</item><item>Type</item><item>Value</item><item>Variable</item></col-names><col-widths><item>150</item><item>100</item><item>181</item><item>168</item></col-widths></Locals></Static>
<Windows>
<Wnd1>
<Tabs>
<Tab>
<Identity>TabID-16311-17664</Identity>
<TabName>Workspace</TabName>
<Factory>Workspace</Factory>
<Session>
<NodeDict><ExpandedNode>solarium</ExpandedNode><ExpandedNode>solarium/DRIVERS</ExpandedNode><ExpandedNode>solarium/DRIVERS/modem</ExpandedNode><ExpandedNode>solarium/PROJECT</ExpandedNode><ExpandedNode>solarium/PROJECT/app</ExpandedNode><ExpandedNode>solarium/PROJECT/data</ExpandedNode><ExpandedNode>solarium/PROJECT/menu</ExpandedNode><ExpandedNode>solarium/PROJECT/service</ExpandedNode></NodeDict></Session>
</Tab>
</Tabs>
<SelectedTab>0</SelectedTab></Wnd1><Wnd3><Tabs><Tab><Identity>TabID-23366-6968</Identity><TabName>Debug Log</TabName><Factory>Debug-Log</Factory><Session/></Tab><Tab><Identity>TabID-1787-14946</Identity><TabName>Breakpoints</TabName><Factory>Breakpoints</Factory></Tab><Tab><Identity>TabID-31768-15979</Identity><TabName>Find in Files</TabName><Factory>Find-in-Files</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd3><Wnd4><Tabs><Tab><Identity>TabID-4750-16799</Identity><TabName>Locals</TabName><Factory>Locals</Factory><Session><Column0>100</Column0><Column1>100</Column1><Column2>100</Column2><Column3>100</Column3></Session></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd4><Wnd8><Tabs><Tab><Identity>TabID-25216-28894</Identity><TabName>Disassembly</TabName><Factory>Disassembly</Factory><Session/></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd8><Wnd9><Tabs><Tab><Identity>TabID-6501-5953</Identity><TabName>Quick Watch</TabName><Factory>QuickWatch</Factory></Tab></Tabs><SelectedTab>0</SelectedTab></Wnd9></Windows>
<Editor>
<Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\OS\app\app.c</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>590</SelStart><SelEnd>590</SelEnd></Tab><ActiveTab>0</ActiveTab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>
<Positions>
<Top><Row0><Sizes><Toolbar-00dee448><key>iaridepm.enu1</key></Toolbar-00dee448></Sizes></Row0><Row1><Sizes><Toolbar-00e47910><key>debuggergui.enu1</key></Toolbar-00e47910></Sizes></Row1></Top><Left><Row0><Sizes><Wnd1><Rect><Top>-2</Top><Left>-2</Left><Bottom>643</Bottom><Right>467</Right><x>-2</x><y>-2</y><xscreen>300</xscreen><yscreen>278</yscreen><sizeHorzCX>156250</sizeHorzCX><sizeHorzCY>283673</sizeHorzCY><sizeVertCX>244271</sizeVertCX><sizeVertCY>658163</sizeVertCY></Rect></Wnd1></Sizes></Row0></Left><Right><Row0><Sizes><Wnd9><Rect><Top>-2</Top><Left>-2</Left><Bottom>242</Bottom><Right>677</Right><x>-2</x><y>-2</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>104167</sizeHorzCX><sizeHorzCY>204082</sizeHorzCY><sizeVertCX>353646</sizeVertCX><sizeVertCY>248980</sizeVertCY></Rect></Wnd9><Wnd8><Rect><Top>0</Top><Left>0</Left><Bottom>0</Bottom><Right>0</Right><x>-2</x><y>240</y><xscreen>200</xscreen><yscreen>200</yscreen><sizeHorzCX>104167</sizeHorzCX><sizeHorzCY>204082</sizeHorzCY><sizeVertCX>353646</sizeVertCX><sizeVertCY>205102</sizeVertCY></Rect></Wnd8><Wnd4><Rect><Top>0</Top><Left>0</Left><Bottom>0</Bottom><Right>0</Right><x>-2</x><y>439</y><xscreen>375</xscreen><yscreen>368</yscreen><sizeHorzCX>195313</sizeHorzCX><sizeHorzCY>375510</sizeHorzCY><sizeVertCX>353646</sizeVertCX><sizeVertCY>208163</sizeVertCY></Rect></Wnd4></Sizes></Row0></Right><Bottom><Row0><Sizes><Wnd3><Rect><Top>-2</Top><Left>-2</Left><Bottom>265</Bottom><Right>1922</Right><x>-2</x><y>-2</y><xscreen>1924</xscreen><yscreen>267</yscreen><sizeHorzCX>1002083</sizeHorzCX><sizeHorzCY>272449</sizeHorzCY><sizeVertCX>156250</sizeVertCX><sizeVertCY>272449</sizeVertCY></Rect></Wnd3></Sizes></Row0></Bottom><Float><Sizes/></Float></Positions>
</Desktop>
</Project>

View File

@ -0,0 +1,37 @@
#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_
// êíîïêè íå íàæàòû
#define KEY_EMPTY 0
// êíîïêè êëàâèàòóðû
#define KEY_F1 1
#define KEY_F2 2
#define KEY_F3 3
#define KEY_LEFT 4
#define KEY_UP 5
#define KEY_RIGHT 6
#define KEY_STOP 7
#define KEY_DOWN 8
#define KEY_START 9
// êíîïêà ïîëüçîâàòåëÿ
#define KEY_USER_START 10
// êíîïêè îòëîæåííîãî ñòàðòà
#define KEY_DEFERRED_CH1 11
#define KEY_DEFERRED_CH2 12
#define KEY_DEFERRED_CH3 13
#define KEY_DEFERRED_CH4 14
#define KEY_DEFERRED_CH5 15
#define KEY_DEFERRED_CH6 16
#define KEY_DEFERRED_CH7 17
#define KEY_DEFERRED_CH8 18
#define KEY_DEFERRED_CH9 19
#define KEY_DEFERRED_CH10 20
#define KEY_COUNT 21
extern void InitKbrd();
extern int GetKbrdEvent(int* event);
#endif //#ifndef _KEYBOARD_H_

View File

@ -0,0 +1,170 @@
#include "iolpc2368.h"
#include "ucos_ii.h"
#include "cpu.h"
#include "app_serv.h"
#include "coin.h"
#include "data.h"
#include "datadesc.h"
#include "modem.h"
OS_STK CoinTaskStk[COIN_TASK_STK_SIZE];
void InitImpInput(void);
CPU_INT32U CoinImpCounter;
void CoinTask(void *p_arg)
{
while(1)
{
CPU_INT32U enable_coin;
OSTimeDly(100);
GetData(&EnableCoinDesc, &enable_coin, 0, DATA_FLAG_SYSTEM_INDEX);
if (enable_coin)
{
if (GetCoinCount())
{
PostUserEvent(EVENT_COIN_INSERTED);
}
}
else
{
CoinDisable();
GetResetCoinCount();
}
}
}
void CoinDisable(void)
{
CPU_INT32U enable;
GetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX);
if (enable) FIO0SET_bit.P0_24 = 1;
}
void CoinEnable(void)
{
CPU_INT32U enable;
GetData(&EnableCoinDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX);
if (enable) FIO0CLR_bit.P0_24 = 1;
}
// ïîëó÷èòü ÷èñëî ìîíåò
CPU_INT32U GetCoinCount(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
CPU_INT32U ctr = CoinImpCounter;
OS_EXIT_CRITICAL();
return ctr;
}
// ïîëó÷èòü ÷èñëî ìîíåò è ñáðîñèòü ñ÷åò÷èê
CPU_INT32U GetResetCoinCount(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
CPU_INT32U ctr = CoinImpCounter;
CoinImpCounter = 0;
OS_EXIT_CRITICAL();
return ctr;
}
// èíèöèàëèçàöèÿ ìîíåòîïðèåìíèêà
void InitCoin(void)
{
CoinImpCounter = 0;
InitImpInput();
OSTaskCreate(CoinTask, (void *)0, (OS_STK *)&CoinTaskStk[COIN_TASK_STK_SIZE-1], COIN_TASK_PRIO);
}
void InputCapture_ISR(void)
{
CPU_INT08U ir = T3IR;
static CPU_INT32U period = 0;
T3IR = 0xFF;
if (ir & 0x10)
{// CR0 interrupt
if (FIO0PIN_bit.P0_23)
{// ïðèøåë çàäíèé ôðîíò
CPU_INT32U cr=T3CR0;
if (((cr-period) > COIN_IMP_MIN_LEN)
&& ((cr-period) < COIN_IMP_MAX_LEN))
CoinImpCounter++;
}
else
{// ïðèøåë ïåðåäíèé ôðîíò
period = T3CR0;
}
}
}
extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk);
/*
P0.23 MK_P9 IMPULSE OUTPUT (èìïóëüñíûé âûõîä ìîíåòîïðèåìíèêà)
P0.24 MK_P8 INHIBIT (áëîêèðîâêà)
*/
// èíèöèàëèçàöèÿ èìïóëüñíîãî âõîäà
// èñïîëüçóåòñÿ CAP3.0
void InitImpInput (void)
{
#define INPUT_CAPTURE_FREQ 100000 // ÷àñòîòà òàêòèðîâàíèÿ ÷àñòîòíûõ âõîäîâ
CPU_INT32U pclk_freq;
CPU_INT32U rld_cnts;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
PINSEL1_bit.P0_24 = 0x0;
PINMODE1_bit.P0_24 = 0;
FIO0DIR_bit.P0_24 = 1;
FIO0MASK_bit.P0_24 = 0;
FIO0SET_bit.P0_24 = 1; // çàïðåòèì ïîêà
PCONP_bit.PCTIM3 = 1;
PCLKSEL1_bit.PCLK_TIMER3 = 2;
PINSEL1_bit.P0_23 = 0x3;
PINMODE1_bit.P0_23 = 0;
FIO0DIR_bit.P0_23 = 0;
FIO0MASK_bit.P0_23 = 0;
pclk_freq = BSP_CPU_PclkFreq(23);
rld_cnts = pclk_freq / INPUT_CAPTURE_FREQ;
T3CTCR_bit.CTM = 0;
T3CTCR_bit.CIS = 0; // select CAP3.0 input
T3PR = rld_cnts-1;
T3MCR = 0;
T3CCR = 0x07;
T3EMR = 0;
T3TCR = 0x03;
T3TCR = 0x01;
VICINTSELECT &= ~(1 << VIC_TIMER3);
VICVECTADDR27 = (CPU_INT32U)InputCapture_ISR;
VICVECTPRIORITY27 = 10;
VICINTENABLE = (1 << VIC_TIMER3);
T3IR = 0xFF;
OS_EXIT_CRITICAL();
}

View File

@ -0,0 +1,15 @@
#ifndef _UART0_H_
#define _UART0_H_
extern void Uart0_Send(unsigned char *buf, int len);
extern int Uart0_Receive(unsigned char *buf, int len, int timeout);
extern void Uart0_Init(CPU_INT32U baud_rate);
extern void Uart0_WrByte(CPU_INT08U tx_byte);
extern void Uart0_Flush(void);
extern int Uart0_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout);
extern int Uart0_Ready();
extern int Uart0_Gotc(void);
extern int Uart0_Getc(void);
extern int Uart0_Putc(unsigned char ch);
#endif //#ifndef _UART0_H_

View File

@ -0,0 +1,462 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/LIB in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to
* help you experience uC/LIB. The fact that the source code is provided
* does NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* STANDARD MEMORY OPERATIONS
*
* Filename : lib_mem.c
* Version : V1.24
* Programmer(s) : ITJ
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* INCLUDE FILES
*********************************************************************************************************
*/
#define LIB_MEM_MODULE
#include <lib_mem.h>
/*$PAGE*/
/*
*********************************************************************************************************
* LOCAL DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL TABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* LOCAL CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_Clr()
*
* Description : Clear data buffer (see Note #2).
*
* Argument(s) : pmem Pointer to memory buffer to clear.
*
* size Number of data buffer octets to clear.
*
* Return(s) : none.
*
* Caller(s) : various.
*
* Note(s) : (1) Null clears allowed (i.e. 0-octet size).
*
* See also 'Mem_Set() Note #1'.
*
* (2) Clear data by setting each data octet to 0.
*********************************************************************************************************
*/
void Mem_Clr (void *pmem,
CPU_SIZE_T size)
{
Mem_Set((void *)pmem,
(CPU_INT08U)0, /* See Note #2. */
(CPU_SIZE_T)size);
}
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_Set()
*
* Description : Fill data buffer with specified data octet.
*
* Argument(s) : pmem Pointer to memory buffer to fill with specified data octet.
*
* data_val Data fill octet value.
*
* size Number of data buffer octets to fill.
*
* Return(s) : none.
*
* Caller(s) : various.
*
* Note(s) : (1) Null sets allowed (i.e. 0-octet size).
*
* (2) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words.
*
* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on
* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses.
*
* (3) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
* address boundary.
*
* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus,
* address values MUST be cast to an appropriately-sized integer value PRIOR to any
* mem_align_modulo arithmetic operation.
*********************************************************************************************************
*/
void Mem_Set (void *pmem,
CPU_INT08U data_val,
CPU_SIZE_T size)
{
CPU_SIZE_T size_rem;
CPU_ALIGN data_align;
CPU_ALIGN *pmem_align;
CPU_INT08U *pmem_08;
CPU_INT08U mem_align_modulo;
CPU_INT08U i;
if (size < 1) { /* See Note #1. */
return;
}
if (pmem == (void *)0) {
return;
}
data_align = 0;
for (i = 0; i < sizeof(CPU_ALIGN); i++) { /* Fill each data_align octet with data val. */
data_align <<= DEF_OCTET_NBR_BITS;
data_align |= (CPU_ALIGN)data_val;
}
size_rem = (CPU_SIZE_T)size;
mem_align_modulo = (CPU_INT08U)((CPU_ADDR)pmem % sizeof(CPU_ALIGN)); /* See Note #3. */
pmem_08 = (CPU_INT08U *)pmem;
if (mem_align_modulo != 0) { /* If leading octets avail, ... */
i = mem_align_modulo;
while ((size_rem > 0) && /* ... start mem buf fill with leading octets ... */
(i < sizeof(CPU_ALIGN ))) { /* ... until next CPU_ALIGN word boundary. */
*pmem_08++ = data_val;
size_rem -= sizeof(CPU_INT08U);
i++;
}
}
pmem_align = (CPU_ALIGN *)pmem_08; /* See Note #2a. */
while (size_rem >= sizeof(CPU_ALIGN)) { /* While mem buf aligned on CPU_ALIGN word boundaries, */
*pmem_align++ = data_align; /* ... fill mem buf with CPU_ALIGN-sized data. */
size_rem -= sizeof(CPU_ALIGN);
}
pmem_08 = (CPU_INT08U *)pmem_align;
while (size_rem > 0) { /* Finish mem buf fill with trailing octets. */
*pmem_08++ = data_val;
size_rem -= sizeof(CPU_INT08U);
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_Copy()
*
* Description : Copy data octets from one buffer to another buffer.
*
* Argument(s) : pdest Pointer to destination memory buffer.
*
* psrc Pointer to source memory buffer.
*
* size Number of data buffer octets to copy.
*
* Return(s) : none.
*
* Caller(s) : various.
*
* Note(s) : (1) Null copies allowed (i.e. 0-octet size).
*
* (2) Memory buffers NOT checked for overlapping.
*
* (3) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words.
*
* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on
* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses.
*
* (4) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
* address boundary.
*
* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus,
* address values MUST be cast to an appropriately-sized integer value PRIOR to any
* mem_align_modulo arithmetic operation.
*********************************************************************************************************
*/
/*$PAGE*/
#if ((!defined(uC_CFG_OPTIMIZE_ASM_EN)) || \
((defined(uC_CFG_OPTIMIZE_ASM_EN)) && \
(uC_CFG_OPTIMIZE_ASM_EN != DEF_ENABLED)))
void Mem_Copy (void *pdest,
void *psrc,
CPU_SIZE_T size)
{
CPU_SIZE_T size_rem;
CPU_ALIGN *pmem_align_dest;
CPU_ALIGN *pmem_align_src;
CPU_INT08U *pmem_08_dest;
CPU_INT08U *pmem_08_src;
CPU_INT08U i;
CPU_INT08U mem_align_modulo_dest;
CPU_INT08U mem_align_modulo_src;
CPU_BOOLEAN mem_aligned;
if (size < 1) { /* See Note #1. */
return;
}
if (pdest == (void *)0) {
return;
}
if (psrc == (void *)0) {
return;
}
size_rem = (CPU_SIZE_T )size;
pmem_08_dest = (CPU_INT08U *)pdest;
pmem_08_src = (CPU_INT08U *)psrc;
/* See Note #4. */
mem_align_modulo_dest = (CPU_INT08U )((CPU_ADDR)pmem_08_dest % sizeof(CPU_ALIGN));
mem_align_modulo_src = (CPU_INT08U )((CPU_ADDR)pmem_08_src % sizeof(CPU_ALIGN));
mem_aligned = (mem_align_modulo_dest == mem_align_modulo_src) ? DEF_YES : DEF_NO;
if (mem_aligned == DEF_YES) { /* If mem bufs' alignment offset equal, ... */
/* ... optimize copy for mem buf alignment. */
if (mem_align_modulo_dest != 0) { /* If leading octets avail, ... */
i = mem_align_modulo_dest;
while ((size_rem > 0) && /* ... start mem buf copy with leading octets ... */
(i < sizeof(CPU_ALIGN ))) { /* ... until next CPU_ALIGN word boundary. */
*pmem_08_dest++ = *pmem_08_src++;
size_rem -= sizeof(CPU_INT08U);
i++;
}
}
pmem_align_dest = (CPU_ALIGN *)pmem_08_dest; /* See Note #3a. */
pmem_align_src = (CPU_ALIGN *)pmem_08_src;
while (size_rem >= sizeof(CPU_ALIGN)) { /* While mem bufs aligned on CPU_ALIGN word boundaries, */
*pmem_align_dest++ = *pmem_align_src++; /* ... copy psrc to pdest with CPU_ALIGN-sized words. */
size_rem -= sizeof(CPU_ALIGN);
}
pmem_08_dest = (CPU_INT08U *)pmem_align_dest;
pmem_08_src = (CPU_INT08U *)pmem_align_src;
}
while (size_rem > 0) { /* For unaligned mem bufs or trailing octets, ... */
*pmem_08_dest++ = *pmem_08_src++; /* ... copy psrc to pdest by octets. */
size_rem -= sizeof(CPU_INT08U);
}
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* Mem_Cmp()
*
* Description : Verify that ALL data octets in two memory buffers are identical in sequence.
*
* Argument(s) : p1_mem Pointer to first memory buffer.
*
* p2_mem Pointer to second memory buffer.
*
* size Number of data buffer octets to compare.
*
* Return(s) : DEF_YES, if 'size' number of data octets are identical in both memory buffers.
*
* DEF_NO, otherwise.
*
* Caller(s) : various.
*
* Note(s) : (1) Null compares allowed (i.e. 0-octet size); 'DEF_YES' returned to indicate identical
* null compare.
*
* (2) Many memory buffer comparisons vary ONLY in the least significant octets -- e.g.
* network address buffers. Consequently, memory buffer comparison is more efficient
* if the comparison starts from the end of the memory buffers which will abort sooner
* on dissimilar memory buffers that vary only in the least significant octets.
*
* (3) For best CPU performance, optimized to fill data buffer using 'CPU_ALIGN'-sized data words.
*
* (a) Since many word-aligned processors REQUIRE that multi-octet words be accessed on
* word-aligned addresses, 'CPU_ALIGN'd words MUST be accessed on 'CPU_ALIGN'd addresses.
*
* (4) Modulo arithmetic is used to determine whether a memory buffer starts on a 'CPU_ALIGN'
* address boundary.
*
* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus,
* address values MUST be cast to an appropriately-sized integer value PRIOR to any
* mem_align_modulo arithmetic operation.
********************************************************************************************************
*/
/*$PAGE*/
CPU_BOOLEAN Mem_Cmp (void *p1_mem,
void *p2_mem,
CPU_SIZE_T size)
{
CPU_SIZE_T size_rem;
CPU_ALIGN *p1_mem_align;
CPU_ALIGN *p2_mem_align;
CPU_INT08U *p1_mem_08;
CPU_INT08U *p2_mem_08;
CPU_INT08U i;
CPU_INT08U mem_align_modulo_1;
CPU_INT08U mem_align_modulo_2;
CPU_BOOLEAN mem_aligned;
CPU_BOOLEAN mem_cmp;
if (size < 1) { /* See Note #1. */
return (DEF_YES);
}
if (p1_mem == (void *)0) {
return (DEF_NO);
}
if (p2_mem == (void *)0) {
return (DEF_NO);
}
mem_cmp = DEF_YES;
size_rem = size;
/* Start @ end of mem bufs (see Note #2). */
p1_mem_08 = (CPU_INT08U *)p1_mem + size;
p2_mem_08 = (CPU_INT08U *)p2_mem + size;
/* See Note #4. */
mem_align_modulo_1 = (CPU_INT08U )((CPU_ADDR)p1_mem_08 % sizeof(CPU_ALIGN));
mem_align_modulo_2 = (CPU_INT08U )((CPU_ADDR)p2_mem_08 % sizeof(CPU_ALIGN));
mem_aligned = (mem_align_modulo_1 == mem_align_modulo_2) ? DEF_YES : DEF_NO;
if (mem_aligned == DEF_YES) { /* If mem bufs' alignment offset equal, ... */
/* ... optimize cmp for mem buf alignment. */
if (mem_align_modulo_1 != 0) { /* If trailing octets avail, ... */
i = mem_align_modulo_1;
while ((mem_cmp == DEF_YES) && /* ... cmp mem bufs while identical & ... */
(size_rem > 0) && /* ... start mem buf cmp with trailing octets ... */
(i > 0)) { /* ... until next CPU_ALIGN word boundary. */
p1_mem_08--;
p2_mem_08--;
if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */
mem_cmp = DEF_NO;
}
size_rem -= sizeof(CPU_INT08U);
i--;
}
}
if (mem_cmp == DEF_YES) { /* If cmp still identical, cmp aligned mem bufs. */
p1_mem_align = (CPU_ALIGN *)p1_mem_08; /* See Note #3a. */
p2_mem_align = (CPU_ALIGN *)p2_mem_08;
while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical & ... */
(size_rem >= sizeof(CPU_ALIGN))) { /* ... mem bufs aligned on CPU_ALIGN word boundaries. */
p1_mem_align--;
p2_mem_align--;
if (*p1_mem_align != *p2_mem_align) { /* If ANY data octet(s) NOT identical, cmp fails. */
mem_cmp = DEF_NO;
}
size_rem -= sizeof(CPU_ALIGN);
}
p1_mem_08 = (CPU_INT08U *)p1_mem_align;
p2_mem_08 = (CPU_INT08U *)p2_mem_align;
}
}
while ((mem_cmp == DEF_YES) && /* Cmp mem bufs while identical ... */
(size_rem > 0)) { /* ... for unaligned mem bufs or trailing octets. */
p1_mem_08--;
p2_mem_08--;
if (*p1_mem_08 != *p2_mem_08) { /* If ANY data octet(s) NOT identical, cmp fails. */
mem_cmp = DEF_NO;
}
size_rem -= sizeof(CPU_INT08U);
}
return (mem_cmp);
}

View File

@ -0,0 +1,186 @@
#ifndef _DATADESC_H_
#define _DATADESC_H_
#include "data.h"
#include "control.h"
#define INCAS_SEND_FLAG 0x87654321
#define MAX_PRICE 9999
#define DEFAULT_PASSWORD 1111
#define MASTER_PASSWORD 11300045//1234567890L
// ñòðóêòóðà êîíôèãóðàöèè êàíàëîâ
typedef struct{
// âêëþ÷åíèå êàíàëà
CPU_INT32U Enable[CHANNELS_NUM];
// òàéì-àóò ïåðåä âêëþ÷åíèåì, ñåê.
CPU_INT32U TimeOutBefore[CHANNELS_NUM];
// òàéì-àóò ïîñëå âûêëþ÷åíèÿ, ìèí.
CPU_INT32U TimeOutAfter[CHANNELS_NUM];
// ìàêñèìàëüíîå âðåìÿ ðàáîòû, ìèí.
CPU_INT32U MaxWorkTime[CHANNELS_NUM];
// ìèíèìàëüíîå âðåìÿ ðàáîòû, ìèí.
CPU_INT32U MinWorkTime[CHANNELS_NUM];
// íàñòðîéêà óèêåíäà, èíäåêñ
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
// íàçâàíèå êàíàëà
CPU_INT32U Name[CHANNELS_NUM];
// ïåðèîäû
#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];
// öåíû
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];
CPU_INT32U PriceTime_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM];
}TChannelConfig;
// ñòðóêòóðà êîíôèãóðàöèè àïïàðàòóðû
typedef struct{
CPU_INT32U EnableValidator;
CPU_INT32U EnableCoinAcceptor;
CPU_INT32U EnableModem;
CPU_INT32U EnableFiscal;
CPU_INT32U EnableFiscalDayClear;
CPU_INT32U ServiceName;
CPU_INT32U CoinPerPulse; // öåíà èìïóëüñà ìîíåòîïðèåìíèêà
CPU_INT32U BillFormat;
CPU_INT32U DisableFiscalErrors; // îòêëþ÷åíèå ðåàêöèè íà îøèáêè ÔÐ
CPU_INT32U EnableEmailErrorSend;
CPU_INT32U EnableEmailStatSend;
CPU_INT32U EnableEmailJournalSend;
CPU_INT32U ClearJournalAfterSend;
CPU_INT32U StatSendHourMin;
CPU_INT32U DeviceId;
}TDeviceConfig;
extern CPU_INT32U PeriodIndex;
extern CPU_INT32U ChannelIndex;
extern TDataDescStruct const DeviceIDDesc;
extern TDataDescStruct const LastEmailSendTime;
extern TDataDescStruct const ChannelIndexDesc;
extern TDataDescStruct const EnableChannelDesc;
extern TDataDescStruct const TimeOutBeforeDesc;
extern TDataDescStruct const TimeOutAfterDesc;
extern TDataDescStruct const MaxWorkTimeDesc;
extern TDataDescStruct const MinWorkTimeDesc;
extern TDataDescStruct const WeekEndDesc;
extern TDataDescStruct const PeriodWeekendIndexDesc;
extern TDataDescStruct const PeriodWeekdaysIndexDesc;
extern TDataDescStruct const ServiceNameDesc;
extern TDataDescStruct const PassDesc;
extern TDataDescStruct const PassCRCDesc;
extern TDataDescStruct const PassTempDesc;
extern CPU_INT32U TempPass;
extern TDataDescStruct const PassTempDesc1;
extern TDataDescStruct const PassTempDesc2;
extern TDataDescStruct const PriceWeekendDesc;
extern TDataDescStruct const PriceWeekdaysDesc;
extern TDataDescStruct const PriceTimeWeekendDesc;
extern TDataDescStruct const PriceTimeWeekdaysDesc;
extern TDataDescStruct const T_Start_WeekdaysDesc;
extern TDataDescStruct const T_End_WeekdaysDesc;
extern TDataDescStruct const T_Start_WeekendDesc;
extern TDataDescStruct const T_End_WeekendDesc;
extern TDataDescStruct const EnableFiscalDesc;
extern TDataDescStruct const EnableCoinDesc;
extern TDataDescStruct const EnableModemDesc;
extern TDataDescStruct const EnableValidatorDesc;
extern TDataDescStruct const CoinPerPulseDesc;
extern TDataDescStruct const EnableFiscalDayClearDesc;
extern TDataDescStruct const InitByDefaultDesc;
extern TDataDescStruct const PrintZReportDesc;
extern TDataDescStruct const PrintXReportDesc;
extern TDataDescStruct const ErrorJournalIndexDesc;
extern TDataDescStruct const EventJournalIndexDesc;
extern TDataDescStruct const JournalEventTimeDesc;
extern TDataDescStruct const JournalErrorNumberDesc0;
extern TDataDescStruct const JournalErrorNumberDesc1;
extern TDataDescStruct const JournalErrorTimeDesc;
extern TDataDescStruct const ClearJournalCmdDesc;
extern TDataDescStruct const SystemTimeDesc;
extern TDataDescStruct const SystemTimeEditDesc;
extern const TDataDescArrayStruct AllDataArray[];
extern CPU_INT32U ErrorJournalIndex;
extern CPU_INT32U EventJournalIndex;
extern TDataDescStruct const CounterRunDesc;
extern TDataDescStruct const CounterMoneyDesc;
extern TDataDescStruct const CounterTimeDesc;
extern TDataDescStruct const CounterChannelRunDesc;
extern TDataDescStruct const CounterChannelMoneyDesc;
extern TDataDescStruct const CounterChannelTimeDesc;
extern TDataDescStruct const ChannelStIndexDesc;
extern TDataDescStruct const ClearStatCmdDesc;
extern TDataDescStruct const BillFormatDesc;
extern TDataDescStruct const NameChannelDesc;
extern TDataDescStruct const AcceptedMoneyDesc;
extern TDataDescStruct const AcceptedMoneyCRC16Desc;
extern TDataDescStruct const DisableFiscalErrorsDesc;
extern TDataDescStruct const EnableEmailErrorSendDesc;
extern TDataDescStruct const EnableEmailJournalSendDesc;
extern TDataDescStruct const ClearJournalAfterSendDesc;
extern TDataDescStruct const StatSendPeriodDesc;
extern TDataDescStruct const JournalErrorNumberDescEng;
extern TDataDescStruct const SendTestEmailDesc;
extern TDataDescStruct const ModemStatusDesc;
extern TDataDescStruct const BillnomIndexDesc;
extern TDataDescStruct const BillnomDesc;
extern TDataDescStruct const BillnomCountersDesc;
extern TDataDescStruct const BillCounterDesc;
extern TDataDescStruct const CounterLongRunDesc;
extern TDataDescStruct const CounterLongMoneyDesc;
extern TDataDescStruct const CounterLongTimeDesc;
extern TDataDescStruct const MasterPassTempDesc;
extern TDataDescStruct const CounterChannelRunLongDesc;
extern TDataDescStruct const CounterChannelMoneyLongDesc;
extern TDataDescStruct const CounterChannelTimeLongDesc;
extern TDataDescStruct const ChannelStLongIndexDesc;
extern TDataDescStruct const StatSendHourMinDesc;
extern TDataDescStruct const IncasSendFlagDesc;
extern TDataDescStruct const IncasMoneyDesc;
extern TDataDescStruct const IncasTimeDesc;
#endif //#ifndef _DATADESC_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,161 @@
#include <includes.h>
#include "spi.h"
#include "fram.h"
void Write_ON(unsigned short address)
{
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_WRITE_ON);
spi_unselectChip(FM25_SPI);
}
void Write_OFF(unsigned short address)
{
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_WRITE_OFF);
spi_unselectChip(FM25_SPI);
}
void Write_Status_Register(unsigned char byte, unsigned short address)
{
spi_getSem();
Write_ON(address);
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_WRITE_STATUS);
SpiExchange(FM25_SPI, byte);
spi_unselectChip(FM25_SPI);
spi_freeSem();
}
void WriteArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array)
{
unsigned short i;
spi_getSem();
Write_ON(uAddress);
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_WRITE);
SpiExchange(FM25_SPI, (char)(uAddress >> 8));
SpiExchange(FM25_SPI, (char)uAddress);
for(i=0;i<uBytesNumber;i++)
{
SpiExchange(FM25_SPI, *(Array+i));
}
spi_unselectChip(FM25_SPI);
Write_OFF(uAddress);
spi_freeSem();
}
// çàïèñü îäíîãî è òîãî æå áàéòà â ìàññèâ àäðåñîâ ôðàì
void SetArrayFram(unsigned short uAddress, unsigned short uBytesNumber, unsigned char byte)
{
unsigned short i;
spi_getSem();
Write_ON(uAddress);
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_WRITE);
SpiExchange(FM25_SPI, (char)(uAddress >> 8));
SpiExchange(FM25_SPI, (char)uAddress);
for(i=0;i<uBytesNumber;i++)
{
SpiExchange(FM25_SPI, byte);
}
spi_unselectChip(FM25_SPI);
Write_OFF(uAddress);
spi_freeSem();
}
void WriteByteFram(unsigned short adress,unsigned char byte)
{
spi_getSem();
Write_ON(adress);
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_WRITE);
SpiExchange(FM25_SPI, (char)(adress >> 8));
SpiExchange(FM25_SPI, (char)adress);
SpiExchange(FM25_SPI, byte);
spi_unselectChip(FM25_SPI);
Write_OFF(adress);
spi_freeSem();
}
unsigned char Read_Status_Register(unsigned short adress)
{
unsigned char temp = 0;
spi_getSem();
Write_OFF(adress);
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_READ_STATUS);
temp = SpiExchange(FM25_SPI, 0x00);
spi_unselectChip(FM25_SPI);
spi_freeSem();
return temp;
}
void ReadArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array)
{
unsigned short i;
spi_getSem();
Write_OFF(uAddress);
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_READ);
SpiExchange(FM25_SPI, (char)(uAddress >> 8));
SpiExchange(FM25_SPI, (char)uAddress);
for(i=0;i<uBytesNumber;i++)
{
*(Array + i) = SpiExchange(FM25_SPI, 0xFF);
}
spi_unselectChip(FM25_SPI);
spi_freeSem();
}
unsigned char ReadByteFram(unsigned short adress)
{
unsigned char temp = 0;
spi_getSem();
Write_OFF(adress);
spi_selectChip(FM25_SPI);
SpiExchange(FM25_SPI, FRAM_READ);
SpiExchange(FM25_SPI, (char)(adress >> 8));
SpiExchange(FM25_SPI, (char)adress);
temp = SpiExchange(FM25_SPI, 0xFF);
spi_unselectChip(FM25_SPI);
spi_freeSem();
return temp;
}
void WriteFullControl(void)
{
}

View File

@ -0,0 +1,279 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/LIB in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to
* help you experience uC/LIB. The fact that the source code is provided
* does NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* ASCII STRING MANAGEMENT
*
* Filename : lib_str.h
* Version : V1.24
* Programmer(s) : ITJ
* JDH
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*********************************************************************************************************
*/
#ifndef LIB_STR_MODULE_PRESENT
#define LIB_STR_MODULE_PRESENT
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*
* Note(s) : (1) The following common software files are located in the following directories :
*
* (a) \<Custom Library Directory>\lib*.*
*
* (b) (1) \<CPU-Compiler Directory>\cpu_def.h
*
* (2) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (2) Compiler MUST be configured to include the '\<Custom Library Directory>\uC-LIB\',
* '\<CPU-Compiler Directory>\' directory, & the specific CPU-compiler directory as
* additional include path directories.
*
* (3) NO compiler-supplied standard library functions SHOULD be used.
*
* #### The reference to standard library header files SHOULD be removed once all custom
* library functions are implemented WITHOUT reference to ANY standard library function(s).
*
* See also 'STANDARD LIBRARY MACRO'S Note #1'.
*********************************************************************************************************
*/
#include <cpu.h>
#include <lib_def.h>
#include <app_cfg.h>
/* See Note #3. */
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
/*
*********************************************************************************************************
* EXTERNS
*********************************************************************************************************
*/
#ifdef LIB_STR_MODULE
#define LIB_STR_EXT
#else
#define LIB_STR_EXT extern
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* DEFAULT CONFIGURATION
*********************************************************************************************************
*/
#ifndef LIB_STR_CFG_FP_EN
#define LIB_STR_CFG_FP_EN DEF_DISABLED
#endif
/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/
#define LIB_STR_NULL ((CPU_CHAR *)0)
#define LIB_STR_CMP_IDENTICAL 0
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* MACRO'S
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* STANDARD LIBRARY MACRO'S
*
* Note(s) : (1) NO compiler-supplied standard library functions SHOULD be used.
*
* #### The reference to standard memory functions SHOULD be removed once all custom library
* functions are implemented WITHOUT reference to ANY standard library function(s).
*
* See also 'INCLUDE FILES Note #3'.
*********************************************************************************************************
*/
/* See Note #1. */
#define Str_IsAlpha(a) isalpha(a)
#define Str_IsDigit(a) isdigit(a)
#define Str_IsSpace(a) isspace(a)
#define Str_IsPrint(a) isprint(a)
#define Str_IsUpper(a) isupper(a)
#define Str_IsLower(a) islower(a)
#define Str_ToUpper(a) toupper(a)
#define Str_ToLower(a) tolower(a)
#define Str_ToLong(a, b, c) strtol((char *)a, (char **)b, c)
#define Str_FmtPrint snprintf
#define Str_FmtScan sscanf
/*$PAGE*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
CPU_SIZE_T Str_Len (CPU_CHAR *pstr);
CPU_CHAR *Str_Copy (CPU_CHAR *pdest,
CPU_CHAR *psrc);
CPU_CHAR *Str_Copy_N (CPU_CHAR *pdest,
CPU_CHAR *psrc,
CPU_SIZE_T len_max);
CPU_CHAR *Str_Cat (CPU_CHAR *pdest,
CPU_CHAR *pstr_cat);
CPU_CHAR *Str_Cat_N (CPU_CHAR *pdest,
CPU_CHAR *pstr_cat,
CPU_SIZE_T len_max);
CPU_INT16S Str_Cmp (CPU_CHAR *p1_str,
CPU_CHAR *p2_str);
CPU_INT16S Str_Cmp_N (CPU_CHAR *p1_str,
CPU_CHAR *p2_str,
CPU_SIZE_T len_max);
CPU_CHAR *Str_Char (CPU_CHAR *pstr,
CPU_CHAR srch_char);
CPU_CHAR *Str_Char_N (CPU_CHAR *pstr,
CPU_SIZE_T len_max,
CPU_CHAR srch_char);
CPU_CHAR *Str_Char_Last(CPU_CHAR *pstr,
CPU_CHAR srch_char);
CPU_CHAR *Str_Str (CPU_CHAR *pstr,
CPU_CHAR *srch_str);
#if (LIB_STR_CFG_FP_EN == DEF_ENABLED)
CPU_CHAR *Str_FmtNbr_32(CPU_FP32 nbr,
CPU_INT08U nbr_dig,
CPU_INT08U nbr_dp,
CPU_BOOLEAN lead_zeros,
CPU_BOOLEAN nul,
CPU_CHAR *pstr_fmt);
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
#ifndef LIB_STR_CFG_FP_EN
#error "LIB_STR_CFG_FP_EN not #define'd in 'app_cfg.h'"
#error " [MUST be DEF_DISABLED] "
#error " [ || DEF_ENABLED ] "
#elif ((LIB_STR_CFG_FP_EN != DEF_DISABLED) && \
(LIB_STR_CFG_FP_EN != DEF_ENABLED ))
#error "LIB_STR_CFG_FP_EN illegally #define'd in 'app_cfg.h'"
#error " [MUST be DEF_DISABLED] "
#error " [ || DEF_ENABLED ] "
#endif
/*
*********************************************************************************************************
* MODULE END
*********************************************************************************************************
*/
#endif /* End of lib str module include. */

View File

@ -0,0 +1,11 @@
#ifndef _UART1_H_
#define _UART1_H_
extern void Uart1_Purge(void);
extern void Uart1_Send(unsigned char *buf, int len);
extern int Uart1_Receive(unsigned char *buf, int len, int timeout);
extern void Uart1_WrByte(CPU_INT08U tx_byte);
extern int Uart1_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout);
extern void Uart1_Init(CPU_INT32U baud_rate);
#endif //#ifndef _UART0_H_

View File

@ -0,0 +1,179 @@
#ifndef _JOURNAL_H_
#define _JOURNAL_H_
#include "control.h"
#include "fiscal.h"
#define ERROR_RECORDS_NUM 256 // ÷èñëî çàïèñåé â æóðíàëå
#define EVENT_RECORDS_NUM 256 // ÷èñëî çàïèñåé â æóðíàëå
// ñòðóêòóðà çàïèñè ñèñòåìíîãî æóðíàëà
typedef struct{
CPU_INT32U time;
// òèï îøèáêè, ïîêà àêñèìóì 256 îøèáîê
CPU_INT32U error;
// íåò îøèáêè
#define ERROR_EMPTY 0
// îøèáêà ñâÿçè ñ êóïþðíèêîì
#define ERROR_VALIDATOR_CONN 1
// êðèòè÷åñêàÿ îøèáêà ðàáîòû êóïþðíèêà
#define ERROR_VALIDATOR_FAILURE 2
// íåêðèòè÷åñêèå îøèáêè êóïþðîïðèåìíèêà
// Âûáðîñ êóïþðû ïðè çàìèíå
#define ERROR_VALIDATOR_INSERTION 3
// Âûáðîñ êóïþðû ïî ìàã.äàò÷èêó
#define ERROR_VALIDATOR_MAGNETIC 4
// Âûáðîñ êóïþðû ïðè òðàíñïîðòèðîâêå
#define ERROR_VALIDATOR_CONVEYING 5
// Âûáðîñ êóïþðû ïî èäåíòèôèêàöèè
#define ERROR_VALIDATOR_IDENT 6
// Âûáðîñ êóïþðû ïî âåðèôèêàöèè
#define ERROR_VALIDATOR_VRFY 7
// Âûáðîñ êóïþðû ïî îïòè÷.äàò÷èêó
#define ERROR_VALIDATOR_OPT 8
// Âûáðîñ êóïþðû ïî çàïðåòó
#define ERROR_VALIDATOR_INHIBIT 9
// Âûáðîñ êóïþðû ïî åìêîñòíîìó äàò÷èêó
#define ERROR_VALIDATOR_CAP 10
// Âûáðîñ êóïþðû ïî äëèíå
#define ERROR_VALIDATOR_LNG 11
// Êàññåòà çàïîëíåíà
#define ERROR_STACKER_FULL 12
// Êàññåòà îòñóòñòâóåò
#define ERROR_STACKER_REMOVED 13
// Çàìèí â êóïþðîïðèåìíèêå
#define ERROR_BV_JAMMED 14
// Çàìèí â êàññåòå
#define ERROR_ST_JAMMED 15
// Ïîïûòêà îáìàíà
#define ERROR_CHEATED 16
// Îøèáêà ñòåêåðíîãî ìîòîðà
#define ERROR_FLR_STACKER 17
// Îøèáêà ñêîðîñòè òðàíñïîðò.ìîòîðà
#define ERROR_TR_SPEED 18
// Îøèáêà òðàíñïîðò.ìîòîðà
#define ERROR_FLR_TRANSPORT 19
// Îøèáêà ìåõàíèçìà âûðàâíèâàíèÿ
#define ERROR_FLR_ALIGNIN 20
// Êàññåòà îòñóòñòâóåò
#define ERROR_FLR_INIT_CAS 21
// Îøèáêà îïòèêè
#define ERROR_FLR_OPT 22
// Îøèáêà ìàã.äàò÷èêà
#define ERROR_FLR_MAG 23
// Îøèáêà åìêîñòíîãî äàò÷èêà
#define ERROR_FLR_CAP 24
// îøèáêà ñâÿçè ñ ìîäåìîì
#define ERROR_MODEM_CONN 25
// îøèáêà ñâÿçè ñ ôèñêàëüíèêîì
#define ERROR_FR_CONN 26
// ÂÑÅ ÎØÈÁÊÈ ÔÐ ÔÀÒÀËÜÍÛÅ
#define ERROR_FR 27
#define ERRORS_NUM (ERROR_FR+FR_ERROR_NUMBER)
}TErrorRecord;
// ñòðóêòóðà çàïèñè æóðíàëà ðàáî÷èõ ñîáûòèé
typedef struct{
// âðåìÿ ñîçäàíèÿ çàïèñè
CPU_INT32U time;
// äàííûå: äëÿ ïîëó÷åíèÿ äåíåã - íîìèíàë êóïþðû, äëÿ ñåàíñà - äëèòåëüíîñòü îïëà÷åííîãî âðåìåíè, ìèí.
CPU_INT32U data;
// òèï ñîáûòèÿ
CPU_INT08U event;
#define JOURNAL_EVENT_NO_EVENT 0 // íåò ñîáûòèÿ
#define JOURNAL_EVENT_MONEY_NOTE 1 // ñîáûòèå ïîëó÷åíèÿ êóïþðû
#define JOURNAL_EVENT_MONEY_COIN 2 // ñîáûòèå ïîëó÷åíèÿ ìîíåòû (êîë-âî ðóáëåé)
#define JOURNAL_EVENT_START_SESSION 3 // ñîáûòèå íà÷àëà ñåàíñà
#define JOURNAL_EVENT_END_SESSION 4 // ñîáûòèå êîíöà ñåàíñà
#define JOURNAL_EVENT_DEVICE_ON 6 // âêëþ÷åíèå óñòðîéñòâà
#define JOURNAL_EVENT_PRINT_BILL 7 // ïå÷àòü ÷åêà
#define JOURNAL_EVENT_PRINT_Z 8 // ïå÷àòü z-îò÷åòà
#define JOURNAL_EVENT_PRINT_X 9 // ïå÷àòü x-îò÷åòà
#define JOURNAL_EVENT_PRINT_BUF 10 // ïå÷àòü x-îò÷åòà
#define JOURNAL_EVENT_CHANGE_MODE 11 // ñìåíà ðåæèìà
#define JOURNAL_EVENT_INCASSATION 12 // èíêàññàöèÿ
#define JOURNAL_EVENT_PASS_FAIL 13 // íåâåðíûé ââîä ïàðîëÿ
#define JOURNAL_EVENT_EMAIL_OK 14 // ïðàâèëüíî îòïðàâëåí email
#define JOURNAL_EVENT_EMAIL_FAIL 15 // îøèáêà ïðè îòïðàâêå email
#define JOURNAL_EVENTS_NUM 16 // ÷èñëî ñîáûòèé
// êàíàë
CPU_INT08U channel;
}TEventRecord;
// ñòðóêòóðà äëÿ õðàíåíèÿ ñ÷åò÷èêîâ
typedef struct{
// ÷èñëî çàïóñêîâ ïîêàíàëüíî
CPU_INT32U CounterChannelRun[CHANNELS_NUM];
// Ñóììàðíîå âðåìÿ ðàáîòû ïîêàíàëüíî, ñåê.
CPU_INT32U CounterChannelTime[CHANNELS_NUM];
// Ñóììà äåíåã ïîêàíàëüíî
CPU_INT32U CounterChannelMoney[CHANNELS_NUM];
// îáùåå ÷èñëî çàïóñêîâ
CPU_INT32U CounterRun;
// îáùåå Ñóììàðíîå âðåìÿ ðàáîòû, ñåê.
CPU_INT32U CounterTime;
// îáùåå Ñóììà äåíåã
CPU_INT32U CounterMoney;
// ñ÷åò÷èêè êóïþð â êóïþðíèêå ïî íîìèíàëàì
CPU_INT32U CounterBillNominals[24];
// îáùèé ñ÷åò÷èê êóïþð (âñåãî â êàññåòå)
CPU_INT32U BillsCount;
}TCounters;
// ñòðóêòóðà äëÿ õðàíåíèÿ äëèííûõ ñ÷åò÷èêîâ
// âåäåì ïîêà òîëüêî ýòè òðè äëèííûõ
typedef struct{
// ÷èñëî çàïóñêîâ ïîêàíàëüíî
CPU_INT32U CounterChannelRunLong[CHANNELS_NUM];
// Ñóììàðíîå âðåìÿ ðàáîòû ïîêàíàëüíî, ñåê.
CPU_INT32U CounterChannelTimeLong[CHANNELS_NUM];
// Ñóììà äåíåã ïîêàíàëüíî
CPU_INT32U CounterChannelMoneyLong[CHANNELS_NUM];
CPU_INT32U CounterRunLong;
CPU_INT32U CounterTimeLong;
CPU_INT32U CounterMoneyLong;
CPU_INT16U crc;
}TCountersLong;
extern CPU_INT32U GetShortMoney();
extern void IncBillnomCounter(CPU_INT32U index);
extern void CheckLongCounters(void);
extern void SaveErrorRecord(CPU_INT32U error);
extern void SaveEventRecord(CPU_INT08U channel, CPU_INT08U event, CPU_INT32U data);
extern void SetErrorFlag(CPU_INT08U error);
extern void ClrErrorFlag(CPU_INT08U error);
extern int TstErrorFlag(CPU_INT08U error);
extern int TstCriticalErrors(void);
extern void ClearErrorJournal(void);
extern void ClearEventJournal(void);
extern void GetEventStr(char* str, char event);
extern int GetEventRecord(TEventRecord* record, CPU_INT32U index);
extern int GetErrorRecord(TErrorRecord* record, CPU_INT32U index);
extern void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money);
extern void ClearCounters(void);
extern void ErrorServer(void);
extern int TstCriticalValidatorErrors(void);
extern void ClrValidatorErrors(void);
extern void PrintEventJournalRecordEng(char* str, TEventRecord *record);
extern void GetEventStrEng(char* str, char event);
extern void ClearBillnomCounter(void);
#endif //#ifndef _JOURNAL_H_

View File

@ -0,0 +1,328 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/CPU in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to
* help you experience uC/CPU. The fact that the source code is provided
* does NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU PORT FILE
*
* ARM
* IAR C Compiler
*
* Filename : cpu.h
* Version : V1.17
* Programmer(s) : ITJ
* JJL
* JDH
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*********************************************************************************************************
*/
#ifndef CPU_CFG_MODULE_PRESENT
#define CPU_CFG_MODULE_PRESENT
/*
*********************************************************************************************************
* CPU INCLUDE FILES
*
* Note(s) : (1) The following CPU files are located in the following directories :
*
* (a) \<CPU-Compiler Directory>\cpu_def.h
*
* (b) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (2) Compiler MUST be configured to include the '\<CPU-Compiler Directory>\' directory & the
* specific CPU-compiler directory as additional include path directories.
*********************************************************************************************************
*/
#include <cpu_def.h>
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURE STANDARD DATA TYPES
*
* Note(s) : (1) Configure standard data types according to CPU-/compiler-specifications.
*
* (2) (a) (1) 'CPU_FNCT_VOID' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has no arguments.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_VOID FnctName;
*
* FnctName();
*
* (b) (1) 'CPU_FNCT_PTR' data type defined to replace the commonly-used function pointer
* data type of a pointer to a function which returns void & has a single void
* pointer argument.
*
* (2) Example function pointer usage :
*
* CPU_FNCT_PTR FnctName;
* void *pobj
*
* FnctName(pobj);
*********************************************************************************************************
*/
typedef void CPU_VOID;
typedef unsigned char CPU_CHAR; /* 8-bit character */
typedef unsigned char CPU_BOOLEAN; /* 8-bit boolean or logical */
typedef unsigned char CPU_INT08U; /* 8-bit unsigned integer */
typedef signed char CPU_INT08S; /* 8-bit signed integer */
typedef unsigned short CPU_INT16U; /* 16-bit unsigned integer */
typedef signed short CPU_INT16S; /* 16-bit signed integer */
typedef unsigned int CPU_INT32U; /* 32-bit unsigned integer */
typedef signed int CPU_INT32S; /* 32-bit signed integer */
typedef float CPU_FP32; /* 32-bit floating point */
typedef double CPU_FP64; /* 64-bit floating point */
typedef unsigned long long CPU_INT64U; /* 64-bit unsigned integer */
typedef void (*CPU_FNCT_VOID)(void); /* See Note #2a. */
typedef void (*CPU_FNCT_PTR )(void *); /* See Note #2b. */
/*$PAGE*/
/*
*********************************************************************************************************
* CPU WORD CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE with CPU's word sizes :
*
* CPU_WORD_SIZE_08 8-bit word size
* CPU_WORD_SIZE_16 16-bit word size
* CPU_WORD_SIZE_32 32-bit word size
* CPU_WORD_SIZE_64 64-bit word size See Note #1a
*
* (a) 64-bit word size NOT currently supported.
*
* (2) Configure CPU_CFG_ENDIAN_TYPE with CPU's data-word-memory order :
*
* CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant
* octet @ lowest memory address)
* CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant
* octet @ lowest memory address)
*********************************************************************************************************
*/
/* Define CPU word sizes (see Note #1) : */
#define CPU_CFG_ADDR_SIZE CPU_WORD_SIZE_32 /* Defines CPU address word size. */
#define CPU_CFG_DATA_SIZE CPU_WORD_SIZE_32 /* Defines CPU data word size. */
#define CPU_CFG_ENDIAN_TYPE CPU_ENDIAN_TYPE_LITTLE /* Defines CPU data word-memory order. */
/*
*********************************************************************************************************
* CONFIGURE CPU ADDRESS & DATA TYPES
*********************************************************************************************************
*/
/* CPU address type based on address bus size. */
#if (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_ADDR;
#elif (CPU_CFG_ADDR_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_ADDR;
#else
typedef CPU_INT08U CPU_ADDR;
#endif
/* CPU data type based on data bus size. */
#if (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_32)
typedef CPU_INT32U CPU_DATA;
#elif (CPU_CFG_DATA_SIZE == CPU_WORD_SIZE_16)
typedef CPU_INT16U CPU_DATA;
#else
typedef CPU_INT08U CPU_DATA;
#endif
typedef CPU_DATA CPU_ALIGN; /* Defines CPU data-word-alignment size. */
typedef CPU_DATA CPU_SIZE_T; /* Defines CPU standard 'size_t' size. */
/*$PAGE*/
/*
*********************************************************************************************************
* CRITICAL SECTION CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method :
*
* Enter/Exit critical sections by ...
*
* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts
* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack
* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable
*
* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support
* multiple levels of interrupts. However, with some CPUs/compilers, this is the only
* available method.
*
* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it DOES support multiple
* levels of interrupts. However, this method assumes that the compiler allows in-line
* assembly AND will correctly modify the local stack pointer when interrupt status is
* pushed/popped onto the stack.
*
* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it DOES support multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (a) Save interrupt status into a local variable
* (b) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (c) Restore interrupt status from a local variable
*
* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT
* allow inline assembly in C source files, critical section macro's MUST call an assembly
* subroutine defined in a 'cpu_a.asm' file located in the following software directory :
*
* \<CPU-Compiler Directory>\<cpu>\<compiler>\
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (3) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need to
* be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). Configure
* 'CPU_SR' data type with the appropriate-sized CPU data type large enough to completely
* store the CPU's/compiler's status word.
*********************************************************************************************************
*/
typedef CPU_INT32U CPU_SR; /* Defines CPU status register size (see Note #3). */
/* Configure CPU critical method (see Note #1) : */
#define CPU_CFG_CRITICAL_METHOD CPU_CRITICAL_METHOD_STATUS_LOCAL
#define CPU_CRITICAL_ENTER() { cpu_sr = CPU_SR_Save(); }
#define CPU_CRITICAL_EXIT() { CPU_SR_Restore(cpu_sr); }
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
CPU_SR CPU_SR_Save (void);
void CPU_SR_Restore(CPU_SR cpu_sr);
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
#ifndef CPU_CFG_ADDR_SIZE
#error "CPU_CFG_ADDR_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#elif ((CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_ADDR_SIZE != CPU_WORD_SIZE_32))
#error "CPU_CFG_ADDR_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#endif
#ifndef CPU_CFG_DATA_SIZE
#error "CPU_CFG_DATA_SIZE not #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#elif ((CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_08) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_16) && \
(CPU_CFG_DATA_SIZE != CPU_WORD_SIZE_32))
#error "CPU_CFG_DATA_SIZE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_WORD_SIZE_08 8-bit alignment]"
#error " [ || CPU_WORD_SIZE_16 16-bit alignment]"
#error " [ || CPU_WORD_SIZE_32 32-bit alignment]"
#endif
#ifndef CPU_CFG_ENDIAN_TYPE
#error "CPU_CFG_ENDIAN_TYPE not #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#elif ((CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_BIG ) && \
(CPU_CFG_ENDIAN_TYPE != CPU_ENDIAN_TYPE_LITTLE))
#error "CPU_CFG_ENDIAN_TYPE illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_ENDIAN_TYPE_BIG ]"
#error " [ || CPU_ENDIAN_TYPE_LITTLE]"
#endif
#ifndef CPU_CFG_CRITICAL_METHOD
#error "CPU_CFG_CRITICAL_METHOD not #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#elif ((CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_INT_DIS_EN ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_STK ) && \
(CPU_CFG_CRITICAL_METHOD != CPU_CRITICAL_METHOD_STATUS_LOCAL))
#error "CPU_CFG_CRITICAL_METHOD illegally #define'd in 'cpu.h' "
#error " [MUST be CPU_CRITICAL_METHOD_INT_DIS_EN ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_STK ]"
#error " [ || CPU_CRITICAL_METHOD_STATUS_LOCAL]"
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*********************************************************************************************************
*/
#endif /* End of CPU cfg module inclusion. */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,615 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/LIB in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to
* help you experience uC/LIB. The fact that the source code is provided
* does NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* STANDARD MEMORY OPERATIONS
*
* Filename : lib_mem.h
* Version : V1.24
* Programmer(s) : ITJ
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*********************************************************************************************************
*/
#ifndef LIB_MEM_MODULE_PRESENT
#define LIB_MEM_MODULE_PRESENT
/*$PAGE*/
/*
*********************************************************************************************************
* INCLUDE FILES
*
* Note(s) : (1) The following common software files are located in the following directories :
*
* (a) \<Custom Library Directory>\lib*.*
*
* (b) (1) \<CPU-Compiler Directory>\cpu_def.h
*
* (2) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (2) Compiler MUST be configured to include the '\<Custom Library Directory>\uC-LIB\',
* '\<CPU-Compiler Directory>\' directory, & the specific CPU-compiler directory as
* additional include path directories.
*
* (3) NO compiler-supplied standard library functions SHOULD be used.
*********************************************************************************************************
*/
#include <cpu.h>
#include <lib_def.h>
#include <app_cfg.h>
/*
*********************************************************************************************************
* EXTERNS
*********************************************************************************************************
*/
#ifdef LIB_MEM_MODULE
#define LIB_MEM_EXT
#else
#define LIB_MEM_EXT extern
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* DATA TYPES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* MACRO'S
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MEMORY DATA VALUE MACRO'S
*
* Note(s) : (1) (a) Some variables & variable buffers to pass & receive data values MUST start on appropriate
* CPU word-aligned addresses. This is required because most word-aligned processors are more
* efficient & may even REQUIRE that multi-octet words start on CPU word-aligned addresses.
*
* (1) For 16-bit word-aligned processors, this means that
*
* all 16- & 32-bit words MUST start on addresses that are multiples of 2 octets
*
* (2) For 32-bit word-aligned processors, this means that
*
* all 16-bit words MUST start on addresses that are multiples of 2 octets
* all 32-bit words MUST start on addresses that are multiples of 4 octets
*
* (b) However, some data values macro's appropriately access data values from any CPU addresses,
* word-aligned or not. Thus for processors that require data word alignment, data words can
* be accessed to/from any CPU address, word-aligned or not, without generating data-word-
* alignment exceptions/faults.
*********************************************************************************************************
*/
/*$PAGE*/
/*
*********************************************************************************************************
* MEM_VAL_GET_xxx()
*
* Description : Decode data values from any CPU memory address.
*
* Argument(s) : addr Lowest CPU memory address of data value to decode (see Notes #2 & #3a).
*
* Return(s) : Decoded data value from CPU memory address (see Notes #1 & #3b).
*
* Caller(s) : various.
*
* Note(s) : (1) Decode data values based on the values' data-word order in CPU memory :
*
* MEM_VAL_GET_xxx_BIG() Decode big- endian data values -- data words' most
* significant octet @ lowest memory address
* MEM_VAL_GET_xxx_LITTLE() Decode little-endian data values -- data words' least
* significant octet @ lowest memory address
* MEM_VAL_GET_xxx() Decode data values using CPU's native or configured
* data-word order
*
* See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
*
* (2) CPU memory addresses/pointers NOT checked for NULL.
*
* (3) (a) MEM_VAL_GET_xxx() macro's decode data values without regard to CPU word-aligned addresses.
* Thus for processors that require data word alignment, data words can be decoded from any
* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults.
*
* (b) However, any variable to receive the returned data value MUST start on an appropriate CPU
* word-aligned address.
*
* See also 'MEMORY DATA VALUE MACRO'S Note #1'.
*
* (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are
* also independent of CPU data-word-alignment & SHOULD be used whenever possible.
*
* See also 'MEM_VAL_COPY_GET_xxx() Note #4'.
*
* (5) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/
* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration
* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order
* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is
* included as an extra precaution in case 'cpu.h' is incorrectly configured.
*********************************************************************************************************
*/
#define MEM_VAL_GET_INT08U_BIG(addr) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS))
#define MEM_VAL_GET_INT16U_BIG(addr) ((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (1 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (0 * DEF_OCTET_NBR_BITS)))
#define MEM_VAL_GET_INT32U_BIG(addr) ((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (3 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (2 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (1 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (0 * DEF_OCTET_NBR_BITS)))
#define MEM_VAL_GET_INT08U_LITTLE(addr) (((CPU_INT08U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS))
#define MEM_VAL_GET_INT16U_LITTLE(addr) ((((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT16U)(*(((CPU_INT08U *)(addr)) + 1))) << (1 * DEF_OCTET_NBR_BITS)))
#define MEM_VAL_GET_INT32U_LITTLE(addr) ((((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 0))) << (0 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 1))) << (1 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 2))) << (2 * DEF_OCTET_NBR_BITS)) + \
(((CPU_INT32U)(*(((CPU_INT08U *)(addr)) + 3))) << (3 * DEF_OCTET_NBR_BITS)))
#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
#define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_BIG(addr)
#define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_BIG(addr)
#define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_BIG(addr)
#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE)
#define MEM_VAL_GET_INT08U(addr) MEM_VAL_GET_INT08U_LITTLE(addr)
#define MEM_VAL_GET_INT16U(addr) MEM_VAL_GET_INT16U_LITTLE(addr)
#define MEM_VAL_GET_INT32U(addr) MEM_VAL_GET_INT32U_LITTLE(addr)
#else /* See Note #5. */
#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' "
#error " [See 'cpu.h CONFIGURATION ERRORS']"
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MEM_VAL_SET_xxx()
*
* Description : Encode data values to any CPU memory address.
*
* Argument(s) : addr Lowest CPU memory address to encode data value (see Notes #2 & #3a).
*
* val Data value to encode (see Notes #1 & #3b).
*
* Return(s) : none.
*
* Caller(s) : various.
*
* Note(s) : (1) Encode data values into CPU memory based on the values' data-word order :
*
* MEM_VAL_SET_xxx_BIG() Encode big- endian data values -- data words' most
* significant octet @ lowest memory address
* MEM_VAL_SET_xxx_LITTLE() Encode little-endian data values -- data words' least
* significant octet @ lowest memory address
* MEM_VAL_SET_xxx() Encode data values using CPU's native or configured
* data-word order
*
* See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
*
* (2) CPU memory addresses/pointers NOT checked for NULL.
*
* (3) (a) MEM_VAL_SET_xxx() macro's encode data values without regard to CPU word-aligned addresses.
* Thus for processors that require data word alignment, data words can be encoded to any
* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults.
*
* (b) However, 'val' data value to encode MUST start on an appropriate CPU word-aligned address.
*
* See also 'MEMORY DATA VALUE MACRO'S Note #1'.
*
* (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are
* also independent of CPU data-word-alignment & SHOULD be used whenever possible.
*
* See also 'MEM_VAL_COPY_SET_xxx() Note #4'.
*
* (5) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/
* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration
* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order
* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is
* included as an extra precaution in case 'cpu.h' is incorrectly configured.
*********************************************************************************************************
*/
#define MEM_VAL_SET_INT08U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFF) >> (0 * DEF_OCTET_NBR_BITS))); }
#define MEM_VAL_SET_INT16U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00) >> (1 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FF) >> (0 * DEF_OCTET_NBR_BITS))); }
#define MEM_VAL_SET_INT32U_BIG(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000) >> (3 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000) >> (2 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00) >> (1 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FF) >> (0 * DEF_OCTET_NBR_BITS))); }
#define MEM_VAL_SET_INT08U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT08U)(val)) & 0xFF) >> (0 * DEF_OCTET_NBR_BITS))); }
#define MEM_VAL_SET_INT16U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0x00FF) >> (0 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT16U)(val)) & 0xFF00) >> (1 * DEF_OCTET_NBR_BITS))); }
#define MEM_VAL_SET_INT32U_LITTLE(addr, val) { (*(((CPU_INT08U *)(addr)) + 0)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x000000FF) >> (0 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 1)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x0000FF00) >> (1 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 2)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0x00FF0000) >> (2 * DEF_OCTET_NBR_BITS))); \
(*(((CPU_INT08U *)(addr)) + 3)) = ((CPU_INT08U)((((CPU_INT32U)(val)) & 0xFF000000) >> (3 * DEF_OCTET_NBR_BITS))); }
#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
#define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_BIG(addr, val)
#define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_BIG(addr, val)
#define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_BIG(addr, val)
#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE)
#define MEM_VAL_SET_INT08U(addr, val) MEM_VAL_SET_INT08U_LITTLE(addr, val)
#define MEM_VAL_SET_INT16U(addr, val) MEM_VAL_SET_INT16U_LITTLE(addr, val)
#define MEM_VAL_SET_INT32U(addr, val) MEM_VAL_SET_INT32U_LITTLE(addr, val)
#else /* See Note #5. */
#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' "
#error " [See 'cpu.h CONFIGURATION ERRORS']"
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MEM_VAL_COPY_GET_xxx()
*
* Description : Copy & decode data values from any CPU memory address to any CPU memory address.
*
* Argument(s) : addr_dest Lowest CPU memory address to copy/decode source address's data value
* (see Notes #2 & #3).
*
* addr_src Lowest CPU memory address of data value to copy/decode
* (see Notes #2 & #3).
*
* Return(s) : none.
*
* Caller(s) : various.
*
* Note(s) : (1) Copy/decode data values based on the values' data-word order :
*
* MEM_VAL_COPY_GET_xxx_BIG() Decode big- endian data values -- data words' most
* significant octet @ lowest memory address
* MEM_VAL_COPY_GET_xxx_LITTLE() Decode little-endian data values -- data words' least
* significant octet @ lowest memory address
* MEM_VAL_COPY_GET_xxx() Decode data values using CPU's native or configured
* data-word order
*
* See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
*
* (2) CPU memory addresses/pointers NOT checked for NULL.
*
* (3) MEM_VAL_COPY_GET_xxx() macro's copy/decode data values without regard to CPU word-aligned
* addresses. Thus for processors that require data word alignment, data words can be copied/
* decoded to/from any CPU address, word-aligned or not, without generating data-word-alignment
* exceptions/faults.
*
* (4) MEM_VAL_COPY_GET_xxx() macro's are more efficient than MEM_VAL_GET_xxx() macro's & are
* also independent of CPU data-word-alignment & SHOULD be used whenever possible.
*
* See also 'MEM_VAL_GET_xxx() Note #4'.
*
* (5) Since octet-order copy/conversion are inverse operations, memory data value gets/sets are
* inverse operations.
*
* See also 'MEM_VAL_COPY_SET_xxx() Note #5'.
*
* (6) The 'CPU_CFG_ENDIAN_TYPE' pre-processor 'else'-conditional code SHOULD never be compiled/
* linked since each 'cpu.h' SHOULD ensure that the CPU data-word-memory order configuration
* constant (CPU_CFG_ENDIAN_TYPE) is configured with an appropriate data-word-memory order
* value (see 'cpu.h CPU WORD CONFIGURATION Note #2'). The 'else'-conditional code is
* included as an extra precaution in case 'cpu.h' is incorrectly configured.
*********************************************************************************************************
*/
/*$PAGE*/
#if (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_BIG)
#define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); }
#define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
(*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
(*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); }
#define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
(*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
(*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src)
#define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src)
#define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src)
#elif (CPU_CFG_ENDIAN_TYPE == CPU_ENDIAN_TYPE_LITTLE)
#define MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 3)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
(*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
(*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); }
#define MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
(*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
(*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); }
#define MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src)
#define MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src)
#define MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src)
#else /* See Note #6. */
#error "CPU_CFG_ENDIAN_TYPE illegally #defined in 'cpu.h' "
#error " [See 'cpu.h CONFIGURATION ERRORS']"
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* MEM_VAL_COPY_SET_xxx()
*
* Description : Copy & encode data values from any CPU memory address to any CPU memory address.
*
* Argument(s) : addr_dest Lowest CPU memory address to copy/encode source address's data value
* (see Notes #2 & #3).
*
* addr_src Lowest CPU memory address of data value to copy/encode
* (see Notes #2 & #3).
*
* Return(s) : none.
*
* Caller(s) : various.
*
* Note(s) : (1) Copy/encode data values based on the values' data-word order :
*
* MEM_VAL_COPY_SET_xxx_BIG() Encode big- endian data values -- data words' most
* significant octet @ lowest memory address
* MEM_VAL_COPY_SET_xxx_LITTLE() Encode little-endian data values -- data words' least
* significant octet @ lowest memory address
* MEM_VAL_COPY_SET_xxx() Encode data values using CPU's native or configured
* data-word order
*
* See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
*
* (2) CPU memory addresses/pointers NOT checked for NULL.
*
* (3) MEM_VAL_COPY_SET_xxx() macro's copy/encode data values without regard to CPU word-aligned
* addresses. Thus for processors that require data word alignment, data words can be copied/
* encoded to/from any CPU address, word-aligned or not, without generating data-word-alignment
* exceptions/faults.
*
* (4) MEM_VAL_COPY_SET_xxx() macro's are more efficient than MEM_VAL_SET_xxx() macro's & are
* also independent of CPU data-word-alignment & SHOULD be used whenever possible.
*
* See also 'MEM_VAL_SET_xxx() Note #4'.
*
* (5) Since octet-order copy/conversion are inverse operations, memory data value gets/sets
* are inverse operations.
*
* See also 'MEM_VAL_COPY_GET_xxx() Note #5'.
*********************************************************************************************************
*/
/* See Note #5. */
#define MEM_VAL_COPY_SET_INT08U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_BIG(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT16U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_BIG(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT32U_BIG(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_BIG(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT08U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U_LITTLE(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT16U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U_LITTLE(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT32U_LITTLE(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U_LITTLE(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT08U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT08U(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT16U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT16U(addr_dest, addr_src)
#define MEM_VAL_COPY_SET_INT32U(addr_dest, addr_src) MEM_VAL_COPY_GET_INT32U(addr_dest, addr_src)
/*$PAGE*/
/*
*********************************************************************************************************
* MEM_VAL_COPY_xxx()
*
* Description : Copy data values from any CPU memory address to any CPU memory address.
*
* Argument(s) : addr_dest Lowest CPU memory address to copy source address's data value
* (see Notes #2 & #3).
*
* addr_src Lowest CPU memory address of data value to copy
* (see Notes #2 & #3).
*
* Return(s) : none.
*
* Caller(s) : various.
*
* Note(s) : (1) MEM_VAL_COPY_xxx() macro's copy data values based on CPU's native data-word order.
*
* See also 'cpu.h CPU WORD CONFIGURATION Note #2'.
*
* (2) CPU memory addresses/pointers NOT checked for NULL.
*
* (3) MEM_VAL_COPY_xxx() macro's copy data values without regard to CPU word-aligned addresses.
* Thus for processors that require data word alignment, data words can be copied to/from any
* CPU address, word-aligned or not, without generating data-word-alignment exceptions/faults.
*********************************************************************************************************
*/
#define MEM_VAL_COPY_08(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); }
#define MEM_VAL_COPY_16(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); }
#define MEM_VAL_COPY_32(addr_dest, addr_src) { (*(((CPU_INT08U *)(addr_dest)) + 0)) = (*(((CPU_INT08U *)(addr_src)) + 0)); \
(*(((CPU_INT08U *)(addr_dest)) + 1)) = (*(((CPU_INT08U *)(addr_src)) + 1)); \
(*(((CPU_INT08U *)(addr_dest)) + 2)) = (*(((CPU_INT08U *)(addr_src)) + 2)); \
(*(((CPU_INT08U *)(addr_dest)) + 3)) = (*(((CPU_INT08U *)(addr_src)) + 3)); }
/*$PAGE*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void Mem_Clr (void *pmem,
CPU_SIZE_T size);
void Mem_Set (void *pmem,
CPU_INT08U data_val,
CPU_SIZE_T size);
void Mem_Copy(void *pdest,
void *psrc,
CPU_SIZE_T size);
CPU_BOOLEAN Mem_Cmp (void *p1_mem,
void *p2_mem,
CPU_SIZE_T size);
/*$PAGE*/
/*
*********************************************************************************************************
* CONFIGURATION ERRORS
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE END
*********************************************************************************************************
*/
#endif /* End of lib mem module include. */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#ifndef _VMCCONSTS_H_
#define _VMCCONSTS_H_
#endif // _VMCCONSTS_H_

View File

@ -0,0 +1,270 @@
#include <includes.h>
#include "uart0.h"
#define UART0_RX_BUFSIZE 128
#define UART0_TX_BUFSIZE 64
unsigned char UART0TXBuffer[UART0_TX_BUFSIZE];
unsigned short UART0TXhead = 0;
unsigned short UART0TXtail = 0;
unsigned short UART0TXcount = 0;
unsigned char UART0RXBuffer[UART0_RX_BUFSIZE];
unsigned short UART0RXhead = 0;
unsigned short UART0RXtail = 0;
unsigned short UART0RXcount = 0;
void Uart0_Flush(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
UART0TXcount = UART0TXhead = UART0TXtail = 0;
UART0RXcount = UART0RXhead = UART0RXtail = 0;
U0IER_bit.THREIE = 0;
U0FCR = 0x06;
OS_EXIT_CRITICAL();
}
int Uart0_Getc(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = -1;
if (UART0RXcount > 0)
{
UART0RXcount--;
res = UART0RXBuffer[UART0RXhead++];
UART0RXhead %= UART0_RX_BUFSIZE;
}
OS_EXIT_CRITICAL();
return res;
}
int Uart0_Gotc(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = 0;
if (UART0RXcount > 0) res = 1;
OS_EXIT_CRITICAL();
return res;
}
int Uart0_Ready()
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = 0;
if (UART0TXcount < UART0_TX_BUFSIZE) res = 1;
OS_EXIT_CRITICAL();
return res;
}
int Uart0_Putc(unsigned char ch)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = 0;
if (UART0TXcount < UART0_TX_BUFSIZE)
{
if (UART0TXcount == 0)
{
if (U0LSR_bit.THRE)
{
U0THR = ch;
}
else
{
UART0TXcount++;
UART0TXBuffer[UART0TXtail++] = ch;
UART0TXtail %= UART0_TX_BUFSIZE;
U0IER = 3;
}
}
else
{
UART0TXcount++;
UART0TXBuffer[UART0TXtail++] = ch;
UART0TXtail %= UART0_TX_BUFSIZE;
U0IER = 3;
}
}
else
{
res = -1;
}
OS_EXIT_CRITICAL();
return res;
}
void Uart0_Isr(void)
{
CPU_INT08U IIRValue;
CPU_INT08U u1lsr;
volatile CPU_INT08U Dummy;
IIRValue = U0IIR;
IIRValue >>= 1; /* skip pending bit in IIR */
IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
if (IIRValue == 2) /* Receive Data Available */
{
/* Receive Data Available */
if (U0LSR_bit.DR)
{
if (UART0RXcount < UART0_RX_BUFSIZE)
{
UART0RXBuffer[UART0RXtail++] = U0RBR;
UART0RXtail %= UART0_RX_BUFSIZE;
UART0RXcount++;
}
else
{
Dummy = U0RBR;
}
}
}
else if (IIRValue == 1) /* THRE, transmit holding register empty */
{
/* THRE interrupt */
if (UART0TXcount > 0)
{
U0THR = UART0TXBuffer[UART0TXhead++];
UART0TXhead %= UART0_TX_BUFSIZE;
UART0TXcount--;
}
else
{
U0IER = 1;
}
}
else
{
Dummy = U0RBR;
u1lsr = U0LSR;
u1lsr = u1lsr;
}
}
void Uart0_Init(CPU_INT32U baud_rate)
{
float div_fp; /* Baud rate divisor floating point precision */
CPU_INT16U div_int; /* Baud rate divisor floating point precision */
CPU_INT08U divlo;
CPU_INT08U divhi;
CPU_INT32U pclk_freq;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
pclk_freq = BSP_CPU_PclkFreq(3); /* Get peripheral clock frequency */
div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */
div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */
divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */
divhi = (div_int >> 8) & 0x00FF;
PCONP_bit.PCUART2 = 1; /* Enable the power bit for UART0 */
U0IER = 0;
U0FCR = 0x06; // enable and reset fifo
U0ACR = 0;
//U1FCR = 0x01; // enable and reset fifo
U0LCR = 0x80; /* Enable acces to Divisor latches */
U0DLL = divlo; /* Load divisor */
U0DLM = divhi;
U0FDR = 0x10;
U0LCR = 0;
U0LCR_bit.WLS = 0x03; // 8 bit
U0LCR_bit.SBS = 0; // 1 stop bit
U0IER = 1;
PINSEL0_bit.P0_2 = 0x1;
PINSEL0_bit.P0_3 = 0x1;
PINMODE0_bit.P0_2 = 0;
PINMODE0_bit.P0_3 = 0;
FIO0DIR_bit.P0_2 = 1;
FIO0DIR_bit.P0_3 = 0;
FIO0MASK_bit.P0_2 = 1;
FIO0MASK_bit.P0_3 = 1;
VICINTSELECT &= ~(1 << VIC_UART0);
VICVECTADDR6 = (CPU_INT32U)Uart0_Isr;
VICINTENABLE = (1 << VIC_UART0);
Uart0_Flush();
OS_EXIT_CRITICAL();
}
void Uart0_WrByte(CPU_INT08U tx_byte)
{
while (Uart0_Putc(tx_byte) != 0) OSTimeDly(1);
}
void Uart0_Send(unsigned char *buf, int len)
{
while (len--) Uart0_WrByte(*buf++);
}
int Uart0_RdByteWithTimeOut(CPU_INT08U *byte, CPU_INT32U timeout)
{
CPU_INT32U ctr = 0;
int res = -1;
while (res < 0) {
res = Uart0_Getc();
if (res >= 0) break;
OSTimeDly(1);
if (ctr++ > timeout) return 0;
}
*byte = res;
return 1;
}
int Uart0_Receive(unsigned char *buf, int len, int timeout)
{
while (len--)
{
if (!Uart0_RdByteWithTimeOut(buf++, timeout)) return 0;
}
return 1;
}

View File

@ -0,0 +1,372 @@
#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;
GetData(&EnableValidatorDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX);
// îáðàáîòêà ñòàòóñà ñâÿçè
if (VConnStat == VCONN_STATUS_NOCONN)
{ // íåò ïîäêëþ÷åíèÿ
if (!enable)
{ // íå âêëþ÷åí
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;
}

View File

@ -0,0 +1,229 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
*
* (c) Copyright 1992-2007, Micrium, Weston, FL
* All Rights Reserved
*
* Generic ARM Port
*
* File : OS_CPU.H
* Version : V1.82
* By : Jean J. Labrosse
* Jean-Denis Hatier
*
* For : ARM7 or ARM9
* Mode : ARM or Thumb
* Toolchain : IAR's EWARM V4.11a and higher
*********************************************************************************************************
*/
#ifndef OS_CPU_H
#define OS_CPU_H
#ifdef OS_CPU_GLOBALS
#define OS_CPU_EXT
#else
#define OS_CPU_EXT extern
#endif
#ifndef OS_CPU_FPU_EN
#define OS_CPU_FPU_EN 0 /* HW floating point support disabled by default */
#endif
/*
*********************************************************************************************************
* INTERRUPT DISABLE TIME MEASUREMENT
*********************************************************************************************************
*/
#define OS_CPU_INT_DIS_MEAS_EN 0
/*
*********************************************************************************************************
* EXCEPTION DEFINES
*********************************************************************************************************
*/
/* ARM exception IDs */
#define OS_CPU_ARM_EXCEPT_RESET 0x00
#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR 0x01
#define OS_CPU_ARM_EXCEPT_SWI 0x02
#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT 0x03
#define OS_CPU_ARM_EXCEPT_DATA_ABORT 0x04
#define OS_CPU_ARM_EXCEPT_ADDR_ABORT 0x05
#define OS_CPU_ARM_EXCEPT_IRQ 0x06
#define OS_CPU_ARM_EXCEPT_FIQ 0x07
#define OS_CPU_ARM_EXCEPT_NBR 0x08
/* ARM exception vectors addresses */
#define OS_CPU_ARM_EXCEPT_RESET_VECT_ADDR (OS_CPU_ARM_EXCEPT_RESET * 0x04 + 0x00)
#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_VECT_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INSTR * 0x04 + 0x00)
#define OS_CPU_ARM_EXCEPT_SWI_VECT_ADDR (OS_CPU_ARM_EXCEPT_SWI * 0x04 + 0x00)
#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x00)
#define OS_CPU_ARM_EXCEPT_DATA_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x00)
#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_VECT_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x00)
#define OS_CPU_ARM_EXCEPT_IRQ_VECT_ADDR (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x00)
#define OS_CPU_ARM_EXCEPT_FIQ_VECT_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x00)
/* ARM exception handlers addresses */
#define OS_CPU_ARM_EXCEPT_RESET_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_RESET * 0x04 + 0x20)
#define OS_CPU_ARM_EXCEPT_UNDEF_INSTR_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_UNDEF_INSTR * 0x04 + 0x20)
#define OS_CPU_ARM_EXCEPT_SWI_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_SWI * 0x04 + 0x20)
#define OS_CPU_ARM_EXCEPT_PREFETCH_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_PREFETCH_ABORT * 0x04 + 0x20)
#define OS_CPU_ARM_EXCEPT_DATA_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_DATA_ABORT * 0x04 + 0x20)
#define OS_CPU_ARM_EXCEPT_ADDR_ABORT_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_ADDR_ABORT * 0x04 + 0x20)
#define OS_CPU_ARM_EXCEPT_IRQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_IRQ * 0x04 + 0x20)
#define OS_CPU_ARM_EXCEPT_FIQ_HANDLER_ADDR (OS_CPU_ARM_EXCEPT_FIQ * 0x04 + 0x20)
/* ARM "Jump To Self" assembled instruction */
#define OS_CPU_ARM_INSTR_JUMP_TO_SELF 0xEAFFFFFE
/* ARM "Jump To Exception Handler" assembled instruction*/
#define OS_CPU_ARM_INSTR_JUMP_TO_HANDLER 0xE59FF018
/*
*********************************************************************************************************
* DATA TYPES
* (Compiler Specific)
*********************************************************************************************************
*/
typedef unsigned char BOOLEAN;
typedef unsigned char INT8U; /* Unsigned 8 bit quantity */
typedef signed char INT8S; /* Signed 8 bit quantity */
typedef unsigned short INT16U; /* Unsigned 16 bit quantity */
typedef signed short INT16S; /* Signed 16 bit quantity */
typedef unsigned int INT32U; /* Unsigned 32 bit quantity */
typedef signed int INT32S; /* Signed 32 bit quantity */
typedef float FP32; /* Single precision floating point */
typedef double FP64; /* Double precision floating point */
typedef unsigned int OS_STK; /* Each stack entry is 32-bit wide */
typedef unsigned int OS_CPU_SR; /* Define size of CPU status register (PSR = 32 bits) */
/*
*********************************************************************************************************
* ARM
*
* Method #1: Disable/Enable interrupts using simple instructions. After critical section, interrupts
* will be enabled even if they were disabled before entering the critical section.
* NOT IMPLEMENTED
*
* Method #2: Disable/Enable interrupts by preserving the state of interrupts. In other words, if
* interrupts were disabled before entering the critical section, they will be disabled when
* leaving the critical section.
* NOT IMPLEMENTED
*
* Method #3: Disable/Enable interrupts by preserving the state of interrupts. Generally speaking you
* would store the state of the interrupt disable flag in the local variable 'cpu_sr' and then
* disable interrupts. 'cpu_sr' is allocated in all of uC/OS-II's functions that need to
* disable interrupts. You would restore the interrupt disable state by copying back 'cpu_sr'
* into the CPU's status register.
*********************************************************************************************************
*/
#define OS_CRITICAL_METHOD 3
#if OS_CRITICAL_METHOD == 3
#if OS_CPU_INT_DIS_MEAS_EN > 0
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save(); \
OS_CPU_IntDisMeasStart();}
#define OS_EXIT_CRITICAL() {OS_CPU_IntDisMeasStop(); \
OS_CPU_SR_Restore(cpu_sr);}
#else
#define OS_ENTER_CRITICAL() {cpu_sr = OS_CPU_SR_Save();}
#define OS_EXIT_CRITICAL() {OS_CPU_SR_Restore(cpu_sr);}
#endif
#endif
/*
*********************************************************************************************************
* ARM Miscellaneous
*********************************************************************************************************
*/
#define OS_STK_GROWTH 1 /* Stack grows from HIGH to LOW memory on ARM */
#define OS_TASK_SW() OSCtxSw()
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
/* Variables used to measure interrupt disable time */
#if OS_CPU_INT_DIS_MEAS_EN > 0
OS_CPU_EXT INT16U OS_CPU_IntDisMeasNestingCtr;
OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsEnter;
OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsExit;
OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsMax;
OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsDelta;
OS_CPU_EXT INT16U OS_CPU_IntDisMeasCntsOvrhd;
#endif
/*
*********************************************************************************************************
* PROTOTYPES
*********************************************************************************************************
*/
#if OS_CRITICAL_METHOD == 3
__arm OS_CPU_SR OS_CPU_SR_Save(void); /* See OS_CPU_A.ASM */
__arm void OS_CPU_SR_Restore(OS_CPU_SR cpu_sr);
#endif
__arm void OS_CPU_SR_INT_Dis(void);
__arm void OS_CPU_SR_INT_En(void);
__arm void OS_CPU_SR_FIQ_Dis(void);
__arm void OS_CPU_SR_FIQ_En(void);
__arm void OS_CPU_SR_IRQ_Dis(void);
__arm void OS_CPU_SR_IRQ_En(void);
#if OS_CPU_FPU_EN > 0
void OS_CPU_FP_Init(void); /* See OS_CPU_C.C */
__arm void OS_CPU_FP_Restore(void *pblk);
__arm void OS_CPU_FP_Save(void *pblk);
#endif
__arm void OSCtxSw(void);
__arm void OSIntCtxSw(void);
__arm void OSStartHighRdy(void);
void OS_CPU_InitExceptVect(void);
__arm void OS_CPU_ARM_ExceptResetHndlr(void);
__arm void OS_CPU_ARM_ExceptUndefInstrHndlr(void);
__arm void OS_CPU_ARM_ExceptSwiHndlr(void);
__arm void OS_CPU_ARM_ExceptPrefetchAbortHndlr(void);
__arm void OS_CPU_ARM_ExceptDataAbortHndlr(void);
__arm void OS_CPU_ARM_ExceptAddrAbortHndlr(void);
__arm void OS_CPU_ARM_ExceptIrqHndlr(void);
__arm void OS_CPU_ARM_ExceptFiqHndlr(void);
void OS_CPU_ExceptHndlr(INT32U except_type);
#if OS_CPU_INT_DIS_MEAS_EN > 0
void OS_CPU_IntDisMeasInit(void);
void OS_CPU_IntDisMeasStart(void);
void OS_CPU_IntDisMeasStop(void);
INT16U OS_CPU_IntDisMeasTmrRd(void);
#endif
#if OS_CPU_ARM_DCC_EN > 0
void OSDCC_Handler(void);
#endif
#endif

View File

@ -0,0 +1,268 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
* TIME MANAGEMENT
*
* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* File : OS_TIME.C
* By : Jean J. Labrosse
* Version : V2.85
*
* LICENSING TERMS:
* ---------------
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
* licensing fee.
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE
#include <ucos_ii.h>
#endif
/*
*********************************************************************************************************
* DELAY TASK 'n' TICKS (n from 0 to 65535)
*
* Description: This function is called to delay execution of the currently running task until the
* specified number of system ticks expires. This, of course, directly equates to delaying
* the current task for some time to expire. No delay will result If the specified delay is
* 0. If the specified delay is greater than 0 then, a context switch will result.
*
* Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'.
* Note that by specifying 0, the task will not be delayed.
*
* Returns : none
*********************************************************************************************************
*/
void OSTimeDly (INT16U ticks)
{
INT8U y;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSIntNesting > 0) { /* See if trying to call from an ISR */
return;
}
if (ticks > 0) { /* 0 means no delay! */
OS_ENTER_CRITICAL();
y = OSTCBCur->OSTCBY; /* Delay current task */
OSRdyTbl[y] &= ~OSTCBCur->OSTCBBitX;
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~OSTCBCur->OSTCBBitY;
}
OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
OS_EXIT_CRITICAL();
OS_Sched(); /* Find next task to run! */
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* DELAY TASK FOR SPECIFIED TIME
*
* Description: This function is called to delay execution of the currently running task until some time
* expires. This call allows you to specify the delay time in HOURS, MINUTES, SECONDS and
* MILLISECONDS instead of ticks.
*
* Arguments : hours specifies the number of hours that the task will be delayed (max. is 255)
* minutes specifies the number of minutes (max. 59)
* seconds specifies the number of seconds (max. 59)
* milli specifies the number of milliseconds (max. 999)
*
* Returns : OS_ERR_NONE
* OS_ERR_TIME_INVALID_MINUTES
* OS_ERR_TIME_INVALID_SECONDS
* OS_ERR_TIME_INVALID_MS
* OS_ERR_TIME_ZERO_DLY
* OS_ERR_TIME_DLY_ISR
*
* Note(s) : The resolution on the milliseconds depends on the tick rate. For example, you can't do
* a 10 mS delay if the ticker interrupts every 100 mS. In this case, the delay would be
* set to 0. The actual delay is rounded to the nearest tick.
*********************************************************************************************************
*/
#if OS_TIME_DLY_HMSM_EN > 0
INT8U OSTimeDlyHMSM (INT8U hours, INT8U minutes, INT8U seconds, INT16U ms)
{
INT32U ticks;
INT16U loops;
if (OSIntNesting > 0) { /* See if trying to call from an ISR */
return (OS_ERR_TIME_DLY_ISR);
}
#if OS_ARG_CHK_EN > 0
if (hours == 0) {
if (minutes == 0) {
if (seconds == 0) {
if (ms == 0) {
return (OS_ERR_TIME_ZERO_DLY);
}
}
}
}
if (minutes > 59) {
return (OS_ERR_TIME_INVALID_MINUTES); /* Validate arguments to be within range */
}
if (seconds > 59) {
return (OS_ERR_TIME_INVALID_SECONDS);
}
if (ms > 999) {
return (OS_ERR_TIME_INVALID_MS);
}
#endif
/* Compute the total number of clock ticks required.. */
/* .. (rounded to the nearest tick) */
ticks = ((INT32U)hours * 3600L + (INT32U)minutes * 60L + (INT32U)seconds) * OS_TICKS_PER_SEC
+ OS_TICKS_PER_SEC * ((INT32U)ms + 500L / OS_TICKS_PER_SEC) / 1000L;
loops = (INT16U)(ticks >> 16); /* Compute the integral number of 65536 tick delays */
ticks = ticks & 0xFFFFL; /* Obtain the fractional number of ticks */
OSTimeDly((INT16U)ticks);
while (loops > 0) {
OSTimeDly((INT16U)32768u);
OSTimeDly((INT16U)32768u);
loops--;
}
return (OS_ERR_NONE);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* RESUME A DELAYED TASK
*
* Description: This function is used resume a task that has been delayed through a call to either
* OSTimeDly() or OSTimeDlyHMSM(). Note that you can call this function to resume a
* task that is waiting for an event with timeout. This would make the task look
* like a timeout occurred.
*
* Also, you cannot resume a task that has called OSTimeDlyHMSM() with a combined time that
* exceeds 65535 clock ticks. In other words, if the clock tick runs at 100 Hz then, you will
* not be able to resume a delayed task that called OSTimeDlyHMSM(0, 10, 55, 350) or higher:
*
* (10 Minutes * 60 + 55 Seconds + 0.35) * 100 ticks/second.
*
* Arguments : prio specifies the priority of the task to resume
*
* Returns : OS_ERR_NONE Task has been resumed
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the maximum allowed
* (i.e. >= OS_LOWEST_PRIO)
* OS_ERR_TIME_NOT_DLY Task is not waiting for time to expire
* OS_ERR_TASK_NOT_EXIST The desired task has not been created or has been assigned to a Mutex.
*********************************************************************************************************
*/
#if OS_TIME_DLY_RESUME_EN > 0
INT8U OSTimeDlyResume (INT8U prio)
{
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3 /* Storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (prio >= OS_LOWEST_PRIO) {
return (OS_ERR_PRIO_INVALID);
}
OS_ENTER_CRITICAL();
ptcb = OSTCBPrioTbl[prio]; /* Make sure that task exist */
if (ptcb == (OS_TCB *)0) {
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
}
if (ptcb == OS_TCB_RESERVED) {
OS_EXIT_CRITICAL();
return (OS_ERR_TASK_NOT_EXIST); /* The task does not exist */
}
if (ptcb->OSTCBDly == 0) { /* See if task is delayed */
OS_EXIT_CRITICAL();
return (OS_ERR_TIME_NOT_DLY); /* Indicate that task was not delayed */
}
ptcb->OSTCBDly = 0; /* Clear the time delay */
if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
ptcb->OSTCBStat &= ~OS_STAT_PEND_ANY; /* Yes, Clear status flag */
ptcb->OSTCBStatPend = OS_STAT_PEND_TO; /* Indicate PEND timeout */
} else {
ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
}
if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */
OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make ready */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OS_EXIT_CRITICAL();
OS_Sched(); /* See if this is new highest priority */
} else {
OS_EXIT_CRITICAL(); /* Task may be suspended */
}
return (OS_ERR_NONE);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* GET CURRENT SYSTEM TIME
*
* Description: This function is used by your application to obtain the current value of the 32-bit
* counter which keeps track of the number of clock ticks.
*
* Arguments : none
*
* Returns : The current value of OSTime
*********************************************************************************************************
*/
#if OS_TIME_GET_SET_EN > 0
INT32U OSTimeGet (void)
{
INT32U ticks;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
ticks = OSTime;
OS_EXIT_CRITICAL();
return (ticks);
}
#endif
/*
*********************************************************************************************************
* SET SYSTEM CLOCK
*
* Description: This function sets the 32-bit counter which keeps track of the number of clock ticks.
*
* Arguments : ticks specifies the new value that OSTime needs to take.
*
* Returns : none
*********************************************************************************************************
*/
#if OS_TIME_GET_SET_EN > 0
void OSTimeSet (INT32U ticks)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
OSTime = ticks;
OS_EXIT_CRITICAL();
}
#endif

View File

@ -0,0 +1,30 @@
#ifndef _FR_H_
#define _FR_H_
// òàéìàóò îæèäàíèÿ ïå÷àòè ÷åêà
#define WAIT_PRINT_TIMEOUT 10000
// ïàðîëü îïåðàòîðà ïî óìîë÷àíèþ
#define DEFAULT_PASS 1
extern CPU_INT08U FiscalConnState;
extern int FReportGet(void);
extern void InitFiscal(void);
extern int IsFiscalConnected(void);
extern void FPend(void);
extern void FPost(void);
extern int PrintFiscalBill(CPU_INT32U money, CPU_INT32U time);
extern int PrintFiscalBillRepeated(CPU_INT32U money, CPU_INT32U time);
extern void SetFiscalErrorByCode(CPU_INT08U err);
extern void ClearFiscalErrors(void);
extern int TstCriticalFiscalError(void);
extern int GetFirstCriticalFiscalError(CPU_INT08U *err);
extern void ClrFiscalErrorByCode(CPU_INT08U err);
extern void FReportPend(void);
extern void FReportPost(void);
extern CPU_INT16U FReportTest(void);
extern int CheckFiscalStatus();
extern int ConnectFiscalFast(void);
#endif //#ifndef _FR_H_

View File

@ -0,0 +1,7 @@
#ifndef _VERSION_H_
#define _VERSION_H_
#define DEVICE_FW_VERSION "03.25"
#endif // #ifndef _VERSION_H_

View File

@ -0,0 +1,322 @@
#include "iolpc2368.h"
#include "ucos_ii.h"
#include "cpu.h"
#include "app_serv.h"
#include "time.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void RTC_Isr (void)
{
CPU_INT32U ilr;
ilr = ILR & 0x7;
if (ilr & 0x1) PostUserEvent(EVENT_SEC);
ILR = ilr;
}
void RTC_ReadTime(TRTC_Data *rtc)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
rtc->sec = SEC;
rtc->min = MIN;
rtc->hour = HOUR;
rtc->day = DOW;
rtc->date = DOM;
rtc->mon = MONTH;
rtc->year = YEAR-2000;
OS_EXIT_CRITICAL();
}
void RTC_SetTime(TRTC_Data *rtc)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
SEC = rtc->sec;
MIN = rtc->min;
HOUR = rtc->hour;
DOW = rtc->day;
DOM = rtc->date;
MONTH = rtc->mon;
YEAR = rtc->year+2000;
OS_EXIT_CRITICAL();
}
extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk);
void InitRTC(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
PCONP_bit.PCRTC = 1;
PCLKSEL0_bit.PCLK_RTC = 0;
OS_ENTER_CRITICAL();
CCR = 0x0011;
PREINT = (BSP_CPU_PclkFreq(9) / 32768) - 1;
PREFRAC = BSP_CPU_PclkFreq(9) - ((PREINT + 1) * 32768);
// If year is corrupt, set reasonable date.
if ((YEAR < 2010) || (HOUR > 23) || (YEAR > 2100)) {
CCR = 0x0000;
YEAR = 2010;
MONTH = 8;
DOM = 8;
HOUR = 7;
MIN = 0;
CCR = 0x0011;
}
VICVECTADDR13 = (CPU_INT32U)RTC_Isr;
VICINTSELECT &= ~(1 << VIC_RTC);
VICVECTPRIORITY13 = 7;
VICINTENABLE = (1 << VIC_RTC);
CISS = 0;
AMR = 0xff;
CIIR = 0x1; // sec interrupt
OS_EXIT_CRITICAL();
}
const char str_sunday[] = "ÂÎÑÊÐÅÑÅÍbÅ";
const char str_monday[] = "ÏÎÍÅÄÅËbÍÈÊ";
const char str_tuesday[] = "ÂÒÎÐÍÈÊ";
const char str_wednesday[] = "ÑÐÅÄÀ";
const char str_thirsday[] = "×ÅÒÂÅÐÃ";
const char str_friday[] = "ÏßÒÍÈÖÀ";
const char str_saturday[] = "ÑÓÁÁÎÒÀ";
const char* weekday[]={str_sunday, str_monday, str_tuesday, str_wednesday, str_thirsday, str_friday, str_saturday};
void GetDayText(char* str, char day)
{
strcpy(str, weekday[day]);
}
const char str_jan[] = "ßÍÂÀÐß";
const char str_feb[] = "ÔÅÂÐÀËß";
const char str_mar[] = "ÌÀÐÒÀ";
const char str_apr[] = "ÀÏÐÅËß";
const char str_may[] = "ÌÀß";
const char str_jun[] = "ÈÞÍß";
const char str_jul[] = "ÈÞËß";
const char str_aug[] = "ÀÂÃÓÑÒÀ";
const char str_sep[] = "ÑÅÍÒßÁÐß";
const char str_okt[] = "ÎÊÒßÁÐß";
const char str_nov[] = "ÍÎßÁÐß";
const char str_dec[] = "ÄÅÊÀÁÐß";
const char* month[]={str_jan, str_feb, str_mar, str_apr, str_may, str_jun, str_jul, str_aug, str_sep, str_okt, str_nov, str_dec};
//×èñëî ñåêóíä îò Ðîæäåñòâà Õðèñòîâà äî 1 ÿíâàðÿ 1970
#define JESUS_TO_70 2007437056
//×èñëî ìèíóò îò Ðîæäåñòâà Õðèñòîâà äî 1 ÿíâàðÿ 1970
#define JESUS_TO_70MIN 1035616320
// ×èñëî äíåé ñ íà÷àëà ãîäà
CPU_INT16U const mon_add[13] = {0,0,31,59,90,120,151,181,212,243,273,304,334};
// ×èñëî äíåé â ìåñÿöàõ
CPU_INT08U const mon_len[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
void PrintRTCDateTimeStringRus(char *str, TRTC_Data *rtc)
{
sprintf(str, "%02d:%02d:%02d %02d/%02d/%02d", rtc->hour, rtc->min, rtc->sec, rtc->date, rtc->mon, rtc->year);
}
void ScanRTCDateTimeStringRus(char *str, TRTC_Data *rtc)
{
int hour, min, sec, date, mon, year;
sscanf(str, "%02d:%02d:%02d %02d/%02d/%02d", &hour, &min, &sec, &date, &mon, &year);
rtc->year = year;
rtc->mon = mon;
rtc->date = date;
rtc->hour = hour;
rtc->min = min;
rtc->sec = sec;
}
// ïðîâåðêà êîððåêòíîñòè äàòû/âðåìåíè
int RTCCheckTime(TRTC_Data *rtc)
{
if (rtc->hour > 23) return -1;
if (rtc->min > 59) return -2;
if (rtc->sec > 59) return -3;
if ((rtc->mon > 12) || (rtc->mon < 1)) return -5;
if (rtc->year > 99) return -6;
if ((rtc->year%4 == 0) && (rtc->mon == 2))
{ // âèñîñêîñíûé
if ((rtc->date == 0) || (rtc->date > 29)) return -4;
}
else
{
if ((rtc->date == 0) || (rtc->date > mon_len[rtc->mon])) return -4;
}
return 0;
}
void PrintRTCDateTimeString(char *str, TRTC_Data *rtc)
{
sprintf(str, "20%02d/%02d/%02d %02d:%02d:%02d", rtc->year, rtc->mon, rtc->date, rtc->hour, rtc->min, rtc->sec);
}
void PrintRTCTimeString(char *str, TRTC_Data *rtc)
{
sprintf(str, "%02d:%02d:%02d", rtc->hour, rtc->min, rtc->sec);
}
void PrintTimeString(char *str, CPU_INT32U time)
{
TRTC_Data rtc_data;
Sec2Date(&rtc_data, time);
PrintRTCDateTimeStringRus(str, &rtc_data);
}
void PrintSecToMinSec(char *str, int seconds)
{
int min_ = seconds/60;
int sec_ = seconds%60;
sprintf(str, "%02d:%02d", min_, sec_);
}
void PrintSecToHourMinSec(char *str, int seconds)
{
int min_ = (seconds/60)%60;
int sec_ = seconds%60;
int hour_ = seconds/3600;
sprintf(str, "%02d:%02d:%02d", hour_, min_, sec_);
}
void PrintSecToBigHourMinSec(char *str, int seconds)
{
int min_ = (seconds/60)%60;
int sec_ = seconds%60;
int hour_ = seconds/3600;
sprintf(str, "%d:%02d:%02d", hour_, min_, sec_);
}
CPU_INT32U Date2Sec(TRTC_Data *pData, CPU_INT08U ucType)
{ // Ðàñ÷åò ãîäà îò Ðîæäåñòâà Õðèñòîâà
CPU_INT16U year = (CPU_INT16U)pData->year + ((pData->year >= 70) ? 1900 : 2000);
//Ðàñ÷åò ìåñÿöåâ îò Ðîæäåñòâà Õðèñòîâà
CPU_INT32U ulIndex = (CPU_INT32U)(((year - 1) * 12) + pData->mon - 1);
//Äëÿ ìåñÿ÷íîãî àðõèâà ðàñ÷åò çàêîí÷åí.
if ( ucType != MONTH_TYPE )
{ //Ðàñ÷åò äíåé îò Ðîæåäñòâà Õðèñòîâà
ulIndex = ((year - 1) * 365L) + ((year - 1)/4) + mon_add[pData->mon] + pData->date;
//Êîððåêöèÿ íà òåêóùèé âèñîêîñíûé ãîä.
if ( (!(year % 4)) && (pData->mon > 2) ) {ulIndex++;}
//Äëÿ ñóòî÷íîãî àðõèâà ðàñ÷åò çàêîí÷åí
if ( ucType != DAY_TYPE )
{ //×èñëî ÷àcîâ
ulIndex = ulIndex * 24L + pData->hour;
if ( ucType != HOUR_TYPE )
{ //×èñëî ìèíóò.
ulIndex = ulIndex * 60L + pData->min;
if ( ucType != MIN_TYPE )
{ //×èñëî ñåêóíä.
ulIndex = ulIndex * 60L + pData->sec;
}//if( )
}//if( )
}//if( )
}//if( )
return ulIndex;
}
//------------------------------------------------------------------------
//Ðàñ÷åò ñåêóíä ñ 1 ÿíâàðÿ 1970 äî ìîìåíòà, îïðåäåëÿåìîãî ñòðóêòóðîé pData
//------------------------------------------------------------------------
CPU_INT32U GetSec( TRTC_Data *pData)
{
CPU_INT32U ulIndex = Date2Sec(pData, MIN_TYPE);//Ïîëó÷àåì ÷èñëî ìèíóò î Ðîæäåñòâà Õðèñòîâà.
ulIndex -= JESUS_TO_70MIN; //Ïîëó÷àåì ÷èñëî ìèíóò ñ 1 ÿíâàðÿ 1970 ãîäà.
ulIndex *= 60L; //Ïåðåâîäèì â ñåêóíäû
ulIndex += pData->sec; //Äîáàâëÿåì ÷èñëî ñåêóíä â äàííîé ìèíóòå.
return ulIndex;
}
// ïîëó÷åíèå ñèñòåìíîãî âðåìåíè â ñeêóíäàõ
CPU_INT32U GetTimeSec(void)
{
TRTC_Data rtc;
RTC_ReadTime(&rtc);
return GetSec(&rtc);
}
//Ïåðåâîä ÷èñëà ñåêóíä â ÷àñû
void Sec2Hour(TRTC_Data *pDest, CPU_INT32U ulSec)
{
pDest->year = 0;
pDest->mon = 0;
pDest->date = 0;
pDest->hour = ulSec/3600L; //÷àñû
ulSec %= 3600L;
pDest->min = ulSec/60L; //ìèíóòû
ulSec %= 60L;
pDest->sec = ulSec; //ñåêóíäû
}
// Ïåðåâîä ÷èñëà ñåêóíä ñ 1 ÿíâàðÿ 1970 ãîäà â ïàðàìåòðû ñòðóêòóðû TRTC_Data.
void Sec2Date(TRTC_Data *pDest, CPU_INT32U ulSec)
{
CPU_INT32U dl = 0;
dl = (ulSec)/86400L;
// óçíàëè äåíü íåäåëè
pDest->day = (dl+4)%7;
if ( ulSec >= 946684800L )
{ //Äàòà ïîçæå 1 ÿíâàðÿ 2000 ãîäà
ulSec -= 946684800L;
pDest->year = 0;
}//if( )
else
{ //Äàòà îò 1970 ãîäà äî 1999 ãîäà
pDest->year = 70;
}//else ( )
for ( dl = 365L;
ulSec >= (dl = 86400L * (365L + visocosn(pDest->year)));
ulSec -= dl, pDest->year++ ){;}
for ( pDest->mon = 1;
ulSec >= ( dl = 86400L *
(mon_len[pDest->mon] + ((pDest->mon == 2) ?
visocosn(pDest->year) : 0))); ulSec -= dl, pDest->mon++){;}
pDest->date = ulSec / (86400L) + 1;
ulSec %= 86400L;
pDest->hour = ulSec / 3600L;
ulSec %= 3600L;
pDest->min = ulSec / 60L;
ulSec %= 60L;
pDest->sec = ulSec;
}

View File

@ -0,0 +1,720 @@
#include <includes.h>
#include "journal.h"
#include "modem.h"
#include "modem_task.h"
#include "data.h"
#include "datadesc.h"
#include "time.h"
OS_STK ModemTaskStk[MODEM_TASK_STK_SIZE];
OS_EVENT *ModemQuery = NULL;
void *ModemTbl[MODEM_QUERY_LEN];
static int index;
static CPU_INT32U enable_journals;
#define STAT_STR_NUM 17
static void GetChannelStatStr(char* str, int ch)
{
CPU_INT32U val;
GetData(&CounterChannelMoneyDesc, &val, ch, DATA_FLAG_DIRECT_INDEX);
sprintf(&str[strlen(str)], "| %2d | %11d ", ch+1, val);
GetData(&CounterChannelRunDesc, &val, ch, DATA_FLAG_DIRECT_INDEX);
sprintf(&str[strlen(str)], "| %7d | ", val);
GetData(&CounterChannelTimeDesc, &val, ch, DATA_FLAG_DIRECT_INDEX);
PrintSecToHourMinSec(&str[strlen(str)], val);
sprintf(&str[strlen(str)], "\r\n");
}
static void GetChannelStatStrLong(char* str, int ch)
{
CPU_INT32U val;
GetData(&CounterChannelMoneyLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX);
sprintf(&str[strlen(str)], "| %2d | %11d ", ch+1, val);
GetData(&CounterChannelRunLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX);
sprintf(&str[strlen(str)], "| %7d | ", val);
GetData(&CounterChannelTimeLongDesc, &val, ch, DATA_FLAG_DIRECT_INDEX);
PrintSecToHourMinSec(&str[strlen(str)], val);
sprintf(&str[strlen(str)], "\r\n");
}
extern CPU_INT32U BillNominals[24];
static int GetEmailStr(char *str)
{
if (index < STAT_STR_NUM)
{
str[0] = 0;
if (index == 0)
{
// çàãîëîâîê
TRTC_Data rtc;
RTC_ReadTime(&rtc);
sprintf(str, "Systemnoe vremya: ");
PrintRTCDateTimeString(&str[strlen(str)], &rtc);
sprintf(&str[strlen(str)], "\r\n\r\n-------------------------------------------------------------\r\nStatistika obshaya. Korotkie schetchiki.\r\n-------------------------------------------------------------\r\n");
}
else if (index == 1)
{
CPU_INT32U val;
// îáùèå ñ÷åò÷èêè
sprintf(str, "| Vsego deneg, rub. | Vsego seansov | Vsego narabotka h:m:s \r\n");
GetData(&CounterMoneyDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
sprintf(&str[strlen(str)], "| %16d ", val);
GetData(&CounterRunDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
sprintf(&str[strlen(str)], "| %12d | ", val);
GetData(&CounterTimeDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
PrintSecToHourMinSec(&str[strlen(str)], val);
sprintf(&str[strlen(str)], "\r\n");
}
else if (index == 2)
{
sprintf(&str[strlen(str)], "\r\n-------------------------------------------------------------\r\nStatistika obshaya. Dlinnye schetchiki\r\n-------------------------------------------------------------\r\n");
}
else if (index == 3)
{
CPU_INT32U val;
// íåîáíóëÿåìûå ñ÷åò÷èêè
sprintf(str, "| Vsego deneg, rub. | Vsego seansov | Vsego narabotka h:m:s \r\n");
GetData(&CounterLongMoneyDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
sprintf(&str[strlen(str)], "| %16d ", val);
GetData(&CounterLongRunDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
sprintf(&str[strlen(str)], "| %12d | ", val);
GetData(&CounterLongTimeDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
PrintSecToHourMinSec(&str[strlen(str)], val);
sprintf(&str[strlen(str)], "\r\n");
}
else if (index == 4)
{
sprintf(str, "\r\n-------------------------------------------------------------\r\nStatistika po kanalam. Korotkie schetchiki.\r\n-------------------------------------------------------------\r\n");
sprintf(&str[strlen(str)], "| Kanal | Deneg, rub. | Seansov | Narabotka h:m:s\r\n");
}
else if (index == 5)
{
int i;
for (i = 0; i < 3; i++)
{
GetChannelStatStr(&str[strlen(str)], i);
}
}
else if (index == 6)
{
int i;
for (i = 3; i < 6; i++)
{
GetChannelStatStr(&str[strlen(str)], i);
}
}
else if (index == 7)
{
int i;
for (i = 6; i < 10; i++)
{
GetChannelStatStr(&str[strlen(str)], i);
}
}
else if (index == 8)
{
sprintf(str, "\r\n-------------------------------------------------------------\r\nStatistika po kanalam. Dlinnye schetchiki.\r\n-------------------------------------------------------------\r\n");
sprintf(&str[strlen(str)], "| Kanal | Deneg, rub. | Seansov | Narabotka h:m:s\r\n");
}
else if (index == 9)
{
int i;
for (i = 0; i < 3; i++)
{
GetChannelStatStrLong(&str[strlen(str)], i);
}
}
else if (index == 10)
{
int i;
for (i = 3; i < 6; i++)
{
GetChannelStatStrLong(&str[strlen(str)], i);
}
}
else if (index == 11)
{
int i;
for (i = 6; i < 10; i++)
{
GetChannelStatStrLong(&str[strlen(str)], i);
}
}
else if (index == 12)
{
CPU_INT32U val;
// âïå÷àòàåì ÷èñëî êóïþð â êóïþðíèêå
sprintf(str, "\r\n-------------------------------------------------------------\r\nKupuropriemnik.\r\n-------------------------------------------------------------\r\n");
GetData(&BillCounterDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
if (!val)
{
// êóïþðíèê ïóñò
sprintf(&str[strlen(str)], "Kupuropriemnik pust.\r\n\r\n");
index++;
index++;
}
else
{
sprintf(&str[strlen(str)], "| Nominal, rub. | Kolichestvo\r\n");
}
}
else if (index == 13)
{
int i;
str[0] = 0;
for (i = 0; i < 6; i++)
{
CPU_INT32U val;
GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX);
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
val = strlen(str);
}
}
else if (index == 14)
{
int i;
str[0] = 0;
for (i = 6; i < 12; i++)
{
CPU_INT32U val;
GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX);
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
}
}
else if (index == 15)
{
int i;
str[0] = 0;
for (i = 12; i < 18; i++)
{
CPU_INT32U val;
GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX);
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
}
}
else if (index == 16)
{
int i;
str[0] = 0;
for (i = 18; i < 24; i++)
{
CPU_INT32U val;
GetData(&BillnomCountersDesc, &val, i, DATA_FLAG_DIRECT_INDEX);
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
}
}
index++;
return 0;
}
else if (index < STAT_STR_NUM+EVENT_RECORDS_NUM)
{
TEventRecord record;
if (enable_journals == 0) return -1;
GetEventRecord(&record, index-STAT_STR_NUM);
str[0] = 0;
if ((index-STAT_STR_NUM) == 0)
{
sprintf(str, "\r\n-------------------------------------------------------------\r\nZhurnal sobytiy\r\n-------------------------------------------------------------\r\n");
}
if (record.time == 0x00000000)
{
index++;
return 0;
}
PrintEventJournalRecordEng(&str[strlen(str)], &record);
index++;
return 0;
}
else if (index < STAT_STR_NUM+EVENT_RECORDS_NUM+ERROR_RECORDS_NUM)
{
CPU_INT32U time = 0;
TRTC_Data rtc_data;
str[0] = 0;
if ((index-(STAT_STR_NUM+EVENT_RECORDS_NUM)) == 0)
{
sprintf(str, "\r\n-------------------------------------------------------------\r\nZhurnal oshibok\r\n-------------------------------------------------------------\r\n");
}
GetData(&JournalErrorTimeDesc, &time, index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX);
if (time == 0x00000000)
{
index++;
return 0;
}
sprintf(&str[strlen(str)], "| ");
GetData(&JournalErrorTimeDesc, &time, index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX);
Sec2Date(&rtc_data, time);
PrintRTCDateTimeString(&str[strlen(str)], &rtc_data);
sprintf(&str[strlen(str)], " | ");
GetDataStr(&JournalErrorNumberDescEng, (CPU_INT08U*)&str[strlen(str)], index-EVENT_RECORDS_NUM-STAT_STR_NUM, DATA_FLAG_DIRECT_INDEX);
sprintf(&str[strlen(str)], "\r\n");
index++;
return 0;
}
return -1;
}
/// îòïðàâêà e-mail ñî ñ÷åò÷èêàìè è æóðíàëàìè
int SendStatistics(void)
{
CPU_INT32U dev_id;
char theme[48];
index = 0;
// íàäî ëè îòïðàâëÿòü æóðíàëû
GetData(&EnableEmailJournalSendDesc, &enable_journals, 0, DATA_FLAG_SYSTEM_INDEX);
// id óñòðîéñòâà óêàæåì â òåìå
GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX);
sprintf(theme, "Report from solarium device id %d.", dev_id);
return ModemSendEmail(theme, GetEmailStr);
}
// âûåìêà íîâîãî çàäàíèÿ äëÿ ìîäåìà
static int GetModemTask(int* event)
{
CPU_INT08U err = 0;
int evt = (int)OSQPend(ModemQuery, 1, &err);
if (err != 0) return 0;
*event = evt;
return 1;
}
int GetTestText(char *str)
{
if (index == 0)
{
index++;
sprintf(str, "Test message from solarium.");
return 0;
}
return -1;
}
// îòïðàâêà òåñòîâîãî ñîîáùåíèÿ
int SendTest(void)
{
CPU_INT32U dev_id;
char theme[48];
GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX);
sprintf(theme, "Test message. Device id %d.", dev_id);
index = 0;
return ModemSendEmail(theme, GetTestText);
}
static CPU_INT32U incas_money;
static CPU_INT32U incas_time;
int GetIncasText(char *str)
{
if (index == 0)
{
// çàãîëîâîê
TRTC_Data rtc;
Sec2Date(&rtc, incas_time);
sprintf(str, "Vremya incassacii: ");
PrintRTCDateTimeString(&str[strlen(str)], &rtc);
sprintf(&str[strlen(str)], "\r\n\r\nSumma %d rub.\r\n", incas_money);
}
else if (index == 1)
{
CPU_INT32U val;
// âïå÷àòàåì ÷èñëî êóïþð â êóïþðíèêå
val = incas_common_bill_counter;
if (!val)
{
// êóïþðíèê ïóñò
sprintf(&str[strlen(str)], "Kupuropriemnik byl pust.\r\n\r\n");
index=100;
}
else
{
sprintf(str, "\r\n-------------------------------------------------------------\r\nKupuropriemnik.\r\n-------------------------------------------------------------\r\n");
sprintf(&str[strlen(str)], "| Nominal, rub. | Kolichestvo\r\n");
}
}
else if (index == 2)
{
int i;
str[0] = 0;
for (i = 0; i < 6; i++)
{
CPU_INT32U val;
val = incas_bill_nom_counter[i];
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
val = strlen(str);
}
}
else if (index == 3)
{
int i;
str[0] = 0;
for (i = 6; i < 12; i++)
{
CPU_INT32U val;
val = incas_bill_nom_counter[i];
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
}
}
else if (index == 4)
{
int i;
str[0] = 0;
for (i = 12; i < 18; i++)
{
CPU_INT32U val;
val = incas_bill_nom_counter[i];
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
}
}
else if (index == 5)
{
int i;
str[0] = 0;
for (i = 18; i < 24; i++)
{
CPU_INT32U val;
val = incas_bill_nom_counter[i];
if (val)
{
sprintf(&str[strlen(str)], "| %13d | %11d \r\n", BillNominals[i], val);
}
}
}
else
{
return -1;
}
index++;
return 0;
}
// îòïðàâêà ñîîáùåíèÿ îá èíêàññàöèè
int SendIncas(void)
{
CPU_INT32U dev_id;
char theme[48];
GetData(&DeviceIDDesc, &dev_id, 0, DATA_FLAG_SYSTEM_INDEX);
sprintf(theme, "Incassation. Device id %d.", dev_id);
index = 0;
return ModemSendEmail(theme, GetIncasText);
}
// ñïèñîê âîçìîæíûõ èíòåðâàëîâ îòïðàâêè
const int send_period_list[7] = {0, 1, 2, 4, 8, 12, 24};
// ãëîáàëüíûé ñòàòóñ ìîäåìà
CPU_INT32U modem_status = 0;
// ïðîâåðêà, â îäíîì ëè ïåðèîäå íàõîäÿòñÿ äâà âðåìåíè
int SamePeriod(CPU_INT32U time1, CPU_INT32U time2, CPU_INT08U period)
{
TRTC_Data rtc1, rtc2;
CPU_INT08U hour1, hour2;
Sec2Date(&rtc1, time1);
Sec2Date(&rtc2, time2);
if ((rtc1.year != rtc2.year) || (rtc1.mon != rtc2.mon) || (rtc1.date != rtc2.date))
{
// äàòà íå ñîâïàäàåò - òî÷íî ðàçíûé ÷àñîâîé ïåðèîä
return 0;
}
// time1 - òåêóùåå âðåìÿ
// îïðåäåëèì âðåìÿ íà÷àëà òåêóùåãî ïåðèîäà
hour1 = rtc1.hour - (rtc1.hour % period);
// îïðåäåëèì âðåìÿ íà÷àëà ïåðèîäà â ïîñëåäíåì âðåìåíè îòïðàâêè
hour2 = rtc2.hour - (rtc2.hour % period);
if (hour1 != hour2)
{
return 0;
}
return 1;
}
#define MODEM_REPEAT_NUM 3
static CPU_INT32U last_stat_send_time;
// çàäà÷à ñåðâåðà ìîäåìà
void ModemTask(void *p_arg)
{
int task;
int send_res, send_ctr, repeat_ctr;
while (1)
{
CPU_INT32U en = 0;
OSTimeDly(100);
if (!IsModemValid())
{
GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX);
if (en)
{
if (!IsModemConn())
{
modem_status = 2;
}
else if (!IsModemConf())
{
modem_status = 1;
}
// ïîïûòàåìñÿ ïåðåïîäêëþ÷èòü ìîäåì
if (InitModem() != 0)
{
SetErrorFlag(ERROR_MODEM_CONN);
}
else
{
ClrErrorFlag(ERROR_MODEM_CONN);
}
}
else
{
modem_status = 0;
}
continue;
}
modem_status = 0;
GetData(&EnableModemDesc, &en, 0, DATA_FLAG_SYSTEM_INDEX);
if (!en)
{
ResetModemValid();
continue;
}
if (GetModemTask(&task))
{
// ðàçáåðåì çàäàíèå
switch (task)
{
case MODEM_TASK_SEND_INCAS:
{
CPU_INT32U temp;
GetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX);
if (temp != INCAS_SEND_FLAG)
{
break;
}
GetData(&IncasMoneyDesc, &incas_money, 0, DATA_FLAG_SYSTEM_INDEX);
GetData(&IncasTimeDesc, &incas_time, 0, DATA_FLAG_SYSTEM_INDEX);
repeat_ctr = 0;
while (repeat_ctr < MODEM_REPEAT_NUM)
{
send_ctr = 0;
while (send_ctr < 3)
{
send_res = SendIncas();
if (send_res == 0) break;
OSTimeDly(1000);
send_ctr++;
}
if (send_ctr < 3)
{
break;
}
else
{
// íå îòïðàâèëîñü - ïåðåèíèöèàëèçèðóåì ìîäåì
InitModem();
}
repeat_ctr++;
}
if (repeat_ctr >= MODEM_REPEAT_NUM)
{
// òî÷íî îøèáêà ìîäåìà
SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0);
// åù¸ ðàç çàïîñòèì, ÷òîáû îòïðàâëÿòü, ïîêà íå îòïðàâèòñÿ
PostModemTask(MODEM_TASK_SEND_INCAS);
}
else
{
temp = 0;
SetData(&IncasSendFlagDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX);
SetData(&IncasMoneyDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX);
SetData(&IncasTimeDesc, &temp, 0, DATA_FLAG_SYSTEM_INDEX);
SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0);
}
}
break;
case MODEM_TASK_SEND_STATISTICS:
repeat_ctr = 0;
while (repeat_ctr < MODEM_REPEAT_NUM)
{
send_ctr = 0;
while (send_ctr < 3)
{
send_res = SendStatistics();
if (send_res == 0) break;
OSTimeDly(1000);
send_ctr++;
}
if (send_ctr < 3)
{
break;
}
else
{
// íå îòïðàâèëîñü - ïåðåèíèöèàëèçèðóåì ìîäåì
InitModem();
}
repeat_ctr++;
}
if (repeat_ctr >= MODEM_REPEAT_NUM)
{
// òî÷íî îøèáêà ìîäåìà
SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0);
// åù¸ ðàç çàñïîñòèì, ÷òîáû îòïðàâëÿòü, ïîêà íå îòïðàâèòñÿ
// íå íàäî - ñàìî çàïîñòèòñÿ, ò.ê. âðåìÿ ìû åù¸ íå ñîõðàíèëè
//PostModemTask(MODEM_TASK_SEND_STATISTICS);
}
else
{
SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0);
ClearCounters();
SetData(&LastEmailSendTime, &last_stat_send_time, 0, DATA_FLAG_SYSTEM_INDEX);
}
break;
case MODEM_TASK_SEND_TEST_MSG:
repeat_ctr = 0;
while (repeat_ctr < 3)
{
send_ctr = 0;
while (send_ctr < 3)
{
send_res = SendTest();
if (send_res == 0) break;
OSTimeDly(1000);
send_ctr++;
}
if (send_ctr < 3)
{
break;
}
else
{
// íå îòïðàâèëîñü - ïåðåèíèöèàëèçèðóåì ìîäåì
InitModem();
}
repeat_ctr++;
}
if (repeat_ctr >= 3)
{
// òî÷íî îøèáêà ìîäåìà, çàáèâàåì íà îòïðàâêó
SaveEventRecord(0, JOURNAL_EVENT_EMAIL_FAIL, 0);
}
else
{
SaveEventRecord(0, JOURNAL_EVENT_EMAIL_OK, 0);
}
break;
case MODEM_TASK_RECONNECT:
// ïîïûòàåìñÿ ïåðåïîäêëþ÷èòü ìîäåì
InitModem();
break;
}
}
else
{
CPU_INT32U send_time, send_hour, send_minute;
CPU_INT32U last_send_time, sec;
TRTC_Data rtc_1, rtc_2;
OSTimeDly(MODEM_TASK_DELAY);
// ïîñìîòðèì òåêóùåå âðåìÿ
GetData(&SystemTimeDesc, &sec, 0, DATA_FLAG_SYSTEM_INDEX);
GetData(&StatSendHourMinDesc, &send_time, 0, DATA_FLAG_SYSTEM_INDEX);
send_hour = send_time / 60;
send_minute = send_time % 60;
// ïðî÷èòàåì ïîñëåäíåå âðåìÿ îòïðàâêè
GetData(&LastEmailSendTime, &last_send_time, 0, DATA_FLAG_SYSTEM_INDEX);
Sec2Date(&rtc_1, sec);
Sec2Date(&rtc_2, last_send_time);
// çàïîñòèì êîìàíäó, åñëè â òåêóùåì ïåðèîäå åù¸ íå îòïðàâëÿëîñü
// îòïðàâëÿåòñÿ âñåãäà ðàç â ñóòêè â 9.10
if ((rtc_1.hour >= send_hour) && (rtc_1.min >= send_minute) && ((rtc_2.date != rtc_1.date) || (rtc_2.year != rtc_1.year) || (rtc_2.mon != rtc_1.mon)))
{
PostModemTask(MODEM_TASK_SEND_STATISTICS);
last_stat_send_time = sec;
//SetData(&LastEmailSendTime, &last_stat_send_time, 0, DATA_FLAG_SYSTEM_INDEX);
// ïîñëåäíåå âðåìÿ îòïðàâêè óñòàíîâèì ïîòîì, òîëüêî â ñëó÷àå óñïåøíîé îòïðàâêè
}
}
}
}
// ïîñòàíîâêà íîâîé çàäà÷è â î÷åðåäü çàäà÷ ìîäåìà
void PostModemTask(int new_task)
{
OSQPost(ModemQuery, (void *)new_task);
}

View File

@ -0,0 +1,141 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* uC/OS-II Configuration File for V2.8x
*
* File : OS_CFG.H
* By : Jean J. Labrosse
* Version : V2.85
*
* LICENSING TERMS:
* ---------------
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
* licensing fee.
*********************************************************************************************************
*/
#ifndef OS_CFG_H
#define OS_CFG_H
/* ---------------------- MISCELLANEOUS ----------------------- */
#define OS_APP_HOOKS_EN 0 /* Application-defined hooks are called from the uC/OS-II hooks */
#define OS_ARG_CHK_EN 0 /* Enable (1) or Disable (0) argument checking */
#define OS_CPU_HOOKS_EN 1 /* uC/OS-II hooks are found in the processor port files */
#define OS_DEBUG_EN 1 /* Enable(1) debug variables */
#define OS_EVENT_NAME_SIZE 0 /* Determine the size of the name of a Sem, Mutex, Mbox or Q */
#define OS_LOWEST_PRIO 31 /* Defines the lowest priority that can be assigned ... */
/* ... MUST NEVER be higher than 254! */
#define OS_MAX_EVENTS 10 /* Max. number of event control blocks in your application */
#define OS_MAX_FLAGS 5 /* Max. number of Event Flag Groups in your application */
#define OS_MAX_MEM_PART 5 /* Max. number of memory partitions */
#define OS_MAX_QS 4 /* Max. number of queue control blocks in your application */
#define OS_MAX_TASKS 16 /* Max. number of tasks in your application, MUST be >= 2 */
#define OS_SCHED_LOCK_EN 1 /* Include code for OSSchedLock() and OSSchedUnlock() */
#define OS_TICK_STEP_EN 1 /* Enable tick stepping feature for uC/OS-View */
#define OS_TICKS_PER_SEC 1000 /* Set the number of ticks in one second */
/* --------------------- TASK STACK SIZE ---------------------- */
#define OS_TASK_TMR_STK_SIZE 128 /* Timer task stack size (# of OS_STK wide entries) */
#define OS_TASK_STAT_STK_SIZE 128 /* Statistics task stack size (# of OS_STK wide entries) */
#define OS_TASK_IDLE_STK_SIZE 128 /* Idle task stack size (# of OS_STK wide entries) */
/* --------------------- TASK MANAGEMENT ---------------------- */
#define OS_TASK_CHANGE_PRIO_EN 1 /* Include code for OSTaskChangePrio() */
#define OS_TASK_CREATE_EN 1 /* Include code for OSTaskCreate() */
#define OS_TASK_CREATE_EXT_EN 1 /* Include code for OSTaskCreateExt() */
#define OS_TASK_DEL_EN 1 /* Include code for OSTaskDel() */
#define OS_TASK_NAME_SIZE 0 /* Determine the size of a task name */
#define OS_TASK_PROFILE_EN 1 /* Include variables in OS_TCB for profiling */
#define OS_TASK_QUERY_EN 1 /* Include code for OSTaskQuery() */
#define OS_TASK_STAT_EN 0 /* Enable (1) or Disable(0) the statistics task */
#define OS_TASK_STAT_STK_CHK_EN 1 /* Check task stacks from statistic task */
#define OS_TASK_SUSPEND_EN 1 /* Include code for OSTaskSuspend() and OSTaskResume() */
#define OS_TASK_SW_HOOK_EN 1 /* Include code for OSTaskSwHook() */
/* ----------------------- EVENT FLAGS ------------------------ */
#define OS_FLAG_EN 1 /* Enable (1) or Disable (0) code generation for EVENT FLAGS */
#define OS_FLAG_ACCEPT_EN 1 /* Include code for OSFlagAccept() */
#define OS_FLAG_DEL_EN 1 /* Include code for OSFlagDel() */
#define OS_FLAG_NAME_SIZE 0 /* Determine the size of the name of an event flag group */
#define OS_FLAGS_NBITS 16 /* Size in #bits of OS_FLAGS data type (8, 16 or 32) */
#define OS_FLAG_QUERY_EN 1 /* Include code for OSFlagQuery() */
#define OS_FLAG_WAIT_CLR_EN 1 /* Include code for Wait on Clear EVENT FLAGS */
/* -------------------- MESSAGE MAILBOXES --------------------- */
#define OS_MBOX_EN 1 /* Enable (1) or Disable (0) code generation for MAILBOXES */
#define OS_MBOX_ACCEPT_EN 1 /* Include code for OSMboxAccept() */
#define OS_MBOX_DEL_EN 1 /* Include code for OSMboxDel() */
#define OS_MBOX_PEND_ABORT_EN 1 /* Include code for OSMboxPendAbort() */
#define OS_MBOX_POST_EN 1 /* Include code for OSMboxPost() */
#define OS_MBOX_POST_OPT_EN 1 /* Include code for OSMboxPostOpt() */
#define OS_MBOX_QUERY_EN 1 /* Include code for OSMboxQuery() */
/* --------------------- MEMORY MANAGEMENT -------------------- */
#define OS_MEM_EN 1 /* Enable (1) or Disable (0) code generation for MEMORY MANAGER */
#define OS_MEM_NAME_SIZE 0 /* Determine the size of a memory partition name */
#define OS_MEM_QUERY_EN 1 /* Include code for OSMemQuery() */
/* ---------------- MUTUAL EXCLUSION SEMAPHORES --------------- */
#define OS_MUTEX_EN 1 /* Enable (1) or Disable (0) code generation for MUTEX */
#define OS_MUTEX_ACCEPT_EN 1 /* Include code for OSMutexAccept() */
#define OS_MUTEX_DEL_EN 1 /* Include code for OSMutexDel() */
#define OS_MUTEX_QUERY_EN 1 /* Include code for OSMutexQuery() */
/* ---------------------- MESSAGE QUEUES ---------------------- */
#define OS_Q_EN 1 /* Enable (1) or Disable (0) code generation for QUEUES */
#define OS_Q_ACCEPT_EN 1 /* Include code for OSQAccept() */
#define OS_Q_DEL_EN 1 /* Include code for OSQDel() */
#define OS_Q_FLUSH_EN 1 /* Include code for OSQFlush() */
#define OS_Q_PEND_ABORT_EN 1 /* Include code for OSQPendAbort() */
#define OS_Q_POST_EN 1 /* Include code for OSQPost() */
#define OS_Q_POST_FRONT_EN 1 /* Include code for OSQPostFront() */
#define OS_Q_POST_OPT_EN 1 /* Include code for OSQPostOpt() */
#define OS_Q_QUERY_EN 1 /* Include code for OSQQuery() */
/* ------------------------ SEMAPHORES ------------------------ */
#define OS_SEM_EN 1 /* Enable (1) or Disable (0) code generation for SEMAPHORES */
#define OS_SEM_ACCEPT_EN 1 /* Include code for OSSemAccept() */
#define OS_SEM_DEL_EN 1 /* Include code for OSSemDel() */
#define OS_SEM_PEND_ABORT_EN 1 /* Include code for OSSemPendAbort() */
#define OS_SEM_QUERY_EN 1 /* Include code for OSSemQuery() */
#define OS_SEM_SET_EN 1 /* Include code for OSSemSet() */
/* --------------------- TIME MANAGEMENT ---------------------- */
#define OS_TIME_DLY_HMSM_EN 1 /* Include code for OSTimeDlyHMSM() */
#define OS_TIME_DLY_RESUME_EN 1 /* Include code for OSTimeDlyResume() */
#define OS_TIME_GET_SET_EN 1 /* Include code for OSTimeGet() and OSTimeSet() */
#define OS_TIME_TICK_HOOK_EN 1 /* Include code for OSTimeTickHook() */
/* --------------------- TIMER MANAGEMENT --------------------- */
#define OS_TMR_EN 1 /* Enable (1) or Disable (0) code generation for TIMERS */
#define OS_TMR_CFG_MAX 16 /* Maximum number of timers */
#define OS_TMR_CFG_NAME_SIZE 0 /* Determine the size of a timer name */
#define OS_TMR_CFG_WHEEL_SIZE 8 /* Size of timer wheel (#Spokes) */
#define OS_TMR_CFG_TICKS_PER_SEC 10 /* Rate at which timer management task runs (Hz) */
#endif

View File

@ -0,0 +1,616 @@
/*
*********************************************************************************************************
* uC/LIB
* CUSTOM LIBRARY MODULES
*
* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/LIB is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/LIB in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to
* help you experience uC/LIB. The fact that the source code is provided
* does NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CORE CUSTOM LIBRARY MODULE
*
* Filename : lib_def.h
* Version : V1.24
* Programmer(s) : ITJ
*********************************************************************************************************
* Note(s) : (1) NO compiler-supplied standard library functions are used in library or product software.
*
* (a) ALL standard library functions are implemented in the custom library modules :
*
* (1) \<Custom Library Directory>\lib*.*
*
* (2) \<Custom Library Directory>\Ports\<cpu>\<compiler>\lib*_a.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (b) Product-specific library functions are implemented in individual products.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MODULE
*********************************************************************************************************
*/
#ifndef LIB_DEF_MODULE_PRESENT
#define LIB_DEF_MODULE_PRESENT
/*$PAGE*/
/*
*********************************************************************************************************
* CUSTOM LIBRARY MODULE VERSION NUMBER
*
* Note(s) : (1) (a) The custom library module software version is denoted as follows :
*
* Vx.yy
*
* where
* V denotes 'Version' label
* x denotes major software version revision number
* yy denotes minor software version revision number
*
* (b) The software version label #define is formatted as follows :
*
* ver = x.yy * 100
*
* where
* ver denotes software version number scaled as an integer value
* x.yy denotes software version number
*********************************************************************************************************
*/
#define LIB_VERSION 124u /* See Note #1. */
/*
*********************************************************************************************************
* INCLUDE FILES
*
* Note(s) : (1) The following common software files are located in the following directories :
*
* (a) \<Custom Library Directory>\lib*.*
*
* (b) (1) \<CPU-Compiler Directory>\cpu_def.h
*
* (2) \<CPU-Compiler Directory>\<cpu>\<compiler>\cpu*.*
*
* where
* <Custom Library Directory> directory path for custom library software
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific processor (CPU)
* <compiler> directory name for specific compiler
*
* (2) Compiler MUST be configured to include the '\<Custom Library Directory>\uC-LIB\',
* '\<CPU-Compiler Directory>\' directory, & the specific CPU-compiler directory as
* additional include path directories.
*********************************************************************************************************
*/
#include <cpu.h>
/*$PAGE*/
/*
*********************************************************************************************************
* STANDARD DEFINES
*********************************************************************************************************
*/
#define DEF_DISABLED 0
#define DEF_ENABLED 1
#define DEF_FALSE 0
#define DEF_TRUE 1
#define DEF_NO 0
#define DEF_YES 1
#define DEF_OFF 0
#define DEF_ON 1
#define DEF_CLR 0
#define DEF_SET 1
#define DEF_ACTIVE 0
#define DEF_INACTIVE 1
#define DEF_FAIL 0
#define DEF_OK 1
/* -------------------- BIT DEFINES ------------------- */
#define DEF_BIT_NONE 0x00
#define DEF_BIT_00 0x01
#define DEF_BIT_01 0x02
#define DEF_BIT_02 0x04
#define DEF_BIT_03 0x08
#define DEF_BIT_04 0x10
#define DEF_BIT_05 0x20
#define DEF_BIT_06 0x40
#define DEF_BIT_07 0x80
#define DEF_BIT_08 0x0100
#define DEF_BIT_09 0x0200
#define DEF_BIT_10 0x0400
#define DEF_BIT_11 0x0800
#define DEF_BIT_12 0x1000
#define DEF_BIT_13 0x2000
#define DEF_BIT_14 0x4000
#define DEF_BIT_15 0x8000
#define DEF_BIT_16 0x00010000
#define DEF_BIT_17 0x00020000
#define DEF_BIT_18 0x00040000
#define DEF_BIT_19 0x00080000
#define DEF_BIT_20 0x00100000
#define DEF_BIT_21 0x00200000
#define DEF_BIT_22 0x00400000
#define DEF_BIT_23 0x00800000
#define DEF_BIT_24 0x01000000
#define DEF_BIT_25 0x02000000
#define DEF_BIT_26 0x04000000
#define DEF_BIT_27 0x08000000
#define DEF_BIT_28 0x10000000
#define DEF_BIT_29 0x20000000
#define DEF_BIT_30 0x40000000
#define DEF_BIT_31 0x80000000
/* ------------------- OCTET DEFINES ------------------ */
#define DEF_OCTET_NBR_BITS 8
#define DEF_OCTET_MASK 0xFF
#define DEF_NIBBLE_NBR_BITS 4
#define DEF_NIBBLE_MASK 0x0F
/*$PAGE*/
/* ------------------ INTEGER DEFINES ----------------- */
#define DEF_INT_08_NBR_BITS 8
#define DEF_INT_08_MASK 0xFF
#define DEF_INT_08U_MIN_VAL 0u
#define DEF_INT_08U_MAX_VAL 255u
#define DEF_INT_08S_MIN_VAL -128
#define DEF_INT_08S_MAX_VAL 127
#define DEF_INT_08S_MIN_VAL_ONES_CPL -127
#define DEF_INT_08S_MAX_VAL_ONES_CPL 127
#define DEF_INT_16_NBR_BITS 16
#define DEF_INT_16_MASK 0xFFFF
#define DEF_INT_16U_MIN_VAL 0u
#define DEF_INT_16U_MAX_VAL 65535u
#define DEF_INT_16S_MIN_VAL -32768
#define DEF_INT_16S_MAX_VAL 32767
#define DEF_INT_16S_MIN_VAL_ONES_CPL -32767
#define DEF_INT_16S_MAX_VAL_ONES_CPL 32767
#define DEF_INT_32_NBR_BITS 32
#define DEF_INT_32_MASK 0xFFFFFFFF
#define DEF_INT_32U_MIN_VAL 0u
#define DEF_INT_32U_MAX_VAL 4294967295u
#define DEF_INT_32S_MIN_VAL -2147483648
#define DEF_INT_32S_MAX_VAL 2147483647
#define DEF_INT_32S_MIN_VAL_ONES_CPL -2147483647
#define DEF_INT_32S_MAX_VAL_ONES_CPL 2147483647
#define DEF_INT_64_NBR_BITS 64
#define DEF_INT_64_MASK 0xFFFFFFFFFFFFFFFF
#define DEF_INT_64U_MIN_VAL 0u
#define DEF_INT_64U_MAX_VAL 18446744073709551615u
#define DEF_INT_64S_MIN_VAL -9223372036854775808
#define DEF_INT_64S_MAX_VAL 9223372036854775807
#define DEF_INT_64S_MIN_VAL_ONES_CPL -9223372036854775807
#define DEF_INT_64S_MAX_VAL_ONES_CPL 9223372036854775807
/*$PAGE*/
/* ---------------- CPU INTEGER DEFINES --------------- */
#define DEF_INT_CPU_NBR_BITS (CPU_CFG_DATA_SIZE * DEF_OCTET_NBR_BITS)
#if (DEF_INT_CPU_NBR_BITS == DEF_INT_08_NBR_BITS)
#define DEF_INT_CPU_MASK DEF_INT_08_MASK
#define DEF_INT_CPU_U_MIN_VAL DEF_INT_08U_MIN_VAL
#define DEF_INT_CPU_U_MAX_VAL DEF_INT_08U_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL DEF_INT_08S_MIN_VAL
#define DEF_INT_CPU_S_MAX_VAL DEF_INT_08S_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_08S_MIN_VAL_ONES_CPL
#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_08S_MAX_VAL_ONES_CPL
#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_16_NBR_BITS)
#define DEF_INT_CPU_MASK DEF_INT_16_MASK
#define DEF_INT_CPU_U_MIN_VAL DEF_INT_16U_MIN_VAL
#define DEF_INT_CPU_U_MAX_VAL DEF_INT_16U_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL DEF_INT_16S_MIN_VAL
#define DEF_INT_CPU_S_MAX_VAL DEF_INT_16S_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_16S_MIN_VAL_ONES_CPL
#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_16S_MAX_VAL_ONES_CPL
#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_32_NBR_BITS)
#define DEF_INT_CPU_MASK DEF_INT_32_MASK
#define DEF_INT_CPU_U_MIN_VAL DEF_INT_32U_MIN_VAL
#define DEF_INT_CPU_U_MAX_VAL DEF_INT_32U_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL DEF_INT_32S_MIN_VAL
#define DEF_INT_CPU_S_MAX_VAL DEF_INT_32S_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_32S_MIN_VAL_ONES_CPL
#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_32S_MAX_VAL_ONES_CPL
#elif (DEF_INT_CPU_NBR_BITS == DEF_INT_64_NBR_BITS)
#define DEF_INT_CPU_MASK DEF_INT_64_MASK
#define DEF_INT_CPU_U_MIN_VAL DEF_INT_64U_MIN_VAL
#define DEF_INT_CPU_U_MAX_VAL DEF_INT_64U_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL DEF_INT_64S_MIN_VAL
#define DEF_INT_CPU_S_MAX_VAL DEF_INT_64S_MAX_VAL
#define DEF_INT_CPU_S_MIN_VAL_ONES_CPL DEF_INT_64S_MIN_VAL_ONES_CPL
#define DEF_INT_CPU_S_MAX_VAL_ONES_CPL DEF_INT_64S_MAX_VAL_ONES_CPL
#else
#error "CPU_CFG_DATA_SIZE illegally #defined in 'cpu.h' "
#error " [See 'cpu.h CONFIGURATION ERRORS']"
#endif
/*$PAGE*/
/* ------------------- TIME DEFINES ------------------- */
#define DEF_TIME_NBR_HR_PER_DAY 24uL
#define DEF_TIME_NBR_MIN_PER_HR 60uL
#define DEF_TIME_NBR_MIN_PER_DAY (DEF_TIME_NBR_MIN_PER_HR * DEF_TIME_NBR_HR_PER_DAY)
#define DEF_TIME_NBR_SEC_PER_MIN 60uL
#define DEF_TIME_NBR_SEC_PER_HR (DEF_TIME_NBR_SEC_PER_MIN * DEF_TIME_NBR_MIN_PER_HR)
#define DEF_TIME_NBR_SEC_PER_DAY (DEF_TIME_NBR_SEC_PER_HR * DEF_TIME_NBR_HR_PER_DAY)
#define DEF_TIME_NBR_mS_PER_SEC 1000uL
#define DEF_TIME_NBR_uS_PER_SEC 1000000uL
#define DEF_TIME_NBR_nS_PER_SEC 1000000000uL
/*$PAGE*/
/*
*********************************************************************************************************
* BIT MACRO'S
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* DEF_BIT()
*
* Description : Create bit mask with single, specified bit set.
*
* Argument(s) : bit Bit number of bit to set.
*
* Return(s) : Bit mask with single, specified bit set.
*
* Caller(s) : various.
*
* Note(s) : (1) 'bit' values that overflow the target CPU &/or compiler environment (e.g. negative
* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors.
*********************************************************************************************************
*/
#define DEF_BIT(bit) (1u << (bit))
/*$PAGE*/
/*
*********************************************************************************************************
* DEF_BIT_MASK()
*
* Description : Shift a bit mask.
*
* Argument(s) : bit_mask Bit mask to shift.
*
* bit_shift Number of bit positions to left-shift bit mask.
*
* Return(s) : Shifted bit mask.
*
* Caller(s) : various.
*
* Note(s) : (1) 'bit_shift' values that overflow the target CPU &/or compiler environment (e.g. negative
* or greater-than-CPU-data-size values) MAY generate compiler warnings &/or errors.
*********************************************************************************************************
*/
#define DEF_BIT_MASK(bit_mask, bit_shift) ((bit_mask) << (bit_shift))
/*
*********************************************************************************************************
* DEF_BIT_FIELD()
*
* Description : Create & shift a contiguous bit field.
*
* Argument(s) : bit_field Number of contiguous bits to set in the bit field.
*
* bit_shift Number of bit positions to left-shift bit field.
*
* Return(s) : Shifted bit field.
*
* Caller(s) : various.
*
* Note(s) : (1) 'bit_field'/'bit_shift' values that overflow the target CPU &/or compiler environment
* (e.g. negative or greater-than-CPU-data-size values) MAY generate compiler warnings
* &/or errors.
*********************************************************************************************************
*/
#define DEF_BIT_FIELD(bit_field, bit_shift) ((((bit_field) >= DEF_INT_CPU_NBR_BITS) ? (DEF_INT_CPU_U_MAX_VAL) \
: (DEF_BIT(bit_field) - 1)) \
<< (bit_shift))
/*$PAGE*/
/*
*********************************************************************************************************
* DEF_BIT_SET()
*
* Description : Set specified bit(s) in a value.
*
* Argument(s) : val Value to modify by setting specified bit(s).
*
* mask Mask of bits to set.
*
* Return(s) : Modified value with specified bit(s) set.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_BIT_SET(val, mask) { (val) |= (mask); }
/*
*********************************************************************************************************
* DEF_BIT_CLR()
*
* Description : Clear specified bit(s) in a value.
*
* Argument(s) : val Value to modify by clearing specified bit(s).
*
* mask Mask of bits to clear.
*
* Return(s) : Modified value with specified bit(s) clear.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_BIT_CLR(val, mask) { (val) &= ~(mask); }
/*$PAGE*/
/*
*********************************************************************************************************
* DEF_BIT_IS_SET()
*
* Description : Determine if specified bit(s) in a value are set.
*
* Argument(s) : val Value to check for specified bit(s) set.
*
* mask Mask of bits to check if set.
*
* Return(s) : DEF_YES, if ALL specified bit(s) are set in value.
*
* DEF_NO, if ALL specified bit(s) are NOT set in value.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_BIT_IS_SET(val, mask) ((((val) & (mask)) == (mask)) ? (DEF_YES) : (DEF_NO ))
/*
*********************************************************************************************************
* DEF_BIT_IS_CLR()
*
* Description : Determine if specified bit(s) in a value are clear.
*
* Argument(s) : val Value to check for specified bit(s) clear.
*
* mask Mask of bits to check if clear.
*
* Return(s) : DEF_YES, if ALL specified bit(s) are clear in value.
*
* DEF_NO, if ALL specified bit(s) are NOT clear in value.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_BIT_IS_CLR(val, mask) (((val) & (mask)) ? (DEF_NO ) : (DEF_YES))
/*$PAGE*/
/*
*********************************************************************************************************
* DEF_BIT_IS_SET_ANY()
*
* Description : Determine if any specified bit(s) in a value are set.
*
* Argument(s) : val Value to check for specified bit(s) set.
*
* mask Mask of bits to check if set.
*
* Return(s) : DEF_YES, if ANY specified bit(s) are set in value.
*
* DEF_NO, if ALL specified bit(s) are NOT set in value.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_BIT_IS_SET_ANY(val, mask) (((val) & (mask)) ? (DEF_YES) : (DEF_NO ))
/*
*********************************************************************************************************
* DEF_BIT_IS_CLR_ANY()
*
* Description : Determine if any specified bit(s) in a value are clear.
*
* Argument(s) : val Value to check for specified bit(s) clear.
*
* mask Mask of bits to check if clear.
*
* Return(s) : DEF_YES, if ANY specified bit(s) are clear in value.
*
* DEF_NO, if ALL specified bit(s) are NOT clear in value.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_BIT_IS_CLR_ANY(val, mask) ((((val) & (mask)) != (mask)) ? (DEF_YES) : (DEF_NO ))
/*$PAGE*/
/*
*********************************************************************************************************
* MATH MACRO'S
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* DEF_MIN()
*
* Description : Determine the minimum of two values.
*
* Argument(s) : a First value.
*
* b Second value.
*
* Return(s) : Minimum of the two values.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_MIN(a, b) (((a) < (b)) ? (a) : (b))
/*
*********************************************************************************************************
* DEF_MAX()
*
* Description : Determine the maximum of two values.
*
* Argument(s) : a First value.
*
* b Second value.
*
* Return(s) : Maximum of the two values.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_MAX(a, b) (((a) > (b)) ? (a) : (b))
/*$PAGE*/
/*
*********************************************************************************************************
* DEF_ABS()
*
* Description : Determine the absolute value of a value.
*
* Argument(s) : a Value to calculate absolute value.
*
* Return(s) : Absolute value of the value.
*
* Caller(s) : various.
*
* Note(s) : none.
*********************************************************************************************************
*/
#define DEF_ABS(a) (((a) < 0) ? (-(a)) : (a))
/*$PAGE*/
/*
*********************************************************************************************************
* MODULE END
*********************************************************************************************************
*/
#endif /* End of lib def module include. */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<Workspace>
<ConfigDictionary>
<CurrentConfigs><Project>solarium/Flash</Project></CurrentConfigs></ConfigDictionary>
<Desktop>
<Static>
<Workspace>
<ColumnWidths>
<Column0>262</Column0><Column1>27</Column1><Column2>27</Column2><Column3>27</Column3></ColumnWidths>
</Workspace>
<Find-in-Files>
<ColumnWidth0>629</ColumnWidth0><ColumnWidth1>62</ColumnWidth1><ColumnWidth2>754</ColumnWidth2></Find-in-Files>
<Build>
<ColumnWidth0>20</ColumnWidth0><ColumnWidth1>916</ColumnWidth1><ColumnWidth2>244</ColumnWidth2><ColumnWidth3>61</ColumnWidth3></Build>
<Debug-Log><ColumnWidth0>20</ColumnWidth0><ColumnWidth1>1222</ColumnWidth1></Debug-Log><TerminalIO/></Static>
<Windows>
<Wnd0>
<Tabs>
<Tab>
<Identity>TabID-4922-2358</Identity>
<TabName>Workspace</TabName>
<Factory>Workspace</Factory>
<Session>
<NodeDict><ExpandedNode>solarium</ExpandedNode><ExpandedNode>solarium/DRIVERS</ExpandedNode><ExpandedNode>solarium/DRIVERS/ccnet</ExpandedNode><ExpandedNode>solarium/DRIVERS/fram</ExpandedNode><ExpandedNode>solarium/DRIVERS/keyboard</ExpandedNode><ExpandedNode>solarium/PROJECT</ExpandedNode><ExpandedNode>solarium/PROJECT/app</ExpandedNode><ExpandedNode>solarium/PROJECT/data</ExpandedNode><ExpandedNode>solarium/PROJECT/menu</ExpandedNode></NodeDict></Session>
</Tab>
</Tabs>
<SelectedTab>0</SelectedTab></Wnd0><Wnd1>
<Tabs>
<Tab>
<Identity>TabID-31733-19868</Identity>
<TabName>Find in Files</TabName>
<Factory>Find-in-Files</Factory>
<Session/>
</Tab>
<Tab>
<Identity>TabID-17681-20541</Identity>
<TabName>Build</TabName>
<Factory>Build</Factory>
<Session/>
</Tab>
<Tab><Identity>TabID-13605-29828</Identity><TabName>Debug Log</TabName><Factory>Debug-Log</Factory><Session/></Tab><Tab><Identity>TabID-31897-1342</Identity><TabName>Breakpoints</TabName><Factory>Breakpoints</Factory></Tab></Tabs>
<SelectedTab>1</SelectedTab></Wnd1></Windows>
<Editor>
<Pane><Tab><Factory>TextEditor</Factory><Filename>$WS_DIR$\PROJECT\version.h</Filename><XPos>0</XPos><YPos>0</YPos><SelStart>77</SelStart><SelEnd>77</SelEnd></Tab><ActiveTab>0</ActiveTab></Pane><ActivePane>0</ActivePane><Sizes><Pane><X>1000000</X><Y>1000000</Y></Pane></Sizes><SplitMode>1</SplitMode></Editor>
<Positions>
<Top><Row0><Sizes><Toolbar-04c8fe98><key>iaridepm.enu1</key></Toolbar-04c8fe98></Sizes></Row0></Top><Left><Row0><Sizes><Wnd0><Rect><Top>-2</Top><Left>-2</Left><Bottom>711</Bottom><Right>357</Right><x>-2</x><y>-2</y><xscreen>224</xscreen><yscreen>0</yscreen><sizeHorzCX>116788</sizeHorzCX><sizeHorzCY>0</sizeHorzCY><sizeVertCX>187174</sizeVertCX><sizeVertCY>730533</sizeVertCY></Rect></Wnd0></Sizes></Row0></Left><Right><Row0><Sizes/></Row0></Right><Bottom><Row0><Sizes><Wnd1><Rect><Top>-2</Top><Left>-2</Left><Bottom>217</Bottom><Right>1920</Right><x>-2</x><y>-2</y><xscreen>1922</xscreen><yscreen>219</yscreen><sizeHorzCX>1002086</sizeHorzCX><sizeHorzCY>224385</sizeHorzCY><sizeVertCX>116788</sizeVertCX><sizeVertCY>0</sizeVertCY></Rect></Wnd1></Sizes></Row0></Bottom><Float><Sizes/></Float></Positions>
</Desktop>
</Workspace>

View File

@ -0,0 +1,711 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
* MUTUAL EXCLUSION SEMAPHORE MANAGEMENT
*
* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* File : OS_MUTEX.C
* By : Jean J. Labrosse
* Version : V2.85
*
* LICENSING TERMS:
* ---------------
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
* licensing fee.
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE
#include <ucos_ii.h>
#endif
#if OS_MUTEX_EN > 0
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
#define OS_MUTEX_KEEP_LOWER_8 (INT16U)0x00FFu
#define OS_MUTEX_KEEP_UPPER_8 (INT16U)0xFF00u
#define OS_MUTEX_AVAILABLE (INT16U)0x00FFu
/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
static void OSMutex_RdyAtPrio(OS_TCB *ptcb, INT8U prio);
/*$PAGE*/
/*
*********************************************************************************************************
* ACCEPT MUTUAL EXCLUSION SEMAPHORE
*
* Description: This function checks the mutual exclusion semaphore to see if a resource is available.
* Unlike OSMutexPend(), OSMutexAccept() does not suspend the calling task if the resource is
* not available or the event did not occur.
*
* Arguments : pevent is a pointer to the event control block
*
* perr is a pointer to an error code which will be returned to your application:
* OS_ERR_NONE if the call was successful.
* OS_ERR_EVENT_TYPE if 'pevent' is not a pointer to a mutex
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
* OS_ERR_PEND_ISR if you called this function from an ISR
* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is
* HIGHER (i.e. a lower number) than the PIP. This error
* indicates that you did not set the PIP higher (lower
* number) than ALL the tasks that compete for the Mutex.
* Unfortunately, this is something that could not be
* detected when the Mutex is created because we don't know
* what tasks will be using the Mutex.
*
* Returns : == OS_TRUE if the resource is available, the mutual exclusion semaphore is acquired
* == OS_FALSE a) if the resource is not available
* b) you didn't pass a pointer to a mutual exclusion semaphore
* c) you called this function from an ISR
*
* Warning(s) : This function CANNOT be called from an ISR because mutual exclusion semaphores are
* intended to be used by tasks only.
*********************************************************************************************************
*/
#if OS_MUTEX_ACCEPT_EN > 0
BOOLEAN OSMutexAccept (OS_EVENT *pevent, INT8U *perr)
{
INT8U pip; /* Priority Inheritance Priority (PIP) */
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (OS_FALSE);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return (OS_FALSE);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return (OS_FALSE);
}
if (OSIntNesting > 0) { /* Make sure it's not called from an ISR */
*perr = OS_ERR_PEND_ISR;
return (OS_FALSE);
}
OS_ENTER_CRITICAL(); /* Get value (0 or 1) of Mutex */
pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP from mutex */
if ((pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Mask off LSByte (Acquire Mutex) */
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save current task priority in LSByte */
pevent->OSEventPtr = (void *)OSTCBCur; /* Link TCB of task owning Mutex */
if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */
OS_EXIT_CRITICAL(); /* ... than current task! */
*perr = OS_ERR_PIP_LOWER;
} else {
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
}
return (OS_TRUE);
}
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (OS_FALSE);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CREATE A MUTUAL EXCLUSION SEMAPHORE
*
* Description: This function creates a mutual exclusion semaphore.
*
* Arguments : prio is the priority to use when accessing the mutual exclusion semaphore. In
* other words, when the semaphore is acquired and a higher priority task
* attempts to obtain the semaphore then the priority of the task owning the
* semaphore is raised to this priority. It is assumed that you will specify
* a priority that is LOWER in value than ANY of the tasks competing for the
* mutex.
*
* perr is a pointer to an error code which will be returned to your application:
* OS_ERR_NONE if the call was successful.
* OS_ERR_CREATE_ISR if you attempted to create a MUTEX from an ISR
* OS_ERR_PRIO_EXIST if a task at the priority inheritance priority
* already exist.
* OS_ERR_PEVENT_NULL No more event control blocks available.
* OS_ERR_PRIO_INVALID if the priority you specify is higher that the
* maximum allowed (i.e. > OS_LOWEST_PRIO)
*
* Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the
* created mutex.
* == (void *)0 if an error is detected.
*
* Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number
* of the task owning the mutex or 0xFF if no task owns the mutex.
*
* 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number
* to use to reduce priority inversion.
*********************************************************************************************************
*/
OS_EVENT *OSMutexCreate (INT8U prio, INT8U *perr)
{
OS_EVENT *pevent;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return ((OS_EVENT *)0);
}
if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */
*perr = OS_ERR_PRIO_INVALID;
return ((OS_EVENT *)0);
}
#endif
if (OSIntNesting > 0) { /* See if called from ISR ... */
*perr = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */
return ((OS_EVENT *)0);
}
OS_ENTER_CRITICAL();
if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */
OS_EXIT_CRITICAL(); /* Task already exist at priority ... */
*perr = OS_ERR_PRIO_EXIST; /* ... inheritance priority */
return ((OS_EVENT *)0);
}
OSTCBPrioTbl[prio] = OS_TCB_RESERVED; /* Reserve the table entry */
pevent = OSEventFreeList; /* Get next free event control block */
if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */
OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */
OS_EXIT_CRITICAL();
*perr = OS_ERR_PEVENT_NULL; /* No more event control blocks */
return (pevent);
}
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */
OS_EXIT_CRITICAL();
pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
pevent->OSEventCnt = (INT16U)((INT16U)prio << 8) | OS_MUTEX_AVAILABLE; /* Resource is avail. */
pevent->OSEventPtr = (void *)0; /* No task owning the mutex */
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?';
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
OS_EventWaitListInit(pevent);
*perr = OS_ERR_NONE;
return (pevent);
}
/*$PAGE*/
/*
*********************************************************************************************************
* DELETE A MUTEX
*
* Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it.
*
* Arguments : pevent is a pointer to the event control block associated with the desired mutex.
*
* opt determines delete options as follows:
* opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending
* opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are waiting.
* In this case, all the tasks pending will be readied.
*
* perr is a pointer to an error code that can contain one of the following values:
* OS_ERR_NONE The call was successful and the mutex was deleted
* OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR
* OS_ERR_INVALID_OPT An invalid option was specified
* OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
*
* Returns : pevent upon error
* (OS_EVENT *)0 if the mutex was successfully deleted.
*
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
* the mutex MUST check the return code of OSMutexPend().
*
* 2) This call can potentially disable interrupts for a long time. The interrupt disable
* time is directly proportional to the number of tasks waiting on the mutex.
*
* 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the
* resource(s) will no longer be guarded by the mutex.
*
* 4) IMPORTANT: In the 'OS_DEL_ALWAYS' case, we assume that the owner of the Mutex (if there
* is one) is ready-to-run and is thus NOT pending on another kernel object or
* has delayed itself. In other words, if a task owns the mutex being deleted,
* that task will be made ready-to-run at its original priority.
*********************************************************************************************************
*/
#if OS_MUTEX_DEL_EN
OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *perr)
{
BOOLEAN tasks_waiting;
OS_EVENT *pevent_return;
INT8U pip; /* Priority inheritance priority */
INT8U prio;
OS_TCB *ptcb;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (pevent);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return (pevent);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return (pevent);
}
if (OSIntNesting > 0) { /* See if called from ISR ... */
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
return (pevent);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mutex */
tasks_waiting = OS_TRUE; /* Yes */
} else {
tasks_waiting = OS_FALSE; /* No */
}
switch (opt) {
case OS_DEL_NO_PEND: /* DELETE MUTEX ONLY IF NO TASK WAITING --- */
if (tasks_waiting == OS_FALSE) {
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?'; /* Unknown name */
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
pip = (INT8U)(pevent->OSEventCnt >> 8);
OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
pevent->OSEventCnt = 0;
OSEventFreeList = pevent;
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */
} else {
OS_EXIT_CRITICAL();
*perr = OS_ERR_TASK_WAITING;
pevent_return = pevent;
}
break;
case OS_DEL_ALWAYS: /* ALWAYS DELETE THE MUTEX ---------------- */
pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP of mutex */
prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original prio */
ptcb = (OS_TCB *)pevent->OSEventPtr;
if (ptcb != (OS_TCB *)0) { /* See if any task owns the mutex */
if (ptcb->OSTCBPrio == pip) { /* See if original prio was changed */
OSMutex_RdyAtPrio(ptcb, prio); /* Yes, Restore the task's original prio */
}
}
while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mutex */
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);
}
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?'; /* Unknown name */
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
pip = (INT8U)(pevent->OSEventCnt >> 8);
OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
pevent->OSEventCnt = 0;
OSEventFreeList = pevent; /* Get next free event control block */
OS_EXIT_CRITICAL();
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
OS_Sched(); /* Find highest priority task ready to run */
}
*perr = OS_ERR_NONE;
pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */
break;
default:
OS_EXIT_CRITICAL();
*perr = OS_ERR_INVALID_OPT;
pevent_return = pevent;
break;
}
return (pevent_return);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* PEND ON MUTUAL EXCLUSION SEMAPHORE
*
* Description: This function waits for a mutual exclusion semaphore.
*
* Arguments : pevent is a pointer to the event control block associated with the desired
* mutex.
*
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
* wait for the resource up to the amount of time specified by this argument.
* If you specify 0, however, your task will wait forever at the specified
* mutex or, until the resource becomes available.
*
* perr is a pointer to where an error message will be deposited. Possible error
* messages are:
* OS_ERR_NONE The call was successful and your task owns the mutex
* OS_ERR_TIMEOUT The mutex was not available within the specified 'timeout'.
* OS_ERR_PEND_ABORT The wait on the mutex was aborted.
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
* would lead to a suspension.
* OS_ERR_PIP_LOWER If the priority of the task that owns the Mutex is
* HIGHER (i.e. a lower number) than the PIP. This error
* indicates that you did not set the PIP higher (lower
* number) than ALL the tasks that compete for the Mutex.
* Unfortunately, this is something that could not be
* detected when the Mutex is created because we don't know
* what tasks will be using the Mutex.
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
*
* Returns : none
*
* Note(s) : 1) The task that owns the Mutex MUST NOT pend on any other event while it owns the mutex.
*
* 2) You MUST NOT change the priority of the task that owns the mutex
*********************************************************************************************************
*/
void OSMutexPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr)
{
INT8U pip; /* Priority Inheritance Priority (PIP) */
INT8U mprio; /* Mutex owner priority */
BOOLEAN rdy; /* Flag indicating task was ready */
OS_TCB *ptcb;
OS_EVENT *pevent2;
INT8U y;
INT8U pend_stat;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return;
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return;
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return;
}
if (OSIntNesting > 0) { /* See if called from ISR ... */
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
return;
}
if (OSLockNesting > 0) { /* See if called with scheduler locked ... */
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
return;
}
OS_ENTER_CRITICAL();
pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get PIP from mutex */
/* Is Mutex available? */
if ((INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8) == OS_MUTEX_AVAILABLE) {
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Yes, Acquire the resource */
pevent->OSEventCnt |= OSTCBCur->OSTCBPrio; /* Save priority of owning task */
pevent->OSEventPtr = (void *)OSTCBCur; /* Point to owning task's OS_TCB */
if (OSTCBCur->OSTCBPrio <= pip) { /* PIP 'must' have a SMALLER prio ... */
OS_EXIT_CRITICAL(); /* ... than current task! */
*perr = OS_ERR_PIP_LOWER;
} else {
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
}
return;
}
mprio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* No, Get priority of mutex owner */
ptcb = (OS_TCB *)(pevent->OSEventPtr); /* Point to TCB of mutex owner */
if (ptcb->OSTCBPrio > pip) { /* Need to promote prio of owner?*/
if (mprio > OSTCBCur->OSTCBPrio) {
y = ptcb->OSTCBY;
if ((OSRdyTbl[y] & ptcb->OSTCBBitX) != 0) { /* See if mutex owner is ready */
OSRdyTbl[y] &= ~ptcb->OSTCBBitX; /* Yes, Remove owner from Rdy ...*/
if (OSRdyTbl[y] == 0) { /* ... list at current prio */
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
rdy = OS_TRUE;
} else {
pevent2 = ptcb->OSTCBEventPtr;
if (pevent2 != (OS_EVENT *)0) { /* Remove from event wait list */
if ((pevent2->OSEventTbl[ptcb->OSTCBY] &= ~ptcb->OSTCBBitX) == 0) {
pevent2->OSEventGrp &= ~ptcb->OSTCBBitY;
}
}
rdy = OS_FALSE; /* No */
}
ptcb->OSTCBPrio = pip; /* Change owner task prio to PIP */
#if OS_LOWEST_PRIO <= 63
ptcb->OSTCBY = (INT8U)( ptcb->OSTCBPrio >> 3);
ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x07);
ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX);
#else
ptcb->OSTCBY = (INT8U)((ptcb->OSTCBPrio >> 4) & 0xFF);
ptcb->OSTCBX = (INT8U)( ptcb->OSTCBPrio & 0x0F);
ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY);
ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX);
#endif
if (rdy == OS_TRUE) { /* If task was ready at owner's priority ...*/
OSRdyGrp |= ptcb->OSTCBBitY; /* ... make it ready at new priority. */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
} else {
pevent2 = ptcb->OSTCBEventPtr;
if (pevent2 != (OS_EVENT *)0) { /* Add to event wait list */
pevent2->OSEventGrp |= ptcb->OSTCBBitY;
pevent2->OSEventTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
}
}
OSTCBPrioTbl[pip] = ptcb;
}
}
OSTCBCur->OSTCBStat |= OS_STAT_MUTEX; /* Mutex not available, pend current task */
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
OSTCBCur->OSTCBDly = timeout; /* Store timeout in current task's TCB */
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
OS_EXIT_CRITICAL();
OS_Sched(); /* Find next highest priority task ready */
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we timed out during the pend */
pend_stat = OSTCBCur->OSTCBStatPend;
OS_EventTOAbort(pevent);
OS_EXIT_CRITICAL();
switch (pend_stat) {
case OS_STAT_PEND_TO:
default:
*perr = OS_ERR_TIMEOUT; /* Indicate that we didn't get mutex within TO */
break;
case OS_STAT_PEND_ABORT:
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted getting mutex */
break;
}
return;
}
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* POST TO A MUTUAL EXCLUSION SEMAPHORE
*
* Description: This function signals a mutual exclusion semaphore
*
* Arguments : pevent is a pointer to the event control block associated with the desired
* mutex.
*
* Returns : OS_ERR_NONE The call was successful and the mutex was signaled.
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
* OS_ERR_PEVENT_NULL 'pevent' is a NULL pointer
* OS_ERR_POST_ISR Attempted to post from an ISR (not valid for MUTEXes)
* OS_ERR_NOT_MUTEX_OWNER The task that did the post is NOT the owner of the MUTEX.
* OS_ERR_PIP_LOWER If the priority of the new task that owns the Mutex is
* HIGHER (i.e. a lower number) than the PIP. This error
* indicates that you did not set the PIP higher (lower
* number) than ALL the tasks that compete for the Mutex.
* Unfortunately, this is something that could not be
* detected when the Mutex is created because we don't know
* what tasks will be using the Mutex.
*********************************************************************************************************
*/
INT8U OSMutexPost (OS_EVENT *pevent)
{
INT8U pip; /* Priority inheritance priority */
INT8U prio;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSIntNesting > 0) { /* See if called from ISR ... */
return (OS_ERR_POST_ISR); /* ... can't POST mutex from an ISR */
}
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
pip = (INT8U)(pevent->OSEventCnt >> 8); /* Get priority inheritance priority of mutex */
prio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8); /* Get owner's original priority */
if (OSTCBCur != (OS_TCB *)pevent->OSEventPtr) { /* See if posting task owns the MUTEX */
OS_EXIT_CRITICAL();
return (OS_ERR_NOT_MUTEX_OWNER);
}
if (OSTCBCur->OSTCBPrio == pip) { /* Did we have to raise current task's priority? */
OSMutex_RdyAtPrio(OSTCBCur, prio); /* Restore the task's original priority */
}
OSTCBPrioTbl[pip] = OS_TCB_RESERVED; /* Reserve table entry */
if (pevent->OSEventGrp != 0) { /* Any task waiting for the mutex? */
/* Yes, Make HPT waiting for mutex ready */
prio = OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX, OS_STAT_PEND_OK);
pevent->OSEventCnt &= OS_MUTEX_KEEP_UPPER_8; /* Save priority of mutex's new owner */
pevent->OSEventCnt |= prio;
pevent->OSEventPtr = OSTCBPrioTbl[prio]; /* Link to new mutex owner's OS_TCB */
if (prio <= pip) { /* PIP 'must' have a SMALLER prio ... */
OS_EXIT_CRITICAL(); /* ... than current task! */
OS_Sched(); /* Find highest priority task ready to run */
return (OS_ERR_PIP_LOWER);
} else {
OS_EXIT_CRITICAL();
OS_Sched(); /* Find highest priority task ready to run */
return (OS_ERR_NONE);
}
}
pevent->OSEventCnt |= OS_MUTEX_AVAILABLE; /* No, Mutex is now available */
pevent->OSEventPtr = (void *)0;
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
/*$PAGE*/
/*
*********************************************************************************************************
* QUERY A MUTUAL EXCLUSION SEMAPHORE
*
* Description: This function obtains information about a mutex
*
* Arguments : pevent is a pointer to the event control block associated with the desired mutex
*
* p_mutex_data is a pointer to a structure that will contain information about the mutex
*
* Returns : OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_QUERY_ISR If you called this function from an ISR
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
* OS_ERR_PDATA_NULL If 'p_mutex_data' is a NULL pointer
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mutex.
*********************************************************************************************************
*/
#if OS_MUTEX_QUERY_EN > 0
INT8U OSMutexQuery (OS_EVENT *pevent, OS_MUTEX_DATA *p_mutex_data)
{
INT8U i;
#if OS_LOWEST_PRIO <= 63
INT8U *psrc;
INT8U *pdest;
#else
INT16U *psrc;
INT16U *pdest;
#endif
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSIntNesting > 0) { /* See if called from ISR ... */
return (OS_ERR_QUERY_ISR); /* ... can't QUERY mutex from an ISR */
}
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (p_mutex_data == (OS_MUTEX_DATA *)0) { /* Validate 'p_mutex_data' */
return (OS_ERR_PDATA_NULL);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
p_mutex_data->OSMutexPIP = (INT8U)(pevent->OSEventCnt >> 8);
p_mutex_data->OSOwnerPrio = (INT8U)(pevent->OSEventCnt & OS_MUTEX_KEEP_LOWER_8);
if (p_mutex_data->OSOwnerPrio == 0xFF) {
p_mutex_data->OSValue = OS_TRUE;
} else {
p_mutex_data->OSValue = OS_FALSE;
}
p_mutex_data->OSEventGrp = pevent->OSEventGrp; /* Copy wait list */
psrc = &pevent->OSEventTbl[0];
pdest = &p_mutex_data->OSEventTbl[0];
for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
*pdest++ = *psrc++;
}
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
#endif /* OS_MUTEX_QUERY_EN */
/*$PAGE*/
/*
*********************************************************************************************************
* RESTORE A TASK BACK TO ITS ORIGINAL PRIORITY
*
* Description: This function makes a task ready at the specified priority
*
* Arguments : ptcb is a pointer to OS_TCB of the task to make ready
*
* prio is the desired priority
*
* Returns : none
*********************************************************************************************************
*/
static void OSMutex_RdyAtPrio (OS_TCB *ptcb, INT8U prio)
{
INT8U y;
y = ptcb->OSTCBY; /* Remove owner from ready list at 'pip' */
OSRdyTbl[y] &= ~ptcb->OSTCBBitX;
if (OSRdyTbl[y] == 0) {
OSRdyGrp &= ~ptcb->OSTCBBitY;
}
ptcb->OSTCBPrio = prio;
#if OS_LOWEST_PRIO <= 63
ptcb->OSTCBY = (INT8U)((prio >> (INT8U)3) & (INT8U)0x07);
ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x07);
ptcb->OSTCBBitY = (INT8U)(1 << ptcb->OSTCBY);
ptcb->OSTCBBitX = (INT8U)(1 << ptcb->OSTCBX);
#else
ptcb->OSTCBY = (INT8U)((prio >> (INT8U)4) & (INT8U)0x0F);
ptcb->OSTCBX = (INT8U) (prio & (INT8U)0x0F);
ptcb->OSTCBBitY = (INT16U)(1 << ptcb->OSTCBY);
ptcb->OSTCBBitX = (INT16U)(1 << ptcb->OSTCBX);
#endif
OSRdyGrp |= ptcb->OSTCBBitY; /* Make task ready at original priority */
OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
OSTCBPrioTbl[prio] = ptcb;
}
#endif /* OS_MUTEX_EN */

View File

@ -0,0 +1,38 @@
#include "cpu.h"
#include "datadesc.h"
#include "journal.h"
typedef struct{
CPU_INT32U SerialNum;
TChannelConfig ChannelConfig;
TDeviceConfig DeviceConfig;
// ñ÷åò÷èêè
TCounters Counters;
// äëèííûå ñ÷åò÷èêè ñ CRC16
TCountersLong CountersLong;
CPU_INT32U FRAM_AcceptedMoney;
CPU_INT32U crc_AcceptedMoney;
// æóðíàë îøèáîê
TErrorRecord ErrorRecords[ERROR_RECORDS_NUM];
// æóðíàë ñîáûòèé
TEventRecord EventRecords[EVENT_RECORDS_NUM];
CPU_INT32U Pass;
CPU_INT32U crc_Pass;
CPU_INT32U LastEmailTime;
CPU_INT32U IncasEmailFlag;
CPU_INT32U IncasMoney;
CPU_INT32U IncasTime;
}TFramMap;

View File

@ -0,0 +1,28 @@
#ifndef _MODEM_TASK_H_
#define _MODEM_TASK_H_
#include "app_serv.h"
// äëèíà î÷åðåäè çàäàíèé ìîäåìà
#define MODEM_QUERY_LEN 8
// çàäåðæêà ìåæäó âûïîëíåíèåì çàäàíèé ìîäåìà
#define MODEM_TASK_DELAY 10000
enum{
MODEM_TASK_NONE = 0,
MODEM_TASK_SEND_STATISTICS,
MODEM_TASK_SEND_TEST_MSG,
MODEM_TASK_RECONNECT,
MODEM_TASK_SEND_INCAS,
};
extern OS_STK ModemTaskStk[MODEM_TASK_STK_SIZE];
extern OS_EVENT *ModemQuery;
extern void *ModemTbl[MODEM_QUERY_LEN];
extern void ModemTask(void *p_arg);
extern void PostModemTask(int new_task);
#endif //#ifndef _MODEM_TASK_H_

View File

@ -0,0 +1,18 @@
#ifndef _COIN_H_
#define _COIN_H_
#define COIN_IMP_MIN_LEN 2200 // ìñ/100
#define COIN_IMP_MAX_LEN 9000 // ìñ/100
extern void InitCoin(void);
extern CPU_INT32U GetCoinCount(void);
extern CPU_INT32U GetResetCoinCount(void);
extern void CoinDisable(void);
extern void CoinEnable(void);
#endif //#ifndef _COIN_H_

View File

@ -0,0 +1,78 @@
#include <includes.h>
#include "app_serv.h"
#include "lcd.h"
#include "spi.h"
#include "keyboard.h"
static OS_STK AppTaskStartStk[APP_TASK_START_STK_SIZE];
static void AppTaskStart(void *p_arg);
/*
*********************************************************************************************************
* main()
*
* Description : This is the standard entry point for C code.
*
* Arguments : none
*
* Returns : none
*********************************************************************************************************
*/
void main (void)
{
BSP_IntDisAll(); /* Disable all interrupts until we are ready to accept them */
OSInit(); /* Initialize "uC/OS-II, The Real-Time Kernel" */
OSTaskCreate(AppTaskStart, (void *)0, (OS_STK *)&AppTaskStartStk[APP_TASK_START_STK_SIZE-1], APP_TASK_START_PRIO);
OSStart(); /* Start multitasking (i.e. give control to uC/OS-II) */
}
/*
*********************************************************************************************************
* AppTaskStart()
*
* Description : The startup task. The uC/OS-II ticker should only be initialize once multitasking starts.
*
* Argument(s) : p_arg Argument passed to 'AppTaskStart()' by 'OSTaskCreate()'.
*
* Return(s) : none.
*
* Note(s) : (1) The first line of code is used to prevent a compiler warning because 'p_arg' is not
* used. The compiler should not generate any code for this statement.
*
* (2) Interrupts are enabled once the task starts because the I-bit of the CCR register was
* set to 0 by 'OSTaskCreate()'.
*********************************************************************************************************
*/
unsigned char arr[256];
static void AppTaskStart (void *p_arg)
{
(void)p_arg;
BSP_Init(); /* Initialize BSP functions */
#if OS_TASK_STAT_EN > 0
OSStatInit(); /* Determine CPU capacity */
#endif
OSTimeDly(1000);
// èíèöèàëèçàöèÿ ïåðèôåðèè
InitLcd();
InitKbrd();
SpiInit();
// ïîëüçîâàòåëüñêàÿ èíèöèàëèçàöèÿ
UserStartupFunc();
while (1) { /* Task body, always written as an infinite loop. */
OSTimeDly(1000);
//PostUserEvent(EVENT_SEC);
}
}

View File

@ -0,0 +1,982 @@
#include <includes.h>
#include "app_serv.h"
#include "fiscal.h"
#include "fr.h"
#include "uart0.h"
#include "data.h"
#include "datadesc.h"
#include "journal.h"
#include "time.h"
TFiscDevType FiscDevInfo;
static TFiscFullStatus FiscFullStatus;
CPU_INT08U FiscalConnState = FISCAL_NOCONN;
OS_EVENT *FLock = NULL;
//OS_EVENT *FReportLock = NULL;
//OS_STK FiscalTaskStk[FISCAL_TASK_STK_SIZE];
// ïðîâåðêà è îáðàáîòêà òåêóùåãî ñòàòóñà ÔÐ
int CheckFiscalStatus()
{
CPU_INT08U err;
int poll;
CPU_INT32U time1, time2;
CPU_INT32U enable;
GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX);
if (!enable) return 0;
time1 = time2 = OSTimeGet();
while (labs(time2 - time1) < WAIT_PRINT_TIMEOUT)
{
OSTimeDly(100);
time2 = OSTimeGet();
// ñíà÷àëà ïîëëèì
poll = FiscPollExt();
if (poll == FISC_UNDEF)
{
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
return -1;
}
else if (poll == FISC_BUSY)
{
continue;
}
// òåïåðü çàïðàøèâàåì ñòàòóñ
if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK)
{
if (err)
{
// åñòü êàêàÿ-òî ãëîáàëüíàÿ îøèáêà
if (err) SetFiscalErrorByCode(err);
FiscalConnState = FISCAL_CONN;
ClrErrorFlag(ERROR_FR_CONN);
}
else
{
// ïðîñòî íåò ñîåäèíåíèÿ
ClearFiscalErrors();
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
}
return -2;
}
// äàëåå ðàçáèðàåì ñòàòóñ
FiscalConnState = FISCAL_CONN;
ClrErrorFlag(ERROR_FR_CONN);
CPU_INT16U flags;
memcpy(&flags, &FiscFullStatus.Flags, sizeof(CPU_INT16U));
// ÊÐÈÒÈ×ÍÛÅ ÔËÀÃÈ:
// ÝÊËÇ (0 íåò, 1 åñòü)
if (!(flags & (1L<<5)))
{
// íåò ÝÊËÇ
SetFiscalErrorByCode(FR_ERROR_CODE_a1);
return -3;
}
else
{
ClrFiscalErrorByCode(FR_ERROR_CODE_a1);
}
ClrFiscalErrorByCode(FR_ERROR_CODE_6b);
// ÏÎÄÐÅÆÈÌ
switch (FiscFullStatus.SubMode)
{
case 1:
// 1. Ïàññèâíîå îòñóòñòâèå áóìàãè ÔÐ íå â ôàçå ïå÷àòè îïåðàöèè íå ïðèíèìàåò îò
// õîñòà êîìàíäû, ñâÿçàííûå ñ ïå÷àòüþ íà òîì äîêóìåíòå, äàò÷èê êîòîðîãî ñîîáùàåò îá
// îòñóòñòâèè áóìàãè.
SetFiscalErrorByCode(FR_ERROR_CODE_6b);
return -4;
case 2:
// 2. Àêòèâíîå îòñóòñòâèå áóìàãè ÔÐ â ôàçå ïå÷àòè îïåðàöèè ïðèíèìàåò òîëüêî
// êîìàíäû, íå ñâÿçàííûå ñ ïå÷àòüþ. Ïåðåõîä èç ýòîãî ïîäðåæèìà òîëüêî â ïîäðåæèì 3.
SetFiscalErrorByCode(FR_ERROR_CODE_6b);
return -5;
case 3:
// 3. Ïîñëå àêòèâíîãî îòñóòñòâèÿ áóìàãè ÔÐ æäåò êîìàíäó ïðîäîëæåíèÿ ïå÷àòè. Êðîìå
// ýòîãî ïðèíèìàåò êîìàíäû, íå ñâÿçàííûå ñ ïå÷àòüþ.
SetFiscalErrorByCode(FR_ERROR_CODE_6b);
// äîïå÷àòûâàåì ÷åê
FiscPrintContinue(DEFAULT_PASS, &err);
return -6;
case 4: //Ôàçà ïå÷àòè îïåðàöèè ïîëíûõ ôèñêàëüíûõ îò÷åòîâ
case 5: //Ôàçà ïå÷àòè îïåðàöèè
continue;
default:
break;
}
// ÐÅÆÈÌ
switch (FiscFullStatus.Mode)
{
case 0:
// 0. Ïðèíòåð â ðàáî÷åì ðåæèìå.
// èëè ïå÷àòü îò÷åòîâ èç áóôåðà
// OK
ClearFiscalErrors();
goto check_exit;
case 1:
// 1. Âûäà÷à äàííûõ.
// OK
ClearFiscalErrors();
goto check_exit;
case 2:
// 2. Îòêðûòàÿ ñìåíà, 24 ÷àñà íå êîí÷èëèñü.
// OK
ClearFiscalErrors();
goto check_exit;
case 3:
// 3. Îòêðûòàÿ ñìåíà, 24 ÷àñà êîí÷èëèñü.
{
CPU_INT32U autoclose;
GetData(&EnableFiscalDayClearDesc, &autoclose, 0, DATA_FLAG_SYSTEM_INDEX);
if (autoclose==2)
{
// çàêðûâàåì ñìåíó â áóôåð
FiscPrintDayReportToBuf(30, &err);
// êàê òîëüêî ïåðåïîëíåíèå áóôåðà, ïå÷àòàåì èç áóôåðà
if (err == FR_ERROR_CODE_4b)
{
SetFiscalErrorByCode(err);
SaveEventRecord(0, JOURNAL_EVENT_PRINT_BUF, GetTimeSec());
FiscPrintDayReportsFromBuf(30, &err);
if (err)
{
SetFiscalErrorByCode(err);
return -8;
}
}
else if (err)
{
SetFiscalErrorByCode(err);
return -9;
}
}
else if (autoclose==1)
{
// çàêðîåì ñìåíó Z-îò÷åòîì
FiscPrintDayReportClear(30, &err);
SaveEventRecord(0, JOURNAL_EVENT_PRINT_Z, GetTimeSec());
if (err)
{
SetFiscalErrorByCode(err);
return -10;
}
}
else if (autoclose==0)
{
// îøèáêà - äîëæåí ïðèéòè îïåðàòîð è çàêðûòü ñìåíó
SetFiscalErrorByCode(FR_ERROR_CODE_4e);
return -11;
}
}
goto check_exit;
case 4:
// 4. Çàêðûòàÿ ñìåíà.
ClearFiscalErrors();
goto check_exit;
case 5:
// 5. Áëîêèðîâêà ïî íåïðàâèëüíîìó ïàðîëþ íàëîãîâîãî èíñïåêòîðà.
SetFiscalErrorByCode(FR_ERROR_CODE_4f);
goto check_exit;
case 6:
// 6. Îæèäàíèå ïîäòâåðæäåíèÿ ââîäà äàòû.
SetFiscalErrorByCode(FR_ERROR_CODE_c0);
goto check_exit;
case 8:
// 8. Îòêðûòûé äîêóìåíò:
// 8.0. Ïðîäàæà.
// 8.1. Ïîêóïêà.
// 8.2. Âîçâðàò ïðîäàæè.
// 8.3. Âîçâðàò ïîêóïêè.
// 8.4. Íåôèñêàëüíûé.
{
CPU_INT64U cash = 0;
CPU_INT08U tax[4] = {0,0,0,0};
FiscCloseBill(DEFAULT_PASS, &cash, &tax[0], "Ñïàñèáî çà ïîêóïêó!!!", &err);
if (err)
{
SetFiscalErrorByCode(err);
return -11;
}
}
goto check_exit;
case 12:
// èäåò ïå÷àòü Z-îò÷åòà
continue;
default:
goto check_exit;
}
}
check_exit:
if (labs(time2 - time1) < WAIT_PRINT_TIMEOUT)
{
// OK
return 0;
}
return -1;
}
#define FISCAL_BAUDS_COUNT 7
static const CPU_INT32U fiscal_bauds[FISCAL_BAUDS_COUNT] = {2400, 4800, 9600, 19200, 38400, 57600, 115200};
// ïîäêëþ÷åíèå ÔÐ
int ConnectFiscal(void)
{
int i, poll;
CPU_INT08U err;
CPU_INT32U enable;
GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX);
FPend();
if (enable)
{
int j;
// ïîëëèì
for (j = FISCAL_BAUDS_COUNT-1; j >= 0; j--)
{
Uart0_Init(fiscal_bauds[j]);
i = 10;
do
{
OSTimeDly(100);
poll = FiscPollExt();
if ((poll == FISC_READY) || (poll == FISC_BUSY)) break;
} while (--i);
// íå íàøëè ïîëëèíãîì
if (i)
{
break;
}
}
if (j < 0)
{
SetErrorFlag(ERROR_FR_CONN);
FiscalConnState = FISCAL_NOCONN;
FPost();
return -1;
}
// çàïðîñèì ñòàòóñ
if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK)
{
if (err)
{
// åñòü êàêàÿ-òî ãëîáàëüíàÿ îøèáêà
// íàäî ðàçîáðàòü ïîäðîáíî
if (err) SetFiscalErrorByCode(err);
}
else
{
// ïðîñòî íåò ñîåäèíåíèÿ
ClearFiscalErrors();
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
FPost();
return -2;
}
}
// ïîäêëþ÷èèëè
FiscalConnState = FISCAL_CONN;
ClrErrorFlag(ERROR_FR_CONN);
}
else
{
// ÔÐ îòêëþ÷åí
FiscalConnState = FISCAL_NOCONN;
ClearFiscalErrors();
ClrErrorFlag(ERROR_FR_CONN);
FPost();
return -3;
}
FPost();
return 0;
}
// ïîäêëþ÷åíèå ÔÐ
int ConnectFiscalFast(void)
{
int i, poll;
CPU_INT08U err;
CPU_INT32U enable;
GetData(&EnableFiscalDesc, &enable, 0, DATA_FLAG_SYSTEM_INDEX);
FPend();
if (enable)
{
int j;
// ïîëëèì
for (j = FISCAL_BAUDS_COUNT-1; j >= 0; j--)
{
Uart0_Init(fiscal_bauds[j]);
i = 2;
do
{
poll = FiscPollExt();
if ((poll == FISC_READY) || (poll == FISC_BUSY)) break;
} while (--i);
// íå íàøëè ïîëëèíãîì
if (i)
{
break;
}
}
if (j < 0)
{
SetErrorFlag(ERROR_FR_CONN);
FiscalConnState = FISCAL_NOCONN;
FPost();
return -1;
}
// çàïðîñèì ñòàòóñ
if (FiscGetFullStatus(DEFAULT_PASS, &FiscFullStatus, &err) != FISC_OK)
{
if (err)
{
// åñòü êàêàÿ-òî ãëîáàëüíàÿ îøèáêà
// íàäî ðàçîáðàòü ïîäðîáíî
if (err) SetFiscalErrorByCode(err);
}
else
{
// ïðîñòî íåò ñîåäèíåíèÿ
ClearFiscalErrors();
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
FPost();
return -2;
}
}
// ïîäêëþ÷èèëè
FiscalConnState = FISCAL_CONN;
ClrErrorFlag(ERROR_FR_CONN);
}
else
{
// ÔÐ îòêëþ÷åí
FiscalConnState = FISCAL_NOCONN;
ClearFiscalErrors();
ClrErrorFlag(ERROR_FR_CONN);
FPost();
return -3;
}
FPost();
return 0;
}
// èíèöèàëèçàöèÿ
void InitFiscal(void)
{
if (!FLock)
{
FLock = OSSemCreate(1);
//FReportLock = OSSemCreate(1);
//OSTaskCreate(FiscalTask, (void *)0, (OS_STK *)&FiscalTaskStk[FISCAL_TASK_STK_SIZE-1], FISCAL_TASK_PRIO);
}
if (ConnectFiscal()) return;
CheckFiscalStatus();
}
int IsFiscalConnected(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int retval;
if (FiscalConnState == FISCAL_CONN) retval=1;
else retval=0;
OS_EXIT_CRITICAL();
return retval;
}
// çàíÿòü
void FPend(void)
{
CPU_INT08U err;
do{
OSSemPend(FLock, 1, &err);
if (!err) break;
OSTimeDly(1);
}while (err);
}
// îñâîáîäèòü
void FPost(void)
{
OSTimeDly(200);
OSSemPost(FLock);
}
/*
// çàíÿòü
void FReportPend(void)
{
CPU_INT08U err;
do{
OSSemPend(FReportLock, 1, &err);
if (!err) break;
OSTimeDly(1);
}while (err);
}
// çàíÿòü 2
int FReportGet(void)
{
CPU_INT08U err;
OSSemPend(FReportLock, 1, &err);
if (!err) return 1;
return 0;
}
// îñâîáîäèòü
void FReportPost(void)
{
if (!FReportTest()) OSSemPost(FReportLock);
}
// ïðîâåðèòü
// 0 - íåäîñòóïåí
// >0 - äîñòóïåí
CPU_INT16U FReportTest(void)
{
return OSSemCheck(FReportLock);
}
*/
// î÷èñòêà âñåõ îøèáîê ÔÐ
void ClearFiscalErrors(void)
{
for (unsigned char i=ERROR_FR; i<ERROR_FR+FR_ERROR_NUMBER; i++)
{
ClrErrorFlag(i);
}
}
static const CPU_INT08U error_codes[FR_ERROR_NUMBER] = {
0x1,//Íåèñïðàâåí íàêîïèòåëü ÔÏ 1, ÔÏ 2 èëè ÷àñû
0x2,//Îòñóòñòâóåò ÔÏ 1
0x3,//Îòñóòñòâóåò ÔÏ 2
0x4,//Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå îáðàùåíèÿ ê ÔÏ
0x5,//Íåò çàïðîøåííûõ äàííûõ
0x6,//ÔÏ â ðåæèìå âûâîäà äàííûõ
0x7,//Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå äëÿ äàííîé ðåàëèçàöèè ÔÏ
0x8,//Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîé ðåàëèçàöèè ÔÏ
0x9,//Íåêîððåêòíàÿ äëèíà êîìàíäû
0x0A,//Ôîðìàò äàííûõ íå BCD
0x0B,//Íåèñïðàâíà ÿ÷åéêà ïàìÿòè ÔÏ ïðè çàïèñè èòîãà
0x11,//Íå ââåäåíà ëèöåíçèÿ
0x12,//Çàâîäñêîé íîìåð óæå ââåäåí
0x13,//Òåêóùàÿ äàòà ìåíüøå äàòû ïîñëåäíåé çàïèñè â ÔÏ
0x14,//Îáëàñòü ñìåííûõ èòîãîâ ÔÏ ïåðåïîëíåíà
0x15,//Ñìåíà óæå îòêðûòà
0x16,//Ñìåíà íå îòêðûòà,//
0x17,//Íîìåð ïåðâîé ñìåíû áîëüøå íîìåðà ïîñëåäíåé ñìåíû,//
0x18,//Äàòà ïåðâîé ñìåíû áîëüøå äàòû ïîñëåäíåé ñìåíû,//
0x19,//Íåò äàííûõ â ÔÏ,//
0x1A,//Îáëàñòü ïåðåðåãèñòðàöèé â ÔÏ ïåðåïîëíåíà,//
0x1B,//Çàâîäñêîé íîìåð íå ââåäåí,//
0x1C,//Â çàäàííîì äèàïàçîíå åñòü ïîâðåæäåííàÿ çàïèñü,//
0x1D,//Ïîâðåæäåíà ïîñëåäíÿÿ çàïèñü ñìåííûõ èòîãîâ,//
0x1F,//Îòñóòñòâóåò ïàìÿòü ðåãèñòðîâ,//
0x20,//Ïåðåïîëíåíèå äåíåæíîãî ðåãèñòðà ïðè äîáàâëåíèè,//
0x21,//Âû÷èòàåìàÿ ñóììà áîëüøå ñîäåðæèìîãî äåíåæíîãî ðåãèñòðà,//
0x22,//Íåâåðíàÿ äàòà,//
0x23,//Íåò çàïèñè àêòèâèçàöèè,//
0x24,//Îáëàñòü àêòèâèçàöèé ïåðåïîëíåíà,//
0x25,//Íåò àêòèâèçàöèè ñ çàïðàøèâàåìûì íîìåðîì,//
0x28,//Â ÔÐ áîëåå 2õ ñáîéíûõ çàïèñåé,//
0x33,//Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå,//
0x35,//Íåêîððåêòíûé ïàðàìåòð ïðè äàííûõ íàñòðîéêàõ,//
0x36,//Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå äëÿ äàííîé ðåàëèçàöèè ÔÐ,//
0x37,//Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîé ðåàëèçàöèè ÔÐ,//
0x38,//Îøèáêà â ÏÇÓ,//+
0x39,//Âíóòðåííÿÿ îøèáêà ÏÎ ÔÐ,//
0x3A,//Ïåðåïîëíåíèå íàêîïëåíèÿ ïî íàäáàâêàì â ñìåíå,//
0x3C,//ÝÊËÇ: íåâåðíûé ðåãèñòðàöèîííûé íîìåð,//
0x3E,//Ïåðåïîëíåíèå íàêîïëåíèÿ ïî ñåêöèÿì â ñìåíå,//
0x3F,//Ïåðåïîëíåíèå íàêîïëåíèÿ ïî ñêèäêàì â ñìåíå,//
0x40,//Ïåðåïîëíåíèå äèàïàçîíà ñêèäîê,//
0x41,//Ïåðåïîëíåíèå äèàïàçîíà îïëàòû íàëè÷íûìè,//
0x42,//Ïåðåïîëíåíèå äèàïàçîíà îïëàòû òèïîì 2,//
0x43,//Ïåðåïîëíåíèå äèàïàçîíà îïëàòû òèïîì 3,//
0x44,//Ïåðåïîëíåíèå äèàïàçîíà îïëàòû òèïîì 4
0x45,//Cóììà âñåõ òèïîâ îïëàòû ìåíüøå èòîãà ÷åêà,//
0x46,//Íå õâàòàåò íàëè÷íîñòè â êàññå,//
0x47,//Ïåðåïîëíåíèå íàêîïëåíèÿ ïî íàëîãàì â ñìåíå,//
0x48,//Ïåðåïîëíåíèå èòîãà ÷åêà,//
0x4A,//Îòêðûò ÷åê - îïåðàöèÿ íåâîçìîæíà,//
0x4B,//Áóôåð ÷åêà ïåðåïîëíåí,//
0x4C,//Ïåðåïîëíåíèå íàêîïëåíèÿ ïî îáîðîòó íàëîãîâ â ñìåíå,//
0x4D,//Âíîñèìàÿ áåçíàëè÷íîé îïëàòîé ñóììà áîëüøå ñóììû ÷åêà,//
0x4E,//Ñìåíà ïðåâûñèëà 24 ÷àñà,//
0x4F,//Íåâåðíûé ïàðîëü,//
0x50,//Èäåò ïå÷àòü ïðåäûäóùåé êîìàíäû,//
0x51,//Ïåðåïîëíåíèå íàêîïëåíèé íàëè÷íûìè â ñìåíå,//
0x52,//Ïåðåïîëíåíèå íàêîïëåíèé ïî òèïó îïëàòû 2 â ñìåíå,//
0x53,//Ïåðåïîëíåíèå íàêîïëåíèé ïî òèïó îïëàòû 3 â ñìåíå,//
0x54,//Ïåðåïîëíåíèå íàêîïëåíèé ïî òèïó îïëàòû 4 â ñìåíå,//
0x56,//Íåò äîêóìåíòà äëÿ ïîâòîðà,//
0x57,//ÝÊËÇ: êîëè÷åñòâî çàêðûòûõ ñìåí íå ñîâïàäàåò ñ ÔÏ,//
0x58,//Îæèäàíèå êîìàíäû ïðîäîëæåíèÿ ïå÷àòè,//
0x59,//Äîêóìåíò îòêðûò äðóãèì îïåðàòîðîì,//
0x5B,//Ïåðåïîëíåíèå äèàïàçîíà íàäáàâîê,//
0x5C,//Ïîíèæåíî íàïðÿæåíèå 24Â
0x5D,//Òàáëèöà íå îïðåäåëåíà,//
0x5E,//Íåêîððåêòíàÿ îïåðàöèÿ,//
0x5F,//Îòðèöàòåëüíûé èòîã ÷åêà,//
0x60,//Ïåðåïîëíåíèå ïðè óìíîæåíèè,//
0x61,//Ïåðåïîëíåíèå äèàïàçîíà öåíû,//
0x62,//Ïåðåïîëíåíèå äèàïàçîíà êîëè÷åñòâà,//
0x63,//Ïåðåïîëíåíèå äèàïàçîíà îòäåëà,//
0x64,//ÔÏ îòñóòñòâóåò,//+
0x65,//Íå õâàòàåò äåíåã â ñåêöèè,//
0x66,//Ïåðåïîëíåíèå äåíåã â ñåêöèè,//
0x67,//Îøèáêà ñâÿçè ñ ÔÏ,//+
0x68,//Íå õâàòàåò äåíåã ïî îáîðîòó íàëîãîâ,//
0x69,//Ïåðåïîëíåíèå äåíåã ïî îáîðîòó íàëîãîâ,//
0x6A,//Îøèáêà ïèòàíèÿ â ìîìåíò îòâåòà ïî I
0x6B,//Íåò ÷åêîâîé ëåíòû,//
0x6C,//Íåò êîíòðîëüíîé ëåíòû,//
0x6D,//Íå õâàòàåò äåíåã ïî íàëîãó,//
0x6E,//Ïåðåïîëíåíèå äåíåã ïî íàëîãó,//
0x6F,//Ïåðåïîëíåíèå ïî âûïëàòå â ñìåíå,//
0x70,//Ïåðåïîëíåíèå ÔÏ,//
0x71,//Îøèáêà îòðåç÷èêà,//+
0x72,//Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîì ïîäðåæèìå,//
0x73,//Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîì ðåæèìå,//
0x74,//Îøèáêà ÎÇÓ,//
0x75,//Îøèáêà ïèòàíèÿ,//+
0x76,//Îøèáêà ïðèíòåðà: íåò èìïóëüñîâ ñ òàõîãåíåðàòîðà,//+
0x77,//Îøèáêà ïðèíòåðà: íåò ñèãíàëà ñ äàò÷èêîâ,//+
0x78,//Çàìåíà ÏÎ,//
0x79,//Çàìåíà ÔÏ,//
0x7A,//Ïîëå íå ðåäàêòèðóåòñÿ
0x7B,//Îøèáêà îáîðóäîâàíèÿ,//
0x7C,//Íå ñîâïàäàåò äàòà,//
0x7D,//Íåâåðíûé ôîðìàò äàòû,//
0x7E,//Íåâåðíîå çíà÷åíèå â ïîëå äëèíû,//
0x7F,//Ïåðåïîëíåíèå äèàïàçîíà èòîãà ÷åêà,//
0x80,//Îøèáêà ñâÿçè ñ ÔÏ,//+
0x81,//Îøèáêà ñâÿçè ñ ÔÏ,//+
0x82,//Îøèáêà ñâÿçè ñ ÔÏ,//+
0x83,//Îøèáêà ñâÿçè ñ ÔÏ,//+
0x84,//Ïåðåïîëíåíèå íàëè÷íîñòè,//
0x85,//Ïåðåïîëíåíèå ïî ïðîäàæàì â ñìåíå,//
0x86,//Ïåðåïîëíåíèå ïî ïîêóïêàì â ñìåíå,//
0x87,//Ïåðåïîëíåíèå ïî âîçâðàòàì ïðîäàæ â ñìåíå,//
0x88,//Ïåðåïîëíåíèå ïî âîçâðàòàì ïîêóïîê â ñìåíå,//
0x89,//Ïåðåïîëíåíèå ïî âíåñåíèþ â ñìåíå,//
0x8A,//Ïåðåïîëíåíèå ïî íàäáàâêàì â ÷åêå,//
0x8B,//Ïåðåïîëíåíèå ïî ñêèäêàì â ÷åêå,//
0x8C,//Îòðèöàòåëüíûé èòîã íàäáàâêè â ÷åêå,//
0x8D,//Îòðèöàòåëüíûé èòîã ñêèäêè â ÷åêå,//
0x8E,//Íóëåâîé èòîã ÷åêà,//
0x8F,//Êàññà íå ôèñêàëèçèðîâàíà,//,//
0x90,//Ïîëå ïðåâûøàåò ðàçìåð, óñòàíîâëåííûé â íàñòðîéêàõ
0x91,//Âûõîä çà ãðàíèöó ïîëÿ ïå÷àòè ïðè äàííûõ íàñòðîéêàõ øðèôòà
0x92,//Íàëîæåíèå ïîëåé
0x93,//Âîññòàíîâëåíèå ÎÇÓ ïðîøëî óñïåøíî
0x94,//Èñ÷åðïàí ëèìèò îïåðàöèé â ÷åêå
0xA0,//Îøèáêà ñâÿçè ñ ÝÊËÇ
0xA1,//ÝÊËÇ îòñóòñòâóåò
0xA2,//ÝÊËÇ: Íåêîððåêòíûé ôîðìàò èëè ïàðàìåòð êîìàíäû
0xA3,//Íåêîððåêòíîå ñîñòîÿíèå ÝÊËÇ
0xA4,//Àâàðèÿ ÝÊËÇ
0xA5,//Àâàðèÿ ÊÑ â ñîñòàâå ÝÊËÇ
0xA6,//Èñ÷åðïàí âðåìåííîé ðåñóðñ ÝÊËÇ
0xA7,//ÝÊËÇ ïåðåïîëíåíà
0xA8,//ÇÊËÇ: Íåâåðíûå äàòà è âðåìÿ
0xA9,//ÝÊËÇ: Íåò çàïðîøåííûõ äàííûõ
0xAA,//Ïåðåïîëíåíèå ÝÊËÇ (îòðèöàòåëüíûé èòîã äîêóìåíòà)
0xB0,//ÝÊËÇ: Ïåðåïîëíåíèå â ïàðàìåòðå êîëè÷åñòâî
0xB1,//ÝÊËÇ: Ïåðåïîëíåíèå â ïàðàìåòðå ñóììà
0xB2,//ÝÊËÇ: Óæå àêòèâèçèðîâàíà
0xC0,//Êîíòðîëü äàòû è âðåìåíè (ïîäòâåðäèòå äàòó è âðåìÿ)
0xC1,//ÝÊËÇ: ñóòî÷íûé îò÷?ò ñ ãàøåíèåì ïðåðâàòü íåëüçÿ
0xC2,//Ïðåâûøåíèå íàïðÿæåíèÿ â áëîêå ïèòàíèÿ
0xC3,//Íåñîâïàäåíèå èòîãîâ ÷åêà è ÝÊËÇ
0xC4,//Íåñîâïàäåíèå íîìåðîâ ñìåí
//0xC5,//Áóôåð ïîäêëàäíîãî äîêóìåíòà ïóñò
//0xC6,//Ïîäêëàäíîé äîêóìåíò îòñóòñòâóåò,//
//0xC7,//Ïîëå íå ðåäàêòèðóåòñÿ â äàííîì ðåæèìå
//0xC8,//Îòñóòñòâóþò,//èìïóëüñû îò òàõîäàò÷èêà
};
// óñòàíîâêà ãëîáàëüíîãî ôëàãà îøèáêè ÔÐ ïî îøèáêè êîäó äðàéâåðà
void SetFiscalErrorByCode(CPU_INT08U err)
{
if (!err) return;
for (unsigned char i=0; i<FR_ERROR_NUMBER; i++)
{
if (error_codes[i] == err)
{
SetErrorFlag(ERROR_FR+i);
break;
}
}
}
// ñáðîñ ãëîáàëüíîãî ôëàãà îøèáêè ÔÐ ïî îøèáêè êîäó äðàéâåðà
void ClrFiscalErrorByCode(CPU_INT08U err)
{
for (unsigned char i=0; i<FR_ERROR_NUMBER; i++)
{
if (error_codes[i] == err)
{
ClrErrorFlag(ERROR_FR+i);
break;
}
}
}
// ïå÷àòü ÷åêà íà ÔÐ
// time òåïåðü â ñåêóíäàõ
int PrintFiscalBill(CPU_INT32U money, CPU_INT32U time)
{
CPU_INT08U err;
CPU_INT64U count = (time*1000)/60;
CPU_INT64U cash = money*100;
CPU_INT64U price = (CPU_INT64U)(((double)money*100*60)/time);
CPU_INT08U tax[4] = {0,0,0,0};
CPU_INT32U format = 0;
CPU_INT08U repeat;
FPend();
if (CheckFiscalStatus() < 0)
{
FPost();
return -100;
}
repeat = 0;
repeat_open:
if (FiscOpenBill(DEFAULT_PASS, FISC_BILL_SELL, &err) != FISC_OK)
{
if (err)
{
// îøèáêà
SetFiscalErrorByCode(err);
}
else
{
// íåò ñîåäèíåíèÿ
ClearFiscalErrors();
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
}
if (repeat)
{
FPost();
return -1;
}
repeat++;
}
if (repeat)
{
if (CheckFiscalStatus() == 0)
{
goto repeat_open;
}
else
{
FPost();
return -200;
}
}
GetData(&BillFormatDesc, &format, 0, DATA_FLAG_SYSTEM_INDEX);
if (format == 0)
{
repeat = 0;
repeat_sell1:
// ïå÷àòàåì êîëè÷åñòâî ìèíóò
if (FiscMakeSell(DEFAULT_PASS, &count, &price, 0, &tax[0], "Óñëóãè ñîëÿðèÿ, ìèí.", &err) != FISC_OK)
{
if (err)
{
SetFiscalErrorByCode(err);
}
else
{
// íåò ñîåäèíåíèÿ
ClearFiscalErrors();
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
}
if (repeat)
{
FPost();
return -2;
}
repeat++;
}
if (repeat)
{
if (CheckFiscalStatus() == 0)
{
goto repeat_sell1;
}
else
{
FPost();
return -300;
}
}
}
else if (format == 1)
{
repeat = 0;
repeat_sell2:
// ïå÷àòàåì òîëüêî îáùóþ ñóììó
count = 1000;
price = money*100;
if (FiscMakeSell(DEFAULT_PASS, &count, &price, 0, &tax[0], "Óñëóãè ñîëÿðèÿ", &err) != FISC_OK)
{
if (err)
{
SetFiscalErrorByCode(err);
}
else
{
// íåò ñîåäèíåíèÿ
ClearFiscalErrors();
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
}
if (repeat)
{
FPost();
return -3;
}
repeat++;
}
if (repeat)
{
if (CheckFiscalStatus() == 0)
{
goto repeat_sell2;
}
else
{
FPost();
return -400;
}
}
}
repeat = 0;
repeat_close:
if (FiscCloseBill(DEFAULT_PASS, &cash, &tax[0], "Ñïàñèáî çà ïîêóïêó!!!", &err) != FISC_OK)
{
if (err)
{
SetFiscalErrorByCode(err);
}
else
{
// íåò ñîåäèíåíèÿ
ClearFiscalErrors();
FiscalConnState = FISCAL_NOCONN;
SetErrorFlag(ERROR_FR_CONN);
}
if (repeat)
{
FPost();
return -4;
}
repeat++;
}
if (repeat)
{
if (CheckFiscalStatus() == 0)
{
goto repeat_close;
}
else
{
FPost();
return -400;
}
}
FPost();
return 0;
}
/*
// ïå÷àòü ÷åêà íà ÔÐ ñ ïîâòîðàìè, íà ñëó÷àé çàêðûòèÿ ñìåíû
int PrintFiscalBillRepeated(CPU_INT32U money, CPU_INT32U time)
{
int res = PrintFiscalBill(money, time);
int i=4;
while ((res != 0) && (i>0))
{
OSTimeDly(5000);
res = PrintFiscalBill(money, time);
i--;
}
return res;
}
*/
int TstFiscalErrorByCode(unsigned char code)
{
for (unsigned char i=0; i<FR_ERROR_NUMBER; i++)
{
if (error_codes[i] == code)
{
return TstErrorFlag(ERROR_FR+i);
}
}
return 0;
}
CPU_INT08U GetFiscalErrorNumberByCode(unsigned char code)
{
for (unsigned char i=0; i<FR_ERROR_NUMBER; i++)
{
if (error_codes[i] == code)
{
return i;
}
}
return 0;
}
#define FR_CRITICAL_ERROR_NUM 70
const CPU_INT08U FiscalCriticalErrorsTable[FR_CRITICAL_ERROR_NUM] = {
FR_ERROR_CODE_1,
FR_ERROR_CODE_2,
FR_ERROR_CODE_6,
FR_ERROR_CODE_a,
FR_ERROR_CODE_b,
FR_ERROR_CODE_11,
FR_ERROR_CODE_13,
FR_ERROR_CODE_14,
FR_ERROR_CODE_17,
FR_ERROR_CODE_18,
FR_ERROR_CODE_1a,
FR_ERROR_CODE_1c,
FR_ERROR_CODE_1d,
FR_ERROR_CODE_1f,
FR_ERROR_CODE_23,
FR_ERROR_CODE_24,
FR_ERROR_CODE_38,
FR_ERROR_CODE_39,
FR_ERROR_CODE_3a,
FR_ERROR_CODE_3c,
FR_ERROR_CODE_3e,
FR_ERROR_CODE_3f,
FR_ERROR_CODE_40,
FR_ERROR_CODE_41,
FR_ERROR_CODE_42,
FR_ERROR_CODE_43,
FR_ERROR_CODE_44,
FR_ERROR_CODE_47,
FR_ERROR_CODE_48,
FR_ERROR_CODE_4c,
FR_ERROR_CODE_4e,
FR_ERROR_CODE_51,
FR_ERROR_CODE_52,
FR_ERROR_CODE_53,
FR_ERROR_CODE_54,
FR_ERROR_CODE_57,
FR_ERROR_CODE_5b,
FR_ERROR_CODE_64,
FR_ERROR_CODE_67,
FR_ERROR_CODE_6a,
FR_ERROR_CODE_6b,
FR_ERROR_CODE_70,
FR_ERROR_CODE_71,
FR_ERROR_CODE_74,
FR_ERROR_CODE_75,
FR_ERROR_CODE_76,
FR_ERROR_CODE_77,
FR_ERROR_CODE_78,
FR_ERROR_CODE_79,
FR_ERROR_CODE_7b,
FR_ERROR_CODE_80,
FR_ERROR_CODE_81,
FR_ERROR_CODE_82,
FR_ERROR_CODE_83,
FR_ERROR_CODE_87,
FR_ERROR_CODE_88,
FR_ERROR_CODE_89,
FR_ERROR_CODE_8a,
FR_ERROR_CODE_8b,
FR_ERROR_CODE_a0,
FR_ERROR_CODE_a1,
FR_ERROR_CODE_a3,
FR_ERROR_CODE_a4,
FR_ERROR_CODE_a5,
FR_ERROR_CODE_a6,
FR_ERROR_CODE_a7,
FR_ERROR_CODE_a8,
FR_ERROR_CODE_a9,
FR_ERROR_CODE_c2,
FR_ERROR_CODE_c4
};
// ïðîâåðêà êðèòè÷åêèõ ôëàãîâ ÔÐ
int TstCriticalFiscalError(void)
{
int res = 0;
for (CPU_INT08U i=0; i<FR_CRITICAL_ERROR_NUM; i++)
{
res |= TstFiscalErrorByCode(FiscalCriticalErrorsTable[i]);
}
return res;
}
// ïîëó÷åíèå ïåðâîãî ïî ïîðÿäêó êðèòè÷åñêîãî ôëàãà ÔÐ
int GetFirstCriticalFiscalError(CPU_INT08U *err)
{
int res = 0;
*err = 0;
for (CPU_INT08U i=0; i<FR_CRITICAL_ERROR_NUM; i++)
{
res = TstFiscalErrorByCode(FiscalCriticalErrorsTable[i]);
if (res) {*err = ERROR_FR+GetFiscalErrorNumberByCode(FiscalCriticalErrorsTable[i]); break;}
}
return res;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,132 @@
;
;********************************************************************************************************
; EXCEPTION VECTORS & STARTUP CODE
;
; File : cstartup.s
; For : ARM7 or ARM9
; Toolchain : IAR EWARM V5.10 and higher
;********************************************************************************************************
;
;********************************************************************************************************
; MACROS AND DEFINIITIONS
;********************************************************************************************************
; Mode, correspords to bits 0-5 in CPSR
MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR
USR_MODE DEFINE 0x10 ; User mode
FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
SVC_MODE DEFINE 0x13 ; Supervisor mode
ABT_MODE DEFINE 0x17 ; Abort mode
UND_MODE DEFINE 0x1B ; Undefined Instruction mode
SYS_MODE DEFINE 0x1F ; System mode
;********************************************************************************************************
; ARM EXCEPTION VECTORS
;********************************************************************************************************
SECTION .intvec:CODE:NOROOT(2)
PUBLIC __vector
PUBLIC __iar_program_start
PUBLIC __vector_0x14
IMPORT OS_CPU_ARM_ExceptUndefInstrHndlr
IMPORT OS_CPU_ARM_ExceptSwiHndlr
IMPORT OS_CPU_ARM_ExceptPrefetchAbortHndlr
IMPORT OS_CPU_ARM_ExceptDataAbortHndlr
IMPORT OS_CPU_ARM_ExceptIrqHndlr
IMPORT OS_CPU_ARM_ExceptFiqHndlr
ARM
__vector:
LDR PC, [PC,#24] ; Absolute jump can reach 4 GByte
LDR PC, [PC,#24] ; Branch to undef_handler
LDR PC, [PC,#24] ; Branch to swi_handler
LDR PC, [PC,#24] ; Branch to prefetch_handler
LDR PC, [PC,#24] ; Branch to data_handler
__vector_0x14:
DC32 0 ; Reserved
LDR PC, [PC,#24] ; Branch to irq_handler
LDR PC, [PC,#24] ; Branch to fiq_handler
DC32 __iar_program_start
DC32 OS_CPU_ARM_ExceptUndefInstrHndlr
DC32 OS_CPU_ARM_ExceptSwiHndlr
DC32 OS_CPU_ARM_ExceptPrefetchAbortHndlr
DC32 OS_CPU_ARM_ExceptDataAbortHndlr
DC32 0
DC32 OS_CPU_ARM_ExceptIrqHndlr
DC32 OS_CPU_ARM_ExceptFiqHndlr
;********************************************************************************************************
; LOW-LEVEL INITIALIZATION
;********************************************************************************************************
SECTION FIQ_STACK:DATA:NOROOT(3)
SECTION IRQ_STACK:DATA:NOROOT(3)
SECTION SVC_STACK:DATA:NOROOT(3)
SECTION ABT_STACK:DATA:NOROOT(3)
SECTION UND_STACK:DATA:NOROOT(3)
SECTION CSTACK:DATA:NOROOT(3)
SECTION text:CODE:NOROOT(2)
REQUIRE __vector
EXTERN ?main
PUBLIC __iar_program_start
EXTERN lowlevel_init
__iar_program_start:
;********************************************************************************************************
; STACK POINTER INITIALIZATION
;********************************************************************************************************
MRS r0,cpsr ; Original PSR value
BIC r0,r0,#MODE_BITS ; Clear the mode bits
ORR r0,r0,#SVC_MODE ; Set SVC mode bits
MSR cpsr_c,r0 ; Change the mode
LDR sp,=SFE(SVC_STACK) ; End of SVC_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits
ORR r0,r0,#UND_MODE ; Set UND mode bits
MSR cpsr_c,r0 ; Change the mode
LDR sp,=SFE(UND_STACK) ; End of UND_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits
ORR r0,r0,#ABT_MODE ; Set ABT mode bits
MSR cpsr_c,r0 ; Change the mode
LDR sp,=SFE(ABT_STACK) ; End of ABT_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits
ORR r0,r0,#FIQ_MODE ; Set FIQ mode bits
MSR cpsr_c,r0 ; Change the mode
LDR sp,=SFE(FIQ_STACK) ; End of FIQ_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits
ORR r0,r0,#IRQ_MODE ; Set IRQ mode bits
MSR cpsr_c,r0 ; Change the mode
LDR sp,=SFE(IRQ_STACK) ; End of IRQ_STACK
BIC r0,r0,#MODE_BITS ; Clear the mode bits
ORR r0,r0,#SYS_MODE ; Set System mode bits
MSR cpsr_c,r0 ; Change the mode
LDR sp,=SFE(CSTACK) ; End of CSTACK
;********************************************************************************************************
; ADDITIONAL INITIALIZATION
;********************************************************************************************************
;********************************************************************************************************
; CONTINUE TO ?main FOR ADDITIONAL INITIALIZATION
;********************************************************************************************************
LDR r0,=?main
BX r0
END

View File

@ -0,0 +1,99 @@
#ifndef _MENU_H_
#define _MENU_H_
#include "cpu.h"
#define MENU_LINES_NUMBER 4
#define MENU_SYMB_NUMBER 20
// ñëóæåáíûå ñèìâîëû
#define SYMB_GO_UP 0x87
#define SYMB_GO_DOWN 0x86
#define SYMB_RIGHT_ARROW 0x13
#define SYMB_DESC_MARK 0x84
#define SYMB_IND_MARK 0x85
#define SYMB_POINT_MARK 0xDF
// ñòðóêòóðà îïèñàíèÿ ïóíêòà ìåíþ
typedef struct{
// òèï ïóíêòà ìåíþ
CPU_INT08U LineType;
#define MENU_LINE_STRING 0 // ïðîñòî ñòðîêà
#define MENU_LINE_GOTO_MENU 1 // ïåðåõîä íà äðóãîå ìåíþ
#define MENU_LINE_SHOW_DESC 2 // îòîáðàæåíèå ïàðàìåòðà
#define MENU_LINE_INDEX 3 // èíäåêñ ìàññèâà
// äîï. ôëàãè
CPU_INT08U Flags;
#define MENU_FIXED_LINE 0x01 // ôèêñèðîâàííàÿ ñòðîêà
#define MENU_INDEX_LINE 0x02 // ñòðîêà ñ èíäåêñîì ìàññèâà
// óêàçàòåëü íà òåêñòîâóþ ñòðîêó èëè äåñêðèïòîð
void* Ptr;
// ïàíåëü äëÿ ïåðåõîäà
void* GoToPtr;
}TMenuLine;
// äëÿ ìàññèâà ñòðîê
typedef struct{
const TMenuLine* pMenuLine;
}TMenuLineArray;
// ñòðóêòóðà îïèñàíèÿ ïàíåëè ìåíþ
typedef struct{
// óêàçàòåëü íà ìàññèâ ñòðîê
const TMenuLineArray* LineArray;
// óêàçàòåëü íà ôóíêöèþ, âûïîëíÿåìóþ ïåðåä âõîäîì â ïàíåëü
void (*InitFunc)(void);
// ÷èñëî ñòðîê â äàííîì ìåíþ
CPU_INT08U LineNum;
// òèï ïàíåëè
CPU_INT08U PanelType;
#define MENU_PANEL_STANDARD 0 // îáû÷íàÿ ïàíåëü, ñ ïåðåìåùåíèåì ïî ìåíþ
#define MENU_PANEL_STATIC 1 // ñòàòè÷åñêàÿ ïàíåëü
}TMenuPanel;
// ýëåìåíò ñòåêà âîçâðàòîâ ìåíþ
typedef struct{
// óêàçàòåëü íà ïðåäûäóùåå ìåíþ
const TMenuPanel* PrevMenu;
// àêòèâíàÿ ëèíèÿ â ïðåäûäóùåì ìåíþ
CPU_INT08U PrevActiveLine;
}TMenuStack;
///////////////////////////////////
// ôóíêöèè äëÿ ðàáîòû ñ ìåíþ
///////////////////////////////////
// èíèöèàëèçàöèÿ ìåíþ
extern void InitMenu(void);
// ïåðåõîä íà çàäàííóþ ïàíåëü ìåíþ
extern void GoToMenu(const TMenuPanel* Menu);
extern void SetMenu(const TMenuPanel* Menu);
// âîçâðàò â ïðåäûäóùåå ìåíþ
extern void GoToPreviousMenu(void);
// ïåðåçàïóñê ìåíþ
extern void ReInitMenu(void);
extern void MenuSprintf(CPU_INT08U* str, CPU_INT08U len, CPU_INT32U Val);
extern TMenuPanel* GetCurrentMenu(void);
extern void RefreshMenu(void);
#endif //#ifndef _MENU_H_

View File

@ -0,0 +1,935 @@
#include <includes.h>
#include "modem.h"
#include "modem_task.h"
#include "app_serv.h"
#include "data.h"
#include "datadesc.h"
#include "uart2.h"
static char additional_buf[256];
#define ModemUart_Ready Uart2_Ready
#define ModemComPortFlush Uart2_Flush
#define ModemUart_Getc Uart2_Getc
#define ModemUart_Gotc Uart2_Gotc
#define ModemUart_Putc Uart2_Putc
#define ModemUart_Init Uart2_Init
static OS_EVENT *ModemLock = NULL;
static char modem_buf[512];
static int modem_connected;
// ïîëó÷èòü äîñòóï ê ìîäåìó
static void GetModem(void)
{
CPU_INT08U err;
while (1)
{
OSSemPend(ModemLock, 1, &err);
if (!err) break;
OSTimeDly(1);
}
}
// îñâîáîäèòü ìîäåì
static void FreeModem(void)
{
OSSemPost(ModemLock);
}
// çàïèñü ñòðîêè â ìîäåì
static void ModemWriteStr(char const *str)
{
while (*str != 0)
{
while (!ModemUart_Ready()) OSTimeDly(1);
ModemUart_Putc(*str++);
}
}
// ÷òåíèå ñòðîêè èç ìîäåìà ïî òàéìàóòó
static int ModemReadStr(char *str, unsigned long timeout)
{
int byte_ctr = 0;
while (byte_ctr < 256)
{
CPU_INT08U byte;
unsigned long to = timeout;
while (!ModemUart_Gotc())
{
if (to == 0)
{
*str = 0x00;
return 0;
}
OSTimeDly(1);
to--;
}
int ch = ModemUart_Getc();
if (ch < 0)
{
*str = 0x00;
return 0;
}
byte = (char)ch;
*str++ = byte;
byte_ctr++;
if (byte == 0x0a) break;
}
*str = 0x00;
return 1;
}
static int ModemReadByte(CPU_INT08U *byte, unsigned long timeout)
{
unsigned long ctr = 0;
while (!ModemUart_Gotc())
{
OSTimeDly(1);
ctr++;
if (ctr > timeout) return 0;
}
*byte = (CPU_INT08U)ModemUart_Getc();
return 1;
}
// ÷òåíèå ñòðîêè èç ìîäåìà èç ñðàâíåíèå ñî ñòðîêîé
static int ModemReadStrAndComp(char *str, char const *format, unsigned long timeout)
{
int result;
if (ModemReadStr(str, timeout))
{
result = strcmp ((char *)str, (char const *)format);
}
else
{
return -1;
}
return result;
}
// èíèöèàëèçàöèÿ/ïðîâåðêà ñîñòîÿíèÿ ìîäåìà
int InitModem(void)
{
int result;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
CPU_INT32U val;
OS_ENTER_CRITICAL();
email_options.valid = 0;
modem_connected = 0;
OS_EXIT_CRITICAL();
GetData(&EnableModemDesc, &val, 0, DATA_FLAG_SYSTEM_INDEX);
if (val)
{
PINSEL1_bit.P0_24 = 0x0;
PINMODE1_bit.P0_24 = 0;
FIO0DIR_bit.P0_24 = 1;
FIO0MASK_bit.P0_24 = 0;
FIO0CLR_bit.P0_24 = 1;
OSTimeDly(1000);
FIO0SET_bit.P0_24 = 1;
OSTimeDly(60000);
ModemUart_Init(115200);
if (!ModemLock) ModemLock = OSSemCreate(1);
GetModem();
// ïðîâåðèì ñâÿçü
sprintf(modem_buf, "AT\r\n");
result = ModemSendOKCommand(modem_buf, 1000);
if (result != 0)
{
FreeModem();
goto EXIT_INIT;
}
// ïðîâåðèì, ââåäåí ëè ïèí
sprintf(modem_buf, "AT+CPIN?\r\n");
result = ModemSendOKCommand(modem_buf, 1000);
if (result != 0)
{
FreeModem();
goto EXIT_INIT;
}
FreeModem();
OS_ENTER_CRITICAL();
modem_connected = 1;
OS_EXIT_CRITICAL();
OSTimeDly(1000);
result = InitModemEmailParams();
}
else
{
result = 0;
}
EXIT_INIT:
// ñîçäàäèì çàäà÷ó è î÷åðåäü ìîäåìà
if (ModemQuery == NULL)
{
ModemQuery = OSQCreate(&ModemTbl[0], MODEM_QUERY_LEN);
OSTaskCreate(ModemTask, (void *)0, (OS_STK *)&ModemTaskStk[MODEM_TASK_STK_SIZE-1], MODEM_TASK_PRIO);
}
return result;
}
// ïîñûëêà ñîîáùåíèÿ ïî òàêîìó-òî íîìåðó òàêîé-òî òåêñò
int ModemSendSMSMessage(char const* number, char const* text)
{
char i;
GetModem();
if (ModemWriteSMS(text, (unsigned char*)&i)) {FreeModem(); return -1;}
ModemComPortFlush();
OSTimeDly(200);
if (ModemSendSMS(number, i)) {FreeModem(); return -1;}
ModemComPortFlush();
OSTimeDly(200);
if (ModemDeleteSMS(i)) {FreeModem(); return -1;}
OSTimeDly(200);
ModemComPortFlush();
FreeModem();
return 0;
}
// ÷òåíèå èç ïàìÿòè ñìñ ñ óêàçàííûì íîìåðîì
int ModemReadSMS(char *text, int index)
{
unsigned char count;
char *ptr;
GetModem();
ModemComPortFlush();
sprintf((char*)modem_buf, "AT+CMGR=%d\r\n", index);
ModemWriteStr(modem_buf);
if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;}
if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;}
// äàëüøå òåêñò ñîîáùåíèÿ
count = 0;
while (count < 160)
{
modem_buf[0] = 0;
if (!ModemReadStr(modem_buf, MODEM_RX_TIMEOUT)) {FreeModem(); return -1;}
if (strcmp(modem_buf, "OK\r\n") == 0)
{
break;
}
else if (strlen(modem_buf) != 0)
{
// åñòü íåïóñòàÿ ñòðîêà
ptr = (char*)modem_buf;
if (strlen((char const*)modem_buf) < 1) {FreeModem(); return -1;}
while (*ptr) {*text++ = *ptr++; count++;}
}
else
{
break;
}
}
FreeModem();
return 0;
}
// ïîñûëêà ñìñ ñ íîìåðîì index èç ïàìÿòè ìîäåìà ïî óêàçàííîìó íîìåðó
int ModemSendSMS(char const* number, unsigned char index)
{
GetModem();
sprintf((char*)modem_buf, "AT+CMSS=%d,%s\r\n", index, number);
ModemWriteStr(modem_buf);
if (ModemReadStrAndComp(modem_buf, "\r\n", 10000)) {FreeModem(); return -1;}
if (!ModemReadStr(modem_buf, 10000)) {FreeModem(); return -1;}
modem_buf[6] = 0;
if (strcmp((char const*)modem_buf, "+CMSS:")) {FreeModem(); return -1;}
if (ModemReadStrAndComp(modem_buf, "\r\n", 10000)) {FreeModem(); return -1;}
if (ModemReadStrAndComp(modem_buf, "OK\r\n", 10000)) {FreeModem(); return -1;}
FreeModem();
return 0;
}
// óäàëåíèå ñìñêè ñ íîìåðîì index èç ïàìÿòè
int ModemDeleteSMS(unsigned char index)
{
int result;
GetModem();
sprintf((char*)modem_buf, "AT+CMGD=%d\r\n",index);
result = ModemSendOKCommand(modem_buf, 1000);
FreeModem();
return result;
}
// çàïèñü ñìñêè ñ óêàçàííûì òåêñòîì â ïàìÿòü, â index çàïèñûâàåò ïîçèöèþ â ïàìÿòè, êóäà ñìñ çàïèñàëîñü
int ModemWriteSMS(char const* text, unsigned char *index)
{
CPU_INT08U byte;
unsigned long word;
int result;
GetModem();
// ïîñûëàåì êîìàíäó
ModemWriteStr("AT+CMGW\r\n");
if (ModemReadStrAndComp(modem_buf, "\r\n", 1000)) {FreeModem(); return -1;}
if (!ModemReadByte(&byte, 1000)) {FreeModem(); return -1;}
if (byte != '>') {FreeModem(); return -1;}
if (!ModemReadByte(&byte, 1000)) {FreeModem(); return -1;}
if (byte != ' ') {FreeModem(); return -1;}
// ââîäèì òåêñò ñîîáùåíèÿ
ModemWriteStr(text);
// êîíåö ñîîáùåíèÿ
ModemUart_Putc(0x1a);
// ïðèíèìàåì îòâåò î çàïèñè
if (ModemReadStrAndComp(modem_buf, "\r\n", 1000)) {FreeModem(); return -1;}
// ïðî÷èòàåì íîìåð ñìñêè â ïàìÿòè, êóäà îíà çàïèñàëàñü
if (!ModemReadStr(modem_buf, 5000)) {FreeModem(); return -1;}
modem_buf[6] = 0;
if (strcmp((char const*)modem_buf, "+CMGW:")) {FreeModem(); return -1;}
{
int len = strlen((char const*)&modem_buf[7]);
if (len == 3) word = modem_buf[7]-0x30;
else if (len == 4) {word = (modem_buf[7]-0x30)*10 + (modem_buf[8]-0x30);}
}
*index = (unsigned char)word;
result = ModemReadStrAndComp(modem_buf, "\r\n", 1000) + ModemReadStrAndComp(modem_buf, "OK\r\n", 1000);
FreeModem();
// ÎÊ
return result;
}
// ïîñûëêà ñòðîêè, íà êîòîðóþ äîëæåí ïðèéòè îòâåò "OK"
// âîçâðàùàåò 0 åñëè îê
int ModemSendOKCommand(char *str, unsigned long timeout)
{
int i;
ModemComPortFlush();
ModemWriteStr(str);
i = MODEM_REPEAT_RX;
while (i--)
{
if (ModemReadStr(str, timeout))
{
if (strcmp(str, "OK\r\n") == 0)
{
return 0;
}
else if (strcmp(str, "ERROR\r\n") == 0)
{
return -2;
}
continue;
}
else
{
return -1;
}
}
return -3;
}
int ModemSendOKData(char *str, int len, unsigned long timeout)
{
int i;
ModemComPortFlush();
for (i = 0; i < len; i++)
{
while (!ModemUart_Ready()) OSTimeDly(1);
ModemUart_Putc(str[i]);
}
i = MODEM_REPEAT_RX;
while (i--)
{
if (ModemReadStr(str, timeout))
{
if (strcmp(str, "OK\r\n") == 0)
{
return 0;
}
else if (strcmp(str, "ERROR\r\n") == 0)
{
return -2;
}
continue;
}
else
{
return -1;
}
}
return -3;
}
// ïîñûëêà ñòðîêè, ñ âîçâðàòîì îòâåòà íà íå¸, îòëè÷íîãî îò "\r\n"
// âîçâðàùàåò 0 åñëè îê
int ModemSendCommand(char *str, unsigned long timeout)
{
CPU_INT08U i;
ModemComPortFlush();
ModemWriteStr(str);
i = MODEM_REPEAT_RX;
while (i--)
{
if (ModemReadStr(str, timeout))
{
if (strcmp(str, "\r\n") == 0)
{
continue;
}
else
{
return 0;
}
}
else
{
return -1;
}
}
return -3;
}
// ïðèåì ñèãíàëà î íîâîé ñìñêå, â num çàïèñûâàåò íîìåð ïðèíÿòîãî ñîîáùåíèÿ, åñëè îíî ïðèíÿòî
int ModemRxNewSMS(unsigned long *num)
{
int len;
GetModem();
if (!ModemReadStr(modem_buf, 10)) {FreeModem(); return 0;}
if (!strcmp((char const*)modem_buf, "\r\n"))
{
// ïðèíèìàåì åù¸ îäíó ñòðîêó
if (!ModemReadStr(modem_buf, 100)) {FreeModem(); return 0;}
}
if (strlen((char const*)modem_buf) < 13) {FreeModem(); return 0;}
modem_buf[6] = 0;
if (strcmp((char const*)modem_buf, "+CMTI:")) {FreeModem(); return 0;}
len = strlen((char*)&modem_buf[12]);
if (len == 3) *num = modem_buf[12]-0x30;
else if (len == 4) {*num = (modem_buf[12]-0x30)*10 + (modem_buf[13]-0x30);}
OSTimeDly(200);
FreeModem();
return 1;
}
typedef struct
{
char const *name; // ñòðîêà íàçâàíèÿ ýëåìåíòà
char *dest; // êóäà ñîæðàíèòü çíà÷åíèå
} CfgElem;
static const CfgElem email_cfg_list[EMAIL_CFG_ELEM_COUNT] =
{
{"[receiver]=", email_options.receiver},
{"[ap_dns]=", email_options.ap_dns},
{"[ap_password]=", email_options.ap_password},
{"[ap_ip]=", email_options.ap_ip},
{"[ap_user]=", email_options.ap_user},
{"[ap_apn]=", email_options.ap_apn},
{"[smtp_user]=", email_options.smtp_user},
{"[smtp_password]=", email_options.smtp_password},
{"[smtp_mail]=", email_options.smtp_mail},
{"[smtp_server]=", email_options.smtp_server},
{"[smtp_port]=", email_options.smtp_port}
};
// èíèöèàëèçàöèÿ ïàðàìåòðîâ äëÿ íàñòðîéêè ïî÷òû
int InitModemEmailParams(void)
{
CPU_INT08U i, j;
char *text;
CPU_INT32U status = 0;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
text = additional_buf;
OS_ENTER_CRITICAL();
email_options.valid = 0;
OS_EXIT_CRITICAL();
for (i = 1; i < 24; i++)
{
if (ModemReadSMS(text, i))
{
// íå ïðî÷èòàëîñü
continue;
}
for (j = 0; j < EMAIL_CFG_ELEM_COUNT; j++)
{
int str_len = strlen(email_cfg_list[j].name);
char flag = 0;
while (str_len--)
{
if (email_cfg_list[j].name[str_len] != text[str_len])
{
flag = 1;
break;
}
}
if (!flag)
{
strcpy(email_cfg_list[j].dest, &text[strlen(email_cfg_list[j].name)]);
for (str_len = 0; str_len < 64; str_len++)
{
if (email_cfg_list[j].dest[str_len] == 0) break;
if (email_cfg_list[j].dest[str_len] == '\r') {email_cfg_list[j].dest[str_len] = 0; break;}
if (email_cfg_list[j].dest[str_len] == '\n') {email_cfg_list[j].dest[str_len] = 0; break;}
}
// íàøëè îïöèþ â ñìñêå
status |= 1L << j;
break;
}
}
OSTimeDly(200);
}
i = 1;
for (j = 0; j < EMAIL_CFG_ELEM_COUNT; j++)
{
if ((status & (1 << j)) == 0)
{
i = 0;
break;
}
}
OS_ENTER_CRITICAL();
email_options.valid = i;
OS_EXIT_CRITICAL();
return 0;
}
void ResetModemValid(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
email_options.valid = 0;
modem_connected = 0;
OS_EXIT_CRITICAL();
}
// ïðîâåðêà, ìîæíî ëè èñïîëüçîâàòü ìîäåì (êîððåêòíîñòü íàñòðîåê è ïîäêëþ÷åíèÿ)
CPU_INT08U IsModemValid(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
CPU_INT08U result = 0;
OS_ENTER_CRITICAL();
if (email_options.valid && modem_connected)
{
result = 1;
}
OS_EXIT_CRITICAL();
return result;
}
CPU_INT08U IsModemConn(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
CPU_INT08U result = 0;
OS_ENTER_CRITICAL();
if (modem_connected)
{
result = 1;
}
OS_EXIT_CRITICAL();
return result;
}
CPU_INT08U IsModemConf(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
CPU_INT08U result = 0;
OS_ENTER_CRITICAL();
if (email_options.valid)
{
result = 1;
}
OS_EXIT_CRITICAL();
return result;
}
// ì.á. çàïóñêàòü ïðè ñòàðòå, ÷òîáû ïðîâåðÿòü, íàñòðàèâàåòñÿ ëè ìîæåì ýòèìè íàñòðîéêàìè
int ModemConfigGprs()
{
int repeat = 0;
if (!email_options.valid) return -1;
GetModem();
REP_1:
sprintf(modem_buf, "AT^SICS=0,conType,GPRS0\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
sprintf(modem_buf, "AT^SISC=0\r\n");
ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT);
OSTimeDly(500);
if (repeat++ == 0) goto REP_1;
FreeModem();
return -5;
}
sprintf(modem_buf, "AT^SICS=0,inactTO,\"20\"\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -6;
}
sprintf(modem_buf, "AT^SICS=0,dns1,\"%s\"\r\n", email_options.ap_dns);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -7;
}
sprintf(modem_buf, "AT^SICS=0,passwd,\"%s\"\r\n", email_options.ap_password);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -8;
}
sprintf(modem_buf, "AT^SICS=0,apn,\"%s\"\r\n", email_options.ap_apn);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -9;
}
sprintf(modem_buf, "AT^SICS=0,user,\"%s\"\r\n", email_options.ap_user);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -10;
}
FreeModem();
return 0;
}
int ModemConfigSmtp()
{
int repeat = 0;
if (!email_options.valid) return -1;
GetModem();
REP_2:
// Select service type SMTP.
sprintf(modem_buf, "AT^SISS=0,srvType,\"Smtp\"\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
sprintf(modem_buf, "AT^SISC=0\r\n");
ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT);
OSTimeDly(10000);
if (repeat++ == 0) goto REP_2;
FreeModem();
return -25;
}
// Choose ASCII alphabet.
sprintf(modem_buf, "AT^SISS=0,alphabet,\"1\"\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -26;
}
// Select connection profile 0.
sprintf(modem_buf, "AT^SISS=0,conId,\"0\"\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -27;
}
// Specify SMTP server address.
sprintf(modem_buf, "AT^SISS=0,address,\"%s\"\r\n", email_options.smtp_server);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -28;
}
// Specify sender's user name required for SMTP authentication.
sprintf(modem_buf, "AT^SISS=0,user,\"%s\"\r\n", email_options.smtp_user);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -29;
}
// Specify password used by the sender for SMTP authentication.
sprintf(modem_buf, "AT^SISS=0,passwd,\"%s\"\r\n", email_options.smtp_password);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -30;
}
// Sender name and password can be used for SMTP authentication.
sprintf(modem_buf, "AT^SISS=0,smAuth,\"1\"\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -31;
}
// Port for SMTP connection.
sprintf(modem_buf, "AT^SISS=0,tcpPort,\"%s\"\r\n", email_options.smtp_port);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -32;
}
FreeModem();
return 0;
}
// Îòïðàâêà ïî÷òû: ïîëó÷àòåëü è îòïðàâèòåëü óæå åñòü â íàñòðîêàõ ìîäåìà,
// çàäàåì òåìó è ïåðåäàåì óêàçàòåëü íà callback ôóíêöèþ, ñ ïîìîùüþ êîòîðîé ïîëó÷àåì òåêñò ïèñüìà
int ModemSendEmail(char *subj, TextCallbackFunc text_callback)
{
char *text;
int result = -1;
if (!email_options.valid) return -50;
result = ModemConfigGprs();
if (result)
{
return result;
}
result = ModemConfigSmtp();
if (result)
{
return result;
}
GetModem();
// Sender's email address.
sprintf(modem_buf, "AT^SISS=0,smFrom,\"%s\"\r\n", email_options.smtp_mail);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -51;
}
// Recipient's email address.
sprintf(modem_buf, "AT^SISS=0,smRcpt,\"%s\"\r\n", email_options.receiver);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -52;
}
// Enter text for subject field.
sprintf(modem_buf, "AT^SISS=0,smSubj,\"%s\"\r\n", subj);
if (ModemSendOKCommand(modem_buf, MODEM_RX_TIMEOUT) != 0)
{
FreeModem();
return -53;
}
sprintf(modem_buf, "AT^SISC=0\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0)
{
FreeModem();
return -54;
}
OSTimeDly(5000);
// Open the service, i.e. start to send the email.
sprintf(modem_buf, "AT^SISO=0\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0)
{
FreeModem();
return -55;
}
if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT))
{
FreeModem();
return -56;
}
if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT))
{
FreeModem();
return -57;
}
if (strcmp(modem_buf, "^SISW: 0, 1\r\n") != 0)
{
return -58;
}
text = additional_buf;
OSTimeDly(1000);
// çàïèñü ñîîáùåíèÿ
while (text_callback(text) == 0)
{
int lenght = strlen(text);
int wr_len, reg, eof;
int wr_ctr = 0;
while (wr_ctr < lenght)
{
sprintf(modem_buf, "AT^SISW=0,%d\r\n", lenght-wr_ctr);
if (ModemSendCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT))
{
result = -59;
goto EMAIL_EXIT_FAIL;
}
sscanf(modem_buf, "^SISW: %d, %d, %d", &reg, &wr_len, &eof);
if ((reg != 0) || (eof != 0) || (wr_len > lenght-wr_ctr) || (wr_len == 0))
{
result = -60;
goto EMAIL_EXIT_FAIL;
}
if (ModemSendOKData(text, wr_len, MODEM_OPEN_SERVICE_TIMEOUT) != 0)
{
result = -61;
goto EMAIL_EXIT_FAIL;
}
if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT))
{
result = -62;
goto EMAIL_EXIT_FAIL;
}
wr_ctr += wr_len;
OSTimeDly(50);
}
}
// Set the <eodFlag> to mark the end of the email body.
// The <eodFlag> is accepted by the service.
sprintf(modem_buf, "AT^SISW=0,0,1\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0)
{
result = -63;
goto EMAIL_EXIT_FAIL;
}
// The "^SISW" URC confirms that all data is sent suc-cessfully.
if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) // odoa
{
result = -64;
goto EMAIL_EXIT_FAIL;
}
if (!ModemReadStr(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT)) // ^sisw
{
result = -65;
goto EMAIL_EXIT_FAIL;
}
if (strcmp(modem_buf, "^SISW: 0, 2\r\n") != 0)
{
result = -66;
goto EMAIL_EXIT_FAIL;
}
// Close the service.
sprintf(modem_buf, "AT^SISC=0\r\n");
if (ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT) != 0)
{
result = -67;
goto EMAIL_EXIT_FAIL;
}
FreeModem();
return 0;
EMAIL_EXIT_FAIL:
sprintf(modem_buf, "AT^SISC=0\r\n");
OSTimeDly(10000);
ModemSendOKCommand(modem_buf, MODEM_OPEN_SERVICE_TIMEOUT);
FreeModem();
return result;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
#ifndef __BSP_H__
#define __BSP_H__
/*
*********************************************************************************************************
* EXTERNS
*********************************************************************************************************
*/
#ifdef BSP_GLOBALS
#define BSP_EXT
#else
#define BSP_EXT extern
#endif
/*
*********************************************************************************************************
* DEFINES
*********************************************************************************************************
*/
#define MAIN_OSC_FRQ 12000000L
#define IRC_OSC_FRQ 4000000L
#define RTC_OSC_FRQ 32768L
/*
*********************************************************************************************************
* PCLK PERIPHERAL IDS
* (see 'BSP_CPU_PclkFreq()')
*********************************************************************************************************
*/
#define PCLK_WDT 0
#define PCLK_TIMER0 1
#define PCLK_TIMER1 2
#define PCLK_UART0 3
#define PCLK_UART1 4
#define PCLK_PWM0 5
#define PCLK_PWM1 6
#define PCLK_I2C0 7
#define PCLK_SPI 8
#define PCLK_RTC 9
#define PCLK_SSP1 10
#define PCLK_DAC 11
#define PCLK_ADC 12
#define PCLK_CAN1 13
#define PCLK_CAN2 14
#define PCLK_ACF 15
#define PCLK_BAT_RAM 16
#define PCLK_GPIO 17
#define PCLK_PCB 18
#define PCLK_I2C1 19
#define PCLK_SSP0 21
#define PCLK_TIMER2 22
#define PCLK_TIMER3 23
#define PCLK_UART2 24
#define PCLK_UART3 25
#define PCLK_I2C2 26
#define PCLK_MCI 27
#define PCLK_SYSCON 29
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* MACRO'S
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void BSP_Init (void);
void BSP_IntDisAll (void);
CPU_INT32U BSP_CPU_ClkFreq (void);
CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U id);
/*
*********************************************************************************************************
* TICK SERVICES
*********************************************************************************************************
*/
void Tmr_TickISR_Handler(void);
#endif

View File

@ -0,0 +1,71 @@
#ifndef _APP_SERV_H_
#define _APP_SERV_H_
#include "app_cfg.h"
extern CPU_INT32U incas_bill_nom_counter[24];
extern CPU_INT32U incas_common_bill_counter;
#define KBRD_TASK_STK_SIZE 256
#define USER_TASK_STK_SIZE 384
#define MENU_TASK_STK_SIZE 512
#define COIN_TASK_STK_SIZE 384
#define VALIDATOR_TASK_STK_SIZE 384
#define FISCAL_TASK_STK_SIZE 384
#define MODEM_TASK_STK_SIZE 768
#define VALIDATOR_TASK_PRIO USER_HIGHEST_PRIO
#define USER_TASK_PRIO (USER_HIGHEST_PRIO+1)
#define COIN_TASK_PRIO (USER_HIGHEST_PRIO+2)
#define KBRD_TASK_PRIO (USER_HIGHEST_PRIO+3)
#define FISCAL_TASK_PRIO (USER_HIGHEST_PRIO+4)
#define MENU_TASK_PRIO (USER_HIGHEST_PRIO+5)
#define MODEM_TASK_PRIO USER_LOWEST_PRIO
enum{
EVENT_SEC = 1,
EVENT_STARTUP,
EVENT_COIN_INSERTED,
EVENT_BILL_ESCROW,
EVENT_BILL_STACKED,
EVENT_MODE_CHANGE,
EVENT_KEY_EMPTY,
EVENT_KEY_F1,
EVENT_KEY_F2,
EVENT_KEY_F3,
EVENT_KEY_LEFT,
EVENT_KEY_UP,
EVENT_KEY_RIGHT,
EVENT_KEY_STOP,
EVENT_KEY_DOWN,
EVENT_KEY_START,
EVENT_KEY_USER_START,
EVENT_KEY_DEFERRED_CH1,
EVENT_KEY_DEFERRED_CH2,
EVENT_KEY_DEFERRED_CH3,
EVENT_KEY_DEFERRED_CH4,
EVENT_KEY_DEFERRED_CH5,
EVENT_KEY_DEFERRED_CH6,
EVENT_KEY_DEFERRED_CH7,
EVENT_KEY_DEFERRED_CH8,
EVENT_KEY_DEFERRED_CH9,
EVENT_KEY_DEFERRED_CH10,
EVENT_INCASSATION,
EVENT_INCASSATION_FINISH
};
#define LED_on() {FIO1SET_bit.P1_21= 1;}
#define LED_off() {FIO1CLR_bit.P1_21= 1;}
extern void UserStartupFunc(void);
extern void PostUserEvent(int event);
extern void InitUserMenu(void);
extern int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time);
#endif //#ifndef _APP_SERV_H_

View File

@ -0,0 +1,15 @@
@REM This batch file has been generated by the IAR Embedded Workbench
@REM C-SPY Debugger, as an aid to preparing a command line for running
@REM the cspybat command line utility using the appropriate settings.
@REM
@REM You can launch cspybat by typing the name of this batch file followed
@REM by the name of the debug file (usually an ELF/DWARF or UBROF file).
@REM Note that this file is generated every time a new debug session
@REM is initialized, so you may want to move or rename the file before
@REM making changes.
@REM
"C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\common\bin\cspybat" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armproc.dll" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armjlink.dll" %1 --plugin "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\bin\armbat.dll" --flash_loader "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\config\flashloader\NXP\FlashNXPLPC512k2.board" --backend -B "--endian=little" "--cpu=ARM7TDMI-S" "--fpu=None" "-p" "C:\Program Files (x86)\IAR Systems\Embedded Workbench 6.0\arm\CONFIG\debugger\NXP\iolpc2368.ddf" "--drv_verify_download" "--semihosting" "--device=LPC2368" "--drv_communication=USB0" "--jlink_speed=adaptive" "--jlink_reset_strategy=0,9"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,725 @@
#include <includes.h>
#include "CCRSProtocol.h"
#include "VMCConst.h"
#include "validator.h"
#include "uart1.h"
#include <math.h>
#include <stdlib.h>
#include <string.h>
int iCmdDelay=20;
int iLastError=0;
// îáíîâëåíèå crc
unsigned short crc16_ccitt(unsigned char data, unsigned short crc)
{ register unsigned short a=0x8408, d = crc, i;
d^= data;
for (i=0; i<8; i++)
{if (d & 0x0001)
{d>>= 1;
d^=a;}
else d>>=1;
}
return d;
}
// ïîäñ÷åò crc
unsigned short CalculateCRC(unsigned char *pBuffer)
{
unsigned short wCRC=0;
int Len = (pBuffer[2]) ? pBuffer[2] : ((unsigned short)pBuffer[4]<<8)+pBuffer[5];
for (int i=0;i<Len-2;i++)wCRC=crc16_ccitt(pBuffer[i],wCRC);
return wCRC;
}
// ïîñûëêà ïîäãîòîâëåííûõ äàííûõ èç áóôåðà è ïðèåì îòâåòà
int SendCommand(unsigned char *BufOut, unsigned char *BufIn)
{
int iRecievingError, iBytesToRecieve;
iRecievingError=RE_TIMEOUT;
for(int iErrCount=0;iErrCount<1;iErrCount++)
{
iBytesToRecieve=6;
PurgeComm();
if(!BufOut[2]) COMPort_Send(BufOut, ((unsigned short)BufOut[4]<<8)+BufOut[5]);
else COMPort_Send(BufOut, BufOut[2]);
if((BufOut[3]==ACK)||(BufOut[3]==NAK))
return iRecievingError=RE_NONE;
if(COMPort_Recieve(BufIn, iBytesToRecieve))
{
if(BufIn[0]!=SYNC)
iRecievingError=RE_SYNC;
else
{
int iLen=((BufIn[2])?BufIn[2]:(BufIn[5]+((unsigned short)BufIn[4]<<8)))-iBytesToRecieve;
if(iLen>0)
{
if(COMPort_Recieve(BufIn+iBytesToRecieve, iLen))
{
iRecievingError=RE_NONE;
break;
}
else
{
iRecievingError=RE_DATA;
PurgeComm();
}
}
else
{
iRecievingError=RE_NONE;
break;
}
}
}
}
return iRecievingError;
}
/**
Ïîñûëêà êîìàíäû
äîïîëíÿåò êîìàíäó àäðåñîì óñòðîéñòâà è crc
âîçâðàùàåò íîìåð îøèáêè è äàííûå ïî óêàçàòåëþ
The function is a simple wrapper for the CCCRSProtocol::SendCommand(LPBYTE BufOut, LPBYTE BufIn) member function
and performs the following actions:
-# Complementing the output frame with the device address and CRC16
-# Sending the frame and receiving a response using CCCRSProtocol::SendCommand(LPBYTE BufOut, LPBYTE BufIn) member function
-# Checking received frame integrity (by CRC16 value)
-# Returning the response wrapped in the CCommand object
\param Cmd a parameter of type CCommand & containing output frame (should contain all required information except of device address and CRC)
\param Addr a parameter of type BYTE containing the device address used for communication.
Refer to \link Addr Device address list \endlink for the valid values
*/
unsigned char tmpBuffer[256];
int TransmitCMD(unsigned char *Cmd, unsigned char Addr, unsigned char **data)
{
int i=(Cmd[2]) ? Cmd[2]
: ((unsigned short)Cmd[4]<<8)+Cmd[5];
Cmd[1] = Addr;
unsigned short wCRC=CalculateCRC(Cmd);
Cmd[i-2] = (unsigned char)wCRC;
Cmd[i-1] = (unsigned char)(wCRC>>8);
int iErrCode=SendCommand(Cmd, tmpBuffer);
if((!iErrCode)&&(Cmd[3])&&(0xFF!=Cmd[3]))
{
if (tmpBuffer[2])
{
wCRC = (unsigned short)tmpBuffer[tmpBuffer[2]-2];
wCRC += (unsigned short)((unsigned short)tmpBuffer[tmpBuffer[2]-1])<<8;
}
else
{
wCRC = 0;
//wCRC=tmpBuffer[(tmpBuffer[2])?tmpBuffer[2]:
// (((unsigned short)(tmpBuffer[4]))<<8)+tmpBuffer[5]-2]+
// (tmpBuffer[(tmpBuffer[2])?tmpBuffer[2]:(((unsigned short)(tmpBuffer[4]))<<8)+tmpBuffer[5]-1]<<8);
}
if(CalculateCRC(tmpBuffer)!=wCRC) iErrCode=RE_CRC;
}
*data = tmpBuffer;
return iErrCode;
}
/** \brief The CCCRSProtocol::Transmit function carries complete protocol exchange
The function is a simple wrapper for the CCCRSProtocol::TransmitCMD(CCommand CMD, BYTE Addr) member function
and performs the following actions:
-# Sending the frame and receiving a response using CCCRSProtocol::TransmitCMD(CCommand CMD, BYTE Addr) member function
-# Checking the device response and determining whether ACK or NAK should be sent
-# Sending ACK or NAK message to the device or retransmitting the command up to 3 times untill communication is successfully completed
-# Returning the response wrapped in the CCommand object
\param CMD a parameter of type CCommand & containing output frame (should contain all required information except of device address and CRC)
\param Addr a parameter of type BYTE containing the device address used for communication.
Refer to \link Addr Device address list \endlink for the valid values
\return CCommand - an object containing response data and communication error code
*/
// ôóíêöèÿ ïîñûëàåò êîìàíäó, ïîñûëàåò ACK è ïîâòîðÿåò êîìàíäó, åñëè îøèáêà
int Transmit(unsigned char *CMD, unsigned char Addr)
{
unsigned char *cmdRes, cmdACK[16];
int error;
VPend();
for (int i=0; i<3; i++)
{
error=TransmitCMD(CMD, Addr, &cmdRes);
cmdACK[0] = SYNC;
cmdACK[2] = 6;
cmdACK[3] = ACK;
if (error == RE_NONE)
{
if((ACK==cmdRes[3]) && (cmdRes[2]==6))
{ // îøèáêè íåò
VPost();
return error;
}
if((NAK==cmdRes[3]) && (cmdRes[2]==6))
{
if (iCmdDelay) Sleep(iCmdDelay);//5
}
else
{
cmdACK[3] = ACK;
TransmitCMD(cmdACK, Addr, &cmdRes);
if (iCmdDelay) Sleep(iCmdDelay);//5
break;
}
}
else
{
if(error != RE_TIMEOUT)
{
cmdACK[3] = NAK;
TransmitCMD(cmdACK, Addr, &cmdRes);
if (iCmdDelay) Sleep(iCmdDelay);//5
}
}
}
VPost();
return error;
}
//////////////////////////////////////////////////////////////////////
// CCNET Commands implementation
/** \defgroup CCNETCommands CCNET protocol commands and requests
The group contains member functions providing interface to CCNET commands and requests.
All functions return a bool result showing whether operation was successfully completed.
In the case of error the error code (refer to \link ErrCode Possible error codes \endlink)
is stored in the CCCRSProtocol::iLastError member variable, which can be used in further analysis.
@{
*/
/** \brief The CCCRSProtocol::CmdReset function sends a RESET command to the device
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if command was acknowledged
*/
unsigned char cc_buf[256];
int CC_CmdReset(unsigned char Addr)
{
const unsigned char Data[]={SYNC,0,6,RESET,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response = Transmit(cc_buf, Addr);
unsigned char ack;
if (!Response)
{
ack = tmpBuffer[3];
if(ack != ACK)
{
iLastError = (ack != ST_INV_CMD) ? ER_NAK : ER_INVALID_CMD;
return 0;
}
else
{
return 1;
}
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdPoll function sends POLL command to the device
The function sends POLL command and fills bytes Z1 and Z2 of the response into the CCCRSProtocol::PollResults structure.
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if exchange was successfully completed
*/
int CC_CmdPoll(unsigned char Addr, TPollResults *PollResults)
{
const unsigned char Data[]={SYNC,0,6,POLL,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf, Addr);
if(!Response)
{
PollResults->Z1 = tmpBuffer[3];
PollResults->Z2 = tmpBuffer[4];
return 1;
}
else
{
PollResults->Z1=0;
PollResults->Z2=0;
return 0;
}
}
/** \brief The CCCRSProtocol::CmdStatus function sends STATUS REQUEST to the device
The response status data is stored in the CCCRSProtocol::BillStatus member structure.
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if exchange was successfully completed
*/
int CC_CmdStatus(unsigned char Addr, TBillStatus* BillStatus)
{
const unsigned char Data[]={SYNC,0,6,GET_STATUS,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf,Addr);
if(!Response)
{
if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6))
{
iLastError=ER_INVALID_CMD;
BillStatus->Enabled=0;
BillStatus->Security=0;
BillStatus->Routing=0;
return 0;
}
BillStatus->Enabled=tmpBuffer[5]+((unsigned long)tmpBuffer[4]<<8)+((unsigned long)tmpBuffer[3]<<16);
BillStatus->Security=tmpBuffer[8]+((unsigned long)tmpBuffer[7]<<8)+((unsigned long)tmpBuffer[6]<<16);
BillStatus->Routing=tmpBuffer[11]+((unsigned long)tmpBuffer[10]<<8)+((unsigned long)tmpBuffer[9]<<16);
return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdIdentification function sends IDENTIFICATION request
The function sends IDENTIFICATION request and stores device identification in the member CCCRSProtocol::Ident structure.
The function supports both new and old identification formats of Bill-To-Bill units.
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if the exchange was successfully completed and data received
*/
int CC_CmdIdentification(unsigned char Addr, TIdent* Ident)
{
const unsigned char Data[]={SYNC,0,6,IDENTIFICATION,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf,Addr);
if (!Response)
{
if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6))
{
iLastError=ER_INVALID_CMD;
return 0;
}
strcpy(Ident->BCCPUBoot,"N/A");
strcpy(Ident->BCCPUVersion,"N/A");
strcpy(Ident->BCCS1Boot,"N/A");
strcpy(Ident->BCCS2Boot,"N/A");
strcpy(Ident->BCCS3Boot,"N/A");
strcpy(Ident->BCCSVersion,"N/A");
strcpy(Ident->BCDispenserBoot,"N/A");
strcpy(Ident->BCDispenserVersion,"N/A");
strcpy(Ident->BVBootVersion,"N/A");
strcpy(Ident->BVVersion,"N/A");
strcpy(Ident->PartNumber,"N/A");
char sTemp[64];
int iPos=3,iLen=15;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->PartNumber,sTemp);
iLen=12;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->SN,sTemp);
char *strTemp=(char*)tmpBuffer+iPos;
Ident->DS1=0;iPos+=8;
for(int i=0;i<7;i++)
{
Ident->DS1<<=8;
Ident->DS1+=strTemp[i];
}
if(tmpBuffer[2]<109) return 1;
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BVBootVersion,sTemp);
iLen=20;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BVVersion,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCCPUBoot,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCCPUVersion,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCDispenserBoot,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCDispenserVersion,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCCS1Boot,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCCS2Boot,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCCS3Boot,sTemp);
iLen=6;
strncpy(sTemp,(char*)tmpBuffer+iPos,iLen);
sTemp[iLen]=0;iPos+=iLen;
strcpy(Ident->BCCSVersion,sTemp);
return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdHold function sends HOLD command to the device
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if exchange successfully completed
*/
int CC_CmdHold(unsigned char Addr)
{
const unsigned char Data[256]={SYNC,0,6,HOLD,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf, Addr);
unsigned char ack;
if(!Response)
{
ack = tmpBuffer[3];
if(ack != ACK)
{
iLastError = (ack!=ST_INV_CMD) ? ER_NAK : ER_INVALID_CMD;
return 0;
}
else return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdSetSecurity function sends SET SECURITY LEVELS command
\param wS a parameter of type DWORD - a bitmap containing security levels to set
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if exchange successfully completed
*/
int CC_CmdSetSecurity(unsigned long wS, unsigned char Addr)
{
const unsigned char Data[]={SYNC,0,9,SET_SECURITY,0,0,0,0,0};
memcpy(cc_buf, Data, sizeof(Data));
cc_buf[4]=(unsigned char)(wS>>16);
cc_buf[5]=(unsigned char)(wS>>8);
cc_buf[6]=(unsigned char)(wS);
int Response=Transmit(cc_buf, Addr);
unsigned char ack;
if(!Response)
{
ack = tmpBuffer[3];
if(ack != ACK)
{
iLastError = (ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD;
return 0;
}
else return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdBillType function sends ENABLE BILL TYPE command
\param enBill a parameter of type DWORD - a bitmap containing 1 in the positions corresponding to the enabled bill types
\param escBill a parameter of type DWORD - a bitmap containing 1 in the positions corresponding to bill type processed with escrow
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool- true if the command was acknowledged
*/
int CC_CmdBillType(unsigned long enBill, unsigned long escBill, unsigned char Addr)
{
unsigned char Data[]={SYNC,0,12,BILL_TYPE,
(unsigned char)(enBill>>16),(unsigned char)(enBill>>8),(unsigned char)enBill,
(unsigned char)(escBill>>16),(unsigned char)(escBill>>8),(unsigned char)escBill,
0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf, Addr);
unsigned char ack;
if (!Response)
{
ack = tmpBuffer[3];
if(ack!=ACK)
{
iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD;
return 0;
}
else return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdPack function sends PACK command
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if the command was acknowledged
*/
int CC_CmdPack(unsigned char Addr)
{
const unsigned char Data[]={SYNC,0,6,PACK,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf,Addr);
unsigned char ack;
if (!Response)
{
ack = tmpBuffer[3];
if(ack!=ACK)
{
iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD;
return 0;
}
else return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdReturn function sends RETURN command
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if the command was acknowledged
*/
int CC_CmdReturn(unsigned char Addr)
{
const unsigned char Data[256]={SYNC,0,6,RETURN,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf,Addr);
unsigned char ack;
if(!Response)
{
ack = tmpBuffer[3];
if(ack!=ACK)
{
iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD;
return 0;
}
else return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdGetBillTable function sends BILL TABLE request
\param BillTable a parameter of type _BillRecord * containing pointer to the _BillRecord array receiving the bill table.
Position in the array corresponds to the bill type and the structure at the position describes that bill type.
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if the response was successfully received
*/
int CC_CmdGetBillTable(unsigned char Addr, TBillRecord *BillTable)
{
const unsigned char Data[]={SYNC,0,6,GET_BILL_TABLE,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf,Addr);
if(!Response)
{
int i;
if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6))
{
iLastError=ER_INVALID_CMD;
for(int i=0;i<24;i++)
{
BillTable[i].Denomination=0;
strcpy(BillTable[i].sCountryCode,"");
}
return 0;
}
for(i=0;i<tmpBuffer[2]-5;i+=5)
{
BillTable[i/5].Denomination=tmpBuffer[i+3];
char sTmp[5];
strncpy(sTmp,(const char *)(tmpBuffer+i+4),3);
sTmp[3]='\0';
strcpy(BillTable[i/5].sCountryCode,sTmp);
if(((tmpBuffer)[i+7])&0x80)
{
for(int j=0; j<((tmpBuffer[i+7])&0x7F);j++)
BillTable[i/5].Denomination/=10;
}
else
{
for(int j=0; j<((tmpBuffer[i+7])&0x7F);j++)
BillTable[i/5].Denomination*=10;
};
}
for(;i<24*5;i+=5)
{
BillTable[i/5].Denomination=0;
strcpy(BillTable[i/5].sCountryCode,"");
}
return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdSetOptions function
\param dwOpt a parameter of type DWORD containing bitmap with options to enable. refer to \link Options Options list \endlink
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if the command was acknowledged
*/
int CC_CmdSetOptions(unsigned long dwOpt, unsigned char Addr)
{
unsigned char Data[]={SYNC,0,10,SET_OPTIONS,
(unsigned char)(dwOpt>>24),(unsigned char)(dwOpt>>16),(unsigned char)(dwOpt>>8),(unsigned char)dwOpt,
0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf,Addr);
if(!Response)
{
unsigned char ack = tmpBuffer[3];
if(ack!=ACK)
{
iLastError=(ack!=ST_INV_CMD)?ER_NAK:ER_INVALID_CMD;
return 0;
}
else return 1;
}
else
{
return 0;
}
}
/** \brief The CCCRSProtocol::CmdGetCRC32 function sends CRC32 request
\param dwCRC a parameter of type DWORD & containing a reference to the variable receiving CRC32 of the firmware.
\param Addr a parameter of type BYTE containing device address. Refer to \link Addr Device address list \endlink for the valid values
\return bool - true if the request was answered
*/
int CC_CmdGetCRC32(unsigned long *dwCRC, unsigned char Addr)
{
unsigned char Data[]={SYNC,0,6,CRC32,0,0};
memcpy(cc_buf, Data, sizeof(Data));
int Response=Transmit(cc_buf,Addr);
if(!Response)
{
if((tmpBuffer[3]==ST_INV_CMD)&&(tmpBuffer[2]==6))
{
iLastError=ER_INVALID_CMD;
dwCRC=0;
return 0;
}
*dwCRC=tmpBuffer[6]+((unsigned long)tmpBuffer[5]<<8)+((unsigned long)tmpBuffer[4]<<16)+((unsigned long)tmpBuffer[3]<<24);
return 1;
}
else
{
dwCRC=0;
return 0;
}
}
/** @} */

View File

@ -0,0 +1,42 @@
#include "cpu.h"
#include "datadesc.h"
#include "journal.h"
typedef struct{
CPU_INT32U SerialNum;
TChannelConfig ChannelConfig;
TDeviceConfig DeviceConfig;
// ñ÷åò÷èêè
TCounters Counters;
// äëèííûå ñ÷åò÷èêè ñ CRC16
TCountersLong CountersLong;
CPU_INT32U FRAM_AcceptedMoney;
CPU_INT32U crc_AcceptedMoney;
// æóðíàë îøèáîê
TErrorRecord ErrorRecords[ERROR_RECORDS_NUM];
// æóðíàë ñîáûòèé
TEventRecord EventRecords[EVENT_RECORDS_NUM];
CPU_INT32U Pass;
CPU_INT32U crc_Pass;
CPU_INT32U LastEmailTime;
CPU_INT32U IncasEmailFlag;
CPU_INT32U IncasMoney;
CPU_INT32U IncasTime;
CPU_INT32U StartButtonName;
CPU_INT32U DefferedStartEnabled[CHANNELS_NUM];
}TFramMap;

View File

@ -0,0 +1,4 @@
execUserPreload()
{
__writeMemory32(0x00000001, 0xE01FC040, "Memory"); // MEMMAP = 1;
}

View File

@ -0,0 +1,23 @@
#ifndef _FRAM_H_
#define _FRAM_H_
#define FRAM_WRITE 0x02
#define FRAM_READ 0x03
#define FRAM_WRITE_ON 0x06
#define FRAM_WRITE_OFF 0x04
#define FRAM_READ_STATUS 0x05
#define FRAM_WRITE_STATUS 0x01
extern void WriteByteFram(unsigned short adress,unsigned char byte);
extern unsigned char ReadByteFram(unsigned short adress);
extern unsigned char Read_Status_Register(unsigned short adress);
extern void Write_Status_Register(unsigned char byte, unsigned short address);
extern void ReadArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array);
extern void WriteArrayFram(unsigned short uAddress,unsigned short uBytesNumber,unsigned char * Array);
extern void SetArrayFram(unsigned short uAddress, unsigned short uBytesNumber, unsigned char byte);
#endif

View File

@ -0,0 +1,44 @@
#ifndef _TIME_H_
#define _TIME_H_
#define visocosn(year) ((year % 4) ? 0 : 1)
typedef struct{
CPU_INT08U sec;
CPU_INT08U min;
CPU_INT08U hour;
CPU_INT08U day;
CPU_INT08U date;
CPU_INT08U mon;
CPU_INT08U year;
}TRTC_Data;
#define SEC_TYPE 1
#define MIN_TYPE 2
#define HOUR_TYPE 3
#define DAY_TYPE 4
#define MONTH_TYPE 5
#define YEAR_TYPE 6
extern void InitRTC(void);
extern void RTC_ReadTime(TRTC_Data *rtc);
extern void RTC_SetTime(TRTC_Data *rtc);
extern void Sec2Date(TRTC_Data *pDest, CPU_INT32U ulSec);
extern void Sec2Hour(TRTC_Data *pDest, CPU_INT32U ulSec);
extern CPU_INT32U GetSec(TRTC_Data *pData);
extern CPU_INT32U Date2Sec(TRTC_Data *pData, CPU_INT08U ucType);
extern void PrintSecToMinSec(char *str, int seconds);
extern void PrintRTSTimeString(char *str, TRTC_Data *rtc);
extern void PrintRTCDateTimeString(char *str, TRTC_Data *rtc);
extern void PrintRTCDateTimeStringRus(char *str, TRTC_Data *rtc);
extern void ScanRTCDateTimeStringRus(char *str, TRTC_Data *rtc);
extern void GetDayText(char* str, char day);
extern CPU_INT32U GetTimeSec(void);
int RTCCheckTime(TRTC_Data *rtc);
extern void PrintTimeString(char *str, CPU_INT32U time);
extern void PrintSecToHourMinSec(char *str, int seconds);
extern void PrintSecToBigHourMinSec(char *str, int seconds);
#endif //#ifndef _TIME_H_

View File

@ -0,0 +1,61 @@
#ifndef _APP_SERV_H_
#define _APP_SERV_H_
#include "app_cfg.h"
extern CPU_INT32U incas_bill_nom_counter[24];
extern CPU_INT32U incas_common_bill_counter;
#define KBRD_TASK_STK_SIZE 256
#define USER_TASK_STK_SIZE 384
#define MENU_TASK_STK_SIZE 512
#define COIN_TASK_STK_SIZE 384
#define VALIDATOR_TASK_STK_SIZE 384
#define FISCAL_TASK_STK_SIZE 384
#define MODEM_TASK_STK_SIZE 768
#define VALIDATOR_TASK_PRIO USER_HIGHEST_PRIO
#define USER_TASK_PRIO (USER_HIGHEST_PRIO+1)
#define COIN_TASK_PRIO (USER_HIGHEST_PRIO+2)
#define KBRD_TASK_PRIO (USER_HIGHEST_PRIO+3)
#define FISCAL_TASK_PRIO (USER_HIGHEST_PRIO+4)
#define MENU_TASK_PRIO (USER_HIGHEST_PRIO+5)
#define MODEM_TASK_PRIO USER_LOWEST_PRIO
enum{
EVENT_SEC = 1,
EVENT_STARTUP,
EVENT_COIN_INSERTED,
EVENT_BILL_ESCROW,
EVENT_BILL_STACKED,
EVENT_MODE_CHANGE,
EVENT_KEY_EMPTY,
EVENT_KEY_F1,
EVENT_KEY_F2,
EVENT_KEY_F3,
EVENT_KEY_LEFT,
EVENT_KEY_UP,
EVENT_KEY_RIGHT,
EVENT_KEY_STOP,
EVENT_KEY_DOWN,
EVENT_KEY_START,
EVENT_KEY_USER_START,
EVENT_INCASSATION,
EVENT_INCASSATION_FINISH
};
#define LED_on() {FIO1SET_bit.P1_21= 1;}
#define LED_off() {FIO1CLR_bit.P1_21= 1;}
extern void UserStartupFunc(void);
extern void PostUserEvent(int event);
extern void InitUserMenu(void);
extern int GetRecentChannelPrice(CPU_INT08U ch, CPU_INT32U* price, CPU_INT32U* time);
#endif //#ifndef _APP_SERV_H_

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<workspace>
<project>
<path>$WS_DIR$\solarium.ewp</path>
</project>
<batchBuild/>
</workspace>

View File

@ -0,0 +1,133 @@
/*
*********************************************************************************************************
* uC/CPU
* CPU CONFIGURATION & PORT LAYER
*
* (c) Copyright 2004-2007; Micrium, Inc.; Weston, FL
*
* All rights reserved. Protected by international copyright laws.
*
* uC/CPU is provided in source form for FREE evaluation, for educational
* use or peaceful research. If you plan on using uC/CPU in a commercial
* product you need to contact Micrium to properly license its use in your
* product. We provide ALL the source code for your convenience and to
* help you experience uC/CPU. The fact that the source code is provided
* does NOT mean that you can use it without paying a licensing fee.
*
* Knowledge of the source code may NOT be used to develop a similar product.
*
* Please help us continue to provide the Embedded community with the finest
* software available. Your honesty is greatly appreciated.
*********************************************************************************************************
*/
/*
*********************************************************************************************************
*
* CPU CONFIGURATION DEFINES
*
* Filename : cpu_def.h
* Version : V1.17
* Programmer(s) : ITJ
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* CPU WORD CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_ADDR_SIZE & CPU_CFG_DATA_SIZE in 'cpu.h' with CPU's word sizes :
*
* CPU_WORD_SIZE_08 8-bit word size
* CPU_WORD_SIZE_16 16-bit word size
* CPU_WORD_SIZE_32 32-bit word size
* CPU_WORD_SIZE_64 64-bit word size See Note #1a
*
* (a) 64-bit word size NOT currently supported.
*
* (b) Ideally, CPU_WORD_SIZE #define's would be calculated at compile-time through use of
* the sizeof() operator. However, some compilers do NOT allow pre-processor directives
* to include run-time macro's -- e.g. 'sizeof()'.
*
* (2) Configure CPU_CFG_ENDIAN_TYPE in 'cpu.h' with CPU's data-word-memory order :
*
* CPU_ENDIAN_TYPE_BIG Big- endian word order (CPU words' most significant
* octet @ lowest memory address)
* CPU_ENDIAN_TYPE_LITTLE Little-endian word order (CPU words' least significant
* octet @ lowest memory address)
*********************************************************************************************************
*/
/* ----------------------- CPU WORD SIZE ---------------------- */
#define CPU_WORD_SIZE_08 1 /* 8-bit word size = sizeof(CPU_INT08x). */
#define CPU_WORD_SIZE_16 2 /* 16-bit word size = sizeof(CPU_INT16x). */
#define CPU_WORD_SIZE_32 4 /* 32-bit word size = sizeof(CPU_INT32x). */
#define CPU_WORD_SIZE_64 8 /* 64-bit word size = sizeof(CPU_INT64x) [see Note #1a]. */
/* ------------------- CPU WORD-ENDIAN ORDER ------------------ */
#define CPU_ENDIAN_TYPE_NONE 0 /* */
#define CPU_ENDIAN_TYPE_BIG 1 /* Big- endian word order (CPU words' most significant ... */
/* ... octet @ lowest mem addr). */
#define CPU_ENDIAN_TYPE_LITTLE 2 /* Little-endian word order (CPU words' least significant ... */
/* ... octet @ lowest mem addr). */
/*$PAGE*/
/*
*********************************************************************************************************
* CRITICAL SECTION CONFIGURATION
*
* Note(s) : (1) Configure CPU_CFG_CRITICAL_METHOD with CPU's/compiler's critical section method :
*
* Enter/Exit critical sections by ...
*
* CPU_CRITICAL_METHOD_INT_DIS_EN Disable/Enable interrupts
* CPU_CRITICAL_METHOD_STATUS_STK Push/Pop interrupt status onto stack
* CPU_CRITICAL_METHOD_STATUS_LOCAL Save/Restore interrupt status to local variable
*
* (a) CPU_CRITICAL_METHOD_INT_DIS_EN is NOT a preferred method since it does NOT support
* multiple levels of interrupts. However, with some CPUs/compilers, this is the only
* available method.
*
* (b) CPU_CRITICAL_METHOD_STATUS_STK is one preferred method since it DOES support multiple
* levels of interrupts. However, this method assumes that the compiler allows in-line
* assembly AND will correctly modify the local stack pointer when interrupt status is
* pushed/popped onto the stack.
*
* (c) CPU_CRITICAL_METHOD_STATUS_LOCAL is one preferred method since it DOES support multiple
* levels of interrupts. However, this method assumes that the compiler provides C-level
* &/or assembly-level functionality for the following :
*
* ENTER CRITICAL SECTION :
* (a) Save interrupt status into a local variable
* (b) Disable interrupts
*
* EXIT CRITICAL SECTION :
* (c) Restore interrupt status from a local variable
*
* (2) Critical section macro's most likely require inline assembly. If the compiler does NOT
* allow inline assembly in C source files, critical section macro's MUST call an assembly
* subroutine defined in a 'cpu_a.asm' file located in the following software directory :
*
* \<CPU-Compiler Directory>\<cpu>\<compiler>\
*
* where
* <CPU-Compiler Directory> directory path for common CPU-compiler software
* <cpu> directory name for specific CPU
* <compiler> directory name for specific compiler
*
* (3) To save/restore interrupt status, a local variable 'cpu_sr' of type 'CPU_SR' MAY need to
* be declared (e.g. if 'CPU_CRITICAL_METHOD_STATUS_LOCAL' method is configured). Configure
* 'CPU_SR' data type in 'cpu.h' with the appropriate-sized CPU data type large enough to
* completely store the CPU's/compiler's status word.
*********************************************************************************************************
*/
/* --------------- CPU CRITICAL SECTION METHODS --------------- */
#define CPU_CRITICAL_METHOD_NONE 0 /* */
#define CPU_CRITICAL_METHOD_INT_DIS_EN 1 /* DIS/EN ints. */
#define CPU_CRITICAL_METHOD_STATUS_STK 2 /* Push/Pop int status onto stk. */
#define CPU_CRITICAL_METHOD_STATUS_LOCAL 3 /* Save/Restore int status to local var. */

View File

@ -0,0 +1,63 @@
#ifndef __MODEM_H__
#define __MODEM_H__
#define MODEM_REPEAT_RX 5
#define MODEM_RX_TIMEOUT 5000
#define MODEM_OPEN_SERVICE_TIMEOUT 30000
/*
strings.append("[receiver]=" + config.get('Receiver', 'email'))
strings.append("[ap_dns]=" + config.get('AccessPoint', 'dns', ''))
strings.append("[ap_password]=" + config.get('AccessPoint', 'password', ''))
strings.append("[ap_ip]=" + config.get('AccessPoint', 'ip', ''))
strings.append("[ap_user]=" + config.get('AccessPoint', 'user', ''))
strings.append("[ap_apn]=" + config.get('AccessPoint', 'apn', ''))
strings.append("[smtp_user]=" + config.get('Smtp', 'user', ''))
strings.append("[smtp_password]=" + config.get('Smtp', 'password', ''))
strings.append("[smtp_mail]=" + config.get('Smtp', 'mail', ''))
strings.append("[smtp_server]=" + config.get('Smtp', 'smtp_server', ''))
strings.append("[smtp_port]=" + config.get('Smtp', 'port', '25'))
*/
typedef struct
{
char receiver[64];
char ap_dns[64];
char ap_password[64];
char ap_ip[64];
char ap_user[64];
char ap_apn[64];
char smtp_user[64];
char smtp_password[64];
char smtp_mail[64];
char smtp_server[64];
char smtp_port[64];
CPU_INT08U valid;
} EmailOptions;
static EmailOptions email_options;
#define EMAIL_CFG_ELEM_COUNT 11
typedef int (*TextCallbackFunc)(char *str);
extern int InitModem(void);
extern void ModemWriteStr(char const *str);
extern int ModemSendOKCommand(char *str, unsigned long timeout);
extern int ModemDeleteSMS(unsigned char index);
extern int ModemWriteSMS(char const* text, unsigned char *index);
extern int ModemSendSMS(char const* number, unsigned char index);
extern int ModemReadSMS(char *text, int index);
extern int ModemSendSMSMessage(char const* number, char const* text);
extern int ModemRxNewSMS(unsigned long *num);
extern int ModemSendCommand(char *str, unsigned long timeout);
extern CPU_INT08U IsModemConn(void);
extern CPU_INT08U IsModemConf(void);
extern int InitModemEmailParams(void);
extern int ModemSendEmail(char *subj, TextCallbackFunc text_callback);
extern CPU_INT08U IsModemValid(void);
extern void ResetModemValid(void);
#endif //#ifndef __MODEM_H__

View File

@ -0,0 +1,24 @@
#ifndef _CONTROL_H_
#define _CONTROL_H_
#define CHANNELS_NUM 10
#define CHANNEL_1 0
#define CHANNEL_2 1
#define CHANNEL_3 2
#define CHANNEL_4 3
#define CHANNEL_5 4
#define CHANNEL_6 5
#define CHANNEL_7 6
#define CHANNEL_8 7
#define CHANNEL_9 8
#define CHANNEL_10 9
extern void InitChannels(void);
extern void ChannelOn(CPU_INT08U ch);
extern void ChannelOff(CPU_INT08U ch);
extern int IsChannelOn(CPU_INT08U ch);
#endif //#ifndef _CONTROL_H_

View File

@ -0,0 +1,62 @@
#ifndef _MENUDESC_H_
#define _MENUDESC_H_
#include "journal.h"
#define START_MENU StartMenuPanel
#define WORK_MENU FirstMenuPanel
#define SERVICE_MENU ServiceMenuPanel
extern char FlagForPrintReport;
extern CPU_INT08U str_IncasMenu_3[32];
extern const TMenuPanel ChannelCountersLongPanel[];
extern const TMenuPanel ChanStatMenuPanel[];
extern const TMenuPanel CommStatMenuPanel[];
extern const TMenuPanel MasterPassMenuPanel[];
extern const TMenuPanel IncasMenuPanel[];
extern const TMenuPanel CommonCountersLongPanel[];
extern const TMenuPanel BillCountersPanel[];
extern const TMenuPanel ModemSetupPanel[];
extern const TMenuPanel CoinSetupPanel[];
extern const TMenuPanel JournalIsReset[];
extern const TMenuPanel ClearJournalMenuPanel[];
extern const TMenuPanel StatIsReset[];
extern const TMenuPanel ClearStatMenu[];
extern const TMenuPanel SettingsIsReset[];
extern const TMenuPanel ResetSettingsMenuPanel[];
extern const TMenuPanel ErrorPassPanel[];
extern const TMenuPanel SetNewPassMenuPanel[];
extern const TMenuPanel SetPassMenuPanel[];
extern const TMenuPanel FrMenuPanel[];
extern const TMenuPanel FrIsOffMenuPanel[];
extern const TMenuPanel zReportMenuPanel[];
extern const TMenuPanel xReportMenuPanel[];
extern const TMenuPanel ReportMenuPanel[];
extern const TMenuPanel FirstMenuPanel[];
extern const TMenuPanel ServiceMenuPanel[];
extern const TMenuPanel StartMenuPanel[];
extern const TMenuPanel SettingsMenuPanel[];
extern const TMenuPanel ChannelMenuPanel[];
extern const TMenuPanel DeviceMenuPanel[];
extern const TMenuPanel GetMoneyMenuPanel[];
extern const TMenuPanel PriceWeekdaysMenuPanel[];
extern const TMenuPanel PriceWeekendMenuPanel[];
extern const TMenuPanel StatisticsMenuPanel[];
extern const TMenuPanel ErrorJournalMenuPanel[];
extern const TMenuPanel SelectJournalMenuPanel[];
extern const TMenuPanel TimeSetupMenuPanel[];
extern const TMenuPanel EventJournalMenuPanel[];
extern const TMenuPanel JournalEmptyMenuPanel[];
extern const TMenuPanel ChannelCountersPanel[];
extern const TMenuPanel CommonCountersPanel[];
extern const TMenuPanel bufReportMenuPanel[];
extern void PrintUserMenuStr(char* str, CPU_INT08U n);
extern void PrintEventJournalRecord(TEventRecord *record);
extern char str_EventNumber[24];
extern char str_EventData[24];
#endif //#ifndef _MENUDESC_H_

View File

@ -0,0 +1,802 @@
/*
Äðàéâåð ôèñêàëüíîãî ðåãèñòðàòîðà ØÒÐÈÕ-Ì
*/
#include <includes.h>
#include "uart0.h"
#include "fiscal.h"
#include "fr.h"
CPU_INT08U fisc_buf[256];
int FiscPollExt(void)
{
CPU_INT08U ack;
int byte;
FiscUartSendByte(FISC_ENQ);
byte = FiscUartRecieveByte(&ack, FISC_TIMEOUT);
if (!byte) return FISC_UNDEF;;
if (ack == FISC_NACK) return FISC_READY;
else if (ack == FISC_ACK) return FISC_BUSY;
return FISC_UNDEF;
}
// ïðîâåðêà ñòàòóñà ÔÐ
int FiscPoll(void)
{
CPU_INT08U ack;
FiscUartSendByte(FISC_ENQ);
if (!FiscUartRecieveByte(&ack, FISC_TIMEOUT)) return FISC_UNDEF;;
if (ack == FISC_NACK) return FISC_READY;
else if (ack == FISC_ACK) return FISC_BUSY;
return FISC_UNDEF;
}
// îòïðàâêà êîìàíäû
int FiscSendCommand(CPU_INT08U cmd, CPU_INT08U *dat, CPU_INT08U len)
{
CPU_INT08U lrc,ack;
FiscPurgeRx();
FiscUartSendByte(FISC_STX);
FiscUartSendByte(len+1);
lrc = len+1;
FiscUartSendByte(cmd);
lrc ^= cmd;
while(len--)
{
FiscUartSendByte(*dat);
lrc ^= *dat++;
}
FiscUartSendByte(lrc);
if (!FiscUartRecieveByte(&ack, FISC_TIMEOUT)) return FISC_ERR;
if (ack == FISC_NACK)
{ // æäåì 5 ñåêóíä, íàïðèìåð
for (int i=0; i<100; i++)
{
FiscSleep(FISC_TIMEOUT);
int poll = FiscPoll();
if (poll == FISC_READY) return FISC_OK;
else if (poll == FISC_BUSY) continue;
return FISC_ERR;
}
}
else if (ack == FISC_ACK) return FISC_OK;
return FISC_ERR;
}
// ïðèåì îòâåòà
// âîçâðàùàåò ðåçóëüòàò, óêàçàòåëü íà äàííûå è äëèíó ïîëÿ äàííûõ
int FiscReceiveAnswer(CPU_INT08U **dat, CPU_INT08U *len, CPU_INT32U timeout)
{
CPU_INT08U byte, lrc, num;
*dat = NULL;
*len = 0;
// ñòàðòîâûé áàéò
if (!FiscUartRecieveByte(&byte, timeout)) return FISC_ERR;
if (byte != FISC_STX) return FISC_ERR;
// äëèíà ñîîáùåíèÿ
if (!FiscUartRecieveByte(&byte, FISC_TIMEOUT)) return FISC_ERR;
if (!byte) return FISC_ERR;
num = byte;
// òåïåðü ïðèíèìàåì ÷èñëî áàéò = byte
if (!FiscUartRecieve(fisc_buf, num, FISC_BYTE_TIMEOUT)) return FISC_ERR;
// ïðèíèìàåì êîíòðîëüíóþ ñóììó
if (!FiscUartRecieveByte(&byte, FISC_BYTE_TIMEOUT)) return FISC_ERR;
// ñ÷èòàåì êîíòðîëüíóþ ñóììó
lrc = num;
for (CPU_INT08U i=0; i<num; i++) lrc ^= fisc_buf[i];
// ïðîâåðÿåì êîíòðîëüíóþ ñóììó
if (lrc != byte) return FISC_ERR;
// âñ¸ îê
FiscUartSendByte(FISC_ACK);
*dat = &fisc_buf[0];
*len = num;
return FISC_OK;
}
// ÷òåíèå çàâîäñêîãî íîìåðà ÔÐ
// !!! â íàøåé âåðñèè ÔÐ íå ïîääåðæèâàåòñÿ !!!
int FiscGetFactoryNumber(CPU_INT32U pass, TFiscFactoryNumber* fnum, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_GET_FACTORY_NUMBER, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if ((sizeof(TFiscFactoryNumber)+2) != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_GET_FACTORY_NUMBER) || (rxdat[1] != 0)) {return FISC_ERR;}
memcpy(fnum, &rxdat[2], sizeof(TFiscFactoryNumber));
return FISC_OK;
}
// êîðîòêèé çàïðîñ ñîñòîÿíèÿ ÔÐ
int FiscGetShortStatus(CPU_INT32U pass, TFiscShortStatus* stat, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
*err = 0;
if (FiscSendCommand(FISC_GET_SHORT_STATUS, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if ((sizeof(TFiscShortStatus)+2) != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_GET_SHORT_STATUS) || (rxdat[1] != 0)) {return FISC_ERR;}
memcpy(stat, &rxdat[2], sizeof(TFiscShortStatus));
return FISC_OK;
}
// ïîëíûé çàïðîñ ñîñòîÿíèÿ ÔÐ
int FiscGetFullStatus(CPU_INT32U pass, TFiscFullStatus* stat, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
*err = 0;
if (FiscSendCommand(FISC_GET_FULL_STATUS, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if ((sizeof(TFiscFullStatus)+2) != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_GET_FULL_STATUS) || (rxdat[1] != 0)) {return FISC_ERR;}
memcpy(stat, &rxdat[2], sizeof(TFiscFullStatus));
return FISC_OK;
}
// ïå÷àòàåò 20 ñèìâîëîâ æèðíûìøðèôòîì
// flags: áèò 0 - ïå÷àòü íà êîíòðîëüíîé ëåíòå, áèò 1 - ïå÷àòü íà ÷åêîâîé ëåíòå
int FiscPrintBoldString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = flags;
memset(&fisc_buf[5], 0, 20);
len = strlen((char const*)str);
if (len > 20) len = 20;
memcpy(&fisc_buf[5], str, len);
if (FiscSendCommand(FISC_PRINT_BOLD_STRING, fisc_buf, 25) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (len != 3) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_BOLD_STRING) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ãóäîê
int FiscBeep(CPU_INT32U pass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_BEEP, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_BEEP) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ïå÷àòü ñòðîêè (ìàêñ. 40 ñèìâîëîâ)
// flags: áèò 0 - ïå÷àòü íà êîíòðîëüíîé ëåíòå, áèò 1 - ïå÷àòü íà ÷åêîâîé ëåíòå
int FiscPrintString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = flags;
memset(&fisc_buf[5], 0, 40);
len = strlen((char const*)str);
if (len > 40) len = 40;
memcpy(&fisc_buf[5], str, len);
if (FiscSendCommand(FISC_PRINT_STRING, fisc_buf, 45) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (len != 3) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_STRING) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ïå÷àòü çàãîëîâêà äîêóìåíòà
int FiscPrintDocHeader(CPU_INT32U pass, CPU_INT08U* str, CPU_INT16U number, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
memset(&fisc_buf[4], 0, 30);
len = strlen((char const*)str);
if (len > 30) len = 30;
memcpy(&fisc_buf[4], str, len);
memcpy(&fisc_buf[34], &number, 2);
if (FiscSendCommand(FISC_PRINT_DOC_HEADER, fisc_buf, 36) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (len != 5) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_DOC_HEADER) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// çàïðîñ äåíåæíîãî ðåãèñòðà ïî íîìåðó
// â ðåãèñòðå 6 áàéò - çàïèñûâàåì â long long
int FiscGetMoneyReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT64U* value, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = reg;
if (FiscSendCommand(FISC_GET_MONEY_REG, fisc_buf, 5) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (9 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_GET_MONEY_REG) || (rxdat[1] != 0)) {return FISC_ERR;}
*value = 0;
memcpy(value, &rxdat[3], 6);
return FISC_OK;
}
// çàïðîñ îïåðàöèîííîãî ðåãèñòðà ïî íîìåðó
// â ðåãèñòðå 2 áàéòà
int FiscGetOperReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT16U* value, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = reg;
if (FiscSendCommand(FISC_GET_OPER_REG, fisc_buf, 5) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (5 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_GET_OPER_REG) || (rxdat[1] != 0)) {return FISC_ERR;}
memcpy(value, &rxdat[3], 2);
return FISC_OK;
}
// îòðåçêà ÷åêà
int FiscBillCut(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = type;
if (FiscSendCommand(FISC_BILL_CUT, fisc_buf, 5) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_BILL_CUT) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ïðîòÿæêà
int FiscPullOutTape(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U strnum, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = flags;
fisc_buf[5] = strnum;
if (FiscSendCommand(FISC_PULL_OUT_TAPE, fisc_buf, 6) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PULL_OUT_TAPE) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// âûáðîñ ïîäêëàäíîãî äîêóìåíòà
// íå ïîääåðæèâàåòñÿ
int FiscEjectUnderlayDoc(CPU_INT32U pass, CPU_INT08U dir, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = dir;
if (FiscSendCommand(FISC_EJECT_UNDERLAY_DOC, fisc_buf, 5) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_EJECT_UNDERLAY_DOC) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ïå÷àòü ñòðîêè çàäàííûì øðèôòîì (ìàêñ. 40 ñèìâîëîâ)
// flags: áèò 0 - ïå÷àòü íà êîíòðîëüíîé ëåíòå, áèò 1 - ïå÷àòü íà ÷åêîâîé ëåíòå
int FiscPrintStringByFont(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U font, CPU_INT08U* str, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = flags;
fisc_buf[5] = flags;
memset(&fisc_buf[6], 0, 40);
len = strlen((char const*)str);
if (len > 40) len = 40;
memcpy(&fisc_buf[6], str, len);
if (FiscSendCommand(FISC_PRINT_STRING_BY_FONT, fisc_buf, 46) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (len != 3) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_STRING_BY_FONT) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ñóòî÷íûé îò÷åò áåç ãàøåíèÿ
int FiscPrintDayReportNoClear(CPU_INT32U admpass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_DAY_REPORT_NO_CLEAR, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_DAY_REPORT_NO_CLEAR) || (rxdat[1] != 0)) {return FISC_ERR;}
OSTimeDly(5000);
return FISC_OK;
}
// ñóòî÷íûé îò÷åò c ãàøåíèåì
int FiscPrintDayReportClear(CPU_INT32U admpass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_DAY_REPORT_CLEAR, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_DAY_REPORT_CLEAR) || (rxdat[1] != 0)) {return FISC_ERR;}
OSTimeDly(5000);
return FISC_OK;
}
// ñóòî÷íûé îò÷åò c ãàøåíèåì â áóôåð
int FiscPrintDayReportToBuf(CPU_INT32U admpass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_DAY_REPORT_TO_BUF, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_DAY_REPORT_TO_BUF) || (rxdat[1] != 0)) {return FISC_ERR;}
OSTimeDly(100);
return FISC_OK;
}
// ñóòî÷íûé îò÷åò c ãàøåíèåì â áóôåð
int FiscPrintDayReportsFromBuf(CPU_INT32U admpass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_DAY_REPORT_FROM_BUF, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_DAY_REPORT_FROM_BUF) || (rxdat[1] != 0)) {return FISC_ERR;}
OSTimeDly(5000);
return FISC_OK;
}
// îò÷åò ïî ñåêöèÿì
int FiscPrintSectionReport(CPU_INT32U admpass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_SECTION_REPORT, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_SECTION_REPORT) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// îò÷åò ïî íàëîãàì
int FiscPrintTaxesReport(CPU_INT32U admpass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_TAXES_REPORT, (CPU_INT08U*)&admpass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_TAXES_REPORT) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// âíåñåíèå äåíåã
// ñóììà - â êîïåéêàõ, doc - ñêâîçíîé íîìåð äîêóìåíòà
int FiscMakeDeposit(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
memcpy(&fisc_buf[4], (CPU_INT08U*)&sum, 4);
fisc_buf[8] = 0;
if (FiscSendCommand(FISC_MAKE_DEPOSIT, fisc_buf, 9) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (5 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_MAKE_DEPOSIT) || (rxdat[1] != 0)) {return FISC_ERR;}
memcpy(doc, (CPU_INT08U*)&rxdat[3], 2);
return FISC_OK;
}
// âûïëàòà
int FiscMakePayout(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
memcpy(&fisc_buf[4], (CPU_INT08U*)&sum, 4);
fisc_buf[8] = 0;
if (FiscSendCommand(FISC_MAKE_PAYOUT, fisc_buf, 9) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (5 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_MAKE_PAYOUT) || (rxdat[1] != 0)) {return FISC_ERR;}
memcpy(doc, (CPU_INT08U*)&rxdat[3], 2);
return FISC_OK;
}
// ïå÷àòü êëèøå
// íå ïîääåðæèâàåòñÿ
int FiscPrintCliche(CPU_INT32U pass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_CLICHE, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_CLICHE) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// êîíåö äîêóìåíòà
int FiscEndDoc(CPU_INT32U pass, CPU_INT08U param, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = param;
if (FiscSendCommand(FISC_END_DOC, fisc_buf, 5) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_END_DOC) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ïå÷àòü ðåêëàìíîãî òåêñòà
int FiscPrintAdvText(CPU_INT32U pass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_PRINT_ADV_TEXT, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_ADV_TEXT) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ïîëó÷åíèå èíôîðìàöèè îá óñòðîéñòâå
int FiscGetDeviceType(TFiscDevType* dev, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
if (FiscSendCommand(FISC_GET_DEVICE_TYPE, NULL, 0) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if ((sizeof(TFiscDevType)+2) < len) {return FISC_ERR;}
if ((rxdat[0] != FISC_GET_DEVICE_TYPE) || (rxdat[1] != 0)) {return FISC_ERR;}
memcpy(dev, &rxdat[2], sizeof(TFiscDevType));
return FISC_OK;
}
// îòêðûòèå ÷åêà
int FiscOpenBill(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
fisc_buf[4] = type;
if (FiscSendCommand(FISC_OPEN_BILL, fisc_buf, 5) != FISC_OK)
{
return FISC_ERR;
}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK)
{
return FISC_ERR;
}
*err = rxdat[1];
if (3 != len)
{
return FISC_ERR;
}
if ((rxdat[0] != FISC_OPEN_BILL) || (rxdat[1] != 0))
{
return FISC_ERR;
}
return FISC_OK;
}
// çàðåãèñòðèðîâàòü ïðîäàæó
int FiscMakeSell(CPU_INT32U pass,
CPU_INT64U *count, CPU_INT64U *price, CPU_INT08U department,
CPU_INT08U* tax, char* text, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
memcpy(&fisc_buf[4], (CPU_INT08U*)count, 5);
memcpy(&fisc_buf[9], (CPU_INT08U*)price, 5);
fisc_buf[14] = department;
memcpy(&fisc_buf[15], (CPU_INT08U*)tax, 4);
memset(&fisc_buf[19], 0, 40);
strcpy((char*)&fisc_buf[19], text);
if (FiscSendCommand(FISC_MAKE_SELL, fisc_buf, 59) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_MAKE_SELL) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// çàêðûòèå ÷åêà
int FiscCloseBill(CPU_INT32U pass, CPU_INT64U *cash, CPU_INT08U* tax, char* text, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
memcpy(&fisc_buf[0], (CPU_INT08U*)&pass, 4);
memcpy(&fisc_buf[4], cash, 5);
memset(&fisc_buf[9], 0, 15+2);
memcpy(&fisc_buf[26], tax, 4);
memset(&fisc_buf[30], 0, 40);
strcpy((char*)&fisc_buf[70], text);
if (FiscSendCommand(FISC_CLOSE_BILL, fisc_buf, 70) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (8 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_CLOSE_BILL) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}
// ïðîäîëæåíèå ïå÷àòè (ïîñëå îòñóòñòâèÿ áóìàãè)
int FiscPrintContinue(CPU_INT32U pass, CPU_INT08U* err)
{
CPU_INT08U* rxdat;
CPU_INT08U len;
*err = 0;
if (FiscSendCommand(FISC_PRINT_CONTINUE, (CPU_INT08U*)&pass, 4) != FISC_OK) {return FISC_ERR;}
if (FiscReceiveAnswer(&rxdat, &len, FISC_ANSWER_TIMEOUT) != FISC_OK) {return FISC_ERR;}
*err = rxdat[1];
if (3 != len) {return FISC_ERR;}
if ((rxdat[0] != FISC_PRINT_CONTINUE) || (rxdat[1] != 0)) {return FISC_ERR;}
return FISC_OK;
}

View File

@ -0,0 +1,395 @@
#ifndef _FISCAL_H_
#define _FISCAL_H_
extern CPU_INT08U FiscalState;
#define FISCAL_NOCONN 0
#define FISCAL_CONN 1
// êîäû ñëóæåáãûõ ñèìâîëîâ
#define FISC_ENQ 0x05
#define FISC_STX 0x02
#define FISC_ACK 0x06
#define FISC_NACK 0x15
// ñêîðîñòü ïåðåäà÷è ïî óìîë÷àíèþ
#define FISC_SPEED 115200
// òàéìàóò îòâåòà ïî óìîë÷àíèþ
#define FISC_TIMEOUT 105
#define FISC_BYTE_TIMEOUT 10
#define FISC_ANSWER_TIMEOUT 5000
// êîäû êîìàíä ÔÐ
#define FISC_GET_FACTORY_NUMBER 0x0f
#define FISC_GET_SHORT_STATUS 0x10
#define FISC_GET_FULL_STATUS 0x11
#define FISC_PRINT_BOLD_STRING 0x12
#define FISC_CONTROL_TAPE 0x01
#define FISC_BILL_TAPE 0x02
#define FISC_UNDERLAY_DOC 0x04
#define FISC_BEEP 0x13
#define FISC_PRINT_STRING 0x17
#define FISC_PRINT_DOC_HEADER 0x18
#define FISC_GET_MONEY_REG 0x1A
#define FISC_GET_OPER_REG 0x1B
#define FISC_BILL_CUT 0x25
#define FISC_FULL_CUT 0
#define FISC_HALF_CUT 1
#define FISC_PULL_OUT_TAPE 0x29
#define FISC_EJECT_UNDERLAY_DOC 0x2A
#define FISC_EJECT_DOWN 0
#define FISC_EJECT_UP 1
#define FISC_PRINT_STRING_BY_FONT 0x2F
#define FISC_PRINT_DAY_REPORT_NO_CLEAR 0x40
#define FISC_PRINT_DAY_REPORT_CLEAR 0x41
#define FISC_PRINT_SECTION_REPORT 0x42
#define FISC_PRINT_TAXES_REPORT 0x43
#define FISC_MAKE_DEPOSIT 0x50
#define FISC_MAKE_PAYOUT 0x51
#define FISC_PRINT_CLICHE 0x52
#define FISC_END_DOC 0x53
#define FISC_WITHOUT_ADV 0 // ñ ðåêëàìîé
#define FISC_WITH_ADV 1 // áåç ðåêëàìû
#define FISC_PRINT_ADV_TEXT 0x54
#define FISC_GET_DEVICE_TYPE 0xFC
#define FISC_OPEN_BILL 0x8D
#define FISC_BILL_SELL 0
#define FISC_BILL_BUY 1
#define FISC_MAKE_SELL 0x80
#define FISC_CLOSE_BILL 0x85
#define FISC_PRINT_CONTINUE 0xB0
#define FISC_PRINT_DAY_REPORT_TO_BUF 0xC6
#define FISC_PRINT_DAY_REPORT_FROM_BUF 0xC7
// ïåðåîïðåäåëåíèå ôóíêöèé ïåðåäà÷è
#define FiscPurgeRx Uart0_Flush
#define FiscUartSend Uart0_Send
#define FiscUartRecieve Uart0_Receive
#define FiscUartRecieveByte Uart0_RdByteWithTimeOut
#define FiscUartSendByte Uart0_WrByte
#define FiscSleep(x) OSTimeDly(x)
// îòâåò íà ïðîâåðêó ñòàòóñà FiscPoll()
#define FISC_READY 0
#define FISC_BUSY -1
#define FISC_UNDEF -2
// êîäû ðåçóëüòàòîâ ôóíêöèé
#define FISC_OK 0
#define FISC_ERR -1
// êîäû îøèáîê ÔÐ
#define FR_ERROR_CODE_1 0x1 //Íåèñïðàâåí íàêîïèòåëü ÔÏ 1, ÔÏ 2 èëè ÷àñû
#define FR_ERROR_CODE_2 0x2 //Îòñóòñòâóåò ÔÏ 1
#define FR_ERROR_CODE_3 0x3 //Îòñóòñòâóåò ÔÏ 2
#define FR_ERROR_CODE_4 0x4 //Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå îáðàùåíèÿ ê ÔÏ
#define FR_ERROR_CODE_5 0x5 //Íåò çàïðîøåííûõ äàííûõ
#define FR_ERROR_CODE_6 0x6 //ÔÏ â ðåæèìå âûâîäà äàííûõ
#define FR_ERROR_CODE_7 0x7 //Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå äëÿ äàííîé ðåàëèçàöèè ÔÏ
#define FR_ERROR_CODE_8 0x8 //Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîé ðåàëèçàöèè ÔÏ
#define FR_ERROR_CODE_9 0x9 //Íåêîððåêòíàÿ äëèíà êîìàíäû
#define FR_ERROR_CODE_a 0x0A //Ôîðìàò äàííûõ íå BCD
#define FR_ERROR_CODE_b 0x0B //Íåèñïðàâíà ÿ÷åéêà ïàìÿòè ÔÏ ïðè çàïèñè èòîãà
#define FR_ERROR_CODE_11 0x11 //Íå ââåäåíà ëèöåíçèÿ
#define FR_ERROR_CODE_12 0x12 //Çàâîäñêîé íîìåð óæå ââåäåí
#define FR_ERROR_CODE_13 0x13 //Òåêóùàÿ äàòà ìåíüøå äàòû ïîñëåäíåé çàïèñè â ÔÏ
#define FR_ERROR_CODE_14 0x14 //Îáëàñòü ñìåííûõ èòîãîâ ÔÏ ïåðåïîëíåíà
#define FR_ERROR_CODE_15 0x15 //Ñìåíà óæå îòêðûòà
#define FR_ERROR_CODE_16 0x16 //Ñìåíà íå îòêðûòà //
#define FR_ERROR_CODE_17 0x17 //Íîìåð ïåðâîé ñìåíû áîëüøå íîìåðà ïîñëåäíåé ñìåíû //
#define FR_ERROR_CODE_18 0x18 //Äàòà ïåðâîé ñìåíû áîëüøå äàòû ïîñëåäíåé ñìåíû //
#define FR_ERROR_CODE_19 0x19 //Íåò äàííûõ â ÔÏ //
#define FR_ERROR_CODE_1a 0x1A //Îáëàñòü ïåðåðåãèñòðàöèé â ÔÏ ïåðåïîëíåíà //
#define FR_ERROR_CODE_1b 0x1B //Çàâîäñêîé íîìåð íå ââåäåí //
#define FR_ERROR_CODE_1c 0x1C //Â çàäàííîì äèàïàçîíå åñòü ïîâðåæäåííàÿ çàïèñü //
#define FR_ERROR_CODE_1d 0x1D //Ïîâðåæäåíà ïîñëåäíÿÿ çàïèñü ñìåííûõ èòîãîâ //
#define FR_ERROR_CODE_1f 0x1F //Îòñóòñòâóåò ïàìÿòü ðåãèñòðîâ //
#define FR_ERROR_CODE_20 0x20 //Ïåðåïîëíåíèå äåíåæíîãî ðåãèñòðà ïðè äîáàâëåíèè //
#define FR_ERROR_CODE_21 0x21 //Âû÷èòàåìàÿ ñóììà áîëüøå ñîäåðæèìîãî äåíåæíîãî ðåãèñòðà //
#define FR_ERROR_CODE_22 0x22 //Íåâåðíàÿ äàòà //
#define FR_ERROR_CODE_23 0x23 //Íåò çàïèñè àêòèâèçàöèè //
#define FR_ERROR_CODE_24 0x24 //Îáëàñòü àêòèâèçàöèé ïåðåïîëíåíà //
#define FR_ERROR_CODE_25 0x25 //Íåò àêòèâèçàöèè ñ çàïðàøèâàåìûì íîìåðîì //
#define FR_ERROR_CODE_28 0x28 //Â ÔÐ áîëåå 2õ ñáîéíûõ çàïèñåé //
#define FR_ERROR_CODE_33 0x33 //Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå //
#define FR_ERROR_CODE_35 0x35 //Íåêîððåêòíûé ïàðàìåòð ïðè äàííûõ íàñòðîéêàõ //
#define FR_ERROR_CODE_36 0x36 //Íåêîððåêòíûå ïàðàìåòðû â êîìàíäå äëÿ äàííîé ðåàëèçàöèè ÔÐ //
#define FR_ERROR_CODE_37 0x37 //Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîé ðåàëèçàöèè ÔÐ //
#define FR_ERROR_CODE_38 0x38 //Îøèáêà â ÏÇÓ //+
#define FR_ERROR_CODE_39 0x39 //Âíóòðåííÿÿ îøèáêà ÏÎ ÔÐ //
#define FR_ERROR_CODE_3a 0x3A //Ïåðåïîëíåíèå íàêîïëåíèÿ ïî íàäáàâêàì â ñìåíå //
#define FR_ERROR_CODE_3c 0x3C //ÝÊËÇ: íåâåðíûé ðåãèñòðàöèîííûé íîìåð //
#define FR_ERROR_CODE_3e 0x3E //Ïåðåïîëíåíèå íàêîïëåíèÿ ïî ñåêöèÿì â ñìåíå //
#define FR_ERROR_CODE_3f 0x3F //Ïåðåïîëíåíèå íàêîïëåíèÿ ïî ñêèäêàì â ñìåíå //
#define FR_ERROR_CODE_40 0x40 //Ïåðåïîëíåíèå äèàïàçîíà ñêèäîê //
#define FR_ERROR_CODE_41 0x41 //Ïåðåïîëíåíèå äèàïàçîíà îïëàòû íàëè÷íûìè //
#define FR_ERROR_CODE_42 0x42 //Ïåðåïîëíåíèå äèàïàçîíà îïëàòû òèïîì 2 //
#define FR_ERROR_CODE_43 0x43 //Ïåðåïîëíåíèå äèàïàçîíà îïëàòû òèïîì 3 //
#define FR_ERROR_CODE_44 0x44 //Ïåðåïîëíåíèå äèàïàçîíà îïëàòû òèïîì 4
#define FR_ERROR_CODE_45 0x45 //Cóììà âñåõ òèïîâ îïëàòû ìåíüøå èòîãà ÷åêà //
#define FR_ERROR_CODE_46 0x46 //Íå õâàòàåò íàëè÷íîñòè â êàññå //
#define FR_ERROR_CODE_47 0x47 //Ïåðåïîëíåíèå íàêîïëåíèÿ ïî íàëîãàì â ñìåíå //
#define FR_ERROR_CODE_48 0x48 //Ïåðåïîëíåíèå èòîãà ÷åêà //
#define FR_ERROR_CODE_4a 0x4A //Îòêðûò ÷åê - îïåðàöèÿ íåâîçìîæíà //
#define FR_ERROR_CODE_4b 0x4B //Áóôåð ÷åêà ïåðåïîëíåí //
#define FR_ERROR_CODE_4c 0x4C //Ïåðåïîëíåíèå íàêîïëåíèÿ ïî îáîðîòó íàëîãîâ â ñìåíå //
#define FR_ERROR_CODE_4d 0x4D //Âíîñèìàÿ áåçíàëè÷íîé îïëàòîé ñóììà áîëüøå ñóììû ÷åêà //
#define FR_ERROR_CODE_4e 0x4E //Ñìåíà ïðåâûñèëà 24 ÷àñà //
#define FR_ERROR_CODE_4f 0x4F //Íåâåðíûé ïàðîëü //
#define FR_ERROR_CODE_50 0x50 //Èäåò ïå÷àòü ïðåäûäóùåé êîìàíäû //
#define FR_ERROR_CODE_51 0x51 //Ïåðåïîëíåíèå íàêîïëåíèé íàëè÷íûìè â ñìåíå //
#define FR_ERROR_CODE_52 0x52 //Ïåðåïîëíåíèå íàêîïëåíèé ïî òèïó îïëàòû 2 â ñìåíå //
#define FR_ERROR_CODE_53 0x53 //Ïåðåïîëíåíèå íàêîïëåíèé ïî òèïó îïëàòû 3 â ñìåíå //
#define FR_ERROR_CODE_54 0x54 //Ïåðåïîëíåíèå íàêîïëåíèé ïî òèïó îïëàòû 4 â ñìåíå //
#define FR_ERROR_CODE_56 0x56 //Íåò äîêóìåíòà äëÿ ïîâòîðà //
#define FR_ERROR_CODE_57 0x57 //ÝÊËÇ: êîëè÷åñòâî çàêðûòûõ ñìåí íå ñîâïàäàåò ñ ÔÏ //
#define FR_ERROR_CODE_58 0x58 //Îæèäàíèå êîìàíäû ïðîäîëæåíèÿ ïå÷àòè //
#define FR_ERROR_CODE_59 0x59 //Äîêóìåíò îòêðûò äðóãèì îïåðàòîðîì //
#define FR_ERROR_CODE_5b 0x5B //Ïåðåïîëíåíèå äèàïàçîíà íàäáàâîê //
#define FR_ERROR_CODE_5c 0x5C //Ïîíèæåíî íàïðÿæåíèå 24Â
#define FR_ERROR_CODE_5d 0x5D //Òàáëèöà íå îïðåäåëåíà //
#define FR_ERROR_CODE_5e 0x5E //Íåêîððåêòíàÿ îïåðàöèÿ //
#define FR_ERROR_CODE_5f 0x5F //Îòðèöàòåëüíûé èòîã ÷åêà //
#define FR_ERROR_CODE_60 0x60 //Ïåðåïîëíåíèå ïðè óìíîæåíèè //
#define FR_ERROR_CODE_61 0x61 //Ïåðåïîëíåíèå äèàïàçîíà öåíû //
#define FR_ERROR_CODE_62 0x62 //Ïåðåïîëíåíèå äèàïàçîíà êîëè÷åñòâà //
#define FR_ERROR_CODE_63 0x63 //Ïåðåïîëíåíèå äèàïàçîíà îòäåëà //
#define FR_ERROR_CODE_64 0x64 //ÔÏ îòñóòñòâóåò //+
#define FR_ERROR_CODE_65 0x65 //Íå õâàòàåò äåíåã â ñåêöèè //
#define FR_ERROR_CODE_66 0x66 //Ïåðåïîëíåíèå äåíåã â ñåêöèè //
#define FR_ERROR_CODE_67 0x67 //Îøèáêà ñâÿçè ñ ÔÏ //+
#define FR_ERROR_CODE_68 0x68 //Íå õâàòàåò äåíåã ïî îáîðîòó íàëîãîâ //
#define FR_ERROR_CODE_69 0x69 //Ïåðåïîëíåíèå äåíåã ïî îáîðîòó íàëîãîâ //
#define FR_ERROR_CODE_6a 0x6A //Îøèáêà ïèòàíèÿ â ìîìåíò îòâåòà ïî I
#define FR_ERROR_CODE_6b 0x6B //Íåò ÷åêîâîé ëåíòû //
#define FR_ERROR_CODE_6c 0x6C //Íåò êîíòðîëüíîé ëåíòû //
#define FR_ERROR_CODE_6d 0x6D //Íå õâàòàåò äåíåã ïî íàëîãó //
#define FR_ERROR_CODE_6e 0x6E //Ïåðåïîëíåíèå äåíåã ïî íàëîãó //
#define FR_ERROR_CODE_6f 0x6F //Ïåðåïîëíåíèå ïî âûïëàòå â ñìåíå //
#define FR_ERROR_CODE_70 0x70 //Ïåðåïîëíåíèå ÔÏ //
#define FR_ERROR_CODE_71 0x71 //Îøèáêà îòðåç÷èêà //+
#define FR_ERROR_CODE_72 0x72 //Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîì ïîäðåæèìå //
#define FR_ERROR_CODE_73 0x73 //Êîìàíäà íå ïîääåðæèâàåòñÿ â äàííîì ðåæèìå //
#define FR_ERROR_CODE_74 0x74 //Îøèáêà ÎÇÓ //
#define FR_ERROR_CODE_75 0x75 //Îøèáêà ïèòàíèÿ //+
#define FR_ERROR_CODE_76 0x76 //Îøèáêà ïðèíòåðà: íåò èìïóëüñîâ ñ òàõîãåíåðàòîðà //+
#define FR_ERROR_CODE_77 0x77 //Îøèáêà ïðèíòåðà: íåò ñèãíàëà ñ äàò÷èêîâ //+
#define FR_ERROR_CODE_78 0x78 //Çàìåíà ÏÎ //
#define FR_ERROR_CODE_79 0x79 //Çàìåíà ÔÏ //
#define FR_ERROR_CODE_7a 0x7A //Ïîëå íå ðåäàêòèðóåòñÿ
#define FR_ERROR_CODE_7b 0x7B //Îøèáêà îáîðóäîâàíèÿ //
#define FR_ERROR_CODE_7c 0x7C //Íå ñîâïàäàåò äàòà //
#define FR_ERROR_CODE_7d 0x7D //Íåâåðíûé ôîðìàò äàòû //
#define FR_ERROR_CODE_7e 0x7E //Íåâåðíîå çíà÷åíèå â ïîëå äëèíû //
#define FR_ERROR_CODE_7f 0x7F //Ïåðåïîëíåíèå äèàïàçîíà èòîãà ÷åêà //
#define FR_ERROR_CODE_80 0x80 //Îøèáêà ñâÿçè ñ ÔÏ //+
#define FR_ERROR_CODE_81 0x81 //Îøèáêà ñâÿçè ñ ÔÏ //+
#define FR_ERROR_CODE_82 0x82 //Îøèáêà ñâÿçè ñ ÔÏ //+
#define FR_ERROR_CODE_83 0x83 //Îøèáêà ñâÿçè ñ ÔÏ //+
#define FR_ERROR_CODE_84 0x84 //Ïåðåïîëíåíèå íàëè÷íîñòè //
#define FR_ERROR_CODE_85 0x85 //Ïåðåïîëíåíèå ïî ïðîäàæàì â ñìåíå //
#define FR_ERROR_CODE_86 0x86 //Ïåðåïîëíåíèå ïî ïîêóïêàì â ñìåíå //
#define FR_ERROR_CODE_87 0x87 //Ïåðåïîëíåíèå ïî âîçâðàòàì ïðîäàæ â ñìåíå //
#define FR_ERROR_CODE_88 0x88 //Ïåðåïîëíåíèå ïî âîçâðàòàì ïîêóïîê â ñìåíå //
#define FR_ERROR_CODE_89 0x89 //Ïåðåïîëíåíèå ïî âíåñåíèþ â ñìåíå //
#define FR_ERROR_CODE_8a 0x8A //Ïåðåïîëíåíèå ïî íàäáàâêàì â ÷åêå //
#define FR_ERROR_CODE_8b 0x8B //Ïåðåïîëíåíèå ïî ñêèäêàì â ÷åêå //
#define FR_ERROR_CODE_8c 0x8C //Îòðèöàòåëüíûé èòîã íàäáàâêè â ÷åêå //
#define FR_ERROR_CODE_8d 0x8D //Îòðèöàòåëüíûé èòîã ñêèäêè â ÷åêå //
#define FR_ERROR_CODE_8e 0x8E //Íóëåâîé èòîã ÷åêà //
#define FR_ERROR_CODE_8f 0x8F //Êàññà íå ôèñêàëèçèðîâàíà // //
#define FR_ERROR_CODE_90 0x90 //Ïîëå ïðåâûøàåò ðàçìåð, óñòàíîâëåííûé â íàñòðîéêàõ
#define FR_ERROR_CODE_91 0x91 //Âûõîä çà ãðàíèöó ïîëÿ ïå÷àòè ïðè äàííûõ íàñòðîéêàõ øðèôòà
#define FR_ERROR_CODE_92 0x92 //Íàëîæåíèå ïîëåé
#define FR_ERROR_CODE_93 0x93 //Âîññòàíîâëåíèå ÎÇÓ ïðîøëî óñïåøíî
#define FR_ERROR_CODE_94 0x94 //Èñ÷åðïàí ëèìèò îïåðàöèé â ÷åêå
#define FR_ERROR_CODE_a0 0xA0 //Îøèáêà ñâÿçè ñ ÝÊËÇ
#define FR_ERROR_CODE_a1 0xA1 //ÝÊËÇ îòñóòñòâóåò
#define FR_ERROR_CODE_a2 0xA2 //ÝÊËÇ: Íåêîððåêòíûé ôîðìàò èëè ïàðàìåòð êîìàíäû
#define FR_ERROR_CODE_a3 0xA3 //Íåêîððåêòíîå ñîñòîÿíèå ÝÊËÇ
#define FR_ERROR_CODE_a4 0xA4 //Àâàðèÿ ÝÊËÇ
#define FR_ERROR_CODE_a5 0xA5 //Àâàðèÿ ÊÑ â ñîñòàâå ÝÊËÇ
#define FR_ERROR_CODE_a6 0xA6 //Èñ÷åðïàí âðåìåííîé ðåñóðñ ÝÊËÇ
#define FR_ERROR_CODE_a7 0xA7 //ÝÊËÇ ïåðåïîëíåíà
#define FR_ERROR_CODE_a8 0xA8 //ÇÊËÇ: Íåâåðíûå äàòà è âðåìÿ
#define FR_ERROR_CODE_a9 0xA9 //ÝÊËÇ: Íåò çàïðîøåííûõ äàííûõ
#define FR_ERROR_CODE_aa 0xAA //Ïåðåïîëíåíèå ÝÊËÇ (îòðèöàòåëüíûé èòîã äîêóìåíòà)
#define FR_ERROR_CODE_b0 0xB0 //ÝÊËÇ: Ïåðåïîëíåíèå â ïàðàìåòðå êîëè÷åñòâî
#define FR_ERROR_CODE_b1 0xB1 //ÝÊËÇ: Ïåðåïîëíåíèå â ïàðàìåòðå ñóììà
#define FR_ERROR_CODE_b2 0xB2 //ÝÊËÇ: Óæå àêòèâèçèðîâàíà
#define FR_ERROR_CODE_c0 0xC0 //Êîíòðîëü äàòû è âðåìåíè (ïîäòâåðäèòå äàòó è âðåìÿ)
#define FR_ERROR_CODE_c1 0xC1 //ÝÊËÇ: ñóòî÷íûé îò÷?ò ñ ãàøåíèåì ïðåðâàòü íåëüçÿ
#define FR_ERROR_CODE_c2 0xC2 //Ïðåâûøåíèå íàïðÿæåíèÿ â áëîêå ïèòàíèÿ
#define FR_ERROR_CODE_c3 0xC3 //Íåñîâïàäåíèå èòîãîâ ÷åêà è ÝÊËÇ
#define FR_ERROR_CODE_c4 0xC4 //Íåñîâïàäåíèå íîìåðîâ ñìåí
//#define FR_ERROR_CODE_c5 0xC5 //Áóôåð ïîäêëàäíîãî äîêóìåíòà ïóñò
//#define FR_ERROR_CODE_c6 0xC6 //Ïîäêëàäíîé äîêóìåíò îòñóòñòâóåò //
//#define FR_ERROR_CODE_c7 0xC7 //Ïîëå íå ðåäàêòèðóåòñÿ â äàííîì ðåæèìå
//#define FR_ERROR_CODE_c8 0xC8 //Îòñóòñòâóþò //èìïóëüñû îò òàõîäàò÷èêà
#define FR_ERROR_NUMBER 143
// ñòðóêòóðà çàâîäñêîãî íîìåðà è ÐÍÌ
#pragma pack(1)
typedef struct{
CPU_INT08U FactoryNumber[7];
CPU_INT08U RNM[7];
}TFiscFactoryNumber;
// ñòðóêòóðà êîðîòêîãî ñîñòîÿíèÿ
#pragma pack(1)
typedef struct{
CPU_INT08U OperatorNumber; // íîìåð îïåðàòîðà 1..30
CPU_INT16U Flags; // ôëàãè ÔÐ
/*
Ôëàãè ÔÐ Áèòîâîå ïîëå (íàçíà÷åíèå áèò):
0 Ðóëîí îïåðàöèîííîãî æóðíàëà (0 íåò, 1 åñòü)
1 Ðóëîí ÷åêîâîé ëåíòû (0 íåò, 1 åñòü)
2 Âåðõíèé äàò÷èê ïîäêëàäíîãî äîêóìåíòà (0 íåò, 1 äà)
3 Íèæíèé äàò÷èê ïîäêëàäíîãî äîêóìåíòà (0 íåò, 1 äà)
4 Ïîëîæåíèå äåñÿòè÷íîé òî÷êè (0 0 çíàêîâ, 1 2 çíàêà)
5 ÝÊËÇ (0 íåò, 1 åñòü)
6 Îïòè÷åñêèé äàò÷èê îïåðàöèîííîãî æóðíàëà (0 áóìàãè íåò, 1 áóìàãà åñòü)
7 Îïòè÷åñêèé äàò÷èê ÷åêîâîé ëåíòû (0 áóìàãè íåò, 1 áóìàãà åñòü)
8 Ðû÷àã òåðìîãîëîâêè êîíòðîëüíîé ëåíòû (0 ïîäíÿò, 1 îïóùåí)
9 Ðû÷àã òåðìîãîëîâêè ÷åêîâîé ëåíòû (0 ïîäíÿò, 1 îïóùåí)
10 Êðûøêà êîðïóñà ÔÐ (0 îïóùåíà, 1 ïîäíÿòà)
11 Äåíåæíûé ÿùèê (0 çàêðûò, 1 îêðûò)
12à Îòêàç ïðàâîãî äàò÷èêà ïðèíòåðà (0 íåò, 1 äà)
12á Áóìàãà íà âõîäå â ïðåçåíòåð (0 íåò, 1 äà)
13à Îòêàç ëåâîãî äàò÷èêà ïðèíòåðà (0 íåò, 1 äà)
13á Áóìàãà íà âûõîäå èç ïðåçåíòåðà (0 íåò, 1 äà)
14 ÝÊËÇ ïî÷òè çàïîëíåíà (0 íåò, 1 äà)
15à Óâåëè÷åííàÿ òî÷íîñòü êîëè÷åñòâà (0 íîðìàëüíàÿ òî÷íîñòü, 1 óâåëè÷åííàÿ
òî÷íîñòü) [äëÿ ÊÊÌ áåç ÝÊËÇ]. Äëÿ ÊÊÌ ñ ÝÊËÇ (1 íîðìàëüíàÿ òî÷íîñòü, 0
óâåëè÷åííàÿ òî÷íîñòü)
15á Áóôåð ïðèíòåðà íåïóñò (0 ïóñò, 1 íåïóñò)
*/
CPU_INT08U Mode; // ðåæèì ÔÐ
CPU_INT08U SubMode; // ïîäðåæèì ÔÐ
CPU_INT08U BillOperationNumber_L; // êîë-âî îïðåàöèé â ÷åêå, ìë. áàéò
CPU_INT08U BatteryVoltage; // íàïðÿæåíèå ðåçåðâíîé áàòàðåè
CPU_INT08U PowerSupplyVoltage; // íàïðÿæåíèå èñòî÷íèêà ïèòàíèÿ
CPU_INT08U ErrorCodeFP; // êîä îøèáêè ÔÏ
CPU_INT08U ErrorCodeEKLZ; // êîä îøèáêè ÝÊËÇ
CPU_INT08U BillOperationNumber_H; // êîë-âî îïðåàöèé â ÷åêå, ñò. áàéò
CPU_INT08U Reserve[3]; // ðåçåðâ
}TFiscShortStatus;
// ñòðóêòóðà ïîëíîãî ñîñòîÿíèÿ
#pragma pack(1)
typedef struct{
/*
Ïîðÿäêîâûé íîìåð îïåðàòîðà (1 áàéò) 1…30
Âåðñèÿ ÏÎ ÔÐ (2 áàéòà)
Ñáîðêà ÏÎ ÔÐ (2 áàéòà)
Äàòà ÏÎ ÔÐ (3 áàéòà) ÄÄ-ÌÌ-ÃÃ
Íîìåð â çàëå (1 áàéò)
Ñêâîçíîé íîìåð òåêóùåãî äîêóìåíòà (2 áàéòà)
Ôëàãè ÔÐ (2 áàéòà)
Ðåæèì ÔÐ (1 áàéò)
Ïîäðåæèì ÔÐ (1 áàéò)
Ïîðò ÔÐ (1 áàéò)
Âåðñèÿ ÏÎ ÔÏ (2 áàéòà)
Ñáîðêà ÏÎ ÔÏ (2 áàéòà)
Äàòà ÏÎ ÔÏ (3 áàéòà) ÄÄ-ÌÌ-ÃÃ
Äàòà (3 áàéòà) ÄÄ-ÌÌ-ÃÃ
Âðåìÿ (3 áàéòà) ××-ÌÌ-ÑÑ
Ôëàãè ÔÏ (1 áàéò)
Áèòîâîå ïîëå (íàçíà÷åíèå áèò):
0 ÔÏ 1 (0 –íåò, 1 åñòü)
1 ÔÏ 2 (0 –íåò, 1 åñòü)
2 Ëèöåíçèÿ (0 íå ââåäåíà, 1 ââåäåíà)
3 Ïåðåïîëíåíèå ÔÏ (0 íåò, 1 åñòü)
4 Áàòàðåÿ ÔÏ (0 >80%, 1 <80%)
5 Ïîñëåäíÿÿ çàïèñü ÔÏ (0 èñïîð÷åíà, 1 êîððåêòíà)
6 Ñìåíà â ÔÏ (0 çàêðûòà, 1 îòêðûòà)
7 24 ÷àñà â ÔÏ (0 íå êîí÷èëèñü, 1 êîí÷èëèñü)
Çàâîäñêîé íîìåð (4 áàéòà)
Íîìåð ïîñëåäíåé çàêðûòîé ñìåíû (2 áàéòà)
Êîëè÷åñòâî ñâîáîäíûõ çàïèñåé â ÔÏ (2 áàéòà)
Êîëè÷åñòâî ïåðåðåãèñòðàöèé (ôèñêàëèçàöèé) (1 áàéò)
Êîëè÷åñòâî îñòàâøèõñÿ ïåðåðåãèñòðàöèé (ôèñêàëèçàöèé) (1 áàéò)
ÈÍÍ (6 áàéò)
*/
CPU_INT08U OperatorNumber; // íîìåð îïåðàòîðà 1..30
CPU_INT08U version[4];
CPU_INT08U version_date[3];
CPU_INT08U nomer_v_zale;
CPU_INT16U document_number;
CPU_INT16U Flags; // ôëàãè ÔÐ
CPU_INT08U Mode; // ðåæèì ÔÐ
CPU_INT08U SubMode; // ïîäðåæèì ÔÐ
CPU_INT08U port;
CPU_INT08U ver_fp[4];
CPU_INT08U date_fp[3];
CPU_INT08U date[3];
CPU_INT08U time[3];
CPU_INT08U fp_flags;
CPU_INT32U FactoryNumber;
CPU_INT16U LastSmena;
CPU_INT16U FpFreePlace;
CPU_INT08U perereg;
CPU_INT08U perereg_free;
CPU_INT08U inn[6];
}TFiscFullStatus;
// ñòðóêòóðà èíôîðìàöèè îá óñòðîéñòâå
#pragma pack(1)
typedef struct{
CPU_INT08U Type; // Òèï óñòðîéñòâà (1 áàéò) 0…255
CPU_INT08U Subtype; // Ïîäòèï óñòðîéñòâà (1 áàéò) 0…255
CPU_INT08U ProtocolVersion; // Âåðñèÿ ïðîòîêîëà äëÿ äàííîãî óñòðîéñòâà (1 áàéò) 0…255
CPU_INT08U ProtocolSubVersion; // Ïîäâåðñèÿ ïðîòîêîëà äëÿ äàííîãî óñòðîéñòâà (1 áàéò) 0…255
CPU_INT08U Model; // Ìîäåëü óñòðîéñòâà (1 áàéò) 0…255
CPU_INT08U Language; // ßçûê óñòðîéñòâà (1 áàéò) 0…255 ðóññêèé 0; àíãëèéñêèé 1;
#define FISC_LANG_RUS 0
#define FISC_LANG_ENG 1
CPU_INT08U Name[32]; // Íàçâàíèå óñòðîéñòâà ñòðîêà ñèìâîëîâ â êîäèðîâêå WIN1251. Êîëè÷åñòâî
// áàéò, îòâîäèìîå ïîä íàçâàíèå óñòðîéñòâà, îïðåäåëÿåòñÿ â êàæäîì êîíêðåòíîì
// ñëó÷àå ñàìîñòîÿòåëüíî ðàçðàáîò÷èêàìè óñòðîéñòâà (X áàéò)
}TFiscDevType;
extern TFiscDevType FiscDevInfo;
// ôóíêöèè
extern int FiscPoll(void);
extern int FiscGetFactoryNumber(CPU_INT32U pass, TFiscFactoryNumber* fnum, CPU_INT08U* err);
extern int FiscGetShortStatus(CPU_INT32U pass, TFiscShortStatus* stat, CPU_INT08U* err);
extern int FiscGetFullStatus(CPU_INT32U pass, TFiscFullStatus* stat, CPU_INT08U* err);
extern int FiscPrintBoldString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err);
extern int FiscBeep(CPU_INT32U pass, CPU_INT08U* err);
extern int FiscPrintString(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U* str, CPU_INT08U* err);
extern int FiscPrintDocHeader(CPU_INT32U pass, CPU_INT08U* str, CPU_INT16U number, CPU_INT08U* err);
extern int FiscGetMoneyReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT64U* value, CPU_INT08U* err);
extern int FiscGetOperReg(CPU_INT32U pass, CPU_INT08U reg, CPU_INT16U* value, CPU_INT08U* err);
extern int FiscBillCut(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err);
extern int FiscPullOutTape(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U strnum, CPU_INT08U* err);
extern int FiscEjectUnderlayDoc(CPU_INT32U pass, CPU_INT08U dir, CPU_INT08U* err);
extern int FiscPrintStringByFont(CPU_INT32U pass, CPU_INT08U flags, CPU_INT08U font, CPU_INT08U* str, CPU_INT08U* err);
extern int FiscPrintDayReportNoClear(CPU_INT32U admpass, CPU_INT08U* err);
extern int FiscPrintDayReportClear(CPU_INT32U admpass, CPU_INT08U* err);
extern int FiscPrintSectionReport(CPU_INT32U admpass, CPU_INT08U* err);
extern int FiscPrintTaxesReport(CPU_INT32U admpass, CPU_INT08U* err);
extern int FiscMakeDeposit(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err);
extern int FiscMakePayout(CPU_INT32U pass, CPU_INT32U sum, CPU_INT16U* doc, CPU_INT08U* err);
extern int FiscPrintCliche(CPU_INT32U pass, CPU_INT08U* err);
extern int FiscEndDoc(CPU_INT32U pass, CPU_INT08U param, CPU_INT08U* err);
extern int FiscPrintAdvText(CPU_INT32U pass, CPU_INT08U* err);
extern int FiscGetDeviceType(TFiscDevType* dev, CPU_INT08U* err);
extern int FiscPrintContinue(CPU_INT32U pass, CPU_INT08U* err);
extern int FiscOpenBill(CPU_INT32U pass, CPU_INT08U type, CPU_INT08U* err);
extern int FiscMakeSell(CPU_INT32U pass, CPU_INT64U *count, CPU_INT64U *price, CPU_INT08U department, CPU_INT08U* tax, char* text, CPU_INT08U* err);
extern int FiscCloseBill(CPU_INT32U pass, CPU_INT64U *cash, CPU_INT08U* tax, char* text, CPU_INT08U* err);
extern int FiscPrintDayReportToBuf(CPU_INT32U admpass, CPU_INT08U* err);
extern int FiscPrintDayReportsFromBuf(CPU_INT32U admpass, CPU_INT08U* err);
extern int FiscPollExt(void);
#endif //#ifndef _FISCAL_H_

View File

@ -0,0 +1,56 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x00000044;
define symbol __ICFEDIT_region_ROM_end__ = 0x0007FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x40000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x40007FFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x400;
define symbol __ICFEDIT_size_svcstack__ = 0x100;
define symbol __ICFEDIT_size_irqstack__ = 0x100;
define symbol __ICFEDIT_size_fiqstack__ = 0x40;
define symbol __ICFEDIT_size_undstack__ = 0x10;
define symbol __ICFEDIT_size_abtstack__ = 0x10;
define symbol __ICFEDIT_size_heap__ = 0x2000;
/**** End of ICF editor section. ###ICF###*/
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define symbol __region_USB_DMA_RAM_start__ = 0x7FD00000;
define symbol __region_USB_DMA_RAM_end__ = 0x7FD01FFF;
define region USB_DMA_RAM_region= mem:[from __region_USB_DMA_RAM_start__ to __region_USB_DMA_RAM_end__];
define symbol __region_EMAC_DMA_RAM_start__ = 0x7FE00000;
define symbol __region_EMAC_DMA_RAM_end__ = 0x7FE03FFF;
define region EMAC_DMA_RAM_region= mem:[from __region_EMAC_DMA_RAM_start__ to __region_EMAC_DMA_RAM_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block SVC_STACK with alignment = 8, size = __ICFEDIT_size_svcstack__ { };
define block IRQ_STACK with alignment = 8, size = __ICFEDIT_size_irqstack__ { };
define block FIQ_STACK with alignment = 8, size = __ICFEDIT_size_fiqstack__ { };
define block UND_STACK with alignment = 8, size = __ICFEDIT_size_undstack__ { };
define block ABT_STACK with alignment = 8, size = __ICFEDIT_size_abtstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
do not initialize { section USB_DMA_RAM };
do not initialize { section EMAC_DMA_RAM };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP };
place in USB_DMA_RAM_region
{ readwrite data section USB_DMA_RAM };
place in EMAC_DMA_RAM_region
{ readwrite data section EMAC_DMA_RAM };

View File

@ -0,0 +1,292 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
* DEBUGGER CONSTANTS
*
* (c) Copyright 1992-2007, Micrium, Weston, FL
* All Rights Reserved
*
* Generic ARM Port
*
* File : OS_DBG.C
* Version : V1.82
* By : Jean J. Labrosse
*
* For : ARM7 or ARM9
* Mode : ARM or Thumb
* Toolchain : IAR's EWARM V4.11a and higher
*********************************************************************************************************
*/
#include <ucos_ii.h>
/* The following #define tells the IAR compiler to 'not' optimize these ... */
/* ... 'const' out since they are not used elsewhere. */
#define OS_COMPILER_OPT __root
/*
*********************************************************************************************************
* DEBUG DATA
*********************************************************************************************************
*/
OS_COMPILER_OPT INT16U const OSDebugEn = OS_DEBUG_EN; /* Debug constants are defined below */
#if OS_DEBUG_EN > 0
OS_COMPILER_OPT INT32U const OSEndiannessTest = 0x12345678L; /* Variable to test CPU endianness */
OS_COMPILER_OPT INT16U const OSEventMax = OS_MAX_EVENTS; /* Number of event control blocks */
OS_COMPILER_OPT INT16U const OSEventNameSize = OS_EVENT_NAME_SIZE; /* Size (in bytes) of event names */
OS_COMPILER_OPT INT16U const OSEventEn = OS_EVENT_EN;
#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0)
OS_COMPILER_OPT INT16U const OSEventSize = sizeof(OS_EVENT); /* Size in Bytes of OS_EVENT */
OS_COMPILER_OPT INT16U const OSEventTblSize = sizeof(OSEventTbl); /* Size of OSEventTbl[] in bytes */
#else
OS_COMPILER_OPT INT16U const OSEventSize = 0;
OS_COMPILER_OPT INT16U const OSEventTblSize = 0;
#endif
OS_COMPILER_OPT INT16U const OSFlagEn = OS_FLAG_EN;
#if (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
OS_COMPILER_OPT INT16U const OSFlagGrpSize = sizeof(OS_FLAG_GRP); /* Size in Bytes of OS_FLAG_GRP */
OS_COMPILER_OPT INT16U const OSFlagNodeSize = sizeof(OS_FLAG_NODE); /* Size in Bytes of OS_FLAG_NODE */
OS_COMPILER_OPT INT16U const OSFlagWidth = sizeof(OS_FLAGS); /* Width (in bytes) of OS_FLAGS */
#else
OS_COMPILER_OPT INT16U const OSFlagGrpSize = 0;
OS_COMPILER_OPT INT16U const OSFlagNodeSize = 0;
OS_COMPILER_OPT INT16U const OSFlagWidth = 0;
#endif
OS_COMPILER_OPT INT16U const OSFlagMax = OS_MAX_FLAGS;
OS_COMPILER_OPT INT16U const OSFlagNameSize = OS_FLAG_NAME_SIZE; /* Size (in bytes) of flag names */
OS_COMPILER_OPT INT16U const OSLowestPrio = OS_LOWEST_PRIO;
OS_COMPILER_OPT INT16U const OSMboxEn = OS_MBOX_EN;
OS_COMPILER_OPT INT16U const OSMemEn = OS_MEM_EN;
OS_COMPILER_OPT INT16U const OSMemMax = OS_MAX_MEM_PART; /* Number of memory partitions */
OS_COMPILER_OPT INT16U const OSMemNameSize = OS_MEM_NAME_SIZE; /* Size (in bytes) of partition names */
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
OS_COMPILER_OPT INT16U const OSMemSize = sizeof(OS_MEM); /* Mem. Partition header sine (bytes) */
OS_COMPILER_OPT INT16U const OSMemTblSize = sizeof(OSMemTbl);
#else
OS_COMPILER_OPT INT16U const OSMemSize = 0;
OS_COMPILER_OPT INT16U const OSMemTblSize = 0;
#endif
OS_COMPILER_OPT INT16U const OSMutexEn = OS_MUTEX_EN;
OS_COMPILER_OPT INT16U const OSPtrSize = sizeof(void *); /* Size in Bytes of a pointer */
OS_COMPILER_OPT INT16U const OSQEn = OS_Q_EN;
OS_COMPILER_OPT INT16U const OSQMax = OS_MAX_QS; /* Number of queues */
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
OS_COMPILER_OPT INT16U const OSQSize = sizeof(OS_Q); /* Size in bytes of OS_Q structure */
#else
OS_COMPILER_OPT INT16U const OSQSize = 0;
#endif
OS_COMPILER_OPT INT16U const OSRdyTblSize = OS_RDY_TBL_SIZE; /* Number of bytes in the ready table */
OS_COMPILER_OPT INT16U const OSSemEn = OS_SEM_EN;
OS_COMPILER_OPT INT16U const OSStkWidth = sizeof(OS_STK); /* Size in Bytes of a stack entry */
OS_COMPILER_OPT INT16U const OSTaskCreateEn = OS_TASK_CREATE_EN;
OS_COMPILER_OPT INT16U const OSTaskCreateExtEn = OS_TASK_CREATE_EXT_EN;
OS_COMPILER_OPT INT16U const OSTaskDelEn = OS_TASK_DEL_EN;
OS_COMPILER_OPT INT16U const OSTaskIdleStkSize = OS_TASK_IDLE_STK_SIZE;
OS_COMPILER_OPT INT16U const OSTaskProfileEn = OS_TASK_PROFILE_EN;
OS_COMPILER_OPT INT16U const OSTaskMax = OS_MAX_TASKS + OS_N_SYS_TASKS; /* Total max. number of tasks */
OS_COMPILER_OPT INT16U const OSTaskNameSize = OS_TASK_NAME_SIZE; /* Size (in bytes) of task names */
OS_COMPILER_OPT INT16U const OSTaskStatEn = OS_TASK_STAT_EN;
OS_COMPILER_OPT INT16U const OSTaskStatStkSize = OS_TASK_STAT_STK_SIZE;
OS_COMPILER_OPT INT16U const OSTaskStatStkChkEn = OS_TASK_STAT_STK_CHK_EN;
OS_COMPILER_OPT INT16U const OSTaskSwHookEn = OS_TASK_SW_HOOK_EN;
OS_COMPILER_OPT INT16U const OSTCBPrioTblMax = OS_LOWEST_PRIO + 1; /* Number of entries in OSTCBPrioTbl[] */
OS_COMPILER_OPT INT16U const OSTCBSize = sizeof(OS_TCB); /* Size in Bytes of OS_TCB */
OS_COMPILER_OPT INT16U const OSTicksPerSec = OS_TICKS_PER_SEC;
OS_COMPILER_OPT INT16U const OSTimeTickHookEn = OS_TIME_TICK_HOOK_EN;
OS_COMPILER_OPT INT16U const OSVersionNbr = OS_VERSION;
OS_COMPILER_OPT INT16U const OSTmrEn = OS_TMR_EN;
OS_COMPILER_OPT INT16U const OSTmrCfgMax = OS_TMR_CFG_MAX;
OS_COMPILER_OPT INT16U const OSTmrCfgNameSize = OS_TMR_CFG_NAME_SIZE;
OS_COMPILER_OPT INT16U const OSTmrCfgWheelSize = OS_TMR_CFG_WHEEL_SIZE;
OS_COMPILER_OPT INT16U const OSTmrCfgTicksPerSec = OS_TMR_CFG_TICKS_PER_SEC;
#if (OS_TMR_EN > 0) && (OS_TMR_CFG_MAX > 0)
OS_COMPILER_OPT INT16U const OSTmrSize = sizeof(OS_TMR);
OS_COMPILER_OPT INT16U const OSTmrTblSize = sizeof(OSTmrTbl);
OS_COMPILER_OPT INT16U const OSTmrWheelSize = sizeof(OS_TMR_WHEEL);
OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = sizeof(OSTmrWheelTbl);
#else
OS_COMPILER_OPT INT16U const OSTmrSize = 0;
OS_COMPILER_OPT INT16U const OSTmrTblSize = 0;
OS_COMPILER_OPT INT16U const OSTmrWheelSize = 0;
OS_COMPILER_OPT INT16U const OSTmrWheelTblSize = 0;
#endif
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* DEBUG DATA
* TOTAL DATA SPACE (i.e. RAM) USED BY uC/OS-II
*********************************************************************************************************
*/
#if OS_DEBUG_EN > 0
OS_COMPILER_OPT INT16U const OSDataSize = sizeof(OSCtxSwCtr)
#if (OS_EVENT_EN > 0) && (OS_MAX_EVENTS > 0)
+ sizeof(OSEventFreeList)
+ sizeof(OSEventTbl)
#endif
#if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
+ sizeof(OSFlagTbl)
+ sizeof(OSFlagFreeList)
#endif
#if OS_TASK_STAT_EN > 0
+ sizeof(OSCPUUsage)
+ sizeof(OSIdleCtrMax)
+ sizeof(OSIdleCtrRun)
+ sizeof(OSStatRdy)
+ sizeof(OSTaskStatStk)
#endif
#if OS_TICK_STEP_EN > 0
+ sizeof(OSTickStepState)
#endif
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
+ sizeof(OSMemFreeList)
+ sizeof(OSMemTbl)
#endif
#if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
+ sizeof(OSQFreeList)
+ sizeof(OSQTbl)
#endif
#if OS_TIME_GET_SET_EN > 0
+ sizeof(OSTime)
#endif
#if (OS_TMR_EN > 0) && (OS_TMR_CFG_MAX > 0)
+ sizeof(OSTmrFree)
+ sizeof(OSTmrUsed)
+ sizeof(OSTmrTime)
+ sizeof(OSTmrSem)
+ sizeof(OSTmrSemSignal)
+ sizeof(OSTmrFreeList)
+ sizeof(OSTmrTbl)
+ sizeof(OSTmrWheelTbl)
#endif
+ sizeof(OSIntNesting)
+ sizeof(OSLockNesting)
+ sizeof(OSPrioCur)
+ sizeof(OSPrioHighRdy)
+ sizeof(OSRdyGrp)
+ sizeof(OSRdyTbl)
+ sizeof(OSRunning)
+ sizeof(OSTaskCtr)
+ sizeof(OSIdleCtr)
+ sizeof(OSTaskIdleStk)
+ sizeof(OSTCBCur)
+ sizeof(OSTCBFreeList)
+ sizeof(OSTCBHighRdy)
+ sizeof(OSTCBList)
+ sizeof(OSTCBPrioTbl)
+ sizeof(OSTCBTbl);
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* OS DEBUG INITIALIZAZTION
*
* Description: This function is used to make sure that debug variables that are unused in the application
* are not optimized away. This function might not be necessary for all compilers. In this
* case, you should simply DELETE the code in this function while still leaving the declaration
* of the function itself.
*
* Arguments : none
*
* Returns : none
*
* Note(s) : (1) This code doesn't do anything, it simply prevents the compiler from optimizing out
* the 'const' variables which are declared in this file.
*********************************************************************************************************
*/
#if OS_VERSION >= 270 && OS_DEBUG_EN > 0
void OSDebugInit (void)
{
void *ptemp;
ptemp = (void *)&OSDebugEn;
ptemp = (void *)&OSEndiannessTest;
ptemp = (void *)&OSEventMax;
ptemp = (void *)&OSEventNameSize;
ptemp = (void *)&OSEventEn;
ptemp = (void *)&OSEventSize;
ptemp = (void *)&OSEventTblSize;
ptemp = (void *)&OSFlagEn;
ptemp = (void *)&OSFlagGrpSize;
ptemp = (void *)&OSFlagNodeSize;
ptemp = (void *)&OSFlagWidth;
ptemp = (void *)&OSFlagMax;
ptemp = (void *)&OSFlagNameSize;
ptemp = (void *)&OSLowestPrio;
ptemp = (void *)&OSMboxEn;
ptemp = (void *)&OSMemEn;
ptemp = (void *)&OSMemMax;
ptemp = (void *)&OSMemNameSize;
ptemp = (void *)&OSMemSize;
ptemp = (void *)&OSMemTblSize;
ptemp = (void *)&OSMutexEn;
ptemp = (void *)&OSPtrSize;
ptemp = (void *)&OSQEn;
ptemp = (void *)&OSQMax;
ptemp = (void *)&OSQSize;
ptemp = (void *)&OSRdyTblSize;
ptemp = (void *)&OSSemEn;
ptemp = (void *)&OSStkWidth;
ptemp = (void *)&OSTaskCreateEn;
ptemp = (void *)&OSTaskCreateExtEn;
ptemp = (void *)&OSTaskDelEn;
ptemp = (void *)&OSTaskIdleStkSize;
ptemp = (void *)&OSTaskProfileEn;
ptemp = (void *)&OSTaskMax;
ptemp = (void *)&OSTaskNameSize;
ptemp = (void *)&OSTaskStatEn;
ptemp = (void *)&OSTaskStatStkSize;
ptemp = (void *)&OSTaskStatStkChkEn;
ptemp = (void *)&OSTaskSwHookEn;
ptemp = (void *)&OSTCBPrioTblMax;
ptemp = (void *)&OSTCBSize;
ptemp = (void *)&OSTicksPerSec;
ptemp = (void *)&OSTimeTickHookEn;
ptemp = (void *)&OSVersionNbr;
ptemp = (void *)&OSDataSize;
ptemp = ptemp; /* Prevent compiler warning for 'ptemp' not being used! */
}
#endif

View File

@ -0,0 +1,228 @@
#include <includes.h>
#include "uart2.h"
static unsigned char UART2TXBuffer[UART2_TX_BUFSIZE];
static unsigned short UART2TXhead = 0;
static unsigned short UART2TXtail = 0;
static unsigned short UART2TXcount = 0;
static unsigned char UART2RXBuffer[UART2_RX_BUFSIZE];
static unsigned short UART2RXhead = 0;
static unsigned short UART2RXtail = 0;
static unsigned short UART2RXcount = 0;
void Uart2_Flush(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
UART2TXcount = UART2TXhead = UART2TXtail = 0;
UART2RXcount = UART2RXhead = UART2RXtail = 0;
U2IER_bit.THREIE = 0;
U2FCR = 0x06;
OS_EXIT_CRITICAL();
}
int Uart2_Getc(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = -1;
if (UART2RXcount > 0)
{
UART2RXcount--;
res = UART2RXBuffer[UART2RXhead++];
UART2RXhead %= UART2_RX_BUFSIZE;
}
OS_EXIT_CRITICAL();
return res;
}
int Uart2_Gotc(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = 0;
if (UART2RXcount > 0) res = 1;
OS_EXIT_CRITICAL();
return res;
}
int Uart2_Ready(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = 0;
if (UART2TXcount < UART2_TX_BUFSIZE) res = 1;
OS_EXIT_CRITICAL();
return res;
}
int Uart2_Putc(unsigned char ch)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
int res = 0;
if (UART2TXcount < UART2_TX_BUFSIZE)
{
if (UART2TXcount == 0)
{
if (U2LSR_bit.THRE)
{
U2THR = ch;
}
else
{
UART2TXcount++;
UART2TXBuffer[UART2TXtail++] = ch;
UART2TXtail %= UART2_TX_BUFSIZE;
U2IER = 3;
}
}
else
{
UART2TXcount++;
UART2TXBuffer[UART2TXtail++] = ch;
UART2TXtail %= UART2_TX_BUFSIZE;
U2IER = 3;
}
}
else
{
res = -1;
}
OS_EXIT_CRITICAL();
return res;
}
static void Uart2_Isr(void)
{
CPU_INT08U IIRValue;
CPU_INT08U u1lsr;
volatile CPU_INT08U Dummy;
IIRValue = U2IIR;
IIRValue >>= 1; /* skip pending bit in IIR */
IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
if (IIRValue == 2) /* Receive Data Available */
{
/* Receive Data Available */
if (U2LSR_bit.DR)
{
if (UART2RXcount < UART2_RX_BUFSIZE)
{
UART2RXBuffer[UART2RXtail++] = U2RBR;
UART2RXtail %= UART2_RX_BUFSIZE;
UART2RXcount++;
}
else
{
Dummy = U2RBR;
}
}
}
else if (IIRValue == 1) /* THRE, transmit holding register empty */
{
/* THRE interrupt */
if (UART2TXcount > 0)
{
U2THR = UART2TXBuffer[UART2TXhead++];
UART2TXhead %= UART2_TX_BUFSIZE;
UART2TXcount--;
}
else
{
U2IER = 1;
}
}
else
{
Dummy = U2RBR;
u1lsr = U2LSR;
u1lsr = u1lsr;
}
}
void Uart2_Init(CPU_INT32U baud_rate)
{
float div_fp; /* Baud rate divisor floating point precision */
CPU_INT16U div_int; /* Baud rate divisor floating point precision */
CPU_INT08U divlo;
CPU_INT08U divhi;
CPU_INT32U pclk_freq;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
pclk_freq = BSP_CPU_PclkFreq(PCLK_UART2); /* Get peripheral clock frequency */
div_fp = (pclk_freq / 16.0 / baud_rate); /* Compute divisor for desired baud rate */
div_int = (CPU_INT16U)(div_fp + 0.5); /* Round the number up */
divlo = div_int & 0x00FF; /* Split divisor into LOW and HIGH bytes */
divhi = (div_int >> 8) & 0x00FF;
PCONP_bit.PCUART2 = 1; /* Enable the power bit for UART0 */
U2IER = 0;
U2FCR = 0x06; // enable and reset fifo
U2ACR = 0;
//U1FCR = 0x01; // enable and reset fifo
U2LCR = 0x80; /* Enable acces to Divisor latches */
U2DLL = divlo; /* Load divisor */
U2DLM = divhi;
U2FDR = 0x10;
U2LCR = 0;
U2LCR_bit.WLS = 0x03; // 8 bit
U2LCR_bit.SBS = 0; // 1 stop bit
U2IER = 1;
PINSEL0_bit.P0_10 = 0x1;
PINSEL0_bit.P0_11 = 0x1;
PINMODE0_bit.P0_10 = 0;
PINMODE0_bit.P0_11 = 0;
FIO0DIR_bit.P0_10 = 1;
FIO0DIR_bit.P0_11 = 0;
FIO0MASK_bit.P0_10 = 1;
FIO0MASK_bit.P0_11 = 1;
VICINTSELECT &= ~(1 << VIC_UART2);
VICVECTADDR28 = (CPU_INT32U)Uart2_Isr;
VICINTENABLE = (1 << VIC_UART2);
Uart2_Flush();
OS_EXIT_CRITICAL();
}

View File

@ -0,0 +1,89 @@
#include <includes.h>
#include "crc16.h"
#if (CRC16_MODEL_TYPE==CRC16_SMALL)
/*
unsigned short CRC16_small(unsigned char *pBuf, unsigned char ucLength)
{
register unsigned char Lo, Hi, ucSym;
if (!ucLength) return 1;
Lo = 0xFF;
Hi = 0xFF;
do{
ucSym = *(pBuf++);
ucSym ^= Hi;
Hi = ( ucSym & 0x02 ) ? (Lo - 0x80) : Lo;
if ( ucSym & 0x01 )
Hi ^= 0xC0;
Lo = ucSym;
Lo >>= 1;
Lo ^= ucSym;
Lo >>= 1;
ucSym ^= Lo;
if ( ucSym & 0x08 ) --ucSym;
if ( ucSym & 0x40 ) --ucSym;
ucSym &= 0x01;
if (ucSym) Lo ^= 0xC0;
Hi ^= ucSym;
}while(--ucLength);
return (unsigned short)((((unsigned short)Hi)<<8) | Lo);
}
*/
#else //(CRC16_MODEL_TYPE==CRC16_LARGE)
unsigned short CRC16_large(unsigned char *pBuf, unsigned char ucLength)
{
unsigned char ucCRCHi = 0xFF; // high CRC byte initialized
unsigned char ucCRCLo = 0xFF; // low CRC byte initialized
unsigned char table_addr;
static const unsigned short CRC_Table[8*32]={
0x0000,0x8005,0x800F,0x000A,0x801B,0x001E,0x0014,0x8011,
0x8033,0x0036,0x003C,0x8039,0x0028,0x802D,0x8027,0x0022,
0x8063,0x0066,0x006C,0x8069,0x0078,0x807D,0x8077,0x0072,
0x0050,0x8055,0x805F,0x005A,0x804B,0x004E,0x0044,0x8041,
0x80C3,0x00C6,0x00CC,0x80C9,0x00D8,0x80DD,0x80D7,0x00D2,
0x00F0,0x80F5,0x80FF,0x00FA,0x80EB,0x00EE,0x00E4,0x80E1,
0x00A0,0x80A5,0x80AF,0x00AA,0x80BB,0x00BE,0x00B4,0x80B1,
0x8093,0x0096,0x009C,0x8099,0x0088,0x808D,0x8087,0x0082,
0x8183,0x0186,0x018C,0x8189,0x0198,0x819D,0x8197,0x0192,
0x01B0,0x81B5,0x81BF,0x01BA,0x81AB,0x01AE,0x01A4,0x81A1,
0x01E0,0x81E5,0x81EF,0x01EA,0x81FB,0x01FE,0x01F4,0x81F1,
0x81D3,0x01D6,0x01DC,0x81D9,0x01C8,0x81CD,0x81C7,0x01C2,
0x0140,0x8145,0x814F,0x014A,0x815B,0x015E,0x0154,0x8151,
0x8173,0x0176,0x017C,0x8179,0x0168,0x816D,0x8167,0x0162,
0x8123,0x0126,0x012C,0x8129,0x0138,0x813D,0x8137,0x0132,
0x0110,0x8115,0x811F,0x011A,0x810B,0x010E,0x0104,0x8101,
0x8303,0x0306,0x030C,0x8309,0x0318,0x831D,0x8317,0x0312,
0x0330,0x8335,0x833F,0x033A,0x832B,0x032E,0x0324,0x8321,
0x0360,0x8365,0x836F,0x036A,0x837B,0x037E,0x0374,0x8371,
0x8353,0x0356,0x035C,0x8359,0x0348,0x834D,0x8347,0x0342,
0x03C0,0x83C5,0x83CF,0x03CA,0x83DB,0x03DE,0x03D4,0x83D1,
0x83F3,0x03F6,0x03FC,0x83F9,0x03E8,0x83ED,0x83E7,0x03E2,
0x83A3,0x03A6,0x03AC,0x83A9,0x03B8,0x83BD,0x83B7,0x03B2,
0x0390,0x8395,0x839F,0x039A,0x838B,0x038E,0x0384,0x8381,
0x0280,0x8285,0x828F,0x028A,0x829B,0x029E,0x0294,0x8291,
0x82B3,0x02B6,0x02BC,0x82B9,0x02A8,0x82AD,0x82A7,0x02A2,
0x82E3,0x02E6,0x02EC,0x82E9,0x02F8,0x82FD,0x82F7,0x02F2,
0x02D0,0x82D5,0x82DF,0x02DA,0x82CB,0x02CE,0x02C4,0x82C1,
0x8243,0x0246,0x024C,0x8249,0x0258,0x825D,0x8257,0x0252,
0x0270,0x8275,0x827F,0x027A,0x826B,0x026E,0x0264,0x8261,
0x0220,0x8225,0x822F,0x022A,0x823B,0x023E,0x0234,0x8231,
0x8213,0x0216,0x021C,0x8219,0x0208,0x820D,0x8207,0x0202};
while(ucLength--){
table_addr=(*pBuf++ ^ ucCRCHi);
ucCRCHi=(CRC_Table[table_addr] >> 8) ^ ucCRCLo;
ucCRCLo=(CRC_Table[table_addr] & 0x00FF);
}
return (unsigned short)((((unsigned short)ucCRCHi)<<8) | (unsigned short)ucCRCLo);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,17 @@
#ifndef _MODE_H_
#define _MODE_H_
#include "cpu.h"
// îïðåäåëåíèÿ ðåæèìîâ
#define MODE_WORK 0
#define MODE_SERVICE 1
// ïîëó÷èòü òåêóùèé ðåæèì ðàáîòû
extern CPU_INT08U GetMode(void);
// ïðîâåðèòü, íå èçìåíèëñÿ ëè ðåæèì ðàáîòû
extern CPU_INT08U CheckMode(void);
// èíèöèàëèçàöèÿ
extern void InitMode(void);
#endif //#ifndef _MODE_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,460 @@
#include <includes.h>
#include <stddef.h>
#include "journal.h"
#include "fram.h"
#include "fram_map.h"
#include "time.h"
#include "fr.h"
#include "crc16.h"
#include "mode.h"
static CPU_INT32U GlobalErrorsFlags[8] = {0,0,0,0,0,0,0,0};
void SetErrorFlag(CPU_INT08U error)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
GlobalErrorsFlags[error/32] |= (1L << (error%32));
OS_EXIT_CRITICAL();
}
void ClrErrorFlag(CPU_INT08U error)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
GlobalErrorsFlags[error/32] &= ~(1L << (error%32));
OS_EXIT_CRITICAL();
}
int TstErrorFlag(CPU_INT08U error)
{
CPU_INT32U temp = 0;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
temp = GlobalErrorsFlags[error/32] & (1L << (error%32));
OS_EXIT_CRITICAL();
return temp;
}
int TstCriticalErrors(void)
{
CPU_INT32U errors = 0;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
CPU_INT32U ignore_fiscal = 0;
GetData(&DisableFiscalErrorsDesc, &ignore_fiscal, 0, DATA_FLAG_SYSTEM_INDEX);
OS_ENTER_CRITICAL();
if (!ignore_fiscal)
{
errors |= TstCriticalFiscalError();
errors |= TstErrorFlag(ERROR_FR_CONN);
/*
if (!FReportTest())
{ // ÔÐ íåäîñòóïåí äëÿ ëþáîé ïå÷àòè
errors |= 0x1;
}
*/
}
errors |= TstErrorFlag(ERROR_VALIDATOR_CONN);
OS_EXIT_CRITICAL();
if (errors) return 1;
return 0;
}
int TstCriticalValidatorErrors(void)
{
return 0;
}
void ClrValidatorErrors(void)
{
for (CPU_INT08U i=ERROR_VALIDATOR_FAILURE; i<ERROR_MODEM_CONN; ++i)
{
ClrErrorFlag(i);
}
}
// çàïèñü â æóðíàë çàïèñè îá îøèáêå
void SaveErrorRecord(CPU_INT32U error)
{
TErrorRecord record;
// íàéòè ñàìóþ ñòàðóþ ïî âðåìåíè çàïèñü è äîáàâèòü íîâóþ ïîñëå íå¸
CPU_INT32U i, ind=0, indm = 0, maxtime = 0;
for (i=0; i<ERROR_RECORDS_NUM; i++)
{
ReadArrayFram(offsetof(TFramMap, ErrorRecords[0])+i*sizeof(TErrorRecord), sizeof(TErrorRecord), (unsigned char*)&record);
if ((record.time == 0) || (record.time == 0xffffffff)) {ind = i; break;}
if (record.time >= maxtime) {maxtime = record.time; indm = i;}
}
if (i >= ERROR_RECORDS_NUM)
{ // âñå çàïèñè çàïîëåíû - çàïèñûâàåì íà ìåñòî ñàìîé ñòàðîé
ind = (indm+1)%ERROR_RECORDS_NUM;
}
record.time = GetTimeSec();
record.error = error;
WriteArrayFram(offsetof(TFramMap, ErrorRecords[0])+ind*sizeof(TErrorRecord), sizeof(TErrorRecord), (unsigned char*)&record);
}
// ïîëó÷èòü çàïèñü èç æóðíàëà îøèáîê
int GetErrorRecord(TErrorRecord* record, CPU_INT32U index)
{
if (index >= ERROR_RECORDS_NUM) return -1;
ReadArrayFram(offsetof(TFramMap, ErrorRecords[0])+index*sizeof(TErrorRecord), sizeof(TErrorRecord), (unsigned char*)record);
return 0;
}
// ïîëó÷èòü çàïèñü èç æóðíàëà ñîáûòèé
int GetEventRecord(TEventRecord* record, CPU_INT32U index)
{
if (index >= EVENT_RECORDS_NUM) return -1;
ReadArrayFram(offsetof(TFramMap, EventRecords[0])+index*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)record);
return 0;
}
// çàïèñü â æóðíàë çàïèñè î ñîáûòèè
void SaveEventRecord(CPU_INT08U channel, CPU_INT08U event, CPU_INT32U data)
{
TEventRecord record;
// íàéòè ñàìóþ ñòàðóþ ïî âðåìåíè çàïèñü è äîáàâèòü íîâóþ ïîñëå íå¸
CPU_INT32U i, ind=0, indm = 0, maxtime = 0;
for (i=0; i<EVENT_RECORDS_NUM; i++)
{
ReadArrayFram(offsetof(TFramMap, EventRecords[0])+i*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)&record);
if ((record.time == 0) || (record.time == 0xffffffff)) {ind = i; break;}
if (record.time >= maxtime) {maxtime = record.time; indm = i;}
}
if (i >= ERROR_RECORDS_NUM)
{ // âñå çàïèñè çàïîëåíû - çàïèñûâàåì íà ìåñòî ñàìîé ñòàðîé
ind = (indm+1)%ERROR_RECORDS_NUM;
}
record.time = GetTimeSec();
record.channel = channel;
record.event = event;
record.data = data;
WriteArrayFram(offsetof(TFramMap, EventRecords[0])+ind*sizeof(TEventRecord), sizeof(TEventRecord), (unsigned char*)&record);
}
void ClearErrorJournal(void)
{
SetArrayFram(offsetof(TFramMap, ErrorRecords), sizeof(TErrorRecord)*ERROR_RECORDS_NUM, 0x00);
}
void ClearEventJournal(void)
{
SetArrayFram(offsetof(TFramMap, EventRecords), sizeof(TEventRecord)*EVENT_RECORDS_NUM, 0x00);
}
void GetEventStr(char* str, char event)
{
switch (event){
case JOURNAL_EVENT_MONEY_NOTE:
sprintf(str, "Âí.êóïþðà ");
break;
case JOURNAL_EVENT_MONEY_COIN:
sprintf(str, "Âí.ìîíåòû ");
break;
case JOURNAL_EVENT_START_SESSION:
sprintf(str, "Íà÷.ñåàíñà ");
break;
case JOURNAL_EVENT_END_SESSION:
sprintf(str, "Êîí.ñåàíñà ");
break;
case JOURNAL_EVENT_DEVICE_ON:
sprintf(str, "Âêëþ÷åíèå");
break;
case JOURNAL_EVENT_PRINT_BILL:
sprintf(str, "Ïå÷àòü ÷åêà");
break;
case JOURNAL_EVENT_PRINT_Z:
sprintf(str, "Ïå÷àòü Z-îò÷åòà");
break;
case JOURNAL_EVENT_PRINT_X:
sprintf(str, "Ïå÷àòü X-îò÷åòà");
break;
case JOURNAL_EVENT_PRINT_BUF:
sprintf(str, "Ïå÷àòü îò÷.èç áóô.");
break;
case JOURNAL_EVENT_CHANGE_MODE:
sprintf(str, "Ñìåíà ðåæèìà");
break;
case JOURNAL_EVENT_INCASSATION:
sprintf(str, "Èíêàññàöèÿ");
break;
case JOURNAL_EVENT_PASS_FAIL:
sprintf(str, "Íåâåðíûé ïàðîëü");
break;
case JOURNAL_EVENT_EMAIL_FAIL:
sprintf(str, "Îøèáêà îòïð.e-mail");
break;
case JOURNAL_EVENT_EMAIL_OK:
sprintf(str, "E-mail îòïð.óñïåøíî");
break;
default:
sprintf(str, "íåò");
break;
}
}
void GetEventStrEng(char* str, char event)
{
switch (event){
case JOURNAL_EVENT_MONEY_NOTE:
sprintf(str, " | Vnesena kupura ");
break;
case JOURNAL_EVENT_MONEY_COIN:
sprintf(str, " | Vneseny monety ");
break;
case JOURNAL_EVENT_START_SESSION:
sprintf(str, " | Nachalo seansa ");
break;
case JOURNAL_EVENT_END_SESSION:
sprintf(str, " | Koneñ seansa ");
break;
case JOURNAL_EVENT_DEVICE_ON:
sprintf(str, " | Vkluchenie ");
break;
case JOURNAL_EVENT_PRINT_BILL:
sprintf(str, " | Pechat' checka ");
break;
case JOURNAL_EVENT_PRINT_Z:
sprintf(str, " | Pechat' Z-otcheta ");
break;
case JOURNAL_EVENT_PRINT_X:
sprintf(str, " | Pechat' X-otcheta ");
break;
case JOURNAL_EVENT_PRINT_BUF:
sprintf(str, " | Pechat' otcheta iz bufera ");
break;
case JOURNAL_EVENT_CHANGE_MODE:
sprintf(str, " | Smena rejima ");
break;
case JOURNAL_EVENT_INCASSATION:
sprintf(str, " | Incassaciya ");
break;
case JOURNAL_EVENT_PASS_FAIL:
sprintf(str, " | Neverniy parol' ");
break;
case JOURNAL_EVENT_EMAIL_FAIL:
sprintf(str, " | Oshibka otpravki e-mail ");
break;
case JOURNAL_EVENT_EMAIL_OK:
sprintf(str, " | E-mail otpravleno uspeshno ");
break;
default:
sprintf(str, " | Net sobytiya ");
break;
}
}
void PrintEventJournalRecordEng(char* str, TEventRecord *record)
{
if (record->event)
{
TRTC_Data rtc_data;
// íàïå÷àòàåì âðåìÿ
Sec2Date(&rtc_data, record->time);
sprintf(str, "| ");
PrintRTCDateTimeString(&str[strlen(str)], &rtc_data);
// íàïå÷àòàåì ñîáûòèå
GetEventStrEng(&str[strlen(str)], record->event);
// íàïå÷àòàåì äîïîëíèòåëüíûå ïîëÿ
if ((record->event == JOURNAL_EVENT_MONEY_NOTE) || (record->event == JOURNAL_EVENT_MONEY_COIN))
{
sprintf(&str[strlen(str)], "kanal %d ", record->channel+1);
sprintf(&str[strlen(str)], "%d rub.", record->data);
}
else if (record->event == JOURNAL_EVENT_START_SESSION)
{
sprintf(&str[strlen(str)], "kanal %d ", record->channel+1);
PrintSecToHourMinSec(&str[strlen(str)], record->data);
}
else if (record->event == JOURNAL_EVENT_END_SESSION)
{
sprintf(&str[strlen(str)], "kanal %d ", record->channel+1);
sprintf(&str[strlen(str)], "");
}
else if (record->event == JOURNAL_EVENT_DEVICE_ON)
{
sprintf(&str[strlen(str)], "");
}
else if (record->event == JOURNAL_EVENT_PRINT_BILL)
{
sprintf(&str[strlen(str)], "kanal %d ", record->channel+1);
}
else if (record->event == JOURNAL_EVENT_PRINT_Z)
{
sprintf(&str[strlen(str)], "");
}
else if (record->event == JOURNAL_EVENT_PRINT_X)
{
sprintf(&str[strlen(str)], "");
}
else if (record->event == JOURNAL_EVENT_PRINT_BUF)
{
sprintf(&str[strlen(str)], "");
}
else if (record->event == JOURNAL_EVENT_CHANGE_MODE)
{
if (record->data == MODE_WORK) sprintf(&str[strlen(str)], "rabota");
else sprintf(&str[strlen(str)], "nastroika");
}
else if (record->event == JOURNAL_EVENT_INCASSATION)
{
sprintf(&str[strlen(str)], "%u rub.", record->data);
}
else if (record->event == JOURNAL_EVENT_PASS_FAIL)
{
sprintf(&str[strlen(str)], "%u", record->data);
}
else if ((record->event == JOURNAL_EVENT_EMAIL_OK) || (record->event == JOURNAL_EVENT_EMAIL_FAIL))
{
sprintf(&str[strlen(str)], "");
}
sprintf(&str[strlen(str)], "\r\n");
}
else
{ // ïóñòàÿ çàïèñü
sprintf(str, "net zapisi\r\n");
}
}
void IncCounter(CPU_INT08U ch, CPU_INT32U time, CPU_INT32U money)
{
CPU_INT32U r, t, m;
TCountersLong long_ctrs;
// óâåëè÷èì êàíàëüíûå ñ÷åò÷èêè
ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelRun)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&r);
ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelTime)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&t);
ReadArrayFram(offsetof(TFramMap, Counters.CounterChannelMoney)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m);
r++;
t+=time;
m+=money;
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);
WriteArrayFram(offsetof(TFramMap, Counters.CounterChannelMoney)+sizeof(CPU_INT32U)*ch, sizeof(CPU_INT32U), (unsigned char*)&m);
// óâåëè÷èì îáùèå ñ÷åò÷èêè
ReadArrayFram(offsetof(TFramMap, Counters.CounterRun), sizeof(CPU_INT32U), (unsigned char*)&r);
ReadArrayFram(offsetof(TFramMap, Counters.CounterTime), sizeof(CPU_INT32U), (unsigned char*)&t);
ReadArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&m);
r++;
t+=time;
m+=money;
WriteArrayFram(offsetof(TFramMap, Counters.CounterRun), sizeof(CPU_INT32U), (unsigned char*)&r);
WriteArrayFram(offsetof(TFramMap, Counters.CounterTime), sizeof(CPU_INT32U), (unsigned char*)&t);
WriteArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&m);
// óâåëè÷èì äëèííûå ñ÷åò÷èêè
ReadArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs);
long_ctrs.CounterChannelRunLong[ch]++;
long_ctrs.CounterChannelTimeLong[ch] += time;
long_ctrs.CounterChannelMoneyLong[ch] += money;
long_ctrs.CounterRunLong++;
long_ctrs.CounterTimeLong += time;
long_ctrs.CounterMoneyLong += money;
long_ctrs.crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc));
WriteArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs);
}
CPU_INT32U GetShortMoney()
{
CPU_INT32U money;
ReadArrayFram(offsetof(TFramMap, Counters.CounterMoney), sizeof(CPU_INT32U), (unsigned char*)&money);
return money;
}
void CheckLongCounters(void)
{
TCountersLong long_ctrs;
CPU_INT16U crc;
ReadArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs);
crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc));
if (crc != long_ctrs.crc)
{
memset(&long_ctrs, 0, sizeof(TCountersLong));
long_ctrs.crc = CRC16((unsigned char*)&long_ctrs, offsetof(TCountersLong, crc));
WriteArrayFram(offsetof(TFramMap, CountersLong), sizeof(TCountersLong), (unsigned char*)&long_ctrs);
/// îáû÷íûå ñ÷åò÷èêè òîæå î÷èñòèì
ClearCounters();
ClearBillnomCounter();
}
}
void ClearCounters(void)
{
SetArrayFram(offsetof(TFramMap, Counters), sizeof(CPU_INT32U)*(CHANNELS_NUM+1)*3, 0x00);
}
/// èíêðåìåíò ñ÷åò÷èêà êóïþð ïî íîìèíàëàì
void IncBillnomCounter(CPU_INT32U index)
{
CPU_INT32U counter;
if (index >= 24) return;
ReadArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*index, sizeof(CPU_INT32U), (unsigned char*)&counter);
counter++;
WriteArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*index, sizeof(CPU_INT32U), (unsigned char*)&counter);
ReadArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter);
counter++;
WriteArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter);
}
/// î÷èñòêà ñ÷åò÷èêîâ êóïþð
void ClearBillnomCounter(void)
{
CPU_INT32U counter = 0;
CPU_INT32U i;
for (i = 0; i < 24; i++)
{
WriteArrayFram(offsetof(TFramMap, Counters.CounterBillNominals)+sizeof(CPU_INT32U)*i, sizeof(CPU_INT32U), (unsigned char*)&counter);
}
WriteArrayFram(offsetof(TFramMap, Counters.BillsCount), sizeof(CPU_INT32U), (unsigned char*)&counter);
}
// ñåðâåð îøèáîê (çàíåñåíèå îøèáîê â æóðíàë)
void ErrorServer(void)
{
static CPU_INT32U PrevFlags[8] = {0,0,0,0,0,0,0,0};
for (int i=0; i<ERRORS_NUM; i++)
{
if (!(PrevFlags[i/32] & (1L<<(i%32)))
&& (TstErrorFlag(i)))
{
// çàïèøåì â æóðíàë
SaveErrorRecord(i);
}
}
memcpy(PrevFlags, GlobalErrorsFlags, sizeof(CPU_INT32U)*8);
}

View File

@ -0,0 +1,434 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
* MEMORY MANAGEMENT
*
* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* File : OS_MEM.C
* By : Jean J. Labrosse
* Version : V2.85
*
* LICENSING TERMS:
* ---------------
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
* licensing fee.
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE
#include <ucos_ii.h>
#endif
#if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
/*
*********************************************************************************************************
* CREATE A MEMORY PARTITION
*
* Description : Create a fixed-sized memory partition that will be managed by uC/OS-II.
*
* Arguments : addr is the starting address of the memory partition
*
* nblks is the number of memory blocks to create from the partition.
*
* blksize is the size (in bytes) of each block in the memory partition.
*
* perr is a pointer to a variable containing an error message which will be set by
* this function to either:
*
* OS_ERR_NONE if the memory partition has been created correctly.
* OS_ERR_MEM_INVALID_ADDR if you are specifying an invalid address for the memory
* storage of the partition or, the block does not align
* on a pointer boundary
* OS_ERR_MEM_INVALID_PART no free partitions available
* OS_ERR_MEM_INVALID_BLKS user specified an invalid number of blocks (must be >= 2)
* OS_ERR_MEM_INVALID_SIZE user specified an invalid block size
* - must be greater than the size of a pointer
* - must be able to hold an integral number of pointers
* Returns : != (OS_MEM *)0 is the partition was created
* == (OS_MEM *)0 if the partition was not created because of invalid arguments or, no
* free partition is available.
*********************************************************************************************************
*/
OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *perr)
{
OS_MEM *pmem;
INT8U *pblk;
void **plink;
INT32U i;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return ((OS_MEM *)0);
}
if (addr == (void *)0) { /* Must pass a valid address for the memory part.*/
*perr = OS_ERR_MEM_INVALID_ADDR;
return ((OS_MEM *)0);
}
if (((INT32U)addr & (sizeof(void *) - 1)) != 0){ /* Must be pointer size aligned */
*perr = OS_ERR_MEM_INVALID_ADDR;
return ((OS_MEM *)0);
}
if (nblks < 2) { /* Must have at least 2 blocks per partition */
*perr = OS_ERR_MEM_INVALID_BLKS;
return ((OS_MEM *)0);
}
if (blksize < sizeof(void *)) { /* Must contain space for at least a pointer */
*perr = OS_ERR_MEM_INVALID_SIZE;
return ((OS_MEM *)0);
}
#endif
OS_ENTER_CRITICAL();
pmem = OSMemFreeList; /* Get next free memory partition */
if (OSMemFreeList != (OS_MEM *)0) { /* See if pool of free partitions was empty */
OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
}
OS_EXIT_CRITICAL();
if (pmem == (OS_MEM *)0) { /* See if we have a memory partition */
*perr = OS_ERR_MEM_INVALID_PART;
return ((OS_MEM *)0);
}
plink = (void **)addr; /* Create linked list of free memory blocks */
pblk = (INT8U *)((INT32U)addr + blksize);
for (i = 0; i < (nblks - 1); i++) {
*plink = (void *)pblk; /* Save pointer to NEXT block in CURRENT block */
plink = (void **)pblk; /* Position to NEXT block */
pblk = (INT8U *)((INT32U)pblk + blksize); /* Point to the FOLLOWING block */
}
*plink = (void *)0; /* Last memory block points to NULL */
pmem->OSMemAddr = addr; /* Store start address of memory partition */
pmem->OSMemFreeList = addr; /* Initialize pointer to pool of free blocks */
pmem->OSMemNFree = nblks; /* Store number of free blocks in MCB */
pmem->OSMemNBlks = nblks;
pmem->OSMemBlkSize = blksize; /* Store block size of each memory blocks */
*perr = OS_ERR_NONE;
return (pmem);
}
/*$PAGE*/
/*
*********************************************************************************************************
* GET A MEMORY BLOCK
*
* Description : Get a memory block from a partition
*
* Arguments : pmem is a pointer to the memory partition control block
*
* perr is a pointer to a variable containing an error message which will be set by this
* function to either:
*
* OS_ERR_NONE if the memory partition has been created correctly.
* OS_ERR_MEM_NO_FREE_BLKS if there are no more free memory blocks to allocate to caller
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
*
* Returns : A pointer to a memory block if no error is detected
* A pointer to NULL if an error is detected
*********************************************************************************************************
*/
void *OSMemGet (OS_MEM *pmem, INT8U *perr)
{
void *pblk;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return ((void *)0);
}
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
*perr = OS_ERR_MEM_INVALID_PMEM;
return ((void *)0);
}
#endif
OS_ENTER_CRITICAL();
if (pmem->OSMemNFree > 0) { /* See if there are any free memory blocks */
pblk = pmem->OSMemFreeList; /* Yes, point to next free memory block */
pmem->OSMemFreeList = *(void **)pblk; /* Adjust pointer to new free list */
pmem->OSMemNFree--; /* One less memory block in this partition */
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE; /* No error */
return (pblk); /* Return memory block to caller */
}
OS_EXIT_CRITICAL();
*perr = OS_ERR_MEM_NO_FREE_BLKS; /* No, Notify caller of empty memory partition */
return ((void *)0); /* Return NULL pointer to caller */
}
/*$PAGE*/
/*
*********************************************************************************************************
* GET THE NAME OF A MEMORY PARTITION
*
* Description: This function is used to obtain the name assigned to a memory partition.
*
* Arguments : pmem is a pointer to the memory partition
*
* pname is a pointer to an ASCII string that will receive the name of the memory partition.
*
* perr is a pointer to an error code that can contain one of the following values:
*
* OS_ERR_NONE if the name was copied to 'pname'
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
* OS_ERR_NAME_GET_ISR You called this function from an ISR
*
* Returns : The length of the string or 0 if 'pmem' is a NULL pointer.
*********************************************************************************************************
*/
#if OS_MEM_NAME_SIZE > 1
INT8U OSMemNameGet (OS_MEM *pmem, INT8U *pname, INT8U *perr)
{
INT8U len;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (0);
}
if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */
*perr = OS_ERR_MEM_INVALID_PMEM;
return (0);
}
if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
*perr = OS_ERR_PNAME_NULL;
return (0);
}
#endif
if (OSIntNesting > 0) { /* See if trying to call from an ISR */
*perr = OS_ERR_NAME_GET_ISR;
return (0);
}
OS_ENTER_CRITICAL();
len = OS_StrCopy(pname, pmem->OSMemName); /* Copy name from OS_MEM */
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (len);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* ASSIGN A NAME TO A MEMORY PARTITION
*
* Description: This function assigns a name to a memory partition.
*
* Arguments : pmem is a pointer to the memory partition
*
* pname is a pointer to an ASCII string that contains the name of the memory partition.
*
* perr is a pointer to an error code that can contain one of the following values:
*
* OS_ERR_NONE if the name was copied to 'pname'
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
* OS_ERR_PNAME_NULL You passed a NULL pointer for 'pname'
* OS_ERR_MEM_NAME_TOO_LONG if the name doesn't fit in the storage area
* OS_ERR_NAME_SET_ISR if you called this function from an ISR
*
* Returns : None
*********************************************************************************************************
*/
#if OS_MEM_NAME_SIZE > 1
void OSMemNameSet (OS_MEM *pmem, INT8U *pname, INT8U *perr)
{
INT8U len;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return;
}
if (pmem == (OS_MEM *)0) { /* Is 'pmem' a NULL pointer? */
*perr = OS_ERR_MEM_INVALID_PMEM;
return;
}
if (pname == (INT8U *)0) { /* Is 'pname' a NULL pointer? */
*perr = OS_ERR_PNAME_NULL;
return;
}
#endif
if (OSIntNesting > 0) { /* See if trying to call from an ISR */
*perr = OS_ERR_NAME_SET_ISR;
return;
}
OS_ENTER_CRITICAL();
len = OS_StrLen(pname); /* Can we fit the string in the storage area? */
if (len > (OS_MEM_NAME_SIZE - 1)) { /* No */
OS_EXIT_CRITICAL();
*perr = OS_ERR_MEM_NAME_TOO_LONG;
return;
}
(void)OS_StrCopy(pmem->OSMemName, pname); /* Yes, copy name to the memory partition header */
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* RELEASE A MEMORY BLOCK
*
* Description : Returns a memory block to a partition
*
* Arguments : pmem is a pointer to the memory partition control block
*
* pblk is a pointer to the memory block being released.
*
* Returns : OS_ERR_NONE if the memory block was inserted into the partition
* OS_ERR_MEM_FULL if you are returning a memory block to an already FULL memory
* partition (You freed more blocks than you allocated!)
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
* OS_ERR_MEM_INVALID_PBLK if you passed a NULL pointer for the block to release.
*********************************************************************************************************
*/
INT8U OSMemPut (OS_MEM *pmem, void *pblk)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
return (OS_ERR_MEM_INVALID_PMEM);
}
if (pblk == (void *)0) { /* Must release a valid block */
return (OS_ERR_MEM_INVALID_PBLK);
}
#endif
OS_ENTER_CRITICAL();
if (pmem->OSMemNFree >= pmem->OSMemNBlks) { /* Make sure all blocks not already returned */
OS_EXIT_CRITICAL();
return (OS_ERR_MEM_FULL);
}
*(void **)pblk = pmem->OSMemFreeList; /* Insert released block into free block list */
pmem->OSMemFreeList = pblk;
pmem->OSMemNFree++; /* One more memory block in this partition */
OS_EXIT_CRITICAL();
return (OS_ERR_NONE); /* Notify caller that memory block was released */
}
/*$PAGE*/
/*
*********************************************************************************************************
* QUERY MEMORY PARTITION
*
* Description : This function is used to determine the number of free memory blocks and the number of
* used memory blocks from a memory partition.
*
* Arguments : pmem is a pointer to the memory partition control block
*
* p_mem_data is a pointer to a structure that will contain information about the memory
* partition.
*
* Returns : OS_ERR_NONE if no errors were found.
* OS_ERR_MEM_INVALID_PMEM if you passed a NULL pointer for 'pmem'
* OS_ERR_MEM_INVALID_PDATA if you passed a NULL pointer to the data recipient.
*********************************************************************************************************
*/
#if OS_MEM_QUERY_EN > 0
INT8U OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *p_mem_data)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pmem == (OS_MEM *)0) { /* Must point to a valid memory partition */
return (OS_ERR_MEM_INVALID_PMEM);
}
if (p_mem_data == (OS_MEM_DATA *)0) { /* Must release a valid storage area for the data */
return (OS_ERR_MEM_INVALID_PDATA);
}
#endif
OS_ENTER_CRITICAL();
p_mem_data->OSAddr = pmem->OSMemAddr;
p_mem_data->OSFreeList = pmem->OSMemFreeList;
p_mem_data->OSBlkSize = pmem->OSMemBlkSize;
p_mem_data->OSNBlks = pmem->OSMemNBlks;
p_mem_data->OSNFree = pmem->OSMemNFree;
OS_EXIT_CRITICAL();
p_mem_data->OSNUsed = p_mem_data->OSNBlks - p_mem_data->OSNFree;
return (OS_ERR_NONE);
}
#endif /* OS_MEM_QUERY_EN */
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE MEMORY PARTITION MANAGER
*
* Description : This function is called by uC/OS-II to initialize the memory partition manager. Your
* application MUST NOT call this function.
*
* Arguments : none
*
* Returns : none
*
* Note(s) : This function is INTERNAL to uC/OS-II and your application should not call it.
*********************************************************************************************************
*/
void OS_MemInit (void)
{
#if OS_MAX_MEM_PART == 1
OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */
OSMemFreeList = (OS_MEM *)&OSMemTbl[0]; /* Point to beginning of free list */
#if OS_MEM_NAME_SIZE > 1
OSMemFreeList->OSMemName[0] = '?'; /* Unknown name */
OSMemFreeList->OSMemName[1] = OS_ASCII_NUL;
#endif
#endif
#if OS_MAX_MEM_PART >= 2
OS_MEM *pmem;
INT16U i;
OS_MemClr((INT8U *)&OSMemTbl[0], sizeof(OSMemTbl)); /* Clear the memory partition table */
pmem = &OSMemTbl[0]; /* Point to memory control block (MCB) */
for (i = 0; i < (OS_MAX_MEM_PART - 1); i++) { /* Init. list of free memory partitions */
pmem->OSMemFreeList = (void *)&OSMemTbl[i+1]; /* Chain list of free partitions */
#if OS_MEM_NAME_SIZE > 1
pmem->OSMemName[0] = '?'; /* Unknown name */
pmem->OSMemName[1] = OS_ASCII_NUL;
#endif
pmem++;
}
pmem->OSMemFreeList = (void *)0; /* Initialize last node */
#if OS_MEM_NAME_SIZE > 1
pmem->OSMemName[0] = '?'; /* Unknown name */
pmem->OSMemName[1] = OS_ASCII_NUL;
#endif
OSMemFreeList = &OSMemTbl[0]; /* Point to beginning of free list */
#endif
}
#endif /* OS_MEM_EN */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,160 @@
#include "iolpc2368.h"
#include "ucos_ii.h"
#include "cpu.h"
#include "app_serv.h"
#include "coin.h"
#include "data.h"
#include "datadesc.h"
#include "modem.h"
OS_STK CoinTaskStk[COIN_TASK_STK_SIZE];
void InitImpInput(void);
CPU_INT32U CoinImpCounter;
void CoinTask(void *p_arg)
{
while(1)
{
CPU_INT32U enable_coin;
OSTimeDly(100);
GetData(&EnableCoinDesc, &enable_coin, 0, DATA_FLAG_SYSTEM_INDEX);
if (enable_coin)
{
if (GetCoinCount())
{
PostUserEvent(EVENT_COIN_INSERTED);
}
}
else
{
CoinDisable();
GetResetCoinCount();
}
}
}
void CoinDisable(void)
{
}
void CoinEnable(void)
{
}
// ïîëó÷èòü ÷èñëî ìîíåò
CPU_INT32U GetCoinCount(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
CPU_INT32U ctr = CoinImpCounter;
OS_EXIT_CRITICAL();
return ctr;
}
// ïîëó÷èòü ÷èñëî ìîíåò è ñáðîñèòü ñ÷åò÷èê
CPU_INT32U GetResetCoinCount(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
CPU_INT32U ctr = CoinImpCounter;
CoinImpCounter = 0;
OS_EXIT_CRITICAL();
return ctr;
}
// èíèöèàëèçàöèÿ ìîíåòîïðèåìíèêà
void InitCoin(void)
{
CoinImpCounter = 0;
InitImpInput();
OSTaskCreate(CoinTask, (void *)0, (OS_STK *)&CoinTaskStk[COIN_TASK_STK_SIZE-1], COIN_TASK_PRIO);
}
void InputCapture_ISR(void)
{
CPU_INT08U ir = T3IR;
static CPU_INT32U period = 0;
T3IR = 0xFF;
if (ir & 0x10)
{// CR0 interrupt
if (FIO0PIN_bit.P0_23)
{// ïðèøåë çàäíèé ôðîíò
CPU_INT32U cr=T3CR0;
if (((cr-period) > COIN_IMP_MIN_LEN)
&& ((cr-period) < COIN_IMP_MAX_LEN))
CoinImpCounter++;
}
else
{// ïðèøåë ïåðåäíèé ôðîíò
period = T3CR0;
}
}
}
extern CPU_INT32U BSP_CPU_PclkFreq (CPU_INT08U pclk);
/*
P0.23 MK_P9 IMPULSE OUTPUT (èìïóëüñíûé âûõîä ìîíåòîïðèåìíèêà)
P0.24 MK_P8 INHIBIT (áëîêèðîâêà)
*/
// èíèöèàëèçàöèÿ èìïóëüñíîãî âõîäà
// èñïîëüçóåòñÿ CAP3.0
void InitImpInput (void)
{
#define INPUT_CAPTURE_FREQ 100000 // ÷àñòîòà òàêòèðîâàíèÿ ÷àñòîòíûõ âõîäîâ
CPU_INT32U pclk_freq;
CPU_INT32U rld_cnts;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
PCONP_bit.PCTIM3 = 1;
PCLKSEL1_bit.PCLK_TIMER3 = 2;
PINSEL1_bit.P0_23 = 0x3;
PINMODE1_bit.P0_23 = 0;
FIO0DIR_bit.P0_23 = 0;
FIO0MASK_bit.P0_23 = 0;
pclk_freq = BSP_CPU_PclkFreq(23);
rld_cnts = pclk_freq / INPUT_CAPTURE_FREQ;
T3CTCR_bit.CTM = 0;
T3CTCR_bit.CIS = 0; // select CAP3.0 input
T3PR = rld_cnts-1;
T3MCR = 0;
T3CCR = 0x07;
T3EMR = 0;
T3TCR = 0x03;
T3TCR = 0x01;
VICINTSELECT &= ~(1 << VIC_TIMER3);
VICVECTADDR27 = (CPU_INT32U)InputCapture_ISR;
VICVECTPRIORITY27 = 10;
VICINTENABLE = (1 << VIC_TIMER3);
T3IR = 0xFF;
OS_EXIT_CRITICAL();
}

View File

@ -0,0 +1,187 @@
#include <includes.h>
#include "control.h"
#include "data.h"
#include "datadesc.h"
#include <stdlib.h>
#include <string.h>
/*
P2.2 MK_P73 Êàíàë 1
P0.9 MK_P76 Êàíàë 2
P0.8 MK_P77 Êàíàë 3
P0.7 MK_P78 Êàíàë 4
P0.6 MK_P79 Êàíàë 5
P0.5 MK_P80 Êàíàë 6
P0.4 MK_P81 Êàíàë 7
P4.28 MK_P82 Êàíàë 8
P1.27 MK_P43 Êàíàë 9
P1.28 MK_P44 Êàíàë 10
*/
CPU_INT16U ChannelStatus; // ïîáèòíî òåêóùèå ñòàòóñû êàíàëîâ
// âêëş÷èòü êàíàë
void ChannelOn(CPU_INT08U ch)
{
ChannelStatus |= (1L << ch);
switch (ch)
{
case 0:
FIO2SET_bit.P2_2 = 1;
break;
case 1:
FIO0SET_bit.P0_9 = 1;
break;
case 2:
FIO0SET_bit.P0_8 = 1;
break;
case 3:
FIO0SET_bit.P0_7 = 1;
break;
case 4:
FIO0SET_bit.P0_6 = 1;
break;
case 5:
FIO0SET_bit.P0_5 = 1;
break;
case 6:
FIO0SET_bit.P0_4 = 1;
break;
case 7:
FIO4SET_bit.P4_28 = 1;
break;
case 8:
FIO1SET_bit.P1_27 = 1;
break;
case 9:
FIO1SET_bit.P1_28 = 1;
break;
}
}
// âûêëş÷èòü êàíàë
void ChannelOff(CPU_INT08U ch)
{
ChannelStatus &= ~(1L << ch);
switch (ch)
{
case 0:
FIO2CLR_bit.P2_2 = 1;
break;
case 1:
FIO0CLR_bit.P0_9 = 1;
break;
case 2:
FIO0CLR_bit.P0_8 = 1;
break;
case 3:
FIO0CLR_bit.P0_7 = 1;
break;
case 4:
FIO0CLR_bit.P0_6 = 1;
break;
case 5:
FIO0CLR_bit.P0_5 = 1;
break;
case 6:
FIO0CLR_bit.P0_4 = 1;
break;
case 7:
FIO4CLR_bit.P4_28 = 1;
break;
case 8:
FIO1CLR_bit.P1_27 = 1;
break;
case 9:
FIO1CLR_bit.P1_28 = 1;
break;
}
}
// èíèöèàëèçàöèÿ êàíàëîâ ïğè ñòàğòå ñèñòåìû
void InitChannels(void)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
// êàíàë 1
PINSEL4_bit.P2_2 = 0x0;
PINMODE4_bit.P2_2 = 0;
FIO2DIR_bit.P2_2 = 1;
FIO2MASK_bit.P2_2 = 0;
FIO2CLR_bit.P2_2 = 1;
// êàíàë 2
PINSEL0_bit.P0_9 = 0x0;
PINMODE0_bit.P0_9 = 0;
FIO0DIR_bit.P0_9 = 1;
FIO0MASK_bit.P0_9 = 0;
FIO0CLR_bit.P0_9 = 1;
// êàíàë 3
PINSEL0_bit.P0_8 = 0x0;
PINMODE0_bit.P0_8 = 0;
FIO0DIR_bit.P0_8 = 1;
FIO0MASK_bit.P0_8 = 0;
FIO0CLR_bit.P0_8 = 1;
// êàíàë 4
PINSEL0_bit.P0_7 = 0x0;
PINMODE0_bit.P0_7 = 0;
FIO0DIR_bit.P0_7 = 1;
FIO0MASK_bit.P0_7 = 0;
FIO0CLR_bit.P0_7 = 1;
// êàíàë 5
PINSEL0_bit.P0_6 = 0x0;
PINMODE0_bit.P0_6 = 0;
FIO0DIR_bit.P0_6 = 1;
FIO0MASK_bit.P0_6 = 0;
FIO0CLR_bit.P0_6 = 1;
// êàíàë 6
PINSEL0_bit.P0_5 = 0x0;
PINMODE0_bit.P0_5 = 0;
FIO0DIR_bit.P0_5 = 1;
FIO0MASK_bit.P0_5 = 0;
FIO0CLR_bit.P0_5 = 1;
// êàíàë 7
PINSEL0_bit.P0_4 = 0x0;
PINMODE0_bit.P0_4 = 0;
FIO0DIR_bit.P0_4 = 1;
FIO0MASK_bit.P0_4 = 0;
FIO0CLR_bit.P0_4 = 1;
// êàíàë 8
PINSEL9_bit.P4_28 = 0x0;
PINMODE9_bit.P4_28 = 0;
FIO4DIR_bit.P4_28 = 1;
FIO4MASK_bit.P4_28 = 0;
FIO4CLR_bit.P4_28 = 1;
// êàíàë 9
PINSEL3_bit.P1_27 = 0x0;
PINMODE3_bit.P1_27 = 0;
FIO1DIR_bit.P1_27 = 1;
FIO1MASK_bit.P1_27 = 0;
FIO1CLR_bit.P1_27 = 1;
// êàíàë 10
PINSEL3_bit.P1_28= 0x0;
PINMODE3_bit.P1_28 = 0;
FIO1DIR_bit.P1_28 = 1;
FIO1MASK_bit.P1_28 = 0;
FIO1CLR_bit.P1_28 = 1;
OS_EXIT_CRITICAL();
}

View File

@ -0,0 +1,333 @@
#include <includes.h>
#include <intrinsics.h>
#include "lcd.h"
const unsigned char rus_sym_table[64]=
{ 0x41,0xA0,0x42,0xA1,0xE0,0x45,0xA3,0xA4,
0xA5,0x03,0x4B,0xA7,0x4D,0x48,0x4F,0xA8,
0x50,0x43,0x54,0xA9,0xAA,0x58,0xE1,0xAB,
0xAC,0xE2,0xAD,0xAE,0x02,0xAF,0xB0,0xB1,
0x61,0xB2,0xB3,0xB4,0xE3,0x65,0xB6,0xB7,
0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0x6F,0xBE,
0x70,0x63,0xBF,0x79,0xE4,0x78,0xE5,0xC0,
0xC1,0xE6,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7 };
void us_delay(unsigned long x)
{
while (x--)
{
for (int i=0; i<5; i++) __no_operation();
}
}
void LCD_putch(unsigned char data)
{
if (data >= 0xC0) data = rus_sym_table[data-0xC0];
LCD_SET_DATA_OUT();
// LCD Upper 4 bits data
LCD_SET_RS_PIN(); // RS = 1, E = 1
LCD_SET_E_PIN();
LCD_CLR_RW_PIN();
us_delay(1);
LCD_OUT_DATA(data >> 4);
us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
us_delay(1);
// LCD Lower 4 bits data
LCD_SET_E_PIN(); // RS = 1, E = 1
us_delay(1);
LCD_OUT_DATA(data);
us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
us_delay(100);
// OSTimeDly(1); // Wait for busy flag (BF)
}
void LCD_putch_table(unsigned char data)
{
LCD_SET_DATA_OUT();
// LCD Upper 4 bits data
LCD_SET_RS_PIN(); // RS = 1, E = 1
LCD_SET_E_PIN();
LCD_CLR_RW_PIN();
us_delay(1);
LCD_OUT_DATA(data >> 4);
us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
us_delay(1);
// LCD Lower 4 bits data
LCD_SET_E_PIN(); // RS = 1, E = 1
us_delay(1);
LCD_OUT_DATA(data);
us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
us_delay(100);
// OSTimeDly(1); // Wait for busy flag (BF)
}
unsigned char LCD_getch()
{
unsigned char data_h, data_l;
LCD_SET_DATA_IN();
// LCD Upper 4 bits data
LCD_SET_RS_PIN(); // RS = 1, E = 1
LCD_SET_E_PIN();
LCD_SET_RW_PIN();
us_delay(1);
data_h = LCD_IN_DATA();
LCD_CLR_E_PIN();
us_delay(1);
// LCD Lower 4 bits data
LCD_SET_E_PIN(); // RS = 1, E = 1
us_delay(1);
data_l = LCD_IN_DATA();
LCD_CLR_E_PIN();
us_delay(100);
return (data_h << 4) | data_l;
}
unsigned char LCD_get_status()
{
unsigned char data_h, data_l;
LCD_SET_DATA_IN();
// LCD Upper 4 bits data
LCD_CLR_RS_PIN(); // RS = 0, E = 1
LCD_SET_E_PIN();
LCD_SET_RW_PIN();
us_delay(1);
data_h = LCD_IN_DATA();
LCD_CLR_E_PIN();
us_delay(1);
// LCD Lower 4 bits data
LCD_SET_E_PIN(); // RS = 0, E = 1
us_delay(1);
data_l = LCD_IN_DATA();
LCD_CLR_E_PIN();
us_delay(100);
return (data_h << 4) | data_l;
}
void LCD_putcmd(unsigned char data,unsigned char cmdtype)
{
LCD_SET_DATA_OUT();
// LCD Upper 4 bits data
LCD_CLR_RS_PIN(); // RS = 0, E = 1
LCD_SET_E_PIN();
LCD_CLR_RW_PIN();
us_delay(1);
LCD_OUT_DATA(data >> 4);
us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
// cmdtype = 0; One cycle write, cmdtype = 1; Two cycle writes
if (cmdtype == LCD_2CYCLE) {
// LCD Lower 4 bits data
us_delay(1);
LCD_SET_E_PIN(); // RS = 0, E = 1
us_delay(1);
LCD_OUT_DATA(data);
us_delay(1);
// E=0; write data
LCD_CLR_E_PIN();
us_delay(1);
//while(LCD_get_status() & 0x80);
OSTimeDly(2); // Wait for busy flag (BF)
//LCD_get_status();
}
}
void InitLcdPins()
{
/*
P2.8 MK_P65 Ñèãíàë A0 èíäèêàòîðà
P2.7 MK_P66 Ñèãíàë E èíäèêàòîðà
P2.6 MK_P67 Ñèãíàë R_W èíäèêàòîðà
P0.19 MK_P59 DB4
P0.20 MK_P58 DB5
P0.21 MK_P57 DB6
P0.22 MK_P56 DB7
*/
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
PINSEL4_bit.P2_8 = 0x0;
PINSEL4_bit.P2_7 = 0x0;
PINSEL4_bit.P2_6 = 0x0;
PINMODE4_bit.P2_8 = 0;
PINMODE4_bit.P2_7 = 0;
PINMODE4_bit.P2_6 = 0;
FIO2DIR_bit.P2_8 = 1;
FIO2DIR_bit.P2_7 = 1;
FIO2DIR_bit.P2_6 = 1;
FIO2MASK_bit.P2_8 = 0;
FIO2MASK_bit.P2_7 = 0;
FIO2MASK_bit.P2_6 = 0;
PINSEL1_bit.P0_19 = 0x0;
PINSEL1_bit.P0_20 = 0x0;
PINSEL1_bit.P0_21 = 0x0;
PINSEL1_bit.P0_22 = 0x0;
PINMODE1_bit.P0_19 = 0;
PINMODE1_bit.P0_20 = 0;
PINMODE1_bit.P0_21 = 0;
PINMODE1_bit.P0_22 = 0;
FIO0DIR_bit.P0_19 = 1;
FIO0DIR_bit.P0_20 = 1;
FIO0DIR_bit.P0_21 = 1;
FIO0DIR_bit.P0_22 = 1;
FIO0MASK_bit.P0_19 = 0;
FIO0MASK_bit.P0_20 = 0;
FIO0MASK_bit.P0_21 = 0;
FIO0MASK_bit.P0_22 = 0;
LCD_CLR_E_PIN();
LCD_CLR_RW_PIN();
LCD_CLR_RS_PIN();
OS_EXIT_CRITICAL();
}
unsigned char test = 0;
void InitLcd()
{
InitLcdPins();
// Wait for more than 15 ms after VCC rises to 4.5 V
OSTimeDly(30);
// Send Command 0x30
LCD_putcmd(0x30,LCD_1CYCLE);
us_delay(40);
// Send Command 0x30
LCD_putcmd(0x30,LCD_1CYCLE);
us_delay(40);
// Send Command 0x30
LCD_putcmd(0x30,LCD_1CYCLE);
us_delay(40);
// Function set: Set interface to be 4 bits long (only 1 cycle write).
LCD_putcmd(0x20,LCD_1CYCLE);
us_delay(40);
// Function set: DL=0;Interface is 4 bits, N=1; 2 Lines, F=0; 5x8 dots font)
LCD_putcmd(0x28,LCD_2CYCLE);
// Display Off: D=0; Display off, C=0; Cursor Off, B=0; Blinking Off
LCD_putcmd(0x08,LCD_2CYCLE);
// Display Clear
LCD_putcmd(0x01,LCD_2CYCLE);
// Entry Mode Set: I/D=1; Increment, S=0; No shift
LCD_putcmd(0x06,LCD_2CYCLE);
// Display On, Cursor Off
LCD_putcmd(0x0C,LCD_2CYCLE);
}
void LCD_gotoline(unsigned char n)
{
switch (n){
case 0: LCD_putcmd(LCD_GOTO_LINE_0, LCD_2CYCLE); break;
case 1: LCD_putcmd(LCD_GOTO_LINE_1, LCD_2CYCLE); break;
case 2: LCD_putcmd(LCD_GOTO_LINE_2, LCD_2CYCLE); break;
case 3: LCD_putcmd(LCD_GOTO_LINE_3, LCD_2CYCLE); break;
default: return;
}
}
// çàïèñü ñòðîêè ñ íîìåðîì n
void LCD_puts(unsigned char *s, unsigned char n)
{
unsigned char i;
LCD_gotoline(n);
i=0;
while((*s != 0) && (*s != '\n') && (i<20))
{
LCD_putch(*s);
s++;
i++;
}
while(i<20)
{
LCD_putch(' ');
i++;
}
}
void LCD_goto(unsigned char m, unsigned char n)
{
switch (n){
case 0: LCD_putcmd(LCD_GOTO_LINE_0+m, LCD_2CYCLE); break;
case 1: LCD_putcmd(LCD_GOTO_LINE_1+m, LCD_2CYCLE); break;
case 2: LCD_putcmd(LCD_GOTO_LINE_2+m, LCD_2CYCLE); break;
case 3: LCD_putcmd(LCD_GOTO_LINE_3+m, LCD_2CYCLE); break;
default: return;
}
}
// çàïèñü ñèìâîëà â ñòðîêó ñ íîìåðîì n â ïîçèöèþ m
void LCD_putc(unsigned char c, unsigned char m, unsigned char n)
{
LCD_goto(m, n);
LCD_putch(c);
}
// çàïèñü ñèìâîëà â ñòðîêó ñ íîìåðîì n â ïîçèöèþ m
void LCD_putc_embed(unsigned char c, unsigned char m, unsigned char n)
{
LCD_goto(m, n);
LCD_putch_table(c);
}
void LCD_clear(void)
{
// Display Clear
LCD_putcmd(0x01,LCD_2CYCLE);
}
void LCD_cursor_on(void)
{
LCD_putcmd(0x0F,LCD_2CYCLE);
}
void LCD_cursor_off(void)
{
LCD_putcmd(0x0C,LCD_2CYCLE);
}

View File

@ -0,0 +1,626 @@
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
* MESSAGE MAILBOX MANAGEMENT
*
* (c) Copyright 1992-2007, Jean J. Labrosse, Weston, FL
* All Rights Reserved
*
* File : OS_MBOX.C
* By : Jean J. Labrosse
* Version : V2.85
*
* LICENSING TERMS:
* ---------------
* uC/OS-II is provided in source form for FREE evaluation, for educational use or for peaceful research.
* If you plan on using uC/OS-II in a commercial product you need to contact Micriµm to properly license
* its use in your product. We provide ALL the source code for your convenience and to help you experience
* uC/OS-II. The fact that the source is provided does NOT mean that you can use it without paying a
* licensing fee.
*********************************************************************************************************
*/
#ifndef OS_MASTER_FILE
#include <ucos_ii.h>
#endif
#if OS_MBOX_EN > 0
/*
*********************************************************************************************************
* ACCEPT MESSAGE FROM MAILBOX
*
* Description: This function checks the mailbox to see if a message is available. Unlike OSMboxPend(),
* OSMboxAccept() does not suspend the calling task if a message is not available.
*
* Arguments : pevent is a pointer to the event control block
*
* Returns : != (void *)0 is the message in the mailbox if one is available. The mailbox is cleared
* so the next time OSMboxAccept() is called, the mailbox will be empty.
* == (void *)0 if the mailbox is empty or,
* if 'pevent' is a NULL pointer or,
* if you didn't pass the proper event pointer.
*********************************************************************************************************
*/
#if OS_MBOX_ACCEPT_EN > 0
void *OSMboxAccept (OS_EVENT *pevent)
{
void *pmsg;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return ((void *)0);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
return ((void *)0);
}
OS_ENTER_CRITICAL();
pmsg = pevent->OSEventPtr;
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */
OS_EXIT_CRITICAL();
return (pmsg); /* Return the message received (or NULL) */
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* CREATE A MESSAGE MAILBOX
*
* Description: This function creates a message mailbox if free event control blocks are available.
*
* Arguments : pmsg is a pointer to a message that you wish to deposit in the mailbox. If
* you set this value to the NULL pointer (i.e. (void *)0) then the mailbox
* will be considered empty.
*
* Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the
* created mailbox
* == (OS_EVENT *)0 if no event control blocks were available
*********************************************************************************************************
*/
OS_EVENT *OSMboxCreate (void *pmsg)
{
OS_EVENT *pevent;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
if (OSIntNesting > 0) { /* See if called from ISR ... */
return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
}
OS_ENTER_CRITICAL();
pevent = OSEventFreeList; /* Get next free event control block */
if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
}
OS_EXIT_CRITICAL();
if (pevent != (OS_EVENT *)0) {
pevent->OSEventType = OS_EVENT_TYPE_MBOX;
pevent->OSEventCnt = 0;
pevent->OSEventPtr = pmsg; /* Deposit message in event control block */
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?';
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
OS_EventWaitListInit(pevent);
}
return (pevent); /* Return pointer to event control block */
}
/*$PAGE*/
/*
*********************************************************************************************************
* DELETE A MAIBOX
*
* Description: This function deletes a mailbox and readies all tasks pending on the mailbox.
*
* Arguments : pevent is a pointer to the event control block associated with the desired
* mailbox.
*
* opt determines delete options as follows:
* opt == OS_DEL_NO_PEND Delete the mailbox ONLY if no task pending
* opt == OS_DEL_ALWAYS Deletes the mailbox even if tasks are waiting.
* In this case, all the tasks pending will be readied.
*
* perr is a pointer to an error code that can contain one of the following values:
* OS_ERR_NONE The call was successful and the mailbox was deleted
* OS_ERR_DEL_ISR If you attempted to delete the mailbox from an ISR
* OS_ERR_INVALID_OPT An invalid option was specified
* OS_ERR_TASK_WAITING One or more tasks were waiting on the mailbox
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
*
* Returns : pevent upon error
* (OS_EVENT *)0 if the mailbox was successfully deleted.
*
* Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
* the mailbox MUST check the return code of OSMboxPend().
* 2) OSMboxAccept() callers will not know that the intended mailbox has been deleted!
* 3) This call can potentially disable interrupts for a long time. The interrupt disable
* time is directly proportional to the number of tasks waiting on the mailbox.
* 4) Because ALL tasks pending on the mailbox will be readied, you MUST be careful in
* applications where the mailbox is used for mutual exclusion because the resource(s)
* will no longer be guarded by the mailbox.
*********************************************************************************************************
*/
#if OS_MBOX_DEL_EN > 0
OS_EVENT *OSMboxDel (OS_EVENT *pevent, INT8U opt, INT8U *perr)
{
BOOLEAN tasks_waiting;
OS_EVENT *pevent_return;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (pevent);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return (pevent);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return (pevent);
}
if (OSIntNesting > 0) { /* See if called from ISR ... */
*perr = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
return (pevent);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mailbox */
tasks_waiting = OS_TRUE; /* Yes */
} else {
tasks_waiting = OS_FALSE; /* No */
}
switch (opt) {
case OS_DEL_NO_PEND: /* Delete mailbox only if no task waiting */
if (tasks_waiting == OS_FALSE) {
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?'; /* Unknown name */
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
pevent->OSEventCnt = 0;
OSEventFreeList = pevent; /* Get next free event control block */
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */
} else {
OS_EXIT_CRITICAL();
*perr = OS_ERR_TASK_WAITING;
pevent_return = pevent;
}
break;
case OS_DEL_ALWAYS: /* Always delete the mailbox */
while (pevent->OSEventGrp != 0) { /* Ready ALL tasks waiting for mailbox */
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_OK);
}
#if OS_EVENT_NAME_SIZE > 1
pevent->OSEventName[0] = '?'; /* Unknown name */
pevent->OSEventName[1] = OS_ASCII_NUL;
#endif
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
pevent->OSEventCnt = 0;
OSEventFreeList = pevent; /* Get next free event control block */
OS_EXIT_CRITICAL();
if (tasks_waiting == OS_TRUE) { /* Reschedule only if task(s) were waiting */
OS_Sched(); /* Find highest priority task ready to run */
}
*perr = OS_ERR_NONE;
pevent_return = (OS_EVENT *)0; /* Mailbox has been deleted */
break;
default:
OS_EXIT_CRITICAL();
*perr = OS_ERR_INVALID_OPT;
pevent_return = pevent;
break;
}
return (pevent_return);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* PEND ON MAILBOX FOR A MESSAGE
*
* Description: This function waits for a message to be sent to a mailbox
*
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
*
* timeout is an optional timeout period (in clock ticks). If non-zero, your task will
* wait for a message to arrive at the mailbox up to the amount of time
* specified by this argument. If you specify 0, however, your task will wait
* forever at the specified mailbox or, until a message arrives.
*
* perr is a pointer to where an error message will be deposited. Possible error
* messages are:
*
* OS_ERR_NONE The call was successful and your task received a
* message.
* OS_ERR_TIMEOUT A message was not received within the specified 'timeout'.
* OS_ERR_PEND_ABORT The wait on the mailbox was aborted.
* OS_ERR_EVENT_TYPE Invalid event type
* OS_ERR_PEND_ISR If you called this function from an ISR and the result
* would lead to a suspension.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
* OS_ERR_PEND_LOCKED If you called this function when the scheduler is locked
*
* Returns : != (void *)0 is a pointer to the message received
* == (void *)0 if no message was received or,
* if 'pevent' is a NULL pointer or,
* if you didn't pass the proper pointer to the event control block.
*********************************************************************************************************
*/
void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *perr)
{
void *pmsg;
INT8U pend_stat;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return ((void *)0);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return ((void *)0);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return ((void *)0);
}
if (OSIntNesting > 0) { /* See if called from ISR ... */
*perr = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
return ((void *)0);
}
if (OSLockNesting > 0) { /* See if called with scheduler locked ... */
*perr = OS_ERR_PEND_LOCKED; /* ... can't PEND when locked */
return ((void *)0);
}
OS_ENTER_CRITICAL();
pmsg = pevent->OSEventPtr;
if (pmsg != (void *)0) { /* See if there is already a message */
pevent->OSEventPtr = (void *)0; /* Clear the mailbox */
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (pmsg); /* Return the message received (or NULL) */
}
OSTCBCur->OSTCBStat |= OS_STAT_MBOX; /* Message not available, task will pend */
OSTCBCur->OSTCBStatPend = OS_STAT_PEND_OK;
OSTCBCur->OSTCBDly = timeout; /* Load timeout in TCB */
OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
OS_EXIT_CRITICAL();
OS_Sched(); /* Find next highest priority task ready to run */
OS_ENTER_CRITICAL();
if (OSTCBCur->OSTCBStatPend != OS_STAT_PEND_OK) { /* See if we weren't given the message */
pend_stat = OSTCBCur->OSTCBStatPend;
OS_EventTOAbort(pevent); /* Timed out, Make task ready */
OS_EXIT_CRITICAL();
switch (pend_stat) {
case OS_STAT_PEND_TO:
default:
*perr = OS_ERR_TIMEOUT; /* Indicate that a timeout occured */
break;
case OS_STAT_PEND_ABORT:
*perr = OS_ERR_PEND_ABORT; /* Indicate that we aborted */
break;
}
return ((void *)0); /* Return a NULL message */
}
pmsg = OSTCBCur->OSTCBMsg;
OSTCBCur->OSTCBMsg = (void *)0; /* Yes, clear message received */
OSTCBCur->OSTCBStat = OS_STAT_RDY;
OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (pmsg); /* Return the message received */
}
/*$PAGE*/
/*
*********************************************************************************************************
* ABORT WAITING ON A MESSAGE MAILBOX
*
* Description: This function aborts & readies any tasks currently waiting on a mailbox. This function
* should be used to fault-abort the wait on the mailbox, rather than to normally signal
* the mailbox via OSMboxPost() or OSMboxPostOpt().
*
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox.
*
* opt determines the type of ABORT performed:
* OS_PEND_OPT_NONE ABORT wait for a single task (HPT) waiting on the
* mailbox
* OS_PEND_OPT_BROADCAST ABORT wait for ALL tasks that are waiting on the
* mailbox
*
* perr is a pointer to where an error message will be deposited. Possible error
* messages are:
*
* OS_ERR_NONE No tasks were waiting on the mailbox.
* OS_ERR_PEND_ABORT At least one task waiting on the mailbox was readied
* and informed of the aborted wait; check return value
* for the number of tasks whose wait on the mailbox
* was aborted.
* OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mailbox.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
*
* Returns : == 0 if no tasks were waiting on the mailbox, or upon error.
* > 0 if one or more tasks waiting on the mailbox are now readied and informed.
*********************************************************************************************************
*/
#if OS_MBOX_PEND_ABORT_EN > 0
INT8U OSMboxPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr)
{
INT8U nbr_tasks;
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (perr == (INT8U *)0) { /* Validate 'perr' */
return (0);
}
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*perr = OS_ERR_PEVENT_NULL;
return (0);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
*perr = OS_ERR_EVENT_TYPE;
return (0);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any task waiting on mailbox? */
nbr_tasks = 0;
switch (opt) {
case OS_PEND_OPT_BROADCAST: /* Do we need to abort ALL waiting tasks? */
while (pevent->OSEventGrp != 0) { /* Yes, ready ALL tasks waiting on mailbox */
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT);
nbr_tasks++;
}
break;
case OS_PEND_OPT_NONE: /* No, ready HPT waiting on mailbox */
default:
(void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MBOX, OS_STAT_PEND_ABORT);
nbr_tasks++;
break;
}
OS_EXIT_CRITICAL();
OS_Sched(); /* Find HPT ready to run */
*perr = OS_ERR_PEND_ABORT;
return (nbr_tasks);
}
OS_EXIT_CRITICAL();
*perr = OS_ERR_NONE;
return (0); /* No tasks waiting on mailbox */
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* POST MESSAGE TO A MAILBOX
*
* Description: This function sends a message to a mailbox
*
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
*
* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer.
*
* Returns : OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one
* message at a time and thus, the message MUST be consumed before you
* are allowed to send another one.
* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
*
* Note(s) : 1) HPT means Highest Priority Task
*********************************************************************************************************
*/
#if OS_MBOX_POST_EN > 0
INT8U OSMboxPost (OS_EVENT *pevent, void *pmsg)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */
return (OS_ERR_POST_NULL_PTR);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */
/* Ready HPT waiting on event */
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);
OS_EXIT_CRITICAL();
OS_Sched(); /* Find highest priority task ready to run */
return (OS_ERR_NONE);
}
if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */
OS_EXIT_CRITICAL();
return (OS_ERR_MBOX_FULL);
}
pevent->OSEventPtr = pmsg; /* Place message in mailbox */
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* POST MESSAGE TO A MAILBOX
*
* Description: This function sends a message to a mailbox
*
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
*
* pmsg is a pointer to the message to send. You MUST NOT send a NULL pointer.
*
* opt determines the type of POST performed:
* OS_POST_OPT_NONE POST to a single waiting task
* (Identical to OSMboxPost())
* OS_POST_OPT_BROADCAST POST to ALL tasks that are waiting on the mailbox
*
* OS_POST_OPT_NO_SCHED Indicates that the scheduler will NOT be invoked
*
* Returns : OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_MBOX_FULL If the mailbox already contains a message. You can can only send one
* message at a time and thus, the message MUST be consumed before you
* are allowed to send another one.
* OS_ERR_EVENT_TYPE If you are attempting to post to a non mailbox.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
* OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
*
* Note(s) : 1) HPT means Highest Priority Task
*
* Warning : Interrupts can be disabled for a long time if you do a 'broadcast'. In fact, the
* interrupt disable time is proportional to the number of tasks waiting on the mailbox.
*********************************************************************************************************
*/
#if OS_MBOX_POST_OPT_EN > 0
INT8U OSMboxPostOpt (OS_EVENT *pevent, void *pmsg, INT8U opt)
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pmsg == (void *)0) { /* Make sure we are not posting a NULL pointer */
return (OS_ERR_POST_NULL_PTR);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0) { /* See if any task pending on mailbox */
if ((opt & OS_POST_OPT_BROADCAST) != 0x00) { /* Do we need to post msg to ALL waiting tasks ? */
while (pevent->OSEventGrp != 0) { /* Yes, Post to ALL tasks waiting on mailbox */
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);
}
} else { /* No, Post to HPT waiting on mbox */
(void)OS_EventTaskRdy(pevent, pmsg, OS_STAT_MBOX, OS_STAT_PEND_OK);
}
OS_EXIT_CRITICAL();
if ((opt & OS_POST_OPT_NO_SCHED) == 0) { /* See if scheduler needs to be invoked */
OS_Sched(); /* Find HPT ready to run */
}
return (OS_ERR_NONE);
}
if (pevent->OSEventPtr != (void *)0) { /* Make sure mailbox doesn't already have a msg */
OS_EXIT_CRITICAL();
return (OS_ERR_MBOX_FULL);
}
pevent->OSEventPtr = pmsg; /* Place message in mailbox */
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* QUERY A MESSAGE MAILBOX
*
* Description: This function obtains information about a message mailbox.
*
* Arguments : pevent is a pointer to the event control block associated with the desired mailbox
*
* p_mbox_data is a pointer to a structure that will contain information about the message
* mailbox.
*
* Returns : OS_ERR_NONE The call was successful and the message was sent
* OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non mailbox.
* OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
* OS_ERR_PDATA_NULL If 'p_mbox_data' is a NULL pointer
*********************************************************************************************************
*/
#if OS_MBOX_QUERY_EN > 0
INT8U OSMboxQuery (OS_EVENT *pevent, OS_MBOX_DATA *p_mbox_data)
{
INT8U i;
#if OS_LOWEST_PRIO <= 63
INT8U *psrc;
INT8U *pdest;
#else
INT16U *psrc;
INT16U *pdest;
#endif
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (p_mbox_data == (OS_MBOX_DATA *)0) { /* Validate 'p_mbox_data' */
return (OS_ERR_PDATA_NULL);
}
#endif
if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
OS_ENTER_CRITICAL();
p_mbox_data->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
psrc = &pevent->OSEventTbl[0];
pdest = &p_mbox_data->OSEventTbl[0];
for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
*pdest++ = *psrc++;
}
p_mbox_data->OSMsg = pevent->OSEventPtr; /* Get message from mailbox */
OS_EXIT_CRITICAL();
return (OS_ERR_NONE);
}
#endif /* OS_MBOX_QUERY_EN */
#endif /* OS_MBOX_EN */

View File

@ -0,0 +1,189 @@
#ifndef _DATADESC_H_
#define _DATADESC_H_
#include "data.h"
#include "control.h"
#define INCAS_SEND_FLAG 0x87654321
#define MAX_PRICE 9999
#define DEFAULT_PASSWORD 1111
#define MASTER_PASSWORD 11300045//1234567890L
// ñòðóêòóðà êîíôèãóðàöèè êàíàëîâ
typedef struct{
// âêëþ÷åíèå êàíàëà
CPU_INT32U Enable[CHANNELS_NUM];
// òàéì-àóò ïåðåä âêëþ÷åíèåì, ñåê.
CPU_INT32U TimeOutBefore[CHANNELS_NUM];
// òàéì-àóò ïîñëå âûêëþ÷åíèÿ, ìèí.
CPU_INT32U TimeOutAfter[CHANNELS_NUM];
// ìàêñèìàëüíîå âðåìÿ ðàáîòû, ìèí.
CPU_INT32U MaxWorkTime[CHANNELS_NUM];
// ìèíèìàëüíîå âðåìÿ ðàáîòû, ìèí.
CPU_INT32U MinWorkTime[CHANNELS_NUM];
// íàñòðîéêà óèêåíäà, èíäåêñ
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
// íàçâàíèå êàíàëà
CPU_INT32U Name[CHANNELS_NUM];
// ïåðèîäû
#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];
// öåíû
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];
CPU_INT32U PriceTime_Weekend[CHANNELS_NUM][PRICE_PERIODS_NUM];
}TChannelConfig;
// ñòðóêòóðà êîíôèãóðàöèè àïïàðàòóðû
typedef struct{
CPU_INT32U EnableValidator;
CPU_INT32U EnableCoinAcceptor;
CPU_INT32U EnableModem;
CPU_INT32U EnableFiscal;
CPU_INT32U EnableFiscalDayClear;
CPU_INT32U ServiceName;
CPU_INT32U CoinPerPulse; // öåíà èìïóëüñà ìîíåòîïðèåìíèêà
CPU_INT32U BillFormat;
CPU_INT32U DisableFiscalErrors; // îòêëþ÷åíèå ðåàêöèè íà îøèáêè ÔÐ
CPU_INT32U EnableEmailErrorSend;
CPU_INT32U EnableEmailStatSend;
CPU_INT32U EnableEmailJournalSend;
CPU_INT32U ClearJournalAfterSend;
CPU_INT32U StatSendHourMin;
CPU_INT32U DeviceId;
}TDeviceConfig;
extern CPU_INT32U PeriodIndex;
extern CPU_INT32U ChannelIndex;
extern TDataDescStruct const DeviceIDDesc;
extern TDataDescStruct const LastEmailSendTime;
extern TDataDescStruct const ChannelIndexDesc;
extern TDataDescStruct const EnableChannelDesc;
extern TDataDescStruct const TimeOutBeforeDesc;
extern TDataDescStruct const TimeOutAfterDesc;
extern TDataDescStruct const MaxWorkTimeDesc;
extern TDataDescStruct const MinWorkTimeDesc;
extern TDataDescStruct const WeekEndDesc;
extern TDataDescStruct const DeferredStartDesc;
extern TDataDescStruct const PeriodWeekendIndexDesc;
extern TDataDescStruct const PeriodWeekdaysIndexDesc;
extern TDataDescStruct const ServiceNameDesc;
extern TDataDescStruct const PassDesc;
extern TDataDescStruct const PassCRCDesc;
extern TDataDescStruct const PassTempDesc;
extern CPU_INT32U TempPass;
extern TDataDescStruct const PassTempDesc1;
extern TDataDescStruct const PassTempDesc2;
extern TDataDescStruct const PriceWeekendDesc;
extern TDataDescStruct const PriceWeekdaysDesc;
extern TDataDescStruct const PriceTimeWeekendDesc;
extern TDataDescStruct const PriceTimeWeekdaysDesc;
extern TDataDescStruct const T_Start_WeekdaysDesc;
extern TDataDescStruct const T_End_WeekdaysDesc;
extern TDataDescStruct const T_Start_WeekendDesc;
extern TDataDescStruct const T_End_WeekendDesc;
extern TDataDescStruct const EnableFiscalDesc;
extern TDataDescStruct const EnableCoinDesc;
extern TDataDescStruct const EnableModemDesc;
extern TDataDescStruct const EnableValidatorDesc;
extern TDataDescStruct const CoinPerPulseDesc;
extern TDataDescStruct const EnableFiscalDayClearDesc;
extern TDataDescStruct const InitByDefaultDesc;
extern TDataDescStruct const PrintZReportDesc;
extern TDataDescStruct const PrintXReportDesc;
extern TDataDescStruct const ErrorJournalIndexDesc;
extern TDataDescStruct const EventJournalIndexDesc;
extern TDataDescStruct const JournalEventTimeDesc;
extern TDataDescStruct const JournalErrorNumberDesc0;
extern TDataDescStruct const JournalErrorNumberDesc1;
extern TDataDescStruct const JournalErrorTimeDesc;
extern TDataDescStruct const ClearJournalCmdDesc;
extern TDataDescStruct const SystemTimeDesc;
extern TDataDescStruct const SystemTimeEditDesc;
extern const TDataDescArrayStruct AllDataArray[];
extern CPU_INT32U ErrorJournalIndex;
extern CPU_INT32U EventJournalIndex;
extern TDataDescStruct const CounterRunDesc;
extern TDataDescStruct const CounterMoneyDesc;
extern TDataDescStruct const CounterTimeDesc;
extern TDataDescStruct const CounterChannelRunDesc;
extern TDataDescStruct const CounterChannelMoneyDesc;
extern TDataDescStruct const CounterChannelTimeDesc;
extern TDataDescStruct const ChannelStIndexDesc;
extern TDataDescStruct const ClearStatCmdDesc;
extern TDataDescStruct const BillFormatDesc;
extern TDataDescStruct const NameChannelDesc;
extern TDataDescStruct const AcceptedMoneyDesc;
extern TDataDescStruct const AcceptedMoneyCRC16Desc;
extern TDataDescStruct const DisableFiscalErrorsDesc;
extern TDataDescStruct const StartButtonNameDesc;
extern TDataDescStruct const EnableEmailErrorSendDesc;
extern TDataDescStruct const EnableEmailJournalSendDesc;
extern TDataDescStruct const ClearJournalAfterSendDesc;
extern TDataDescStruct const StatSendPeriodDesc;
extern TDataDescStruct const JournalErrorNumberDescEng;
extern TDataDescStruct const SendTestEmailDesc;
extern TDataDescStruct const ModemStatusDesc;
extern TDataDescStruct const BillnomIndexDesc;
extern TDataDescStruct const BillnomDesc;
extern TDataDescStruct const BillnomCountersDesc;
extern TDataDescStruct const BillCounterDesc;
extern TDataDescStruct const CounterLongRunDesc;
extern TDataDescStruct const CounterLongMoneyDesc;
extern TDataDescStruct const CounterLongTimeDesc;
extern TDataDescStruct const MasterPassTempDesc;
extern TDataDescStruct const CounterChannelRunLongDesc;
extern TDataDescStruct const CounterChannelMoneyLongDesc;
extern TDataDescStruct const CounterChannelTimeLongDesc;
extern TDataDescStruct const ChannelStLongIndexDesc;
extern TDataDescStruct const StatSendHourMinDesc;
extern TDataDescStruct const IncasSendFlagDesc;
extern TDataDescStruct const IncasMoneyDesc;
extern TDataDescStruct const IncasTimeDesc;
#endif //#ifndef _DATADESC_H_

View File

@ -0,0 +1,94 @@
#include "iolpc2368.h"
#include "ucos_ii.h"
#include <stdlib.h>
#include "cpu.h"
#include "spi.h"
OS_EVENT *SpiLock = NULL;
unsigned char SpiExchange(unsigned char spi, unsigned char ch)
{
SSP0DR = ch;
while(SSP0SR_bit.BSY);
return SSP0DR;
}
void SpiInit(void)
{
// on spi power
PCONP_bit.PCSSP0 = 1;
// clk = cclk
PCLKSEL1_bit.PCLK_SSP0 = 1;
// pin select
PINSEL0_bit.P0_15 = 0x2;
PINSEL1_bit.P0_16 = 0x0; // FRAM CS
PINSEL1_bit.P0_17 = 0x2;
PINSEL1_bit.P0_18 = 0x2;
PINMODE0_bit.P0_15 = 2;
PINMODE1_bit.P0_16 = 0;
PINMODE1_bit.P0_17 = 2;
PINMODE1_bit.P0_18 = 2;
// Chip select
FIO0MASK_bit.P0_16 = 0;
FIO0DIR_bit.P0_16 = 1;
FIO0SET_bit.P0_16 = 1;
FIO0MASK_bit.P0_15 = 1;
FIO0MASK_bit.P0_17 = 1;
FIO0MASK_bit.P0_18 = 1;
SSP0CR0_bit.DSS = 7; // 8-bit
SSP0CR0_bit.FRF = 0; // spi
SSP0CR0_bit.SPO = 0;
SSP0CR0_bit.SPH = 0;
SSP0CR0_bit.SCR = 1;
SSP0CR1_bit.LBM = 0;
SSP0CR1_bit.SSE = 1;
SSP0CR1_bit.MS = 0; // master
SSP0CR1_bit.SOD = 0;
SSP0CPSR_bit.CPSDVSR = 2;
SSP0IMSC = 0;
SSP0DMACR = 0;
if (!SpiLock) SpiLock = OSSemCreate(1);
}
unsigned char spi_selectChip(unsigned char spi)
{
if (spi == FM25_SPI){
FIO0CLR_bit.P0_16 = 1;
}
return 0;
}
unsigned char spi_unselectChip(unsigned char spi)
{
if (spi == FM25_SPI){
FIO0SET_bit.P0_16 = 1;
}
return 0;
}
void spi_getSem()
{
CPU_INT08U err;
do{
OSSemPend(SpiLock, 1, &err);
if (!err) break;
OSTimeDly(1);
}while (err);
}
void spi_freeSem()
{
OSSemPost(SpiLock);
}

View File

@ -0,0 +1,357 @@
#include <includes.h>
#include "data.h"
#include "datadesc.h"
#include "fram.h"
#include "time.h"
#include <stdlib.h>
#include <stddef.h>
// ïîëó÷åíèå äàííûõ
int GetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags)
{
TVariant32 Val;
CPU_INT32U ofst = 0;
// îïðåäåëèì äîï. ñìåùåíèå äëÿ ìàññèâà
if (desc->IsArray)
{
if (flags == DATA_FLAG_DIRECT_INDEX)
{
ofst = (index >= desc->ArraySize) ? desc->ArrayOffset*(desc->ArraySize-1) : desc->ArrayOffset*index;
}
else
{
GetData((TDataDescStruct*)desc->ArrayIndex, &ofst, 0, DATA_FLAG_SYSTEM_INDEX);
ofst *= desc->ArrayOffset;
}
}
// ñ÷èòàåì çíà÷åíèå ïàðàìåòðà
if (desc->Location == DATA_LOC_RAM)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
memcpy(&Val, (CPU_INT08U*)desc->Data+ofst, sizeof(CPU_INT32U));
OS_EXIT_CRITICAL();
}
else if (desc->Location == DATA_LOC_FRAM)
{
ReadArrayFram((CPU_INT32U)desc->Data+ofst, sizeof(CPU_INT32U), (CPU_INT08U*)&Val);
}
else return DATA_ERR;
// âñ¸ ÎÊ
memcpy(buf, &Val, sizeof(CPU_INT32U));
return DATA_OK;
}
// çàïèñü äàííûõ
int SetData(const TDataDescStruct* desc, void* buf, CPU_INT32U index, CPU_INT08U flags)
{
TVariant32 Val;
CPU_INT32U ofst = 0;
if (desc->Desc == DATA_DESC_VIEW) return DATA_ERR;
// ïðîâåðèì äîïóñòèìîñòü çíà÷åíèé
if (desc->RangeValue)
{
TVariant32 ValMin, ValMax;
TRangeValueULONG* RVal = desc->RangeValue;
memcpy(&ValMin, &RVal->Min, sizeof(CPU_INT32U));
memcpy(&ValMax, &RVal->Max, sizeof(CPU_INT32U));
memcpy(&Val, buf, sizeof(CPU_INT32U));
if (desc->Type == DATA_TYPE_ULONG)
{
if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) return DATA_ERR;
}
else if (desc->Type == DATA_TYPE_SLONG)
{
if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) return DATA_ERR;
}
else if (desc->Type == DATA_TYPE_FLOAT)
{
if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) return DATA_ERR;
}
else if (desc->Type == DATA_TYPE_TIME)
{
}
else if (desc->Type == DATA_TYPE_HOUR_MIN)
{
if (Val.Val32U >= 24*60) return DATA_ERR;
}
else return DATA_ERR;
}
else
{
memcpy(&Val, buf, sizeof(CPU_INT32U));
}
// îïðåäåëèì äîï. ñìåùåíèå äëÿ ìàññèâà
if (desc->IsArray)
{
if (flags == DATA_FLAG_DIRECT_INDEX)
{
ofst = (index >= desc->ArraySize) ? desc->ArrayOffset*(desc->ArraySize-1) : desc->ArrayOffset*index;
}
else
{
GetData((TDataDescStruct*)desc->ArrayIndex, &ofst, 0, DATA_FLAG_SYSTEM_INDEX);
ofst *= desc->ArrayOffset;
}
}
// çàïèøåì çíà÷åíèå
if (desc->Location == DATA_LOC_RAM)
{
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr = 0;
#endif
OS_ENTER_CRITICAL();
memcpy((CPU_INT08U*)desc->Data+ofst, &Val, sizeof(CPU_INT32U));
OS_EXIT_CRITICAL();
}
else if (desc->Location == DATA_LOC_FRAM)
{
WriteArrayFram((CPU_INT32U)desc->Data+ofst, sizeof(CPU_INT32U), (CPU_INT08U*)&Val);
}
else return DATA_ERR;
// ôóíêöèÿ ïî èçìåíåíèþ
if (desc->OnchangeFunc) desc->OnchangeFunc();
// âñ¸ ÎÊ
return DATA_OK;
}
// ïîëó÷åíèå ìàêñèìóìà ïàðàìåòðà äåñêðèïòîðà
int GetDataMax(const TDataDescStruct* desc, void* buf)
{
if (desc->RangeValue)
{
TRangeValueULONG* RVal = desc->RangeValue;
memcpy(buf, &RVal->Max, sizeof(CPU_INT32U));
}
else
{
*(CPU_INT32U*)&buf = 0;
}
return DATA_OK;
}
// ïîëó÷åíèå ìèíèìóìà ïàðàìåòðà äåñêðèïòîðà
int GetDataMin(const TDataDescStruct* desc, void* buf)
{
if (desc->RangeValue)
{
TRangeValueULONG* RVal = desc->RangeValue;
memcpy(buf, &RVal->Min, sizeof(CPU_INT32U));
}
else
{
*(CPU_INT32U*)&buf = 0;
}
return DATA_OK;
}
// ïîëó÷åíèå ñòðîêè ñ îòôîðìàòèðîâàííûì çíà÷åíèåì
int GetDataStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags)
{
TVariant32 Val;
GetData(desc, &Val, index, flags);
if (desc->Type == DATA_TYPE_ULONG)
{
if (desc->IsIndex)
{ // èíäåêñíûé ïàðàìåòð
if (desc->RangeValue)
{
TRangeValueULONG* range = (TRangeValueULONG*)desc->RangeValue;
if ((Val.Val32U >= range->Min) && (Val.Val32U <= range->Max)) strcpy((char*)buf, (char const*)desc->Items[Val.Val32U]);
else {strcpy((char*)buf, ""); return DATA_ERR;}
}
else if (desc->Desc == DATA_DESC_VIEW)
{
strcpy((char*)buf, (char const*)desc->Items[Val.Val32U]);
}
else
{
strcpy((char*)buf, "");
}
}
else
{
sprintf((char*)buf, "%d", Val.Val32U);
}
}
else if (desc->Type == DATA_TYPE_SLONG)
{
sprintf((char*)buf, "%d", Val.Val32S);
}
else if (desc->Type == DATA_TYPE_FLOAT)
{
sprintf((char*)buf, "%0.3f", Val.ValFloat);
}
else if (desc->Type == DATA_TYPE_TIME)
{
PrintTimeString((char*)buf, Val.Val32U);
}
else if (desc->Type == DATA_TYPE_TIME_COUNT)
{
PrintSecToBigHourMinSec((char*)buf, Val.Val32U);
}
else if (desc->Type == DATA_TYPE_HOUR_MIN)
{
int min_ = Val.Val32U % 60;
int hour_ = Val.Val32U / 60;
sprintf((char*)buf, "%02d:%02d", hour_, min_);
}
else return DATA_ERR;
return DATA_OK;
}
// ïîëó÷åíèå ïîëíîé ñòðîêè ñ íàçâàíèåì è çíà÷åíèåì
int GetDataFullStr(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U index, CPU_INT08U flags)
{
GetDataNameStr(desc, buf);
if (desc->Name)
{
if (desc->IsIndex) strcat((char*)&buf[strlen((char*)buf)], " ");
else strcat((char*)&buf[strlen((char*)buf)], "=");
}
GetDataStr(desc, &buf[strlen((char*)buf)], index, flags);
return DATA_OK;
}
// ïîëó÷åíèå ñòðîêè ñ èìåíåì
int GetDataNameStr(const TDataDescStruct* desc, CPU_INT08U* buf)
{
if (desc->Name) strcpy((char*)buf, (char const*)desc->Name);
else strcpy((char*)buf, "");
return DATA_OK;
}
// ïîëó÷åíèå ñòðîêè ñî çíà÷åíèåì íäåêñíîé ñòðîêè ïî èíäåêñó
int GetDataItem(const TDataDescStruct* desc, CPU_INT08U* buf, CPU_INT32U itemindex)
{
if (!desc->IsIndex) {buf[0]=0;return DATA_ERR;}
if (desc->Type != DATA_TYPE_ULONG) {buf[0]=0;return DATA_ERR;}
// èíäåêñíûé ïàðàìåòð
if (desc->RangeValue)
{
TRangeValueULONG* range = (TRangeValueULONG*)desc->RangeValue;
if ((itemindex >= range->Min) && (itemindex <= range->Max)) strcpy((char*)buf, (char const*)desc->Items[itemindex]);
else return DATA_ERR;
}
else
{
strcpy((char*)buf, "");
}
return DATA_OK;
}
// èíèöèàëèçàöèÿ ïî óìîë÷àíèþ
int InitDataByDefault(const TDataDescStruct* desc, CPU_INT32U index)
{
SetData(desc, (void*)&desc->DefaultValue, index, DATA_FLAG_DIRECT_INDEX);
return DATA_OK;
}
// èíèöèàëèçàöèÿ ïðè ñòàðòå
int InitData(const TDataDescStruct* desc)
{
return DATA_OK;
}
// ïðîâåðêà ãðàíèö
int CheckDataRange(const TDataDescStruct* desc)
{
TVariant32 ValMin, ValMax, Val;
TRangeValueULONG* RVal = desc->RangeValue;
if (!desc->RangeValue) return DATA_OK;
memcpy(&ValMin, &RVal->Min, sizeof(CPU_INT32U));
memcpy(&ValMax, &RVal->Max, sizeof(CPU_INT32U));
if (desc->IsArray)
{
for (int i = 0; i < desc->ArraySize; i++)
{
GetData(desc, &Val, i, DATA_FLAG_DIRECT_INDEX);
if (desc->Type == DATA_TYPE_ULONG)
{
if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) InitDataByDefault(desc, i);
}
else if (desc->Type == DATA_TYPE_SLONG)
{
if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) InitDataByDefault(desc, i);
}
else if (desc->Type == DATA_TYPE_FLOAT)
{
if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) InitDataByDefault(desc, i);
}
else return DATA_ERR;
}
}
else
{
GetData(desc, &Val, 0, DATA_FLAG_DIRECT_INDEX);
if (desc->Type == DATA_TYPE_ULONG)
{
if ((Val.Val32U > ValMax.Val32U) || (Val.Val32U < ValMin.Val32U)) InitDataByDefault(desc, 0);
}
else if (desc->Type == DATA_TYPE_SLONG)
{
if ((Val.Val32S > ValMax.Val32S) || (Val.Val32S < ValMin.Val32S)) InitDataByDefault(desc, 0);
}
else if (desc->Type == DATA_TYPE_FLOAT)
{
if ((Val.ValFloat > ValMax.ValFloat) || (Val.ValFloat < ValMin.ValFloat)) InitDataByDefault(desc, 0);
}
else return DATA_ERR;
}
return DATA_OK;
}
// èíèöèàëèçàöèÿ ïî óìîë÷àíèþ, âêëþ÷àÿ ìàññèâû
int InitDescByDefault(const TDataDescStruct* desc)
{
if (desc->IsArray)
{
for (int i = 0; i < desc->ArraySize; i++) InitDataByDefault(desc, i);
}
else
{
InitDataByDefault(desc, 0);
}
return DATA_OK;
}
// ïðîâåðêà âñåõ äåñòðèïòîðîâ
int CheckAllData(void)
{
int i = 0;
while (AllDataArray[i].ptr != NULL)
{
CheckDataRange(AllDataArray[i].ptr);
i++;
}
return DATA_OK;
}

View File

@ -0,0 +1,20 @@
#ifndef _VALIDATOR_H_
#define _VALIDATOR_H_
#define CC_VALIDATOR_SPEED 9600
#define CC_POLL_TIME_OUT 150
#define CC_BUS_RESET_TIME_OUT 100
#define VCONN_STATUS_CONN 0
#define VCONN_STATUS_NOCONN 1
// ìàêñèìàëüíîå ÷èñëî ïîääåðæèâàåìûõ áàíêíîò
#define V_BILLS_NUMBER 24
extern void StartUpValidator(void);
extern int IsValidatorConnected(void);
extern void VPend(void);
extern void VPost(void);
extern CPU_INT32U GetResetBillCount(CPU_INT32U *bill_index);
#endif //#define _VALIDATOR_H_

Some files were not shown because too many files have changed in this diff Show More