T168_111\system\PrtEng:第1~4

Calibration.c                。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define CALIBRATION_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <stdlib.h>
#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XADC.h"
#include "XTimer.h"
#include "XTask.h"
#include "XProFile.h"
#include "XVarBank.h"
#include "PrtEng.h"

extern VOID SetTaskStatus(VOID); // ch_20220428
extern VOID ResetTaskStatus(VOID); // ch_20220428
extern UCHAR ReturnTaskStatus(VOID); // ch_20220428

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#define CALDEBUG                0
#define MEDIA_CHANGELESS        0
#define MEDIA_CHANGE_RAISING    1
#define MEDIA_CHANGE_FALLING    2

#define CAL_TRANSMISSIVE        0
#define CAL_REFLECTIVE            1

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

typedef struct
{
    INT State;
    INT Buf[3];
    INT Value;
    INT Keep;
} _MediaChange;

typedef struct
{
    INT Limit;
    INT Total;
    INT Conv;
    INT ConvCnt;
    INT Paper;
    INT GapBline;
    INT Preprint;
} _CalRecord;

typedef struct
{
    _eSensorType Type;
    INT          Scale;            //范围
    BYTE         ADChanel;
    INT          Sens[2];
} _CalSensor;

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC BOOL CalibrationEnd;
STATIC _CalResult CalResult;
STATIC UCHAR OnceCalDone = 0; // ch_20220416 : First FN_PRINT to get SIZE&GAP then feed (not print).

#if defined(ANALOG_MEDIA)
STATIC INT PreprintLength;
STATIC INT CalSensTransmissive;
STATIC INT CalSensReflective;
STATIC _MediaChange CalChange[2][MAX_SENSOR_SCALE];
STATIC _AnalogMedia CalMedia[2][MAX_SENSOR_SCALE];
STATIC _CalRecord CalRecord[2][MAX_SENSOR_SCALE][2];
#endif

#ifdef DEBUG_PRNT
LONG G_GetHereCnt[12] = {0}; // ch_20211213
#endif

VOID InitialCalibration(VOID)
{
    STATIC BOOL ready = FALSE;
    FLOAT data;

    if (ready == FALSE)        // First initialization
    {
#if defined(ANALOG_MEDIA)
        PreprintLength = 0;
        if (GetProfileInt("LENGTH PREPRINT", &data))
            PreprintLength = (INT)data * MOTOR_STEP_RATE;

        CalSensTransmissive = 0;
        if (GetProfileInt("TRANSMISSIVE SENSITIVITY CALIBRATION", &data))
            CalSensTransmissive = (INT)data;

        CalSensReflective = 0;
        if (GetProfileInt("REFLECTIVE SENSITIVITY CALIBRATION", &data))
            CalSensReflective = (INT)data;
#endif
        ready = TRUE;
    }
    else if (CalResult.SetSize)
        WaitWorkJobEnd();

    CalResult.Finish  = FALSE;
    CalResult.SetSize = FALSE;
}

_CalResult *GrabCalibrationResult(VOID)
{
    return &CalResult;
}

#if defined(DIVIDE_INTENSION)

#if defined(ANALOG_MEDIA)

STATIC VOID ClearCalibrationRecord(_CalRecord *Rec)
{
    _PrintCfg *CalCfg = GrabPrintConfig();

    Rec->Limit    = CalCfg->LimitFeed * MOTOR_STEP_RATE;
    Rec->Total    = Rec->Limit * 2;
    Rec->Conv     = 0;
    Rec->ConvCnt  = 0;
    Rec->Paper    = 0;
    Rec->GapBline = 0;
    Rec->Preprint = 0;
}

STATIC VOID ClearMediaChange(_MediaChange *Change)
{
    Change->State  = MEDIA_CHANGELESS;
    Change->Buf[2] = 0;
    Change->Buf[1] = 0;
    Change->Buf[0] = 0;
    Change->Value  = 0;
    Change->Keep   = 0;
}

STATIC INT MakeChange(_MediaChange *Change, INT Value)
{
    if (Change->State == MEDIA_CHANGELESS)
    {
        if (Change->Buf[2] + 6 < Change->Buf[1] &&
            Change->Buf[1] + 6 < Change->Buf[0] &&
            Change->Buf[0] + 6 < Value)
            Change->State = MEDIA_CHANGE_RAISING;
        if (Change->Buf[2] - 6 > Change->Buf[1] &&
            Change->Buf[1] - 6 > Change->Buf[0] &&
            Change->Buf[0] - 6 > Value)
            Change->State = MEDIA_CHANGE_FALLING;
    }
    if (Change->State == MEDIA_CHANGE_RAISING)
    {
        if (Change->Buf[2] >= Change->Buf[1] &&
            Change->Buf[1] >= Change->Buf[0] &&
            Change->Buf[0] >= Value)
        {
            Change->State = MEDIA_CHANGELESS;
            Change->Value = Value;
        }
    }
    if (Change->State == MEDIA_CHANGE_FALLING)
    {
        if (Change->Buf[2] <= Change->Buf[1] &&
            Change->Buf[1] <= Change->Buf[0] &&
            Change->Buf[0] <= Value)
        {
            Change->State = MEDIA_CHANGELESS;
            Change->Value = Value;
        }
    }
    Change->Buf[2] = Change->Buf[1];
    Change->Buf[1] = Change->Buf[0];
    Change->Buf[0] = Value;
    return Change->Value;
}

/******************************************************************************
 *
 * Function:
 *        CalibrationProgram
 *
 * Description: 
 *
 * Input:
 *
 * Output:
 *        Boolean type represents true or false
 *
 ******************************************************************************/
 #define CAL_DLY_TIME 76800 // ch_20220717
 #define CAL_DLY_INC_TIME 32000 // ch_20220717
 
 #define Calibration_Debug 
 #undef Calibration_Debug
 #if defined(Calibration_Debug) 
char ii[2][3000];
WORD ii2[3000];
int ii3[3000];
int ii4[3000];
int ii5[3000];
int ii6[3000];
int ii_index[7]={0,0,0,0,0,0,0};
#endif

WORD calResult[100] = {0}; // ch_20220311
int calResultIndex = 0; // ch_20220311

/*这段代码看起来是一个用于传感器校准的程序,其中涉及到了对传感器进行读取和处理的过程。程序主要包括了以下功能:

通过对传感器信号进行采样和滤波,获取传感器反射或透射数据。

对传感器反射或透射数据进行分析和处理,计算出纸张和间隙的尺寸。

根据传感器模式(透射或反射)、自动检测类型以及其他条件,选择合适的传感器工作模式和参数。

对校准结果进行调整,并设置检测类型、尺寸和其他相关参数。

最后将校准结果保存到相应的数据结构中,并完成校准过程。

*/
STATIC VOID CalibrationProgram(_CalResult *CalResult)
{
    _PrintCfg *CalCfg = GrabPrintConfig();                                             //1.获取打印机的配置信息
    _CalSensor Sensor[] = {                                                            //2.设置需要校准的传感器信息,包括传感器类型、量程、AD值以及位置信息
        {  GAP_SENSOR,   GAP_SENSOR_SCALE,   GAP_SENSOR_AD, {256, 128}},
        {BLINE_SENSOR, BLINE_SENSOR_SCALE, BLINE_SENSOR_AD, {256, 128}}
    };
    INT Mode = CAL_TRANSMISSIVE;                                                      //3.设置校准模式为透射模式,设置预设纸张和间隙位置,设置循环次数和步进值
    INT PrePaper    = CalResult->PrePaper * MOTOR_STEP_RATE;
    INT PreGapBline = CalResult->PreGapBline * MOTOR_STEP_RATE;
    INT Times = 2;
    INT Step = 1;

    INT PaperResult, GapBlineResult, RefResult;                                        //4.进行校准过程,包括获取当前强度和灵敏度值,计算传感器信号和位置,并判断当前结果是否有效
    INT Inten, Sens;
    INT Signal, Position, i;
    BOOL Valid, Invalid;
    WORD Value;
    FLOAT fTmp1 = 0.0; // ch_20220112
UCHAR MaxCalTimes = 0; // ch_20220715                                                  //5.记录每次校准结果,并更新最大校准次数

WORD ad[6000] = {0}; // ch_20220315
int ad_index = 0; // ch_20220315    
UCHAR ad_times = 2; // ch_20220316
UCHAR ad_deinit_times = 0; // ch_20220316
ULONG DlyTime4Cal = CAL_DLY_TIME + CAL_DLY_INC_TIME*(GetContinuousCalTimes()-1); // ch_20220721   //6.最后,通过延时等待的方式,等待校准完成,并记录校准时间

#if defined(CARRIAGE_OPEN_MODEL)                                                   //7.检测机器有没有开盖,开盖就停止校准
    // stop when the carriage open
    if (IsCarriageOpen() && CalCfg->CarriageOpen)
        return;
#endif

//ADCInit4Cal(); // ch_20220305
sysprintf("Reg_ADC_Clk = %x\n", inp32(REG_CLKDIV3)); // ch_20220305      ?

    // trigger the protection circuit
    Trigger74123();                                                              //8.出发保护电路,函数没实现

    // open the stepper motor power
    SetStepMotorCurrent(CURRENT_100);                                            //9.设置步进电机电流等级
    DelayTime(3000000);
//根据一些条件进行传感器和色带的控制和设置/
#if defined(RIBBON_MODEL)              //色带模式  判断 CalResult->Ribbon 是否为真,满足条件则调用 RibbonControl() 函数控制色带,
                                       //   并传入 CalResult->Ribbon、DCM_FORWARD 和 CalCfg->RibbonInside 作为参数。
    if (CalResult->Ribbon){             //

        RibbonControl(CalResult->Ribbon, DCM_FORWARD, CalCfg->RibbonInside);  
    }
#endif

    if (CalSensTransmissive)              //判断 CalSensTransmissive 是否为真(非零值)。满足条件则将 CalSensTransmissive 的值赋给 Sensor[CAL_TRANSMISSIVE].Sens[0]。
        Sensor[CAL_TRANSMISSIVE].Sens[0] = CalSensTransmissive;
    if (CalSensReflective)
        Sensor[CAL_REFLECTIVE].Sens[0] = CalSensReflective;
//根据传感器模式判断 Mode 的值。如果 CalResult->SensorMode 的值等于 BLINE_MODE 或 CONTINUE_MODE_R,则将 CAL_REFLECTIVE 赋给 Mode
    if (CalResult->SensorMode == BLINE_MODE || CalResult->SensorMode == CONTINUE_MODE_R)   
        Mode = CAL_REFLECTIVE;
//通过一系列条件判断,确定 Times 的值。首先判断是否禁用自动检测类型且传感器模式为 CAL_TRANSMISSIVE 且存在 CalSensTransmissive 值。或者判断是否禁用自动检测类型且传感器模式为
//    CAL_REFLECTIVE 且存在 CalSensReflective 值。或者判断是否启用了自动检测类型且同时存在 CalSensTransmissive 和 CalSensReflective 值。如果满足任意一个条件,则将 Times 的值设置为 1
    if ((!CalResult->AutoDetectType && Mode == CAL_TRANSMISSIVE && CalSensTransmissive) ||
        (!CalResult->AutoDetectType && Mode == CAL_REFLECTIVE && CalSensReflective) ||
        (CalResult->AutoDetectType && CalSensTransmissive && CalSensReflective))
        Times = 1;

    for (Sens = 0; Sens < Times; Sens++)   ///for_1
    {
        // initial variable    对一些数据结构进行了初始化和清除操作
        for (Inten = 0; Inten < MAX_SENSOR_SCALE; Inten++)    //MAX_SENSOR_SCALE=16    ///for_2
        {
            ClearAnalogMedia(&CalMedia[0][Inten]);
            ClearAnalogMedia(&CalMedia[1][Inten]);
            ClearMediaChange(&CalChange[0][Inten]);
            ClearMediaChange(&CalChange[1][Inten]);
            ClearCalibrationRecord(&CalRecord[0][Inten][Sens]);
            ClearCalibrationRecord(&CalRecord[1][Inten][Sens]);

#ifdef DEBUG_PRNT
GetHereCnt[0]++; // ch_20211213            
#endif
        }    ///for_2

        while (1)     while
        {
            if (CalResult->AutoDetectType)
            {
                Mode = (Mode == CAL_TRANSMISSIVE) ? CAL_REFLECTIVE : CAL_TRANSMISSIVE;
//sysprintf("Mode = %d\n", Mode); // ch_20211213    循环进来执行
                Step = 2;
            }

#if defined(CARRIAGE_OPEN_MODEL)
            // stop when the carriage open
            if (IsCarriageOpen() && CalCfg->CarriageOpen)    //开盖停止
                break;
#endif
//    sysprintf("Motor_1\n");
            // stepper motor forward                       //步进电机正转
            MotorPhaseChange(MOTOR_FORWARD);

            EnableSensor(Sensor[Mode].Type, Sensor[Mode].Scale - 1, CalResult->Ribbon, 0);     //使能传感器
            DelayTime(8000);

                       //debug_printf("%s_Scale:%d\n", __FUNCTION__,Sensor[Mode].Scale);
            //在循环中,通过改变传感器的强度,读取传感器的值,并进行一系列的处理和判断来确定传感器的位置和尺寸
            for (Inten = Sensor[Mode].Scale - 1; Inten > 0; Inten--) //Mode =1时,Inten值为(1-3),Mode =0时,Inten值为(1-15),
            {     //根据传感器的模式和强度设置,获取当前强度对应的校准变化和校准介质。                         for_3
                _MediaChange *Change = &CalChange[Mode][Inten];
                _AnalogMedia *Media = &CalMedia[Mode][Inten];
                _CalRecord *Rec = &CalRecord[Mode][Inten][Sens];                

//    sysprintf("S%d\t%d\t", Mode, Inten);
       //启用传感器,并延时一段时间,然后开始进行AD转换并读取转换结果
                EnableSensor(Sensor[Mode].Type, Inten, CalResult->Ribbon, 0);
#if defined(TTP2410M_MACH) || defined(TTP286M_MACH)
                DelayTime(38400 / Sensor[Mode].Scale);
#else

#if ORIGIN_STEP_MOTOR_DRIVE
                DelayTime(/*76800*/DlyTime4Cal / Sensor[Mode].Scale); // ch_20220717
#endif
#endif
                              //debug_printf("%s:%d\n", __FUNCTION__,Sensor[Mode].ADChanel);
                StartADConvert(Sensor[Mode].ADChanel); // ch_2022035
                DelayTime(1000); // ch_20220717
                Value = ReadAD(Sensor[Mode].ADChanel);
                
//        sysprintf("V%d\t", Value);
//sysprintf("%d\t%d\n", Mode, Sensor[Mode].ADChanel);
            //对读取的结果进行滤波处理,然后根据是否开启自动参考值校准进行参考值的设定。
                AnalogMediaFilter(Media, Value);
                if (!CalCfg->AutoSensorRef)         //连续纸和间隙纸定标都不进来执行
                {
                    INT Up    = Media->UpFilter.Avg;              //
                    INT Down  = Media->DownFilter.Avg;            //
                    INT Point = MakeChange(Change, Value);       //
                    INT Phase = TRUE;                            //
                    INT Ref   = 0;                               //
//    sysprintf("AutoSR..\n");                
#if defined(BLINE_LEVEL_DOWN)
                    if (Sensor[Mode].Type == BLINE_SENSOR)        //
                        Phase = FALSE;
#endif
                    if (CalResult->SensorMode == GAP_MODE && GetGapSensorReverse())   //
                        Phase = !Phase;

                    if (Phase)
                    {
                        if (Point < Up - Sensor[Mode].Sens[Sens])                    //
                        {
                            if (Change->Keep < Point || Change->Keep == 0)            //
                                Change->Keep = Point;
                        }
                        Down = Change->Keep;
                    }
                    else
                    {
                        if (Point > Down + Sensor[Mode].Sens[Sens])                  //
                        {
                            if (Change->Keep > Point || Change->Keep == 0)            //
                                Change->Keep = Point;
                        }
                        Up = Change->Keep;
                    }
                    if (Change->Keep != 0)
                        Ref = GetSensorRef(Sensor[Mode].Type, Up, Down);
                    if (Ref)
                        EnableSensor(Sensor[Mode].Type, Inten, CalResult->Ribbon, Ref);  //
                }
sysprintf("c:%d,L:%d,T:%d\n",Rec->Conv,Rec->Limit,Rec->Total); 
//通过打印数据得出连续纸定标时Rec->Preprint一直为0;Rec->Conv一直为0(后边偶尔等于1),Rec->Paper一直为0,Rec->Limit值为2032循环减2直到为0又从2032开始循环减2
//Rec->Total值为4064循环减2直到Rec->Limit为0时又从4064开始循环减2
                if (Rec->Preprint < MAX(PreprintLength, PrePaper + PreGapBline))            //若预印长度小于预设值, 即预打印长度还未达到最大值,则继续增加。
                {
#ifdef DEBUG_PRNT                
GetHereCnt[1]++; // ch_20211213                
#endif
    //    sysprintf("AutoSR..11\n");       //间隙纸和连续纸定标没进来执行
                    Rec->Preprint += Step;
                    continue;
                }

                // is terminate         如果不满足终止条件,则继续进行下一次循环    在终止条件中,会判断校准记录的总数、限制数、和Conv(状态)是否满足特定条件。                
                                       //如果满足,则继续进行下一次循环。否则,将跳过下一次循环。在每一次循环中,还有其他一些判断条件和计算,用于确定校准记录的大小和位置。
                if (Rec->Total <= 0 || Rec->Limit <= 0 || Rec->Conv == 4)
{
#ifdef DEBUG_PRNT
GetHereCnt[2]++; // ch_20211213
#endif
//    sysprintf("AutoSR..22\n");   //间隙纸定标偶尔进来执行
                    continue;
}                    
             
                Rec->Total -= Step;
                Rec->Limit -= Step;

                // FIXME: caused size miscalculation
                if (Media->UpFilter.Avg < Media->DownFilter.Avg + Sensor[Mode].Sens[Sens])
{
#ifdef DEBUG_PRNT
GetHereCnt[3]++; // ch_20211213
#endif
    //sysprintf("AutoSR..33\n");    //连续纸和间隙纸定标都进来执行
                    continue;
}                    
            //如果是间隙传感器且预印长度不为0,则判断是否满足预印长度范围要求。
                if (Sensor[Mode].Type == GAP_SENSOR && PreprintLength)
                {
                    _AnalogMedia *MediaMax = &CalMedia[Mode][Sensor[Mode].Scale - 1];
    //sysprintf("AutoSR..44\n");    //连续纸和间隙纸定标都不进来执行                
#if defined(GAP_LEVEL_UP)
                    if (Media->UpFilter.Avg > MediaMax->UpFilter.Avg - 80)
{
#ifdef DEBUG_PRNT
GetHereCnt[4]++; // ch_20211213
#endif
                        continue;
}                        
#else
                    if (Media->DownFilter.Avg < MediaMax->DownFilter.Avg + 40)
{

                        continue;
}                        
#endif
                }
            //根据传感器类型和校准结果计算信号位置。
                if (Sensor[Mode].Type == GAP_SENSOR)
//                    Signal = GapSensorSignal(Media); // ch_20220720
                    Signal = GapSensorSignal4Cal(Media); // ch_20220720
                else
//                    Signal = BlineSensorSignal(Media); // ch_20220604
                    Signal = BlineSensorSignal4Cal(Media); // ch_20220604
//                Position = GetSensorPosition(Sensor[Mode].Type, Signal); // ch_20220706
                Position = GetSensorPosition4Cal(Sensor[Mode].Type, Signal); // ch_20220706    

                // Conv Gap -> Paper -> Gap -> Paper
    
                if ((Rec->Conv == 0 && Position == POSITION_ON_GAP_BLINE) ||
                    (Rec->Conv == 1 && Position == POSITION_ON_PAPER)     ||
                    (Rec->Conv == 2 && Position == POSITION_ON_GAP_BLINE) ||
                    (Rec->Conv == 3 && Position == POSITION_ON_PAPER))
                {
#ifdef DEBUG_PRNT                
GetHereCnt[6]++; // ch_20211213
#endif
    //sysprintf("AutoSR..55\n");  //间隙纸定标进来执行
                       // SendPrintf("\r\nC%d,%d,%d,%d,%d",Inten,Rec->Conv,2032-Rec->Limit,Rec->Paper,Rec->GapBline);
                    if (Rec->ConvCnt++ >= 2)    // cross-check
                    {
#ifdef DEBUG_PRNT                    
GetHereCnt[7]++; // ch_20211213                    
#endif
                        Rec->ConvCnt = 0;
                        Rec->Conv += 1;            // sensor state change
                        Rec->Limit = CalCfg->LimitFeed * MOTOR_STEP_RATE;
                    }
                }
                else
                    Rec->ConvCnt = 0;

                // calculate size
                if (Rec->Conv == 2) Rec->Paper += Step;        // in Paper
                if (Rec->Conv == 3) Rec->GapBline += Step;    // in Gap or Bline

                if (Rec->Conv == 4)
                {
#if ORIGIN_STEP_MOTOR_DRIVE
                    CONST STATIC INT PaperMin    = ((INT)MM_DOT * 2) * MOTOR_STEP_RATE;
                    CONST STATIC INT GapBlineMin = MM_DOT * MOTOR_STEP_RATE;
                    CONST STATIC INT GapBlineMax = ((INT)MM_DOT * 40) * MOTOR_STEP_RATE;
#endif
//sysprintf("AutoSR..66\n");   //间隙纸定标进来执行
#if NEW_STEP_MOTOR_DRIVE
#if FULL_STEP_FULL_CURRENT                
                    CONST STATIC INT PaperMin    = ((INT)MM_DOT * 2) * MOTOR_STEP_RATE;
                    CONST STATIC INT GapBlineMin = MM_DOT * MOTOR_STEP_RATE;
          CONST STATIC INT GapBlineMax = ((INT)MM_DOT * 40) * MOTOR_STEP_RATE;
#elif HALF_STEP_FULL_CURRENT
                    CONST STATIC INT PaperMin    = (INT)(MM_DOT * 2 * MOTOR_STEP_RATE / 2);
                    CONST STATIC INT GapBlineMin = (INT)(MM_DOT * MOTOR_STEP_RATE / 2);
                    CONST STATIC INT GapBlineMax = (INT)(MM_DOT * 40 * MOTOR_STEP_RATE / 2);
#elif HALF_STEP_PART_CURRENT
                    CONST STATIC INT PaperMin    = (INT)(MM_DOT * 2 * MOTOR_STEP_RATE / 2);
                    CONST STATIC INT GapBlineMin = (INT)(MM_DOT * MOTOR_STEP_RATE / 2);
          CONST STATIC INT GapBlineMax = (INT)(MM_DOT * 40 * MOTOR_STEP_RATE / 2);
#endif

#endif

                    // check size error    计算尺寸并进行错误校验
                    if (Rec->Paper < PaperMin || Rec->GapBline < GapBlineMin || Rec->GapBline>GapBlineMax)
                    {
#ifdef DEBUG_PRNT                    
GetHereCnt[8]++; // ch_20211213
#endif
            sysprintf("AutoSR..66..1\n");         //间隙纸定标不执行    
                        // afresh
                        Rec->Conv     = 0;
                        Rec->ConvCnt  = 0;
                        Rec->Paper    = 0;
                        Rec->GapBline = 0;
                    }

                    else if (PrePaper && PreGapBline)  //如果之前的预印长度和预间隙/基线长度都不为0,且当前结果与之前结果差异过大,则将限制次数设为0,表示无用。
                    {
                        INT MissPaper = (PrePaper / 4) + PaperMin;
                        INT MissGapBline = (PreGapBline / 4) + GapBlineMin;
sysprintf("AutoSR..66..2\n"); 
                        if (abs(PrePaper - Rec->Paper) > MissPaper ||
                            abs(PreGapBline - Rec->GapBline) > MissGapBline)
                            Rec->Limit = 0;    // useless
                    }
                }
            }//for_3

            DisableSensor(Sensor[Mode].Type);

DelayTime(1000); // ch_20220717

            Inten = 0;
            for (i = Sensor[Mode].Scale - 1; i > 0; i--)
            {
                _AnalogMedia *Media = &CalMedia[Mode][i];
                _CalRecord *Rec = &CalRecord[Mode][i][Sens];
//sysprintf("AutoSR..77\n");    //连续纸和间隙纸都进来执行
                if (IsAnalogMediaReady(Media, Sensor[Mode].Sens[Sens]) && Rec->Limit > 0)
                {
                    _AnalogMedia *Expect = &CalMedia[Mode][Inten];
                    if (Expect->UpFilter.Avg - Expect->DownFilter.Avg + 32
                        < Media->UpFilter.Avg - Media->DownFilter.Avg)
                        Inten = i;
                }
            }

            if (Sensor[Mode].Type == GAP_SENSOR && PreprintLength)
            {
                _AnalogMedia *MediaMax = &CalMedia[Mode][Sensor[Mode].Scale - 1];
//sysprintf("AutoSR..88\n");  //连续纸和间隙纸都不进来执行
                for (i = 1; i < Sensor[Mode].Scale - 1; i++)
                {
                    _AnalogMedia *Media = &CalMedia[Mode][i];
#if defined(GAP_LEVEL_UP)
                    if (Media->UpFilter.Avg > MediaMax->UpFilter.Avg - 80)
                        break;
#else
                    if (Media->DownFilter.Avg < MediaMax->DownFilter.Avg + 40)
                        break;
#endif
                    Inten = i;
                }
            }

            if (CalResult->AutoDetectType && Mode == CAL_TRANSMISSIVE &&
                CalRecord[Mode][Inten][Sens].Paper < CalRecord[Mode][Inten][Sens].GapBline)
{
#ifdef DEBUG_PRNT
GetHereCnt[9]++; // ch_20211213
#endif
    sysprintf("AutoSR..88..1\n");     //间隙纸定标进来执行(在定标不到位置的情况下进来执行)//
                continue;
}                

            Valid = FALSE;
            Invalid = TRUE;
            for (i = Sensor[Mode].Scale - 1; i > 0; i--)
            {
                _CalRecord *Rec = &CalRecord[Mode][i][Sens];
//sysprintf("AutoSR..99\n");  //连续纸和间隙纸定标都进来执行
                if (Rec->Conv == 4 && Rec->Limit > 0)
                {
            //   sysprintf("AutoSR..99..1\n");//间隙纸定标最后进来执行3次就跳出循环结束定标    
                    if (i == Inten)
                    {
                //        sysprintf("AutoSR..99..22\n");   //间隙纸打印最后进来执行        
                        PaperResult = Rec->Paper;
                        GapBlineResult = Rec->GapBline;
                        RefResult = CalMedia[Mode][Inten].Ref;
                        Valid = TRUE;
                    }
                }
                if (Rec->Conv != 4 && Rec->Limit > 0)
                    Invalid = FALSE;
                else if(Rec->Limit == 0){           //lisonglong_20240109
                    PaperResult = Rec->Paper;
                    GapBlineResult = Rec->GapBline;
                    RefResult = CalMedia[Mode][Inten].Ref;
                    Valid = TRUE;
                }
            }
#ifdef DEBUG_PRNT            
GetHereCnt[10]++; // ch_20211213            
#endif

//Valid = FALSE; Invalid = FALSE; // ch_20220316

            if (Valid || Invalid)
                break;
            
            // ch_20220717
            if (!ad_deinit_times)
            {
                ad_deinit_times = 1;
//                sysprintf("Deinit once...\n");
            }
            ADCDeinit();            
            DelayTime(1000/*200*/); // ch_20220628 : changed to 100.
            ADCInit();
            DelayTime(1000/*200*/); // ch_20220628 : changed to 100.            
        }       /while

//sysprintf("ad_times = %d\n", ad_times); // ch_20220316

        if (Valid)
            break;
        
        // ch_20220628
        else {        
//            Sens = 0; // ch_20220630 : sometimes calibrating cannot stop.

            //
            // ch_20220717
            if (++MaxCalTimes > 6)
                break;
            else {

                if (Sens >= 1)
                    Sens = 0;

                if (MaxCalTimes > 3)
                    DlyTime4Cal += CAL_DLY_INC_TIME;
                else if (DlyTime4Cal > 5)
                    DlyTime4Cal += (CAL_DLY_INC_TIME<<1);
            }
            //
            
sysprintf("Deinit once...\n");                    
            ADCDeinit();
            DelayTime(500);
            ADCInit();    
            DelayTime(500);        
        }
    }///for_1

//sysprintf("%d\t%d\n", Mode, Sensor[Mode].ADChanel); // ch_20220315    
    
    // close the stepper motor power
    DelayTime(200000);
    SetStepMotorCurrent(CURRENT_OFF);

#if defined(RIBBON_MODEL)
    if (CalResult->Ribbon)
        RibbonControl(FALSE, DCM_STOP, CalCfg->RibbonInside);
#endif

#if defined(CARRIAGE_OPEN_MODEL)
    // stop when the carriage open
    if (IsCarriageOpen() && CalCfg->CarriageOpen)
        return;
#endif

    if (Valid)
    {
//sysprintf("AutoSR..1010\n");   //间隙纸最后进来执行1次
        // adjust the result of size
        if (CalResult->Ribbon)
        {        
//sysprintf("Before : CalResult->Paper = %d\t->GapBline = %d\n", PaperResult, GapBlineResult); // ch_20220310

//            PaperResult = PaperResult * 1000 / TT_ADD_PERCENT / MOTOR_STEP_RATE; // ch_20220112
            // ch_20220112
            fTmp1 = PaperResult * 1000 / TT_ADD_PERCENT / MOTOR_STEP_RATE;
            fTmp1 += 0.5;
            PaperResult = (INT)fTmp1;

//            GapBlineResult = GapBlineResult * 1000 / TT_ADD_PERCENT / MOTOR_STEP_RATE; // ch_20220112
            // ch_20220112
            fTmp1 = GapBlineResult * 1000 / TT_ADD_PERCENT / MOTOR_STEP_RATE;
            fTmp1 += 0.5;
            GapBlineResult = (INT)fTmp1;
            
//sysprintf("R_After : CalResult->PR = %d\t->GBR = %d\n", PaperResult, GapBlineResult); // ch_20220310
        }
        else
        {
//sysprintf("Before : CalResult->Paper = %d\t->GapBline = %d\n", PaperResult, GapBlineResult); // ch_20220310

//            PaperResult = PaperResult * 1000 / DT_ADD_PERCENT / MOTOR_STEP_RATE; // ch_20220112
            // ch_20220112
            fTmp1 = PaperResult * 1000 / DT_ADD_PERCENT / MOTOR_STEP_RATE;
            fTmp1 += 0.5;
            PaperResult = (INT)fTmp1;
            
//            GapBlineResult = GapBlineResult * 1000  / DT_ADD_PERCENT / MOTOR_STEP_RATE; // ch_20220112
          // ch_20220112
            fTmp1 = GapBlineResult * 1000 / DT_ADD_PERCENT / MOTOR_STEP_RATE;
            fTmp1 += 0.5;
            GapBlineResult = (INT)fTmp1;

//sysprintf("nR_After : CalResult->PR = %d\t->GBR = %d\n", PaperResult, GapBlineResult); // ch_20220310            
        }
        if (CalResult->PrePaper)
            PaperResult = CalResult->PrePaper;
        if (CalResult->PreGapBline)
            GapBlineResult = CalResult->PreGapBline;

        // set detect type
        if (CalResult->AutoDetectType)
        {
            if (Mode == CAL_TRANSMISSIVE)
                CalResult->SensorMode = GAP_MODE;
            if (Mode == CAL_REFLECTIVE)
                CalResult->SensorMode = BLINE_MODE;
        }

        // bline mode
        if (CalResult->SensorMode == BLINE_MODE)
        {
            //SIZE---BM
            CalResult->fPaperSize = PaperResult;            
            CalResult->fBlineSize = GapBlineResult;

// ch_20220306
//if ((CalResult->fBlineSize > 8) && (CalResult->fBlineSize <= 16))
//    CalResult->fBlineSize = 16;
//else if ((CalResult->fBlineSize > 16) && (CalResult->fBlineSize < 45 /*<= 30*/))
//    CalResult->fBlineSize = 24;
            
            debug_printf("G:%d,%d\n",CalResult->BlineInten,Inten);
            CalResult->BlineInten = Inten;
            CalResult->BlineRef = RefResult;
            
        }

        // gap mode
        else
        {
            //SIZE---GAP
            CalResult->SensorMode = GAP_MODE;
            CalResult->fPaperSize = PaperResult;

            CalResult->fGapSize = GapBlineResult;
            CalResult->GapInten = Inten;
            CalResult->GapRef = RefResult;
                    
        }
    }
    // continuous mode
    else if (Invalid)
    {
#ifdef DEBUG_PRNT    
sysprintf("Exec INVALID branch : CalResult->SensorMode = %d\n", CalResult->SensorMode); // ch_20211211
sysprintf("CalMedia[GAP_MODE][12].UpFilter.Avg = %d\tCalMedia[GAP_MODE][12].DownFilter.Avg = %d\n", \
        CalMedia[GAP_MODE][12].UpFilter.Avg, CalMedia[GAP_MODE][12].DownFilter.Avg);
#endif
//sysprintf("AutoSR..1111\n");
        if (CalResult->SensorMode == CONTINUE_MODE_R)
        {
//sysprintf("CR\n"); // ch_20220315    

            EnableSensor(BLINE_SENSOR, 1, CalResult->Ribbon, 0);
            DelayTime(50000);
            for (Inten = 1; Inten < BLINE_SENSOR_SCALE - 1; Inten++)
            {
                EnableSensor(BLINE_SENSOR, Inten, CalResult->Ribbon, 0);
                DelayTime(2560000 / BLINE_SENSOR_SCALE);
                StartADConvert(BLINE_SENSOR_AD);
                Value = ReadAD(BLINE_SENSOR_AD);
                //debug_printf("8");
#if defined(BLINE_LEVEL_UP)
                if (Value < BLINE_LIMIT)
{
#ifdef DEBUG_PRNT
sysprintf("%s_Value : %d\n", __FUNCTION__, Value);
#endif

                    break;
}
#elif defined(BLINE_LEVEL_DOWN)
                if (Value > BLINE_LIMIT)
                    break;
#endif
            }
            DisableSensor(BLINE_SENSOR);
    
            CalResult->SensorMode = CONTINUE_MODE_R;
            CalResult->ContinuousInten = (Inten + BLINE_SENSOR_SCALE) >> 1;
            CalResult->ContinuousRef = (Value + BLINE_LIMIT) >> 1;

//sysprintf("C%d\t%d\n", CalResult->SensorMode, Value); // ch_20211213                
        }
        else
        {
//sysprintf("CT\n"); // ch_20220315        

            EnableSensor(GAP_SENSOR, GAP_SENSOR_SCALE - 1, CalResult->Ribbon, 0);
            DelayTime(50000);
            for (Inten = GAP_SENSOR_SCALE - 1; Inten > 1; Inten--)
            {
                EnableSensor(GAP_SENSOR, Inten, CalResult->Ribbon, 0);
                DelayTime(2560000 / GAP_SENSOR_SCALE);
                StartADConvert(GAP_SENSOR_AD);
                Value = ReadAD(GAP_SENSOR_AD);

#ifdef DEBUG_PRNT                
sysprintf("CT%d\t", Value); // ch_20211213
#endif
                
//#if defined(GAP_LEVEL_UP)
//                if (Value < GAP_LIMIT)
//                    break;
//#elif defined(GAP_LEVEL_DOWN)
//                if (Value > 300/*GAP_LIMIT*/)
                if (Value >= ((CalMedia[GAP_MODE][12].UpFilter.Avg + CalMedia[GAP_MODE][12].DownFilter.Avg) >> 1))  
                    break;
//#endif
            }
            DisableSensor(GAP_SENSOR);

#ifdef DEBUG_PRNT
sysprintf("\n"); // ch_20211213            
#endif

            CalResult->SensorMode = CONTINUE_MODE_T;
#ifdef DEBUG_PRNT
sysprintf("%s_SensorMode : %d\n", __FUNCTION__, CalResult->SensorMode);            
#endif
            CalResult->ContinuousInten = 2;//(Inten + 1) >> 1; // ch_20220528 : changed to 1 from "(Inten + 1) >> 1"
#ifdef DEBUG_PRNT
sysprintf("%s_Inten = %d\tContinuousInten = %d\n", __FUNCTION__, Inten, CalResult->ContinuousInten);            
#endif
            CalResult->ContinuousRef = (Value + GAP_LIMIT) >> 1;
#ifdef DEBUG_PRNT
sysprintf("%s_ContinuousRef : %d\n", __FUNCTION__, CalResult->ContinuousRef);            
#endif

//sysprintf("C%d,%d,%d\n", CalResult->SensorMode, Value, CalResult->ContinuousInten); // ch_20211213    
        }
    }
    CalResult->DownFilterAvg = CalMedia[Mode][Inten].DownFilter.Avg; // ch_20220719
    CalResult->UpFilterAvg = CalMedia[Mode][Inten].UpFilter.Avg; // ch_20220719
    CalResult->Finish = TRUE;
    OnceCalDone = 1; // ch_20220416


    ResetGetCalMediaFlg(); // ch_20220720

#if (CALDEBUG == 1)
    SendPrintf("\r\n Paper : %d", (INT)CalResult->fPaperSize);
    SendPrintf("\t Gap : %d", (INT)CalResult->fGapSize);
    SendPrintf("\t Bline : %d", (INT)CalResult->fBlineSize);
    SendPrintf("\t Sensor : %d", (INT)CalResult->SensorMode);
    SendPrintf("\r\n Inten : %d", Inten);
    SendPrintf("\t Up : %d", CalMedia[Mode][Inten].UpFilter.Avg);
    SendPrintf("\t Down : %d", CalMedia[Mode][Inten].DownFilter.Avg);
    SendPrintf("\t Ref : %d\r\n", CalMedia[Mode][Inten].Ref);
#endif
}

#else

/******************************************************************************
 *
 * Function:
 *        CalibrationProgram
 *
 * Description: 
 *
 * Input:
 *
 * Output:
 *        Boolean type represents true or false
 *
 ******************************************************************************/
STATIC VOID CalibrationProgram(_CalResult *CalResult)
{
    _PrintCfg *CalCfg = GrabPrintConfig();
    INT Min[4] = { MAX_SENSOR_SCALE, MAX_SENSOR_SCALE, MAX_SENSOR_SCALE, MAX_SENSOR_SCALE };
    INT Max[4] = { 0, 0, 0, 0 };
    INT Statistic[MAX_SENSOR_SCALE], Most;
    INT Up, Down, Intension;
    INT Conv, ConvCnt, Limit, Fluc;
    INT Paper, GapBline;
    INT Signal, Position;
    INT i;

#if defined(CARRIAGE_OPEN_MODEL)
    if (IsCarriageOpen() && CalCfg->CarriageOpen)
        return;
#endif

    Trigger74123();

    // Start Step Motor
    SetStepMotorCurrent(CURRENT_100);

#if defined(TTP243PP_PCB)
    DelayTime(3000000);
#else
    DelayTime(1500000);
#endif

#if defined(RIBBON_MODEL)
    if (CalResult->Ribbon){

        RibbonControl(CalResult->Ribbon, DCM_FORWARD, CalCfg->RibbonInside);
    }
#endif

    memset(Statistic, 0, sizeof(Statistic));

    Limit    = CalCfg->LimitFeed * MOTOR_STEP_RATE;
    Conv     = 0;
    ConvCnt  = 0;
    Paper    = 0;
    GapBline = 0;
    Fluc     = 0;

    while (1)
    {
#if defined(CARRIAGE_OPEN_MODEL)
        if (IsCarriageOpen() && CalCfg->CarriageOpen)
            break;
#endif                
        MotorPhaseChange(MOTOR_FORWARD);
            Up = MAX_SENSOR_SCALE;
        Down = 0;
        Intension = MAX_SENSOR_SCALE >> 1;    // MAX_SENSOR_SCALE * 0.5

        while (Up-Down > 1)
        {
            if (CalResult->SensorMode == BLINE_MODE)
            {

                EnableSensor(BLINE_SENSOR, 0, CalResult->Ribbon, 0);
                DelayTime(600);
                EnableSensor(BLINE_SENSOR, Intension, CalResult->Ribbon, HALF_AD_SCALE);
                DelayTime(1500);
                if (GetSensorSignal(BLINE_SENSOR) == SENSOR_DETECTED)    // if reflection
                    Up = Intension;
                else
                    Down = Intension;
            }
            else
            {
                EnableSensor(GAP_SENSOR, Intension, CalResult->Ribbon, HALF_AD_SCALE);
                DelayTime(1600);
                if (GetSensorSignal(GAP_SENSOR) == SENSOR_DETECTED)    // if through
                    Up = Intension;
                else
                    Down = Intension;
            }
            Intension = (Up + Down) >> 1;
        }

        Statistic[Intension] += 1;
        Most = 0;
        for (i = 0; i < MAX_SENSOR_SCALE; i++)
        {
            if (Statistic[Most] < Statistic[i])
                Most = i;
        }

#if defined(RIBBON_MODEL)
        // in case of Notch tag without ribbon
        if (CalResult->SensorMode == BLINE_MODE && Intension == 0 && !CalResult->Ribbon)
            Intension = MAX_SENSOR_SCALE;
#endif                
        for (i = 0; i < 4; i++)
        {
            if (Intension > Max[i] || Max[i] == 0)
            {
                Max[i] = Intension;
                break;
            }
            if (Max[2] == Max[3])
            {
                Max[0] = Max[1];
                Max[1] = Max[2];
                Max[2] = Max[3];
                Max[3] = Intension;
            }

            if (Intension < Min[i] || Min[i] == MAX_SENSOR_SCALE)
            {
                Min[i] = Intension;
                break;
            }
            if (Min[2] == Min[3])
            {
                Min[0] = Min[1];
                Min[1] = Min[2];
                Min[2] = Min[3];
                Min[3] = Intension;
            }
        }

        Up = (Max[1] + Max[2]) >> 1;
        Down = (Min[1] + Min[2]) >> 1;
        if (Up == MAX_SENSOR_SCALE) Up -= 1;
        if (Down < 5) Down += 1;

        if (Up > Down + (Down>>3) &&  Max[3] != 0 && Min[3] != MAX_SENSOR_SCALE)
        {            
            if (CalResult->SensorMode == BLINE_MODE)
            {
            //    Intension = (Up + Down + Fluc) >> 1;    //            //    i = (Down << 1) + (Down >> 1);            // Down*2.5
            //    if (Intension > i) Intension = i;
                if (Up - Down > 10)
                    Intension = Down + 8;
                else if (Up - Down > 5)
                    Intension = Up - 3;
                else
                    Intension = (Up + Down + Fluc) >> 1;    //
                EnableSensor(BLINE_SENSOR, Intension, CalResult->Ribbon, HALF_AD_SCALE);
                DelayTime(3000);
            }
            else
            {
                if (Up > Most && Most > Down)
                    Up = Most;

                Intension = (Up + Down + Fluc) >> 1;    //
                EnableSensor(GAP_SENSOR, Intension, CalResult->Ribbon, HALF_AD_SCALE);
                DelayTime(3000);
            }
                        //             if (CalResult->SensorMode == BLINE_MODE)
            {
                Signal = GetSensorSignal(BLINE_SENSOR);
                Position = GetSensorPosition(BLINE_SENSOR, Signal);
                if ((Conv == 0 && Position == POSITION_ON_GAP_BLINE) ||    // Conv=0 ?? BLine                     (Conv == 1 && Position == POSITION_ON_PAPER)     ||    // Conv=1 ?? Paper                     (Conv == 2 && Position == POSITION_ON_GAP_BLINE) ||    // Conv=2 ?? BLine                     (Conv == 3 && Position == POSITION_ON_PAPER))        // Conv=3 ?? Paper                 {
                    if (ConvCnt++ == 4)    //                     {
                        ConvCnt = 0;
                        Conv += 1;        // Sensor                         Limit = CalCfg->LimitFeed * MOTOR_STEP_RATE;
                    }
                }
                else
                    ConvCnt = 0;
            }
            else
            {
                Signal = GetSensorSignal(GAP_SENSOR);
                Position = GetSensorPosition(GAP_SENSOR, Signal);
                if ((Conv == 0 && Position == POSITION_ON_GAP_BLINE) ||    //                        (Conv == 1 && Position == POSITION_ON_PAPER)     ||    //                      (Conv == 2 && Position == POSITION_ON_GAP_BLINE) ||    //                        (Conv == 3 && Position == POSITION_ON_PAPER))        //                  {
                    if (ConvCnt++ == 2)    //                     {
                        ConvCnt = 0;
                        Conv += 1;        // Sensor                         Limit = CalCfg->LimitFeed * MOTOR_STEP_RATE;
                    }
                }
                else
                    ConvCnt = 0;
            }
        }
        else
        {
            DelayTime(3000);
        }
                if (Conv == 2) Paper++;        // Conv=2 in Paper
        if (Conv == 3) GapBline++;    // Conv=3 in GAP, Bline

        /* --- Continuous or Empty Paper --- */
        if (--Limit == 0)
        {                        if (Fluc == 0  && Up == Down + 1)
            {
                Limit = CalCfg->LimitFeed * MOTOR_STEP_RATE;
                Conv = 0;
                ConvCnt = 0;
                Paper = 0;
                GapBline = 0;
                Fluc ^= 0x1;    //            }
            else
                break;
        }

        /* --- Gap or Bline Paper --- */
        if (Conv == 4)
        {                        if (Paper < ((INT)MM_DOT << 1) || GapBline < MM_DOT)
            {
                Conv = 0;
                ConvCnt = 0;
                Paper = 0;
                GapBline = 0;
                Fluc ^= 0x1;    //            }
            else
                break;
        }
    }

    if (CalResult->SensorMode == BLINE_MODE)
        DisableSensor(BLINE_SENSOR);
    else
        DisableSensor(GAP_SENSOR);

#if defined(TTP243PP_PCB)
    DelayTime(200000);
#else
    DelayTime(100000);
#endif

    // Close Step Motor
    SetStepMotorCurrent(CURRENT_OFF);

#if defined(RIBBON_MODEL)
    if (CalResult->Ribbon){
        RibbonControl(FALSE, DCM_STOP, CalCfg->RibbonInside);
    }
#endif

#if defined(CARRIAGE_OPEN_MODEL)
    /* */
    if (IsCarriageOpen() && CalCfg->CarriageOpen)
        return;
#endif

    if (CalResult->Ribbon)
    {
        Paper = Paper * 1000 / TT_ADD_PERCENT / MOTOR_STEP_RATE;
        GapBline = GapBline * 1000 / TT_ADD_PERCENT / MOTOR_STEP_RATE;
    }
    else
    {
        Paper = Paper * 1000 / DT_ADD_PERCENT / MOTOR_STEP_RATE;
        GapBline = GapBline * 1000  / DT_ADD_PERCENT / MOTOR_STEP_RATE;
    }

    if (Limit > 0)
    {
        if (CalResult->SensorMode == BLINE_MODE)    // BLine         {
            CalResult->fPaperSize = Paper;
            CalResult->fBlineSize = GapBline;
            CalResult->BlineInten = Intension;
        }
        else    // Gap         {
            i = 6 + ((Up * ((INT)MM_DOT - 1)) >> 6);
            CalResult->SensorMode = GAP_MODE;
            CalResult->fPaperSize = Paper + i;
            CalResult->fGapSize = GapBline - i;
            CalResult->GapInten = Intension;
        }
    }
    else    //    {
        CalResult->SensorMode = CONTINUE_MODE_T;
        CalResult->ContinuousInten = (Up + 2) >> 1;    //    }
    CalResult->Finish = TRUE;

#if (CALDEBUG == 1)
    SendPrintf("\r\n Paper : %d", (INT)CalResult->fPaperSize);
    SendPrintf("\t Gap : %d", (INT)CalResult->fGapSize);
    SendPrintf("\t Bline : %d", (INT)CalResult->fBlineSize);
    SendPrintf("\r\n Up : %d", Up);
    SendPrintf("\t Intension : %d", Intension);
    SendPrintf("\t Down : %d", Down);
#endif
}

#endif

STATIC TASK(ExecuteCalibration, arg)
{
    CalibrationProgram((_CalResult *)arg);
    CalibrationEnd = TRUE;
    ResetTaskStatus(); // ch_20220428
    TaskExit();
}

// /*  这段代码是一个标定过程的函数实现,它接收一个_WorkJob结构体指针和一个BOOL类型的参数SetSize作为输入 判断标定过程的状态。
//在函数开始时,定义了一个静态变量state并初始化为FALSE,以及一个整型变量imask。
//如果state为TRUE,则表示正在进行标定过程,进入if语句块。在if语句块中,首先判断标定是否结束,然后判断标定结果是否完成。
//如果标定结果已完成,则从GrabPrintConfig()函数获取_PrintCfg结构体指针CalCfg,并将CalResult中的一些值赋给WorkJob中相应的成员变量。
//接着根据WorkJob的类型是否为CAL_JOB或SetSize是否为TRUE,更新CalCfg中的一些成员变量,并重新分配图像缓冲区。最后根据WorkJob的SensorMode选择相应的传感器模式,并设置传感器的参数。

//如果标定结果未完成,则state保持为TRUE。

//如果state为FALSE,则表示标定过程尚未开始,进入else语句块。在else语句块中,将WorkJob中的一些成员变量赋给CalResult中相应的成员变量,
//并将CalibrationEnd和AutoDetectType设置为FALSE和TRUE。然后创建一个新的任务ExecuteCalibration,并将CalResult作为参数传递给该任务。

//最后,函数返回state的值。

//总体来说,这段代码实现了标定过程的逻辑,根据状态进行相应的操作,并提供了一些接口用于获取和设置标定结果。  */
///

BOOL CalibrationProcess(_WorkJob *WorkJob, BOOL SetSize)     //  <--WorkJobProcess()
{
    STATIC BOOL state = FALSE;
    INT imask; // ch_20220409

    if (state)    //正在标定
    {
        if (CalibrationEnd)     //判断标定是否结束
        {
            if (CalResult.Finish) //标定结果是否完成
            {
                _PrintCfg *CalCfg = GrabPrintConfig();

//sysprintf("CalibrationEnd.\n"); // ch_20220409                

                WorkJob->GapInten        = CalResult.GapInten;
                debug_printf("I:%d,%d",WorkJob->BlineInten,CalResult.BlineInten);
                WorkJob->BlineInten      = CalResult.BlineInten;
                WorkJob->ContinuousInten = CalResult.ContinuousInten;
                WorkJob->GapRef          = CalResult.GapRef;
                WorkJob->BlineRef        = CalResult.BlineRef;
                WorkJob->ContinuousRef   = CalResult.ContinuousRef;

                if (WorkJob->AutoSensorRef)
                    WorkJob->GapRef = WorkJob->BlineRef = 0;

                if (WorkJob->Type == CAL_JOB || SetSize)
                {
                    CalCfg->SensorMode = WorkJob->SensorMode = CalResult.SensorMode;
                    CalCfg->fPaperSize = WorkJob->fPaperSize = CalResult.fPaperSize;
                    CalCfg->fGapSize   = WorkJob->fGapSize   = CalResult.fGapSize;
                    CalCfg->fBlineSize = WorkJob->fBlineSize = CalResult.fBlineSize;

                    WorkJob->fLabelSize = WorkJob->fPaperSize;
                    if  (WorkJob->SensorMode == GAP_MODE)
                        WorkJob->fLabelSize += WorkJob->fGapSize;
                    else if (WorkJob->SensorMode == BLINE_MODE)
                        WorkJob->fLabelSize += WorkJob->fBlineSize;

                    if (WorkJob->Type != CAL_JOB)    // FIXME: unsafe reallocate image buffer
                        ReallocImageBuffer(&sImageBuffer, (WORD)WorkJob->fLabelSize);

                    CalResult.SetSize = SetSize;
                }

                if (WorkJob->SensorMode == CalResult.SensorMode)
                {
                    if (WorkJob->SensorMode == GAP_MODE)
                    {
                        CalCfg->GapInten = WorkJob->GapInten;
                        CalCfg->GapRef   = WorkJob->GapRef;
                        EnableSensor(GAP_SENSOR, WorkJob->GapInten, WorkJob->Ribbon, WorkJob->GapRef);
                    }
                    else if (WorkJob->SensorMode == BLINE_MODE)
                    {
                        CalCfg->BlineInten = WorkJob->BlineInten;
                        CalCfg->BlineRef   = WorkJob->BlineRef;
                        EnableSensor(BLINE_SENSOR, WorkJob->BlineInten, WorkJob->Ribbon, WorkJob->BlineRef);
                    }
                    else if (WorkJob->SensorMode == CONTINUE_MODE_R)
                    {
                        CalCfg->ContinuousInten = WorkJob->ContinuousInten;
                        CalCfg->ContinuousRef   = WorkJob->ContinuousRef;
                        EnableSensor(BLINE_SENSOR, WorkJob->ContinuousInten, WorkJob->Ribbon, WorkJob->ContinuousRef);
                    }
                    else
                    {
                        CalCfg->ContinuousInten = WorkJob->ContinuousInten;
                        CalCfg->ContinuousRef   = WorkJob->ContinuousRef;
                        EnableSensor(GAP_SENSOR, WorkJob->ContinuousInten, WorkJob->Ribbon, WorkJob->ContinuousRef);
                    }                    
                }    
                //
                // ch_20220409
//                imask = DisableInterrupt(INTERRUPT_MASK);
//                SaveVarBank();
//                EnableInterrupt(imask);
                //
            }
            state = FALSE;
        }
    }
    else      //定标尚未开始
    {
#ifdef DEBUG_PRNT
sysprintf("Enter CalibrationProcess() ELSE branch...\n"); // ch_20211211
#endif

        CalResult.SensorMode      = WorkJob->SensorMode;
        CalResult.GapInten        = WorkJob->GapInten;             //间隙辉度
        debug_printf("J:%d,%d",CalResult.BlineInten,WorkJob->BlineInten);
        CalResult.BlineInten      = WorkJob->BlineInten;          //
        CalResult.ContinuousInten = WorkJob->ContinuousInten;
        CalResult.GapRef          = WorkJob->GapRef;
        CalResult.BlineRef        = WorkJob->BlineRef;
        CalResult.ContinuousRef   = WorkJob->ContinuousRef;
        CalResult.fPaperSize      = WorkJob->fPaperSize;
        CalResult.fGapSize        = WorkJob->fGapSize;
        CalResult.fBlineSize      = WorkJob->fBlineSize;
        CalResult.PrePaper        = WorkJob->PrePaper;
        CalResult.PreGapBline     = WorkJob->PreGapBline;
        CalResult.AutoDetectType  = TRUE;//WorkJob->AutoDetectType; // ch_20211215 : set as TRUE
        CalResult.Ribbon          = WorkJob->Ribbon;
        CalResult.SetSize         = FALSE;
        CalResult.Finish          = FALSE;

        CalibrationEnd = FALSE;      // 标定结果
        while (ReturnTaskStatus()); // ch_20220428
        SetTaskStatus(); // ch_20220428
        TaskCreate(ExecuteCalibration, &CalResult, TASK_CAL_STACK);
        state = TRUE;
    }
    return state;
}

// ch_20211216
BOOL GetCalibratedStat(VOID)
{
    return CalibrationEnd;
}

// ch_20211216
VOID ResetCalibratedStat(BOOL status)
{
    CalibrationEnd = status;

}

// ch_20220705
VOID InitializeCalRslt(_CalResult* Result) {
    memcpy(&CalResult, Result, sizeof(_CalResult));
    
//sysprintf("CalRslt_%d/%d/%d/%d/%d\n", CalResult.SensorMode, (WORD)CalResult.fGapSize, (WORD)CalResult.fBlineSize, CalResult.DownFilterAvg, CalResult.UpFilterAvg);    
}

// ch_20220218
_CalResult* GetCalResult(VOID)
{
    return &CalResult;
}

/
// ch_20220416
UCHAR IsOnceCalDone(VOID) {
    return OnceCalDone;
}

VOID RstOnceCaldoneFlg(VOID) {
    OnceCalDone = 0;
}
/

/
// ch_20220718
_AnalogMedia* GetMediaData(VOID) {
    if (GetCalibratedStat())
        if (GAP_MODE == CalResult.SensorMode)
            return &CalMedia[0][CalResult.GapInten];
        else if (BLINE_MODE == CalResult.SensorMode)
            return &CalMedia[1][CalResult.BlineInten];
        else return NULL;
    else
        return NULL;
}
/

#endif

JobErrMgr.c                 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define JOBERRMGR_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XTimer.h"
#include "XADC.h"
#include "XLED.h"
#include "XKey.h"
#include "XTPH.h"
#include "XBuzzer.h"
#include "XCentronic.h"
#include "XTask.h"
#include "XComm.h"
#include "XDisplay.h"
#include "XVarBank.h"
#include "XFunction.h"
#include "PrtEng.h"

extern int ad_value_print[6000]; // ch_20220317
extern int ad_v_print_index;  // ch_20220317

STATIC UCHAR printErrHeadDone = 0; // ch_20220429
STATIC UCHAR printErrPaperDone = 0; // ch_20220429
STATIC UCHAR printErrRibbonDone = 0; // ch_20220429


/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#define JOB_CLEAR_ERROR                0
#define JOB_CLEAR_RESET                1
#define JOB_CLEAR_CANCEL            2
#define JOB_CLEAR_RECOVER            3

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC XCALLBACK ErrorEvent = _NULL;//EltronErrorEvent

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC TASK(JobErrorTask, arg)
{
    INT item = -1;

#if defined(LCD_MODEL) && defined(MENU_TSPL_3)
    item = ErrorMenu();
#endif
    if (arg) *(INT *)arg = item;
    TaskExit();
}

STATIC VOID JobErrorAppear(WORD state)
{
    STATIC UCHAR errAppearCnt = 0; // ch_20220510
    _ePolyLEDStat LEDState = 0; // ch_20220608

    /
    // ch_20220608
//#if defined(MONO_LED)
//    ShowLED(HID_LED_IDLE, HID_LED_OFF, HID_LED_ON);
//#elif defined(POLY_LED)
//    ShowLED(HID_LED_RED);
//#endif
    if (state&ERROR_TPH_OVERHEAT || state&ERROR_TPH_OPEN) {
#if defined(MONO_LED)
        ShowLED(HID_LED_IDLE, HID_LED_OFF, HID_LED_ON);
#elif defined(POLY_LED)
        /
        // ch_20220608
        LEDState = GetLEDStat();
        BackupPrevLEDStat();
//sysprintf("LEDState_%d\n", LEDState); // ch_20220608
        if (LED_FLASH_BLUE == LEDState)
            CancelPeriodFunc(FlashGreenLED);
        else if (LED_FLASH_RED_BLUE == LEDState)
            CancelPeriodFunc(FlashBlueRedLED);
        else if (LED_FLASH_RED_BLUE_FAST == LEDState)
            CancelPeriodFunc(FlashBlueRedLEDFast);        
        /
        ShowLED(HID_LED_RED);
#endif
        // ch_20220608
        if (state&ERROR_TPH_OVERHEAT)
            SaveVarBank();
    }
    else if (state & ERROR_PAPER_JAM || state & ERROR_PAPER_EMPTY ||
        state & ERROR_RIBBON_JAM || state & ERROR_RIBBON_EMPTY)        
//    if (state & ERROR_PAPER_JAM || state & ERROR_PAPER_EMPTY ||
//        state & ERROR_RIBBON_JAM || state & ERROR_RIBBON_EMPTY)
    /
    {
        if (state & ERROR_PAPER_JAM || state & ERROR_PAPER_EMPTY)
            ErrorPaperSound();
        else if (state & ERROR_RIBBON_JAM || state & ERROR_RIBBON_EMPTY)
            ErrorRibbonSound();        

#if defined(MONO_LED)
        StartPeriodFunc(FlashLED3);
#elif defined(POLY_LED)
//        StartPeriodFunc(FlashRedLED); // ch_20211221
        /
        // ch_20220418
//        StartPeriodFunc(FlashBlueRedLED); // ch_20211221
        if (state & ERROR_RIBBON_EMPTY || state & ERROR_PAPER_EMPTY) {            
            SetLEDStat(LED_FLASH_RED_BLUE); // ch_20220608
            StartPeriodFunc(FlashBlueRedLED);
        }
        else if (state & ERROR_RIBBON_JAM || state & ERROR_PAPER_JAM) {            
            SetLEDStat(LED_FLASH_RED_BLUE_FAST); // ch_20220608
            StartPeriodFunc(FlashBlueRedLEDFast);
        }
//sysprintf("A_LED_S_%d\n", GetLEDStat()); // ch_20220609
        /
#endif

        /
        // ch_20220510
        if (++errAppearCnt >= 3) {
            errAppearCnt = 0;
            SaveVarBank();
        }            
        /
    }

#if defined(LCD_MODEL)
    if (state & ERROR_PAPER_JAM)
        SetDisplayStatus(DIS_PAPER_JAM);
    if (state & ERROR_PAPER_EMPTY)
        SetDisplayStatus(DIS_PAPER_EMPTY);
    if (state & ERROR_RIBBON_JAM || state & ERROR_RIBBON_EMPTY)
        SetDisplayStatus(DIS_RIBBON_EMPTY);
    if (state & ERROR_CUTTER)
        SetDisplayStatus(DIS_CUTTER_ERROR);
#endif

    if (state & ERROR_PAPER_EMPTY)
        SetCenStatus(TRUE, TRUE, TRUE);
    else
        SetCenStatus(TRUE, TRUE, FALSE);
}

STATIC INT JobErrorClear(_MotionJob *MJob)
{
    STATIC INT DelayNum = DELAY_TIME_NULL;
    STATIC INT SelectItem = 0;
    STATIC BOOL PressMenu = FALSE;
    STATIC BOOL PressFeed = FALSE;
    _WorkJob *WorkJob = &MJob->WorkJob;
    WORD Temp;

    if (PressMenu)
    {
        if (SelectItem != 0)
        {
            PressMenu = FALSE;
            if (SelectItem == 1)
                return JOB_CLEAR_CANCEL;
            if (SelectItem == 2)
                return JOB_CLEAR_RESET;
        }
    }
    else if (!PressFeed)
    {
#if defined(MENU_TSPL_3)
        if (GetKey(MENU_KEY))
        {
            PressMenu = TRUE;
            SelectItem = 0;
            TaskCreate(JobErrorTask, &SelectItem, TASK_MENU_STACK);
        }
#endif
    }

    if (MJob->ErrState & ERROR_TPH_OVERHEAT)
    {
        if (CheckDelayTimer(DelayNum))
            return JOB_CLEAR_ERROR;
        ClrDelayTime(DelayNum);
        DelayNum = SetDelayTime(500);

        StartADConvert(TPH_TEMP_AD);
        Temp = ReadAD(TPH_TEMP_AD);
        Temp = CalculateTPHTemp(Temp);
#if defined(LCD_MODEL)
        SetDisplayOverTemp(Temp);
#endif
        if (Temp > WorkJob->PrintHeat)
            return JOB_CLEAR_ERROR;

        ClrDelayTime(DelayNum);
        DelayNum = DELAY_TIME_NULL;
    }

#if defined(TTP245C_MACH)
    else if (MJob->ErrState & ERROR_MOTOR_OVERHEAT)
    {
        if (CheckDelayTimer(DelayNum))
            return JOB_CLEAR_ERROR;
        ClrDelayTime(DelayNum);
        DelayNum = SetDelayTime(500);

        Temp = GetMotorTemp();
#if defined(LCD_MODEL)
        SetDisplayOverTemp(Temp);
#endif
        if (Temp > WorkJob->MotorMoveHeat)
            return JOB_CLEAR_ERROR;

        ClrDelayTime(DelayNum);
        DelayNum = DELAY_TIME_NULL;
    }
#endif

    else
    {
        if (!PressFeed)
        {
            if (!GetKey(FEED_KEY))
                return JOB_CLEAR_ERROR;
            PressFeed = TRUE;
        }

        if (PressFeed)
        {
            PressFeed = FALSE;
        }
    }

    return JOB_CLEAR_RECOVER;
}

STATIC VOID JobErrorRecover(_MotionJob *MJob, _MotionJob *BackupJob, INT JobClear)
{
    _WorkJob *WorkJob = &MJob->WorkJob;
    _ePolyLEDStat LEDState = 0; // ch_20220608

#ifdef DEBUG_PRNT
sysprintf("Enter JobErrorRecover()...\n"); // ch_20211216
#endif

    if (MJob->ErrState & ERROR_TPH_OVERHEAT)
    {

#if defined(MONO_LED)
        ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_OFF);
#elif defined(POLY_LED)
        /
        // ch_20220608
//        ShowLED(HID_LED_GREEN);
        LEDState = GetPrevLEDStat();
        SetLEDStat(LEDState); // ch_20220609
//sysprintf("Prev_LED_S_%d\n", LEDState); // ch_20220609
        if (LED_FLASH_RED_BLUE == LEDState) {
            StartPeriodFunc(FlashBlueRedLED);
        }
        else if (LED_FLASH_RED_BLUE_FAST == LEDState) {
            StartPeriodFunc(FlashBlueRedLEDFast);
        }
        else if (LED_FLASH_BLUE == LEDState) {            
            StartPeriodFunc(FlashGreenLED);
        }
        else
            ShowLED(HID_LED_GREEN);
        /
#endif

#if defined(LCD_MODEL)
        ClrDisplayStatus(DIS_OVER_HEAT);
#endif
        SetCenStatus(TRUE, FALSE, FALSE);

        MJob->State = JOB_NEW;
        MJob->ErrState &= ~ERROR_TPH_OVERHEAT;
    }

#if defined(TTP245C_MACH)
    else if (MJob->ErrState & ERROR_MOTOR_OVERHEAT)
    {

#if defined(MONO_LED)
        ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_OFF);
#elif defined(POLY_LED)
        ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
        ClrDisplayStatus(DIS_OVER_HEAT);
#endif
        SetCenStatus(TRUE, FALSE, FALSE);

        MJob->State = JOB_NEW;
        MJob->ErrState &= ~ERROR_MOTOR_OVERHEAT;
    }

#endif

#if  defined(TTP245P_PCB) ||defined(T045_PCB) ||defined(T40_PCB)
    else if (MJob->ErrState & ERROR_CUTTER)
    {

#if defined(MONO_LED)
        ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_OFF);
#elif defined(POLY_LED)
        ShowLED(HID_LED_GREEN);
#endif

#if defined(LCD_MODEL)
        ClrDisplayStatus(DIS_CUTTER_ERROR);
#endif
        SetCenStatus(TRUE, FALSE, FALSE);

        MJob->State = JOB_PRINTING;
        MJob->ErrState &= ~ERROR_CUTTER;
    }

#else
    else if (MJob->ErrState & ERROR_CUTTER)
        PrinterReboot();

#endif

    else if (MJob->ErrState & ERROR_TPH_OPEN
        || MJob->ErrState & ERROR_PAPER_JAM || MJob->ErrState & ERROR_PAPER_EMPTY
        || MJob->ErrState & ERROR_RIBBON_JAM || MJob->ErrState & ERROR_RIBBON_EMPTY)
    {
        printErrHeadDone = 0; // ch_20220429
        printErrPaperDone = 0; // ch_20220429
        printErrRibbonDone = 0; // ch_20220429    

        // ch_20220721
        if (MJob->ErrState & ERROR_PAPER_JAM || MJob->ErrState & ERROR_PAPER_EMPTY)
            InitialAnalogMedia();

#if defined(MONO_LED)
        CancelPeriodFunc(FlashLED3);
        ShowLED(HID_LED_IDLE, HID_LED_ON, HID_LED_OFF);
#elif defined(POLY_LED)
//        CancelPeriodFunc(FlashRedLED); // ch_20211221
        //
        LEDState = GetLEDStat(); // ch_20220609
//sysprintf("LED_S_%d\n", LEDState); // ch_20220609
        if (LED_FLASH_RED_BLUE == LEDState) // ch_20220609
            CancelPeriodFunc(FlashBlueRedLED); // ch_20211221
//        if (MJob->ErrState & ERROR_TPH_OPEN || 
//            MJob->ErrState & ERROR_PAPER_EMPTY || MJob->ErrState & ERROR_RIBBON_EMPTY)
//            CancelPeriodFunc(FlashBlueRedLED);
//        else if (MJob->ErrState & ERROR_PAPER_JAM || MJob->ErrState & ERROR_RIBBON_JAM) {
        else if (LED_FLASH_RED_BLUE_FAST == LEDState) // ch_20220609
            CancelPeriodFunc(FlashBlueRedLEDFast); // ch_20220421

        CancelPeriodFunc(FlashRedLED); // ch_20220624

ClrFeedStepCnt(); // ch_20220605

//sysprintf("Done\n"); // ch_20220421            
//        }
//        if (GetCarriageOpenOrClose()) { // ch_20220709 // ch_20220617
            ResetPrevLEDStat(); // ch_20220609
            SetLEDStat(LED_ON_BLUE); // CH_20220609
            ShowLED(HID_LED_GREEN); // ch_20220617
//        }
        
            ClrRibbonVars(); // ch_20220726
        //
//        ShowLED(HID_LED_GREEN); // ch_20220617
#endif

#if defined(LCD_MODEL)
        if (MJob->ErrState & ERROR_TPH_OPEN)
            ClrDisplayStatus(DIS_CARRIAGE_RECOVER);
        if (MJob->ErrState & ERROR_PAPER_JAM)
            ClrDisplayStatus(DIS_PAPER_JAM);
        if (MJob->ErrState & ERROR_PAPER_EMPTY)
            ClrDisplayStatus(DIS_PAPER_EMPTY);
        if (MJob->ErrState & ERROR_RIBBON_JAM || MJob->ErrState & ERROR_RIBBON_EMPTY)
            ClrDisplayStatus(DIS_RIBBON_EMPTY);
#endif
        SetCenStatus(TRUE, FALSE, FALSE);

#if defined(DIVIDE_INTENSION)
        if (MJob->ErrState & ERROR_TPH_OPEN && WorkJob->Measure)
        {
            MJob->ErrState = _NULL;
            MJob->State = JOB_NEW;
        }
        else
#endif
        {
            MJob->ErrState = _NULL;
            MJob->State = JOB_NEW;

            if (JobClear == JOB_CLEAR_RECOVER)
            {
                if (BackupJob->State == JOB_NULL)
                    *BackupJob = *MJob;

                WorkJob->Type = FEED_JOB;
                WorkJob->Quantity = 1;
            }
        }
    }

    if (JobClear == JOB_CLEAR_RESET)
        PrinterReboot();

    if (JobClear == JOB_CLEAR_CANCEL)
    {
        MJob->ErrState = _NULL;
        MJob->State = JOB_NEW;
        CancelActiveJob();
    }
}

VOID JobErrorManager(_MotionJob *MJob, _MotionJob *BackupJob)
{
    STATIC BOOL PreKeyFunc = FALSE;
    INT JobClear;

    if (MJob->State != JOB_ERROR)
    {
        MJob->State = JOB_ERROR;
        MJob->Monitor = MONITOR_ERROR;
        JobErrorAppear(MJob->ErrState);
        PreKeyFunc = StopKeyFunc();
        StopTPH();

        if (ErrorEvent)
            ErrorEvent();
    }

    if ((JobClear = JobErrorClear(MJob)) == JOB_CLEAR_ERROR)
        return;

    GetKey(FEED_KEY);
    GetKey(PAUSE_KEY);
    GetKey(MENU_KEY);
    StartKeyFunc(PreKeyFunc);

    JobErrorRecover(MJob, BackupJob, JobClear);
}

VOID SetErrorEvent(XCALLBACK event)
{
    ErrorEvent = event;
}

VOID ErrorHeadSound(VOID)
{
    STATIC SHORT ErrSoundSeq = 0;
    STATIC SHORT Lv;

//#ifdef DEBUG_PRNT    
//sysprintf("ErrorHeadSound() : %d!!!\n", GetJobErrorState()); // ch_20211210
if (0 == printErrHeadDone) { // ch_20220429
    printErrHeadDone = 1; // ch_20220429
    sysprintf("ErrorHeadSound()...\n"); // ch_20211210
}
//#endif

    if (CheckBuzzerStatus())
        return;

    switch (ErrSoundSeq)
    {
        case 0:
            StartPeriodFunc(ErrorHeadSound);
            Lv = 4;
            ErrSoundSeq = 1;
            break;

        case 1:
            EnableBuzzer((WORD)Lv, (WORD)20);
            Lv += 4;
            if (Lv > 16)
                ErrSoundSeq = 2;
            break;

        case 2:
            CancelPeriodFunc(ErrorHeadSound);
            ErrSoundSeq = 0;
            break;
    }
}

VOID ErrorPaperSound(VOID)
{
    STATIC SHORT ErrSoundSeq = 0;
    STATIC SHORT Lv;

int i = 0; // ch_20220317    

//#ifdef DEBUG_PRNT
//sysprintf("Enter ErrorPaperSound() : %d!!!\n", GetJobErrorState()); // ch_20211210
if (0 == printErrPaperDone) { // ch_20220429
    printErrPaperDone = 1; // ch_20220429
    sysprintf("ErrorPaperSound()...\n"); // ch_20211210
}

//#endif

    // ch_20220126
//    ResetCalibratedStat(FALSE); // ch_20211216

    if (CheckBuzzerStatus())
        return;

    switch (ErrSoundSeq)
    {
        case 0:
            StartPeriodFunc(ErrorPaperSound);
            Lv = 10;
            ErrSoundSeq = 1;
            break;

        case 1:
            EnableBuzzer((WORD)Lv, (WORD)50);
            Lv -= 5;
            if (Lv < 0)
                ErrSoundSeq = 2;
            break;

        case 2:
            CancelPeriodFunc(ErrorPaperSound);
            ErrSoundSeq = 0;

            break;
    }
}

VOID ErrorRibbonSound(VOID)
{
    STATIC SHORT ErrSoundSeq = 0;
    STATIC SHORT Freq;
    STATIC SHORT Lv;

//#ifdef DEBUG_PRNT
//sysprintf("Enter ErrorRibbonSound() : %d!!!\n", GetJobErrorState()); // ch_20211210
if (0 == printErrRibbonDone) { // ch_20220429
    printErrRibbonDone = 1; // ch_20220429
    sysprintf("ErrorRibbonSound()...\n"); // ch_20211210
}
//#endif
    
    if (CheckBuzzerStatus())
        return;

    switch (ErrSoundSeq)
    {
        case 0:
            StartPeriodFunc(ErrorRibbonSound);
            Freq = 1;
            Lv = 10;
            ErrSoundSeq = 1;
            break;

        case 1:
            EnableBuzzer((WORD)Lv, (WORD)50);
            Lv -= 5;
            if (Lv < 0)
                ErrSoundSeq = 2;
            break;

        case 2:
            if (Freq--)
            {
                Lv = 10;
                ErrSoundSeq = 1;
            }
            else
            {
                CancelPeriodFunc(ErrorRibbonSound);
                ErrSoundSeq = 0;
            }
            break;
    }
}

JobMgr.c            。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define JOBMGR_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "XImgMgr.h"
#include "PrtEng.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#define WORK_JOB_MAX                    6

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

STATIC VOID ExecuteJob(_MotionJob *);
STATIC VOID CloseJob(_MotionJob *);
STATIC BOOL AddWorkJob(_WorkJob *);
STATIC BOOL NextWorkJob(_WorkJob *);

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC _WorkJob asWorkJobBuf[WORK_JOB_MAX];
STATIC _WorkJob *EndWorkJob;
STATIC _WorkJob *PutWorkJob;
STATIC _WorkJob *GetWorkJob;
STATIC WORD WorkJobTotal;

STATIC _MotionJob ActiveJob;
STATIC _MotionJob InsertJob;

STATIC BOOL JobCancel;
STATIC BOOL JobLock;

STATIC UINT JobBatchNumber;
STATIC UINT DirtyBatchNumber;

VOID InitialJobManager(VOID)
{
    EndWorkJob = asWorkJobBuf + WORK_JOB_MAX;
    PutWorkJob = asWorkJobBuf;
    GetWorkJob = asWorkJobBuf;
    WorkJobTotal = 0;

    ActiveJob.State    = JOB_NULL;
    ActiveJob.Monitor  = MONITOR_IDLE;
    ActiveJob.ErrState = _NULL;

    InsertJob.State    = JOB_NULL;
    InsertJob.Monitor  = MONITOR_IDLE;
    InsertJob.ErrState = _NULL;

    JobCancel = FALSE;
    JobLock   = FALSE;

    JobBatchNumber   = 0;
    DirtyBatchNumber = 0;
}

VOID StartJobManager(VOID)
{
    JobLock = FALSE;
}

VOID StopJobManager(VOID)
{
    JobLock = TRUE;
}

#if defined(__HITACHI__)
#pragma inline(CheckJobLock)
#endif

BOOL CheckJobLock(VOID)
{
    return JobLock;
}

_MotionJob *GetActiveJob(VOID)
{
    return &ActiveJob;
}

_eJobState GetJobState(VOID)
{
    return ActiveJob.State;
}

VOID SetJobState(_eJobState State)
{
    ActiveJob.State = State;
}

#if defined(__HITACHI__)
#pragma inline(GetJobMonitor)
#endif

_eJobMonitor GetJobMonitor(VOID)
{
    return ActiveJob.Monitor;
}

VOID SetJobMonitor(_eJobMonitor Monitor)
{
    ActiveJob.Monitor = Monitor;
}

#if defined(__HITACHI__)
#pragma inline(GetJobErrorState)
#endif

WORD GetJobErrorState(VOID)
{
    return (ActiveJob.ErrState & ERROR_JOB_ALL_STATE);
}

VOID SetJobErrorState(WORD State)
{
    ActiveJob.ErrState |= State;
}

VOID ClrJobErrorState(WORD State)
{
    ActiveJob.ErrState &= ~State;
}

VOID WaitWorkJobEnd(VOID)
{
    while (IsMotion())
        NutSleep(10);
}
//
//判断工作任务是否已有批次号,如果没有则给它分配一个新的批次号。
//不断尝试将工作任务添加到队列中,直到成功为止。
//如果工作任务的批次号等于脏批次号,则返回0。
//如果成功将工作任务添加到队列中,则返回它的批次号。
//其中,AddWorkJob函数是用于将工作任务添加到队列中并启动运动控制的函数,但具体实现需要看到该函数的代码才能确定。DirtyBatchNumber可能是用于标记队列中的脏批次号,但也需要更多上下文才能确定。
///   //双击定标进来执行,PC下发打印进来执行    
UINT QueueWorkJob(_WorkJob *WorkJob)  //<--PrintBatch()        
{
    if (WorkJob->BatchNumber == 0)
    {
        while (JobBatchNumber == 0 || JobBatchNumber == DirtyBatchNumber)
            JobBatchNumber += 1;
        WorkJob->BatchNumber = JobBatchNumber++;
    }
sysprintf("QueueWorkJob--\n");    
    while (1)
    {
        if (WorkJob->BatchNumber == DirtyBatchNumber)
            return 0;
        if (AddWorkJob(WorkJob))//->EnableMotion    
            break;
        NutSleep(10);
    }
    return WorkJob->BatchNumber;
}
/
/*  1 该函数检查ActiveJob的错误状态和作业状态。如果存在错误状态且作业状态不为空,则调用JobErrorManager函数处理错误作业。

    2 如果ActiveJob的状态是JOB_WAIT或JOB_FINISHED,并且InsertJob的状态不为空且WorkJob的数量大于0,
      或者ActiveJob的状态是JOB_FINISHED并且存在其他工作作业(WorkJobTotal>0),则调用CloseJob函数关闭当前作业。

    3 如果ActiveJob的状态是JOB_NULL,首先检查InsertJob的状态,如果不为空,则将ActiveJob设置为InsertJob并执行ExecuteJob函数开始执行作业,
      然后将InsertJob的状态设置为空。如果InsertJob的状态为空,而且可以找到下一个工作作业(通过NextWorkJob函数),则将ActiveJob设置为该作业并执行ExecuteJob函数开始执行作业。
      如果都不满足,则调用DisableMotion函数停止电机。

    4 根据JobLock的值,确定是否需要锁定作业。如果JobLock为真且ActiveJob的状态为JOB_NEW,则将其状态设置为JOB_LOCK;如果ActiveJob的状态为JOB_PRINTING,则将其状态设置为JOB_PAUSE。

    5 根据JobCancel的值,确定是否需要取消作业。如果JobCancel为真且ActiveJob的状态为JOB_NEW,则将其状态设置为JOB_DELETE;
      如果ActiveJob的状态为JOB_PRINTING或JOB_PAUSE,则将其状态设置为JOB_CANCEL。最后,将JobCancel的值设为FALSE。

    6 最后,返回ActiveJob的指针。

总体而言,该函数根据不同的条件处理作业状态,包括处理错误作业、关闭作业、执行作业、锁定作业和取消作业
*/
PC下发打印进来执行
_MotionJob *JobEventHand(VOID)     //<-MotionISR(VOID)     
{
    //--- Error Job ---//
    if (ActiveJob.ErrState && ActiveJob.State != JOB_NULL)
    {
#if 1
            static WORD ErrState_bak;
            static _eJobState  State_bak;
            if(ActiveJob.State != State_bak||ActiveJob.ErrState != ErrState_bak)
            {
                //debug_printf("ErrState:%d,%d\n",ActiveJob.ErrState,ActiveJob.State);//ERROR_TPH_OPEN
                
//#ifdef DEBUG_PRNT
sysprintf("Job_E%d,Job_S%d\n", ActiveJob.ErrState, ActiveJob.State); // ch_20211216
//#endif

                State_bak = ActiveJob.State;
                ErrState_bak = ActiveJob.ErrState;
            }
#endif
        JobErrorManager(&ActiveJob, &InsertJob);             //管理错误状态
    }
    //--- Close Job ---//
    if (ActiveJob.State == JOB_WAIT || ActiveJob.State == JOB_FINISHED)
    {
        if (InsertJob.State != JOB_NULL && InsertJob.WorkJob.Quantity)
        {
            CloseJob(&ActiveJob);
        }
        else if (ActiveJob.State == JOB_FINISHED || WorkJobTotal)
        {
            CloseJob(&ActiveJob);
            if (InsertJob.State != JOB_NULL)
                CloseJob(&InsertJob);
        }
    }
//sysprintf("JobEventHand--\r\n");
    //--- Execute Job ---//
    if (ActiveJob.State == JOB_NULL)
    {
    sysprintf("JEH--1\r\n");    //PC下发打印开始和最后各进来执行一次
        if (InsertJob.State != JOB_NULL)    //插入工作不为空
        {
            ActiveJob = InsertJob;
            ExecuteJob(&ActiveJob);
            InsertJob.State = JOB_NULL;
        }
        else if (NextWorkJob(&ActiveJob.WorkJob))
        {
            ExecuteJob(&ActiveJob);
        }
        else
            DisableMotion();       //关闭中断
    }

    //--- Lock Job ---//
    if (JobLock)
     {
    sysprintf("JEH--2\r\n");   
         if (ActiveJob.State == JOB_NEW)
             ActiveJob.State = JOB_LOCK;
         if (ActiveJob.State == JOB_PRINTING)
             ActiveJob.State = JOB_PAUSE;
     }
    else                        //PC下发打印时循环进来执行
    {
    sysprintf("JEH--3\r\n");
        if (ActiveJob.State == JOB_PAUSE)
             ActiveJob.State = JOB_PRINTING;
    }
    //--- Cancel Job ---//
    if (JobCancel)
    {
    sysprintf("JEH--4\r\n");
         if (ActiveJob.State == JOB_NEW)
            ActiveJob.State = JOB_DELETE;
         if (ActiveJob.State == JOB_PRINTING || ActiveJob.State == JOB_PAUSE)
            ActiveJob.State = JOB_CANCEL;

        JobCancel = FALSE;
    }
    return &ActiveJob;
}
///
/*  1  首先获取到定标结果,然后根据定标结果和工作任务的条件进行一系列操作。

    2 如果定标结果已经完成,并且工作任务的传感器模式与定标结果的传感器模式相匹配,那么会将定标结果中的一些值赋给工作任务的对应字段。

    3 接下来根据工作任务的传感器模式调用不同的传感器使能函数,并根据一些条件设置剩余步数。

    4 最后,将任务的状态设置为新任务,并清空错误状态。
*/
//   //PC下发打印时开始进来执行一次
STATIC VOID ExecuteJob(_MotionJob *MJob)     //<--JobEventHand(VOID)  
{
    _WorkJob *WorkJob = &MJob->WorkJob;
    _CalResult *pCalResult = GrabCalibrationResult();           //1 获取定标结果
sysprintf("ExecuteJob...\n");
       //debug_printf("F:%d",WorkJob->BlineInten);
    if (pCalResult->Finish && WorkJob->SensorMode == pCalResult->SensorMode)    // 2 工作任务传感器模式与定标结果的传感器模式相匹配
    {
        WorkJob->GapInten = pCalResult->GapInten;
        WorkJob->BlineInten = pCalResult->BlineInten;
        //debug_printf("E:%d",pCalResult->BlineInten);
        WorkJob->ContinuousInten = pCalResult->ContinuousInten;
        WorkJob->GapRef = pCalResult->GapRef;
        WorkJob->BlineRef = pCalResult->BlineRef;
        WorkJob->ContinuousRef = pCalResult->ContinuousRef;

        if (WorkJob->AutoSensorRef)
            WorkJob->GapRef = WorkJob->BlineRef = 0;

        if (pCalResult->SetSize)
        {
            WorkJob->SensorMode = pCalResult->SensorMode;
            WorkJob->fPaperSize = pCalResult->fPaperSize;
            WorkJob->fGapSize   = pCalResult->fGapSize;
            WorkJob->fBlineSize = pCalResult->fBlineSize;

            WorkJob->fLabelSize = WorkJob->fPaperSize;
            if  (WorkJob->SensorMode == GAP_MODE)
                WorkJob->fLabelSize += WorkJob->fGapSize;
            else if (WorkJob->SensorMode == BLINE_MODE)
                WorkJob->fLabelSize += WorkJob->fBlineSize;
        }
    }
    if (WorkJob->SensorMode == GAP_MODE)                                 // 3 根据工作任务的传感器模式调用不同的传感器使能函数
        EnableSensor(GAP_SENSOR, WorkJob->GapInten, WorkJob->Ribbon, WorkJob->GapRef);
    else if (WorkJob->SensorMode == BLINE_MODE)
        EnableSensor(BLINE_SENSOR, WorkJob->BlineInten, WorkJob->Ribbon, WorkJob->BlineRef);
    else if (WorkJob->SensorMode == CONTINUE_MODE_R)
        EnableSensor(BLINE_SENSOR, WorkJob->ContinuousInten, WorkJob->Ribbon, WorkJob->ContinuousRef);
    else
        EnableSensor(GAP_SENSOR, WorkJob->ContinuousInten, WorkJob->Ribbon, WorkJob->ContinuousRef);

#if defined(RIBBON_MODEL)
    if (WorkJob->Ribbon == TRUE)
        EnableSensor(RIBBON_SENSOR, WorkJob->RibbonInten, 0, WorkJob->RibbonRef);
#endif

#if defined(TTP2410M_MACH)
    SetJobRemainStep(0, WorkJob->Ribbon);
    if (WorkJob->Type == FEED_JOB || WorkJob->Type == PRINT_JOB)
        SetJobRemainStep((INT)WorkJob->fLabelSize * WorkJob->Quantity, WorkJob->Ribbon);
    else if (WorkJob->Type == MOTOR_JOB && WorkJob->MotorDir == MOTOR_FORWARD)
        SetJobRemainStep(WorkJob->Quantity, WorkJob->Ribbon);
#endif

//将任务的状态设置为新任务,并清空错误状态。
    MJob->State = JOB_NEW;       
    MJob->ErrState = _NULL;
}

STATIC VOID CloseJob(_MotionJob *MJob)
{
    _WorkJob *WorkJob = &MJob->WorkJob;

    if (WorkJob->Type == PRINT_JOB)
        FreeImageBuffer(&WorkJob->ImgBuf);

    if (WorkJob->SensorMode == BLINE_MODE ||
        WorkJob->SensorMode == CONTINUE_MODE_R)
        DisableSensor(BLINE_SENSOR);
    else
        DisableSensor(GAP_SENSOR);

#if defined(RIBBON_MODEL)
    if (WorkJob->Ribbon == TRUE)
        DisableSensor(RIBBON_SENSOR);
#endif

    if (WorkJob->Callback)
        WorkJob->Callback();

    MJob->State = JOB_NULL;
    MJob->Monitor = MONITOR_IDLE;
    MJob->ErrState = _NULL;
}

/*  函数的作用是将传入的工作任务添加到一个任务队列中。
    1 代码中首先检查任务队列是否已满,如果已满则返回FALSE。

    2 然后将传入的工作任务数据复制到队列的末尾,更新队列的末尾位置PutWorkJob。如果队列已经达到最大容量,则将PutWorkJob指针重置为队列的起始位置。

    3 接着禁用中断,并在修改全局变量WorkJobTotal时保证原子性。最后重新启用中断并返回TRUE表示任务添加成功。

*/
  //单击按键会进来执行1次    PC下发打印也会进来
STATIC BOOL AddWorkJob(_WorkJob *WorkJob)     //QueueWorkJob(_WorkJob *WorkJob)
{
    INT imask;

    
sysprintf("AddWorkJob\n");
    if (WorkJobTotal >= WORK_JOB_MAX)   //检查任务队列是否已满,如果已满则返回FALSE
        return FALSE;

    *PutWorkJob = *WorkJob;                // copy job data

    if (++PutWorkJob >= EndWorkJob)     //更新队列的末尾位置PutWorkJob  如果队列已经达到最大容量,则将PutWorkJob指针重置为队列的起始位置。
        PutWorkJob = asWorkJobBuf;

    imask = DisableInterrupt(MOTION_IMASK);  //禁用中断

    WorkJobTotal += 1;

    EnableMotion();

    EnableInterrupt(imask);

    return TRUE;
}

STATIC BOOL NextWorkJob(_WorkJob *WorkJob)
{
    INT imask;

    if (WorkJobTotal == 0)
        return FALSE;

    *WorkJob = *GetWorkJob;                // copy job data

    if (++GetWorkJob >= EndWorkJob)
        GetWorkJob = asWorkJobBuf;

    imask = DisableInterrupt(MOTION_IMASK);

    WorkJobTotal -= 1;

    EnableInterrupt(imask);

    return TRUE;
}

VOID CancelActiveJob(VOID)
{
    INT imask;

    if (!IsMotion())
        return;

    imask = DisableInterrupt(MOTION_IMASK);

    DirtyBatchNumber = ActiveJob.WorkJob.BatchNumber;

    while (WorkJobTotal)
    {
        if (GetWorkJob->BatchNumber != DirtyBatchNumber)
            break;

        if (GetWorkJob->Type == PRINT_JOB)
            FreeImageBuffer(&GetWorkJob->ImgBuf);

        if (GetWorkJob->Callback)
            GetWorkJob->Callback();

        if (++GetWorkJob >= EndWorkJob)
            GetWorkJob = asWorkJobBuf;
        WorkJobTotal -= 1;
    }

    JobCancel = TRUE;

    EnableInterrupt(imask);
}

INT GetRestJobStep(INT CurrOffset)
{
    _WorkJob *WorkJob = GetWorkJob;
    INT JobCnt = WorkJobTotal;
    INT TotalStep = 0;
    INT OffsetStep = 0;
    INT Step;

    while (JobCnt--)
    {
        CurrOffset = 0;
        OffsetStep = 0;
        if (WorkJob->Type == FEED_JOB || WorkJob->Type == PRINT_JOB)
        {
            OffsetStep = CorrectShrinkage(GetOffsetDis(WorkJob), WorkJob->Ribbon);
            if (WorkJob->PrintOutMode == PEEL_MODE || WorkJob->PrintOutMode == CUTTER_MODE)
            {
                TotalStep += CorrectShrinkage((INT)WorkJob->fLabelSize, WorkJob->Ribbon);
                break;
            }
            Step = (INT)WorkJob->fLabelSize * WorkJob->Quantity;
            if (Step > 10000) Step = 10000;        // avoid over the "int" type
            TotalStep += CorrectShrinkage(Step, WorkJob->Ribbon);
        }
        else if (WorkJob->Type == MOTOR_JOB && WorkJob->MotorDir == MOTOR_FORWARD)
            TotalStep += CorrectShrinkage(WorkJob->Quantity, WorkJob->Ribbon);
        else
            break;

        if (++WorkJob >= EndWorkJob)
            WorkJob = asWorkJobBuf;
    }
    return (TotalStep + OffsetStep) * MOTOR_STEP_RATE + CurrOffset;
}

PosMgr.c             。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define POSMGR_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <stdio.h>
#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XVarBank.h"
#include "XProFile.h"
#include "PrtEng.h"

extern INT GetMotorCounter(VOID); // ch_20220218
extern _CalResult* GetCalResult(VOID); // ch_20220219


/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

enum {
    AUTO,
    FRONT,
    REAR,
};

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/* None */

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

STATIC _PrintCfg* pPosCfg;
STATIC _ePositionState PositionState;
STATIC INT RegistrationWay;
STATIC SHORT OffsetBase;
STATIC SHORT ShiftYBase;

STATIC SHORT TransmissiveDis;
STATIC SHORT ReflectiveDis;
STATIC SHORT TearDis;
STATIC SHORT PeelDis;
STATIC SHORT CutDis;

STATIC SHORT FabricCutDis;
STATIC SHORT LinerlessDis;

/******************************************************************************
 *
 * Function:
 *    
 *
 * Description: 
 *        
 *
 * Input:
 *      None
 *
 * Output:
 *      None.
 *
 ******************************************************************************/
VOID InitialPositionManager(VOID)
{
    CHAR buffer[32];
    FLOAT data;

    pPosCfg = GrabPrintConfig();

    RegistrationWay = AUTO;
    if (GetProfileString("LABEL REGIST", buffer))
    {
        if (strcmp("FRONT", buffer) == 0)
            RegistrationWay = FRONT;
        if (strcmp("REAR", buffer) == 0)
            RegistrationWay = REAR;
    }

    OffsetBase = 0;
    if (GetProfileInt("BASE OF OFFSET", &data))
        OffsetBase = (SHORT)data;

    ShiftYBase = 0;
    if (GetProfileInt("SHIFT YBASE", &data))
        ShiftYBase = (SHORT)data;

    TransmissiveDis = TPH_GAP_DIS;
    if (GetProfileInt("OFFSET OF TRANSMISSIVE", &data))
            TransmissiveDis+=(SHORT)data;
    if (GetProfileInt("DISTANCE OF TRANSMISSIVE", &data))
        TransmissiveDis = (SHORT)data;

    ReflectiveDis = TPH_BLINE_DIS;
    if (GetProfileInt("OFFSET OF REFLECTIVE", &data))
            ReflectiveDis+=(SHORT)data;
    if (GetProfileInt("DISTANCE OF REFLECTIVE", &data))
        ReflectiveDis = (SHORT)data;

    TearDis = TPH_TEAR_DIS;
    if (GetProfileInt("OFFSET OF TEAR", &data))
            TearDis+=(SHORT)data;
    if (GetProfileInt("DISTANCE OF TEAR", &data))
        TearDis = (SHORT)data;

    PeelDis = TPH_PEEL_DIS;
    if (GetProfileInt("OFFSET OF PEEL", &data))
            PeelDis+=(SHORT)data;
    if (GetProfileInt("DISTANCE OF PEEL", &data))
        PeelDis = (SHORT)data;

    CutDis = TPH_CUT_DIS;
    if (GetProfileInt("OFFSET OF CUT", &data))
        CutDis += (SHORT)data;
    if (GetProfileInt("DISTANCE OF CUT", &data))
        CutDis = (SHORT)data;

#if defined(TPH_FABRIC_CUT_DIS)
    FabricCutDis = TPH_FABRIC_CUT_DIS;
    if (GetProfileInt("CUTTER OFFSET OF FABRIC", &data))
            FabricCutDis+=(SHORT)data;
    if (GetProfileInt("CUTTER DISTANCEOF FABRIC", &data))
        FabricCutDis = (SHORT)data;
#endif

#if defined(TPH_LINERLESS_DIS)
    LinerlessDis = TPH_LINERLESS_DIS;
    if (GetProfileInt("LINERLESS OFFSET OF TEAR", &data))
            LinerlessDis+=(SHORT)data;
    if (GetProfileInt("DISTANCE OF LINERLESS", &data))
        LinerlessDis = (SHORT)data;
#endif

    PositionState = DO_NOT_NEED;
}

VOID SetPositionData(SHORT gap_dis,SHORT bline_dis,SHORT tear_dis,SHORT peel_dis,SHORT cut_dis)
{
        TransmissiveDis+=gap_dis;
        ReflectiveDis+=bline_dis;
        TearDis+=tear_dis;
        CutDis+=cut_dis;
        PeelDis+=peel_dis ;
}

VOID SetPositionState(_ePositionState State)
{
    PositionState = State;
}

SHORT GetOffsetDis(_WorkJob *WorkJob)
{
    WORD GapBmSize;
    SHORT Offset;

    _CalResult* pCalResult; // ch_20220819

//    // ch_20220219
//    _CalResult* pCalResult;
//    FLOAT fActualLabelSize = 0.0;
//    GapBmSize = 0;
//    pCalResult = GetCalResult();
//    if (GAP_MODE == pCalResult->SensorMode)
//        GapBmSize = (WORD)pCalResult->fGapSize;
//    else if (BLINE_MODE == pCalResult->SensorMode)
//        GapBmSize = (WORD)pCalResult->fBlineSize;

    if (WorkJob->Type == MOTOR_JOB || pPosCfg->OverHead)
        return 0;
    
    GapBmSize = 0;
    /
    // ch_20220819
    if (GetCalibratedStat()) {
        pCalResult = GetCalResult();
        if (WorkJob->SensorMode == GAP_MODE)
            GapBmSize = (WORD)pCalResult->fGapSize;
        else if (WorkJob->SensorMode == BLINE_MODE)
            GapBmSize = (WORD)pCalResult->fBlineSize;        
    }
    else {
    /
        if (WorkJob->SensorMode == GAP_MODE)
            GapBmSize = (WORD)WorkJob->fGapSize;
        else if (WorkJob->SensorMode == BLINE_MODE)
            GapBmSize = (WORD)WorkJob->fBlineSize;
    }

    Offset = 0;

    if (WorkJob->PrintOutMode == OFF_MODE)
        Offset = OffsetBase + WorkJob->OffsetDis;
    else if (WorkJob->PrintOutMode == TEAR_MODE)
    {
            Offset = OffsetBase + WorkJob->OffsetDis + TearDis - (GapBmSize >> 1);
//#ifdef DEBUG_PRNT
//sysprintf("Offset %d = OffsetBase %d + WorkJob->OffsetDis %d + TearDis %d - GapBmSize>>1 %d\n", 
//    Offset, OffsetBase, WorkJob->OffsetDis, TearDis, GapBmSize>>1); // ch_20220104
//#endif        
    }
    else if (WorkJob->PrintOutMode == PEEL_MODE)
        Offset = OffsetBase + WorkJob->OffsetDis + PeelDis - GapBmSize;

#if defined(TPH_LINERLESS_DIS)
    else if (WorkJob->PrintOutMode == CUTTER_MODE && IsLinerless())
        Offset = OffsetBase + WorkJob->OffsetDis + LinerlessDis - (GapBmSize >> 1);
#endif

#if defined(TPH_FABRIC_CUT_DIS)
    else if (WorkJob->PrintOutMode == CUTTER_MODE && IsFabricCutter())
        Offset = OffsetBase + WorkJob->OffsetDis + FabricCutDis - (GapBmSize >> 1);
#endif

    else if (WorkJob->PrintOutMode == CUTTER_MODE)
        Offset = OffsetBase + WorkJob->OffsetDis + CutDis - (GapBmSize >> 1);

    if (Offset < 0)
        Offset = 0;

//sysprintf("Os%d\n", Offset); // ch_20220111    

    return Offset;
}

SHORT GetShiftDis(_WorkJob *WorkJob)
{
    SHORT ShiftDis;

    ShiftDis = ShiftYBase + WorkJob->ShiftDis;
    if (WorkJob->SensorMode == GAP_MODE)
        ShiftDis -= WorkJob->fGapOffset;
    else if (WorkJob->SensorMode == BLINE_MODE)
        ShiftDis -= WorkJob->fBlineOffset;

    return ShiftDis;
}

#if 1
SHORT GetHeadDis(_WorkJob *WorkJob)
{
    SHORT HeadDis;

    HeadDis = 0;
    if (WorkJob->SensorMode == GAP_MODE)
        HeadDis = TransmissiveDis;
    else if (WorkJob->SensorMode == BLINE_MODE)
        HeadDis = ReflectiveDis;

    return HeadDis;
}
#endif

// ch_20220219
#if 0
FLOAT GetHeadDis(_WorkJob *WorkJob)
{
    FLOAT HeadDis;

    HeadDis = 0;
    if (WorkJob->SensorMode == GAP_MODE)
        HeadDis = TransmissiveDis;
    else if (WorkJob->SensorMode == BLINE_MODE)
        HeadDis = ReflectiveDis;

    return HeadDis;
}
#endif

#if 1
///
/*函数中的主要逻辑如下:

首先,将GetHeadDis(WorkJob)、pPosCfg->AdjustHead和pPosCfg->OverHead相加,得到fNextPaperDis的初始值。
接下来,通过一个循环,将fNextPaperDis与WorkJob->fLabelSize进行比较。如果fNextPaperDis大于WorkJob->fLabelSize,则每次减去WorkJob->fLabelSize,直到fNextPaperDis不再大于WorkJob->fLabelSize。
如果fNextPaperDis小于0,则将其设为0。
最后,将fNextPaperDis转换为WORD类型,并作为函数的返回值。
该函数的作用是计算下一个纸张的位置。具体实现细节可能需要查看其他相关代码

*/
WORD GetNextPaperDis(_WorkJob *WorkJob)     //<--WorkJobProcess(_MotionJob *MJob, BOOL Print)
{
    FLOAT fNextPaperDis;

    fNextPaperDis = GetHeadDis(WorkJob) + pPosCfg->AdjustHead + pPosCfg->OverHead; // 514

    while (fNextPaperDis > WorkJob->fLabelSize)
        fNextPaperDis -= WorkJob->fLabelSize;

    if (fNextPaperDis < 0)
        fNextPaperDis = 0;

//sysprintf("\nfN = %d\n", (WORD)fNextPaperDis); // ch_20220217

    return (WORD)fNextPaperDis;
}
#endif

VOID GapBlinePosition(_MotionJob *MJob, INT SensorPos, INT PreSensorPos)
{
    _WorkJob *WorkJob = &MJob->WorkJob;
    WORD NextPaperDis;
    INT Modify;
//    UCHAR u8Temp1 = 0; // ch_20220616 // ch_20220314

//STATIC WORD gapBmCnt = 0; // ch_20220311

    if (WorkJob->Type != PRINT_JOB && WorkJob->Type != FEED_JOB)
        return;

    if (GetPreMotorDir() != MOTOR_FORWARD)
        return;

//    u8Temp1 = GetFakePosOnPaper(); // ch_20220616
     if (SensorPos == POSITION_ON_PAPER && (PreSensorPos == POSITION_ON_GAP_BLINE || PreSensorPos == POSITION_ON_DETECTING))
//     if ((SensorPos == POSITION_ON_PAPER && (PreSensorPos == POSITION_ON_GAP_BLINE 
//        || PreSensorPos == POSITION_ON_DETECTING)) || u8Temp1) // ch_20220616 // ch_20220313
     {
//sysprintf("P\t"); // ch_20220312
//sysprintf("F%d\t", u8Temp1); // ch_20220314
// ch_20220312
//if (u8Temp1)
//    ResetFakePosOnPaper();

        if (PositionState == TO_POSITION && RegistrationWay != REAR)
        {
            NextPaperDis = GetNextPaperDis(WorkJob);
//sysprintf("N%d,", NextPaperDis); // ch_20220317

            Modify = CorrectShrinkage(NextPaperDis, WorkJob->Ribbon);
//sysprintf("M%d,%d,%d,", Modify, SurplusPrintLine(), WorkJob->PrintFullImage); // ch_20220402            
            if (Modify + MM_DOT < SurplusPrintLine() && WorkJob->PrintFullImage && WorkJob->Type == PRINT_JOB)
                return;
            if (RegistrationWay == FRONT ||
                (NextPaperDis < (INT)WorkJob->fPaperSize || NextPaperDis > (INT)WorkJob->fLabelSize))
            {
//sysprintf("P: Prev: %d\t", GetMotorStepCounter());

                // ch_20220629 : comment.
//                ///
//                // ch_20220625
//                if (PRINT_JOB == WorkJob->Type) {
//                    if (Modify > 8)             
//                        Modify -= 8;
//                    else if (Modify > 4)
//                        Modify -= 4;
//                }
//                ///

                // reset motor step let paper feed to TPH position
                ModifyMotorStep(Modify);                
//                if (!u8Temp1) // ch_20220616 // ch_20220318
//                {
                    PositionState = DO_NOT_NEED;
//                    if (WorkJob->PreventJumpPage) // ch_20220707
                    if ((WorkJob->PreventJumpPage)&&(PRINT_JOB==WorkJob->Type)) // ch_20220707
                        PositionState = AVOID_SKIP_LABEL;
//                }
//sysprintf("P : %d\t%d\n", GetMotorStepCounter(), PositionState); // ch_20220316                
//sysprintf("P_%d\n", GetMotorStepCounter()); // ch_20220316
            }
            // ch_20220307
            else
            {
//                sysprintf("P_%d,%d,%d,%d\n", NextPaperDis, (INT)WorkJob->fPaperSize, (INT)WorkJob->fLabelSize, GetMotorStepCounter());
            }                
        }
     }

//sysprintf("Po%d\t%d\t", PreSensorPos, SensorPos); // ch_20220314
    if (SensorPos == POSITION_ON_GAP_BLINE && (PreSensorPos == POSITION_ON_PAPER || PreSensorPos == POSITION_ON_DETECTING))
//    if (SensorPos == POSITION_ON_GAP_BLINE && 
//        (PreSensorPos == POSITION_ON_PAPER || PreSensorPos == POSITION_ON_DETECTING)) // ch_20220314    
    {
//sysprintf("G\t"); // ch_20220312

        if (PositionState == TO_POSITION && RegistrationWay != FRONT)
        {
            NextPaperDis = GetNextPaperDis(WorkJob);
//sysprintf("N%d\t", NextPaperDis); // ch_20220317
            Modify = NextPaperDis - (INT)WorkJob->fPaperSize + TPH_GAP_DIS_MIS; // ch_20220308
            if (Modify < 0)
                Modify += (INT)WorkJob->fLabelSize;

            if (Modify >  WorkJob->IgnoreSize)
                Modify -= WorkJob->IgnoreSize;

            Modify = CorrectShrinkage(Modify, WorkJob->Ribbon);
            if (Modify + MM_DOT < SurplusPrintLine() && WorkJob->PrintFullImage && WorkJob->Type == PRINT_JOB)
                return;

            if (RegistrationWay == REAR ||
                (NextPaperDis >= (INT)WorkJob->fPaperSize && NextPaperDis <= (INT)WorkJob->fLabelSize))
            {
//sysprintf("G0 : Prev: %d\t", GetMotorStepCounter());                
                // reset motor step let paper feed to TPH position
                ModifyMotorStep(Modify);
                PositionState = DO_NOT_NEED;
//sysprintf("G0 : %d\t%d\n", GetMotorStepCounter(), PositionState);
//sysprintf("G0_%d\n", GetMotorStepCounter());
            }
            // ch_20220307
            else
            {
//                sysprintf("G0_%d,%d,%d,%d\n", NextPaperDis, (INT)WorkJob->fPaperSize, (INT)WorkJob->fLabelSize, GetMotorStepCounter());
            }            
        }
        else if (PositionState == AVOID_SKIP_LABEL)
        {
            NextPaperDis = GetHeadDis(WorkJob) + pPosCfg->AdjustHead + pPosCfg->OverHead;

            Modify = 0;
            if (WorkJob->SensorMode == GAP_MODE)
                Modify = (INT)WorkJob->fGapSize;
            else if (WorkJob->SensorMode == BLINE_MODE)
                Modify = (INT)WorkJob->fBlineSize;

            Modify -= (INT)MM_DOT;    // decrease 1 mm
            if (Modify < 0)
                Modify = 0;

            if (Modify + MM_DOT < SurplusPrintLine() && WorkJob->PrintFullImage && WorkJob->Type == PRINT_JOB)
                return;
            if (Modify < GetMotorStepCounter() && NextPaperDis + MM_DOT > (INT)WorkJob->fPaperSize)
            {
//sysprintf("G1 : Prev: %d\t", GetMotorStepCounter());            
                // reset motor step let paper feed to TPH position
                ModifyMotorStep(Modify);
                PositionState = DO_NOT_NEED;
//sysprintf("G1_%d\t%d\n", GetMotorStepCounter(), PositionState);
//sysprintf("G1_%d\n", GetMotorStepCounter());
            }
            // ch_20220307
            else
            {
//                sysprintf("G1_%d,%d,%d\n", NextPaperDis, Modify, GetMotorStepCounter());
            }            
        }
    }
}
 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值