PT606668DC\Src:第9~18

/****************************************************************************
 * File Name: ICON.h
 *
 * Description:
 *					ICON
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2018/03/15		Original
 *
 *****************************************************************************/
 #ifndef __ICON_H__
 #define __ICON_H__ 
#include "stm32f1xx_hal.h"
#include "Types.h"
#include "Image.h"

extern const IMAGE_R BMP_BTConn[2];
extern const IMAGE_R BMP_FontName[2];
extern const IMAGE_R BMP_FontSize[3];
extern const IMAGE_R BMP_FontStyle[5];
extern const IMAGE_R BMP_TitleFrame[2];
extern const IMAGE_R BMP_BatteryLevel[7];
extern const IMAGE_R BMP_ChargeIcon[2];
extern const IMAGE_R BMP_IME[4];
extern const IMAGE_R IME_SYMBOL_MORE;
extern const IMAGE_R BMP_LineNo[6];
extern const IMAGE_R BMP_TempNo[20];
extern const IMAGE_R BMP_Logo;
extern const IMAGE_R BMP_mm;
extern const IMAGE_R BMP_Orientation[2];
extern const IMAGE_R BMP_Return;
//extern const IMAGE_R BMP_SmallNo[12];
//extern const IMAGE_R BMP_HSmallNo[10];
extern const IMAGE_R BMP_TitleBar;
extern const IMAGE_R BMP_8x16Ascii[95];
extern const IMAGE_R BMP_Selected[2];
extern const IMAGE_R BMP_Scroll[4];
extern const IMAGE_R BMP_Align[4];
extern const IMAGE_R BMP_FontSizeIcon[3];
extern const IMAGE_R BMP_FontStyleIcon[4];
extern const IMAGE_R BMP_FontWidthIcon[3];
extern const IMAGE_R BMP_SpacingIcon[3];
extern const IMAGE_R ICON_Barcode;
extern const IMAGE_R ICON_QRCode;
extern const IMAGE_R BMP_PanelIcon[4];
extern const IMAGE_R BMP_FormIcon[9];

extern const IMAGE_R BMP_TempTitle_Bobbin;
extern const IMAGE_R BMP_TempTitle_Flag[2];
extern const IMAGE_R BMP_TempTitle_Panel1[2];
extern const IMAGE_R BMP_TempTitle_Panel2[2];
extern const IMAGE_R BMP_TempTitle_Panel3[1];
extern const IMAGE_R BMP_TempTitle_Panel4[1];
extern const IMAGE_R BMP_TempTitle_Form1[3];
extern const IMAGE_R BMP_TempTitle_Form2[3];
extern const IMAGE_R BMP_TempTitle_Form3[2];
extern const IMAGE_R BMP_TempTitle_Form4[4];
extern const IMAGE_R BMP_TempTitle_Form5[3];
extern const IMAGE_R BMP_TempTitle_Form6[3];
extern const IMAGE_R BMP_TempTitle_Form7[2];
extern const IMAGE_R BMP_TempTitle_Form8[2];
extern const IMAGE_R BMP_TempTitle_Form9[2];

extern const IMAGE_R BMP_TempIcon[4];

extern const IMAGE_R BMP_Battery[5];
extern const IMAGE_R BMP_SpaceIcon[2];
extern const IMAGE_R BMP_AlertIcon;

//typedef struct
//{
//	const IMAGE_R Icon;
//	const IMAGE_R Frame[5][3];	// [6mm,9mm,12mm, 18mm, none][start, mid, end]
//}ST_FRAME_ICON_INFO;
//extern const ST_FRAME_ICON_INFO BMP_FrameInfo[12];
enum
{
    BORDERLINE_NONE,
    BORDERLINE_SOLID_NARROW,
    BORDERLINE_SOLID,
    BORDERLINE_SOLID_WIDE,
    BORDERLINE_DASHED_NARROW,
    BORDERLINE_DASHED,
    BORDERLINE_DASHED_WIDE,
    ENUM_FRAME_BORDERLINE_TYPE_COUNT
};
typedef BYTE ENUM_FRAME_BORDERLINE_TYPE;
typedef struct
{
    ENUM_FRAME_BORDERLINE_TYPE LineType;
	const IMAGE_R *Head;
	const IMAGE_R *Tail;
}ST_FRAME_DATA;

extern const ST_FRAME_DATA FrameInfo[47][3];
//typedef struct
//{
//	const ST_FRAME_DATA Frame[3];   // 6mm,9mm,12mm;
//}ST_FRAME_ICON_INFO_EX;
typedef struct
{
    BYTE Offset;
    BYTE Count;
    //const ST_FRAME_ICON_INFO *FrameIcon;
}ST_FRAME_GROUP_INFO;
extern const ST_FRAME_GROUP_INFO FrameGroupInfoTable[3];

extern const IMAGE_R TempBobbinCfg[1];
extern const IMAGE_R TempFlagCfg[1];
extern const IMAGE_R TempPanelCfg[4];
extern const IMAGE_R TempFormCfg[9];

extern const IMAGE_R ICON_BTConn[2];
extern const IMAGE_R ICON_Setting;
extern const IMAGE_R ICON_PHOpen;
extern const IMAGE_R ICON_NoPaper;
extern const IMAGE_R ICON_USBConn;
extern const IMAGE_R ICON_DcConn;
extern const IMAGE_R ICON_BatLevel[5];
#endif
// __ICON_H__






















//                                Image.c  




/****************************************************************************
 * File Name: Image.c
 *
 * Description:
 *					Image
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2016/05/08		Original
 *
 *****************************************************************************/
#define __IMAGE_C__
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "Image.h"
IMAGE *ImageCreate(UINT16 width, UINT16 height)
{
    IMAGE *ptr = (IMAGE *)pvPortMalloc(sizeof(IMAGE));
    if(ptr == NULL)
    {
        return NULL;
    }
    ptr->Data   = (BYTE *)pvPortMalloc(width * ((height + 7) / 8));
    if(ptr->Data == NULL)
    {
        free(ptr);
        return NULL;
    }
    memset(ptr->Data, 0, width * ((height + 7) / 8));
    ptr->Width  = width;
    ptr->Height = height;
    return ptr;    
}
IMAGE *ImageCopy(IMAGE *srcImage)
{
    IMAGE *pImage = ImageCreate(pImage->Width, pImage->Height);
    memcpy(pImage->Data, srcImage->Data, srcImage->Width * ((srcImage->Height + 7) / 8));
    return pImage;
}
void ImageClose(IMAGE *pImage)
{
    if(pImage != NULL)
    {
        vPortFree(pImage->Data);
        vPortFree(pImage);
    }
}

void ImageResize(IMAGE *pImage, UINT16 newWidth, UINT16 newHeight)
{
    if(pImage != NULL)
    {
        vPortFree(pImage->Data);
        pImage->Data   = (BYTE *)pvPortMalloc(newWidth * ((newHeight + 7) / 8));
        memset(pImage->Data, 0, newWidth * ((newHeight + 7) / 8));
        pImage->Width  = newWidth;
        pImage->Height = newHeight;
    }
}

void ImageCleanAll(IMAGE *pImage)
{
    if(pImage != NULL)
    {
        memset(pImage->Data, 0, (pImage->Width * ((pImage->Height + 7)/ 8)));
    }
}

void ImageSetField(IMAGE *pImage, BYTE data, UINT16 x, UINT16 y, UINT16 weight, UINT16 height)
{
    UINT16 i;
    if(pImage != NULL)
    {
        for(i = 0; i < (height + 7)/8; i++)
        {
            memset(&pImage->Data[(i + (y / 8)) * pImage->Width + x], data, weight);
        }
    }
}
void ImageCover(IMAGE *pDest, IMAGE *pSrc, UINT16 x, UINT16 y)
{
    UINT16 w, h;
    if(((y % 8) == 0) && ((pSrc->Height % 8) == 0))
    {
        for(h = 0; h < ((pSrc->Height + 7) / 8); h++)
        {
            if((y + h * 8) < pDest->Height)
            {
                memcpy(&pDest->Data[x + ( (h + y / 8) * pDest->Width)], &pSrc->Data[h * pSrc->Width], MIN(pSrc->Width, pDest->Width - x));
            }
        }
    }
    else
    {
        for(w = 0; w < pSrc->Width; w++)
        {
            for(h = 0; h < pSrc->Height; h++)
            {
                if(((w + x) < pDest->Width) && ((y + h) < pDest->Height))
                {
                    ImageSetBit(pDest, x + w, y + h, ImageGetBit(pSrc, w, h));
                }
            }
        }
    }
}
void ImageCoverR(IMAGE *pDest, IMAGE_R src, UINT16 x, UINT16 y)
{
    UINT16 w, h;
    if(((y % 8) == 0) && ((src.Height % 8) == 0))
    {
        for(h = 0; h < (src.Height / 8); h++)
        {
            if((y + h * 8) < pDest->Height)
            {
                memcpy(&pDest->Data[x + ( (h + y / 8) * pDest->Width)], &src.Data[h * src.Width], MIN(src.Width, pDest->Width - x));
            }
        }
    }
    else
    {
        for(w = 0; w < src.Width; w++)
        {
            for(h = 0; h < src.Height; h++)
            {
                if(((w + x) < pDest->Width) && ((y + h) < pDest->Height))
                {
                    ImageSetBit(pDest, x + w, y + h, ImageGetBit((IMAGE *)&src, w, h));
                }
            }
        }
    }
}
void ImageCoverEx(IMAGE *pDest, IMAGE *pSrc, POINT dstPos, POINT srcPos, SIZE size)
{
    UINT16 w, h;
    if(((dstPos.Y % 8) == 0) && ((srcPos.Y % 8) == 0) && ((size.Height % 8) == 0))
    {
        for(h = 0; (h < (size.Height / 8)) && (h < (size.Height / 8)); h++)
        {
            if((dstPos.Y + h * 8) < pDest->Height)
            {
                memcpy(&pDest->Data[dstPos.X + ( (h + dstPos.Y / 8) * pDest->Width)], &pSrc->Data[srcPos.X + h * pSrc->Width], MIN(size.Width, pDest->Width - dstPos.X));
            }
        }
    }
    else
    {
        for(w = 0; w < size.Width; w++)
        {
            for(h = 0; h < size.Height; h++)
            {
                if(((dstPos.Y + h) < pDest->Height) && ((dstPos.X + w) < pDest->Width))
                {
                    ImageSetBit(pDest, dstPos.X + w, dstPos.Y + h, ImageGetBit(pSrc, srcPos.X + w, srcPos.Y + h));
                }
            }
        }
    }
}
void ImageSetFieldEx(IMAGE *pImage, BYTE data, BYTE dataBits, UINT16 x, UINT16 y, UINT16 weight, UINT16 height)
{
    UINT16 w, h, i;
    if(pImage == NULL)
    {
        return;
    }
    
    if(((y % 8) == 0) && ((height % 8) == 0) && (dataBits >= 8))
    {
        for(h = 0; h < height/8; h++)
        {
            memset(&pImage->Data[(h + (y / 8)) * pImage->Width + x], data, weight);
        }
    }
    else
    {
        for(w = 0; w < weight; w++)
        {
            for(h = 0; h < height/8; h++)
            {
                for(i = 0; i < dataBits; i++)
                {
                    ImageSetBit(pImage, x + w, y + h + i, (data >> i) & 1);
                }
            }
        }
    }
}
void ImageDrawLine(IMAGE *pImage, UINT16 x1, UINT16 y1, UINT16 x2, UINT16 y2, BYTE size)
{
    UINT16 j, i, h = 0, xIndex = 0, yIndex = 0;
    for(j = x1; (j <= x2) && (j < pImage->Width); j++)
    {
        xIndex = j;
        yIndex = y1 + ( j - x1) * (y2 - y1)/(x2 - x1);
        for(h = 0; h < size; h++)
        {
            if((xIndex + h) < pImage->Width)
            {
                for(i = 0; i < size; i++)
                {
                    if((yIndex + i) < pImage->Height)
                    {
                        pImage->Data[pImage->Width * ((yIndex + i) / 8) + (xIndex + h)] |= 1 << ((yIndex + i) % 8);
                    }
                }
            }
        }
    }
    for(j = y1; (j <= y2) && (j < pImage->Height); j++)
    {
        xIndex = x1 + ( j - y1) * (x2 - x1)/(y2 - y1);
        yIndex = j;
        for(h = 0; h < size; h++)
        {
            if((xIndex + h) < pImage->Width)
            {
                for(i = 0; i < size; i++)
                {
                    if((yIndex + i) < pImage->Height)
                    {
                        pImage->Data[pImage->Width * ((yIndex + i) / 8) + (xIndex + h)] |= 1 << ((yIndex + i) % 8);
                    }
                }
            }
        }
    }
}
void ImageDrawDashedLine(IMAGE *pImage, UINT16 x1, UINT16 y1, UINT16 x2, UINT16 y2, BYTE size, BYTE gapBlack, BYTE gapWhite)
{
    UINT16 j, i, h = 0, xIndex = 0, yIndex = 0;
    for(j = x1; (j <= x2) && (j < pImage->Width); j++)
    {
        if((j % (gapBlack + gapWhite)) >= gapBlack)
        {
            continue;
        }
//        counter++;
        xIndex = j;
        yIndex = y1 + ( j - x1) * (y2 - y1)/(x2 - x1);
        for(h = 0; h < size; h++)
        {
            if((xIndex + h) < pImage->Width)
            {
                for(i = 0; i < size; i++)
                {
                    if((yIndex + i) < pImage->Height)
                    {
                        pImage->Data[pImage->Width * ((yIndex + i) / 8) + (xIndex + h)] |= 1 << ((yIndex + i) % 8);
                    }
                }
            }
        }
    }
    for(j = y1; (j <= y2) && (j < pImage->Height); j++)
    {
        if((j % (gapBlack + gapWhite)) >= gapBlack)
        {
            continue;
        }
//        counter++;
        xIndex = x1 + ( j - y1) * (x2 - x1)/(y2 - y1);
        yIndex = j;
        for(h = 0; h < size; h++)
        {
            if((xIndex + h) < pImage->Width)
            {
                for(i = 0; i < size; i++)
                {
                    if((yIndex + i) < pImage->Height)
                    {
                        pImage->Data[pImage->Width * ((yIndex + i) / 8) + (xIndex + h)] |= 1 << ((yIndex + i) % 8);
                    }
                }
            }
        }
    }
}
void ImageSetBit(IMAGE *pImage, UINT16 x, UINT16 y, BYTE status)
{
    if((x >= pImage->Width) || (y >= pImage->Height))
    {
        return;
    }
    if(status)
    {
        pImage->Data[(y / 8) * pImage->Width + x] |= (1 << (y % 8));
    }
    else
    {
        pImage->Data[(y / 8) * pImage->Width + x] &= ~(1 << (y % 8));
    }
}
BYTE ImageGetBit(IMAGE *pImage, UINT16 x, UINT16 y)
{
    return (pImage->Data[(y / 8) * pImage->Width + x] >> (y % 8)) & 1;    
}
void ImageRotate(IMAGE *pImage, ENUM_ROTATE rotate)
{
    IMAGE *pImgTemp = NULL;
    UINT16 x, y;
//    BYTE status = 0;
    if(rotate == ROTATE_0)
    {
        return;
    }
    if(pImage != NULL)
    {
        pImgTemp = ImageCreate(pImage->Height, pImage->Width);
        switch(rotate)
        {
            case ROTATE_90:
                for(x = 0; x < pImage->Width; x++)
                {
                    for(y = 0; y < pImage->Height; y++)
                    {
                       ImageSetBit(pImgTemp,  y, pImgTemp->Height - x - 1, ImageGetBit(pImage, x, y));
                    }
                }
                break;
            case ROTATE_180:
                for(x = 0; x < pImage->Width; x++)
                {
                    for(y = 0; y < pImage->Height; y++)
                    {
                       ImageSetBit(pImgTemp,  pImgTemp->Width - y - 1, pImgTemp->Height - x - 1, ImageGetBit(pImage, x, y));
                    }
                }
                break;
            case ROTATE_270:
                for(x = 0; x < pImage->Width; x++)
                {
                    for(y = 0; y < pImage->Height; y++)
                    {
                       ImageSetBit(pImgTemp,  pImgTemp->Width - y - 1, x, ImageGetBit(pImage, x, y));
                    }
                }
                break;
        }
        pImage->Height = pImgTemp->Height;
        pImage->Width  = pImgTemp->Width;
        vPortFree(pImage->Data);
        pImage->Data = pImgTemp->Data;
        vPortFree(pImgTemp);
    }
}
UINT16 ImageCalcBlackCount(IMAGE *pImage, UINT16 x1, UINT16 y1, UINT16 x2, UINT16 y2)
{
    UINT16 w, h;
    UINT16 count = 0;
    if(pImage == NULL)
    {
        return 0;
    }
    for(w = x1; w <= x2; w++)
    {
        for(h = y1; h <= y2; h++)
        {
           count += ImageGetBit(pImage, w, h);
        }
    }
    return count;
}
void ImageZoom(IMAGE *pImage, UINT16 newWidth, UINT16 newHeight)
{
    IMAGE *pImgTemp = NULL;
    UINT16 i, j;
    UINT32 scale, scaleH, sum = 0, startX, startY, endX, endY;
    if((pImage->Width == newWidth) && (pImage->Height == newHeight))
    {
        return;
    }
    if(pImage != NULL)
    {
        pImgTemp = ImageCreate(newWidth, newHeight);
        if(pImage->Width > newWidth)    
        {
            scale = ((pImage->Width) * 1000/ newWidth);
            scaleH = ((pImage->Height) * 1000/ newHeight);
            for(j = 0; j < newHeight; j++)
            {
                for(i = 0; i < newWidth; i++)
                {
                    startX = MAX(((i * scale)/1000), 0);
                    startY = MAX(((j * scaleH)/1000), 0);
                    endX = MIN(startX + (scale > 1000), pImage->Width - 1);
                    endY = MIN(startY + (scaleH > 1000), pImage->Height - 1);
                    
                    sum = ImageCalcBlackCount(pImage, startX, startY, endX, endY);
                    sum += (ImageGetBit(pImage, startX, startY) * 1);
                    ImageSetBit(pImgTemp, i, j, (sum * 3) >= (((endX - startX + 1) * (endY - startY + 1))) + 1);
                }
            }
        }
        else
        {            
            scale  = (newWidth  / pImage->Width);
            scaleH = (newHeight / pImage->Height);
            for(j = 0; j < newHeight; j++)
            {
                for(i = 0; i < newWidth; i++)
                {
              //      ImageSetBit(pImgTemp, i, j, ImageGetBit(pImage,i / scale, j / scaleH));
                    if((i % scale) == 0)
                    { 
                        if((j % scaleH) == 0)
                        {
                            ImageSetBit(pImgTemp, i, j, ImageGetBit(pImage,i / scale, j / scaleH));
                        }
                        else
                        {
                            ImageSetBit(pImgTemp, i, j, ImageGetBit(pImage,i / scale, j / scaleH) | ImageGetBit(pImage,i / scale, MIN(pImage->Height - 1 ,(j / scaleH) + 1)));
                        }
                    }
                    else
                    {
                        if((j % scaleH) == 0)
                        {
                             ImageSetBit(pImgTemp, i, j, ImageGetBit(pImage,i / scale, j / scaleH) | ImageGetBit(pImage,MIN(pImage->Width - 1, (i / scale) + 1), j / scaleH));
                        }
                        else
                        {
                           BYTE a = ImageGetBit(pImage,i / scale, j / scaleH) + ImageGetBit(pImage,MIN(pImage->Width - 1, (i / scale) + 1), MIN(pImage->Height - 1 ,(j / scaleH) + 1));
                           BYTE b = ImageGetBit(pImage,MIN(pImage->Width - 1, (i / scale) + 1), j / scaleH) + ImageGetBit(pImage,i / scale, MIN(pImage->Height - 1 ,(j / scaleH) + 1));
                            ImageSetBit(pImgTemp, i, j, (a + b) >= 2);
                    
                        }
                     //   ImageGetBit(pImage,i / scale, j / scaleH)
                     //   ImageSetBit(pImgTemp, i, j, );
                    }
//                    startX = MAX(((i * scale)/1000), 0);
//                    startY = MAX(((j * scaleH)/1000), 0);
//                    endX = MIN(startX + (scale > 1000), pImage->Width - 1);
//                    endY = MIN(startY + (scaleH > 1000), pImage->Height - 1);
//                    
//                    sum = ImageCalcBlackCount(pImage, startX, startY, endX, endY);
//                    sum += (ImageGetBit(pImage, startX, startY) * 1);
//                    ImageSetBit(pImgTemp, i, j, (sum * 3) >= (((endX - startX + 1) * (endY - startY + 1))) + 1);
                }
            }
        }
        ImageResize(pImage, newWidth, newHeight);
        memcpy(pImage->Data, pImgTemp->Data, pImage->Height * pImage->Width / 8);        
        ImageClose(pImgTemp);
    }
}
void ImageSetAlign(IMAGE *pImage, BYTE align)  // 0:Left, 1:Center, 2:Right
{
    BYTE *ptr = NULL;
    UINT16 i, j, leftBorder = 0, rightBorder = 0, offset = 0;
    if(pImage == NULL)
    {
        return ;
    }
    leftBorder = 0;
    for(i = 0; i < pImage->Width;i++)
    {
        BYTE flag = 0;
        for(j = 0; j < pImage->Height / 8; j++)
        {
            if(pImage->Data[j * pImage->Width + i] != 0)
            {
                flag = 1;
                break;
            }
        }
        if(flag)
        {
            leftBorder = i + 1;
            break;
        }
    }
    rightBorder = 0;
    for(i = 0; i < pImage->Width - leftBorder + 1;i++)
    {
        BYTE flag = 0;
        for(j = 0; j < pImage->Height / 8; j++)
        {
            if(pImage->Data[(j + 1) * pImage->Width - i - 1] != 0)
            {
                flag = 1;
                break;
            }
        }
        if(flag == 1)
        {
            rightBorder = i + 1;
            break;
        }
    }
    if((rightBorder <= 1) && (leftBorder <= 1))
    {
        return;
    }
    ptr = (BYTE *)pvPortMalloc(pImage->Width * pImage->Height / 8);
    memset(ptr, 0, pImage->Width * pImage->Height / 8);
    switch(align)
    {
        case 0:
        {
            offset = 0;
            break;
        }
        case 1:
        {
            offset = (leftBorder + rightBorder) / 2;
            break;
        }
        case 2:
        {
            offset = (leftBorder + rightBorder);
            break;
        }
    }

    for(i = 0; i < pImage->Height / 8; i++)
    {
        memcpy(&ptr[i * pImage->Width + offset], &pImage->Data[i * pImage->Width + leftBorder - 1],  pImage->Width - leftBorder - rightBorder + 2);
    }
    vPortFree(pImage->Data);
    pImage->Data = ptr;  
}

void ImageRemoveBorder(IMAGE *pImage, BYTE margin, UINT16 minSize)
{
    BYTE *ptr = NULL;
    UINT16 i, j, leftBorder = 0, rightBorder = 0, newWidth = 0, offset = 0;
    if(pImage != NULL)
    {
        leftBorder = 0;
        for(i = 0; i < pImage->Width;i++)
        {
            BYTE flag = 0;
            for(j = 0; j < pImage->Height / 8; j++)
            {
                if(pImage->Data[j * pImage->Width + i] != 0)
                {
                    flag = 1;
                    break;
                }
            }
            if(flag)
            {
                leftBorder = i + 1;
                break;
            }
        }
        rightBorder = 0;
        for(i = 0; i < pImage->Width - leftBorder + 1;i++)
        {
            BYTE flag = 0;
            for(j = 0; j < pImage->Height / 8; j++)
            {
                if(pImage->Data[(j + 1) * pImage->Width - i - 1] != 0)
                {
                    flag = 1;
                    break;
                }
            }
            if(flag == 1)
            {
                rightBorder = i + 1;
                break;
            }
        }
        newWidth = MAX(0, pImage->Width - (leftBorder + rightBorder));
        if(newWidth < minSize)
        {
            offset   = (minSize - newWidth) / 2;
            newWidth = minSize;
        }
        newWidth += margin * 2;
        ptr = (BYTE *)pvPortMalloc(newWidth * pImage->Height / 8);
        memset(ptr, 0, newWidth * pImage->Height / 8);
        for(i = 0; i < pImage->Height / 8; i++)
        {
            memcpy(&ptr[i * newWidth + margin + offset], &pImage->Data[i * pImage->Width + leftBorder - 1],  pImage->Width - leftBorder - rightBorder + 2);//newWidth -  margin); //
        }
        vPortFree(pImage->Data);
        pImage->Data = ptr;
        pImage->Width = newWidth;
    }   
}

void ImageFontBold(IMAGE *pImage)
{
//    UINT16 newWidth;
    BYTE *ptr = NULL;
    UINT16 i, j;
    if(pImage != NULL)
    {
//        newWidth = (pImage->Width + 1);
//        ptr = (BYTE *)pvPortMalloc(newWidth * pImage->Height / 8);
//        memset(ptr, 0, (pImage->Width + 1) * pImage->Height / 8);    
//        for (j = 0; j <  pImage->Height / 8; j++)
//        {
//            ptr[j * (pImage->Width + 1)] = pImage->Data[j * pImage->Width];
//            for (i = 0; i < pImage->Width - 1; i++)
//            {
//                ptr[j * newWidth + i + 1] = pImage->Data[j * pImage->Width + i + 1] |  pImage->Data[j * pImage->Width + i]; 
//            }
//        }        
//        vPortFree(pImage->Data);
//        pImage->Data = ptr;
//        pImage->Width = newWidth;
       
        ptr = (BYTE *)pvPortMalloc(pImage->Width * pImage->Height / 8);
        memset(ptr, 0, pImage->Width * pImage->Height / 8);    
        for (j = 0; j <  pImage->Height / 8; j++)
        {
            ptr[j * pImage->Width] = pImage->Data[j * pImage->Width];
            for (i = 0; i < (pImage->Width - 1); i++)
            {
                ptr[j * pImage->Width + i + 1] =  pImage->Data[j * pImage->Width + i + 1] | pImage->Data[j * pImage->Width + i]; 
            }
        }        
        vPortFree(pImage->Data);
        pImage->Data = ptr;
//        pImage->Width = newWidth;
    }   
}
void ImageFontItalic(IMAGE *pImage)
{
    UINT16 newWidth;
    BYTE *ptr = NULL;
    UINT16 i, j, k;
    if(pImage != NULL)
    {
        newWidth = (pImage->Width + (pImage->Height / 3));
        ptr = (BYTE *)pvPortMalloc(newWidth * pImage->Height / 8);
        memset(ptr, 0, newWidth * pImage->Height / 8);    
        
        for ( j = 0; j < pImage->Height / 8; j++)
        {
            for (i = 0; i < pImage->Width; i++)
            {
                for (k = 0; k < 8; k++)
                {
                    BYTE offset = (pImage->Height - (k + j * 8)) * (pImage->Width / 3) / pImage->Width;
                    ptr[j * newWidth + i + offset] |= (pImage->Data[j * pImage->Width + i] & (1 << k ));
                }
            }
        }
        vPortFree(pImage->Data);
        pImage->Data = ptr;
        pImage->Width = newWidth;
    }   
}
//void ImageFontItalicEx(IMAGE *pImage, UINT16 x, UINT16 y, UINT16 width, UINT16 height)
//{
//    UINT16 newWidth;
//    BYTE *ptr = NULL;
//    UINT16 i, j, k;
//    if(pImage != NULL)
//    {
//        newWidth = (pImage->Width + (pImage->Height / 3));
//        ptr = (BYTE *)pvPortMalloc(newWidth * pImage->Height / 8);
//        memset(ptr, 0, newWidth * pImage->Height / 8);    
//        
//        for ( j = 0; j < pImage->Height / 8; j++)
//        {
//            for (i = 0; i < pImage->Width; i++)
//            {
//                for (k = 0; k < 8; k++)
//                {
//                    BYTE offset = (pImage->Height - (k + j * 8)) * (pImage->Width / 3) / pImage->Width;
//                    ptr[j * newWidth + i + offset] |= (pImage->Data[j * pImage->Width + i] & (1 << k ));
//                }
//            }
//        }
//        vPortFree(pImage->Data);
//        pImage->Data = ptr;
//        pImage->Width = newWidth;
//    }   
//}
void ImageReverse(IMAGE *pImage)
{
    UINT32 i;
    for(i = 0; i < (pImage->Width * pImage->Height / 8); i++)
    {
        pImage->Data[i] = ~pImage->Data[i];
    }
}

IMAGE *ImageCombine(IMAGE *pImage1, IMAGE *pImage2)
{
//    UINT16 i;
    IMAGE *pNewImage = NULL;
    pNewImage = ImageCreate(pImage1->Width + pImage2->Width, MAX(pImage1->Height, pImage2->Height));
    ImageCover(pNewImage, pImage1, 0, 0);
    ImageCover(pNewImage, pImage2, pImage1->Width, 0);
    ImageClose(pImage1);
    ImageClose(pImage2);    
    return pNewImage;
}
    
//__IMAGE_C__





















//                                  Image.h



/****************************************************************************
 * File Name: Image.h
 *
 * Description:
 *					Image
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2016/03/27		Original
 *
 *****************************************************************************/
#ifndef __IMAGE_H__
#define __IMAGE_H__
#include "stm32f1xx_hal.h"
#include "Types.h"
enum
{
    ROTATE_0,
    ROTATE_90,
    ROTATE_180,
    ROTATE_270,
};
typedef BYTE ENUM_ROTATE;
typedef struct __PACKED__
{
    UINT16 Width;
    UINT16 Height;
    BYTE *Data;
}IMAGE;

typedef struct __PACKED__
{
    const UINT16 Width;
    const UINT16 Height;
    const BYTE *Data;
}IMAGE_R;


IMAGE *ImageCreate(UINT16 width, UINT16 height);

IMAGE *ImageCopy(IMAGE *srcImage);
void ImageClose(IMAGE *pImage);
void ImageResize(IMAGE *pImage, UINT16 newWidth, UINT16 newHeight);
void ImageRotate(IMAGE *pImage, ENUM_ROTATE rotate);
void ImageRemoveBorder(IMAGE *pImage, BYTE margin, UINT16 minSize);
void ImageFontBold(IMAGE *pImage);
void ImageFontItalic(IMAGE *pImage);
void ImageReverse(IMAGE *pImage);
void ImageSetField(IMAGE *pImage, BYTE data, UINT16 x, UINT16 y, UINT16 weight, UINT16 height);
//void ImageCleanField(ST_IMAGE *pImage, UINT16 x, UINT16 y, UINT16 weight, UINT16 height);
void ImageCleanAll(IMAGE *pImage);
void ImageCover(IMAGE *pDest, IMAGE *pSrc, UINT16 x, UINT16 y);
void ImageCoverR(IMAGE *pDest, IMAGE_R src, UINT16 x, UINT16 y);
void ImageCoverEx(IMAGE *pDest, IMAGE *pSrc, POINT dstPos, POINT srcPos, SIZE size);
void ImageDrawLine(IMAGE *pImage, UINT16 x1, UINT16 y1, UINT16 x2, UINT16 y2, BYTE size);
void ImageDrawDashedLine(IMAGE *pImage, UINT16 x1, UINT16 y1, UINT16 x2, UINT16 y2, BYTE size, BYTE gapBlack, BYTE gapWhite);
//UINT16 ImagePutText(ST_IMAGE *pImage, UINT16 columnIndex, UINT16 rowIndex, char *pText, ENUM_FONT_NAME fontName, BYTE helfShape, ENUM_FONT_STYLE fontStyle, BYTE size, ENUM_FONT_SPACING fontSpacing, ENUM_FONT_WIDTH fontWidth);
//UINT16 ImagePutTextEx(ST_IMAGE *pImage, UINT16 columnIndex, UINT16 rowIndex, UINT16 *pText, BYTE length, ENUM_FONT_NAME fontName, BYTE helfShape, ENUM_FONT_STYLE fontStyle, BYTE size, ENUM_FONT_SPACING fontSpacing, ENUM_FONT_WIDTH fontWidth, ENUM_ORIENTATION orientation, UINT16 spaceCount);
void ImageZoom(IMAGE *pImage, UINT16 newWidth, UINT16 newHeight);
IMAGE *ImageCombine(IMAGE *pImage1, IMAGE *pImage2);

void ImageSetBit(IMAGE *pImage, UINT16 x, UINT16 y, BYTE status);
BYTE ImageGetBit(IMAGE *pImage, UINT16 x, UINT16 y);
void ImageZoomEx(IMAGE *pSrcImage, IMAGE *pDestImage, UINT16 srcX, UINT16 srcY, UINT16 srcWidth, UINT16 srcHeight, UINT16 destX, UINT16 destY, UINT16 destWidth, UINT16 destHeight);
void ImageSetAlign(IMAGE *pImage, BYTE align);  // 0:Left, 1:Center, 2:Right


//UINT16 ImageGetTextColumnLength(UINT16 *pText, BYTE length, ENUM_FONT_NAME fontName, BYTE helfShape, ENUM_FONT_STYLE fontStyle, BYTE size, ENUM_FONT_SPACING fontSpacing, ENUM_FONT_WIDTH fontWidth, ENUM_ORIENTATION orientation);
#endif
//__IMAGE_H__





















//                              Language.c  


/****************************************************************************
 * File Name: Language.c
 *
 * Description:
 *            Language
 *
 * --------------------------------------------------------------------
 * Revision Author      Date        Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2018/03/21      Original
 *
 *****************************************************************************/
#include "hal.h"
#include "Language.h"
#include "IODefines.h"

LANGUAGE_CATEGORY ChineseLan = {
	.SerialNo           = "序列号",
	.SoftVer            = "软件版本",
	.SelfCheck          = "打印自检",
	.LanguageSel        = "语言",
	.LanguageOption     = {"简体中文","English","Italian","Русский"},
	.PrintDensity       = "打印浓度",
	.DensityOption      = {"(最淡)1", "2", "3", "(较淡)4", "5", "(正常)6", "7", "8", "9", "(较浓)10", "11", "12", "13", "14", "(最浓)15"},
	.PrintSpeed         = "打印速度",
	.SpeedOption        = {"(最慢)1", "(较慢)2", "(正常)3", "(较快)4", "(最快)5"},
	.PrintDistance      = "天线距离",
	.TxPower      		= "发射功率",
//	.DistanceOption     = {"15 mm", "25 mm", "35 mm", "45 mm", "55 mm", "65 mm", "75 mm", "85 mm", "95 mm", "90 mm", "100 mm"},
	.ShutdownMode       = "关机模式",
	.ShutdownModeOption = {"从不", "5分钟", "10分钟", "20分钟", "30分钟"},
	.PaperType          = "纸张类型",
#if defined(MODEL_PT68DC)
	.PaperTypeOption    = {"连续纸", "黑标纸", "间隙纸", "定位孔","UHF标签"},
#elif defined(MODEL_PT60DC)
	.PaperTypeOption    = {"连续纸", "黑标纸", "间隙纸", "定位孔","HF标签"},
#elif defined(MODEL_PT66DC)
	.PaperTypeOption    = {"连续纸", "黑标纸", "间隙纸", "定位孔"},
#else
	#error ""
#endif	
	.AutoCalibration    = "自动标定",
	.ResetFactory       = "恢复出厂",
	.ResetFactoryMsg    = {"请先断开\n蓝牙连接", "恢复设置\n请稍等", "恢复设置\n成功"},
	.MacAdd             = "MAC 地址",
    .AlertMsg           = { "打印头\n未锁紧",
                            "未检测到\n纸张",
                            "未检测到\n间隙",
                            "电池电量低",
                            "碳带用尽",
                            "定标失败", 
                            "未检测到\n碳带",
                            "未检测到\n黑标",
                            "未检测到\n定位孔"},
    .Printing           = {"打印中","继续打印\n\n是            否","定标中","定标完成"},
    .Upgrading 	         = "升级中...",
};

LANGUAGE_CATEGORY EnglishLan = {
	.SerialNo           = "Serial No.",
	.SoftVer            = "Software Version",
	.SelfCheck          = "Print Selftest",
	.LanguageSel        = "Language",
	.LanguageOption     = {"简体中文","English","Italiano","Русский"},
	.PrintDensity       = "Print Density",	
	.TxPower      		= "TX Power",
	.DensityOption      = {"(Lightest)1", "2", "3", "(Light)4", "5", "(Normal)6", "7", "8", "9", "(Dark)10", "11", "12", "13", "14", "(Darkest)15"},
	.PrintSpeed         = "Print Speed",
	.SpeedOption        = {"(Slowest)1", "(Slow)2", "(Normal)3", "(Fast)4", "(Fastest)5"},
	.PrintDistance      = "Chip Distance",
//	.DistanceOption     = {"0 mm", "3 mm", "6 mm", "9 mm", "12 mm", "15 mm", "18 mm", "21 mm", "24 mm", "27 mm", "30 mm"},
	.ShutdownMode       = "Shutdown Mode",
	.ShutdownModeOption = {"Never", "5 Minutes", "10 Minutes", "20 Minutes", "30 Minutes"},
	.PaperType          = "Paper Type",
#if defined(MODEL_PT68DC)
	.PaperTypeOption    = {"Continuous", "Mark Paper", "Gap Paper", "Locating Hole","UHF Tag"},
#elif defined(MODEL_PT60DC)
	.PaperTypeOption    = {"Continuous", "Mark Paper", "Gap Paper", "Locating Hole","HF Tag"},
#elif defined(MODEL_PT66DC)
	.PaperTypeOption    = {"Continuous", "Mark Paper", "Gap Paper", "Locating Hole"},
#else
	#error ""
#endif	
	.AutoCalibration    = "Auto Calibration",
	.ResetFactory       = "Restore To\nFactory Settings",
	.ResetFactoryMsg    = {"Disconnect\nBluetooth First", "Factory Settings\nWait a Moment", "Success"},
	.MacAdd             = "MAC Address",
    .AlertMsg           = {"Printer Head\nis Unlocked",
                            "Out of Paper",
                            "Failed to Detect\nthe Gap",
                            "Low Battery",
                            "Run Out of\nRibbon", 
                            "Calibration failed",
                            "Out of Ribbon",
                            "Failed to Detect\nthe Mark",
                            "Failed to Detect\nthe Hole",},
	.Printing           = {"Printing","Continue\nPrinting\nYes           No","Calibrating","Success"},
    .Upgrading 	         = "Upgrading...",
};

#ifdef BRAND_ORVED
LANGUAGE_CATEGORY ItalianoLan = {
	.SerialNo           = "N. Seriale",
	.SoftVer            = "Vers. Software",
	.SelfCheck          = "Stampa di Prova",
	.LanguageSel        = "Lingua",
	.LanguageOption     = {"简体中文","Inglese","Italiano","Русский"},
	.PrintDensity       = "Densità Stampa",	
	.TxPower      		= "Potenza TX",
	.DensityOption      = {"(Chiarissimo)1", "2", "3", "(Chiaro)4", "5", "(Normale)6", "7", "8", "9", "(Scuro)10", "11", "12", "13", "14", "(Scurissimo)15"},
	.PrintSpeed         = "Velocità Stampa",
	.SpeedOption        = {"(Lentissima)1", "(Lenta)2", "(Normale)3", "(Veloce)4", "(Rapida)5"},
	.PrintDistance      = "Distanza chip",
	.ShutdownMode       = "Auto Spegnimento",
	.ShutdownModeOption = {"Mai", "5 Min", "10 Min", "20 Min", "30 Min"},
	.PaperType          = "Tipo Etichetta",
#if defined(MODEL_PT68DC)
	.PaperTypeOption    = {"Continua", "Marchiata", "Separata", "Forata","UHF Tag"},
#elif defined(MODEL_PT60DC)
	.PaperTypeOption    = {"Continua", "Marchiata", "Separata", "Forata","HF Tag"},
#elif defined(MODEL_PT66DC)
	.PaperTypeOption    = {"Continua", "Marchiata", "Separata", "Forata"},
#else
	#error ""
#endif	
	.AutoCalibration    = "Calibrazione",
	.ResetFactory       = "Reset Dati\ndi Fabbrica",//Reset ai Dati\ndi Fabbrica",
	.ResetFactoryMsg    = {"Disconnettere\nBluetooth", "Reset in Corso", "Eseguito"},
	.MacAdd             = "Indirizzo MAC",
    .AlertMsg           = { "Testina di\nStampa Sbloccata",         //"打印头\n未锁紧",
                            "Carta Esaurita",                       //"未检测到\n纸张",
                            "Impossibile\nRilevare\nl'intervallo",  //"未检测到\n间隙",
                            "Batteria Scarica",                     //"电池电量低",
                            "Ribbon in\nEsaurimento",               //"碳带用尽",
                            "Calibrazione\nnon riuscita",           //"定标失败", 
                            "Ribbon Esaurito",                     //"未检测到\n碳带",
                            "Impossibile\nRilevare\nil Segno",      //"未检测到\n黑标",
                            "Impossibile\nRilevare il foro"},       //"未检测到\n定位孔"},
	.Printing           = {"Stampa in Corso","Stampa Continua\n\nSì            No","Calibrazione\nin Corso","Eseguito"},
    .Upgrading 	         = "Aggiornamento...",
};
#endif
#ifdef BRAND_RU

LANGUAGE_CATEGORY RuLan = {
	.SerialNo           = "Номер серии",                     //序列号
	.SoftVer            = "Версия ПО",          //软件版本   
	.SelfCheck          = "Тест",            //打印自检
	.LanguageSel        = "Язык",                         //语言
	.LanguageOption     = {"简体中文","English","Italian","Русский"},     //"简体中文","English","Italian","русский язык"
	.PrintDensity       = "Яркость печати",                  //打印浓度
	.TxPower      		= "Potenza TX",
	.DensityOption      = {"1", "2", "3", "4", "5", "стандapтный 6", "7", "8", "9", "10", "11", "12", "13", "14", "15"},
	.PrintSpeed         = "Скорость печати",
	.SpeedOption        = {"медленно 1", "медленнее 2", "стандapтная 3", "Быстpее 4", "Быстpо 5"},
	.PrintDistance      = "Distanza chip",
	.ShutdownMode       = "выключение",
	.ShutdownModeOption = {"Никогда", "5 мин", "10 мин", "20 мин", "30 мин"},
	.PaperType          = "Тип бумаги",
#if defined(MODEL_PT68DC)
	.PaperTypeOption    = {"Непрерывный", "черая метка", "брешь", "дырокол","UHF"},
#elif defined(MODEL_PT60DC)
	.PaperTypeOption    = {"Непрерывный", "черая метка", "брешь", "дырокол","HF"},
#elif defined(MODEL_PT66DC)
	.PaperTypeOption    = {"Непрерывный", "черая метка", "брешь", "дырокол"},
#else
	#error ""
#endif	
	.AutoCalibration    = "калибровка",
	.ResetFactory       = "Сброс",
	.ResetFactoryMsg    = {"Сначала отключите Bluetooth", "Сбросьте\nПодождите", "Успех"},
	.MacAdd             = "MAC-адрес",
    .AlertMsg           = { "Головка готова",
                            "Нет бумаги",
                            "Не найти разрыв",
                            "Зарядите\nбатарею",
                            "Поменяйте\nленту",
                            "Головка принтера\nперегрета", 
                            "Нет риббона",
                            "Не найти метку",
                            "Нет отверстия"},
    .Printing           = {"Печать...","Печатать далее\n\n  Да       Нет ","Калибровка...","Успех"},
    .Upgrading 	        = "Обновление...",
};
#endif
#ifdef BRAND_ORVED
LANGUAGE_CATEGORY *pLanguage = &ItalianoLan;
#elif defined(BRAND_RU)
LANGUAGE_CATEGORY *pLanguage = &RuLan;
#else
LANGUAGE_CATEGORY *pLanguage = &ChineseLan;
#endif
//ENUM_LANGUAGE CurrentLanguage = LANGUAGE_CHINESE;
void LanguageSwitch(ENUM_LANGUAGE lan)
{ 
    switch (lan)
    {
        case LANGUAGE_ENGLISH:
        {
            pLanguage = &EnglishLan;
            break;
        }
#ifdef BRAND_ORVED
        default:
        case LANGUAGE_ITALIANO:
        {
            pLanguage = &ItalianoLan;
            break;
        }
#elif  defined(BRAND_RU)
        default:
        case LANGUAGE_RU:
        {
            pLanguage = &RuLan;
            break;
        }
#else
        default:
        case LANGUAGE_CHINESE:
        {
            pLanguage = &ChineseLan;
            break;
        }
#endif
    }
}





















//                                       Language.h  



/****************************************************************************
 * File Name: Language.h
 *
 * Description:
 *			    Language
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2018/03/15		Original
 *
 *****************************************************************************/
#ifndef __LANGUAGE_H__
#define __LANGUAGE_H__ 
#include "hal.h"
#include "Structures.h"
enum
{
    ALERT_HEAT_SWITCH_OPEN,
    ALERT_NO_PAPER,
    ALERT_NO_DETECT_GAP,
    ALERT_BATTERY_LOW,
    ALERT_OUT_OF_RIBBON,
    ALERT_CALIBRATION_FAILED,
    ALERT_NO_RIBBON,
    ALERT_NO_DETECT_MARK,
    ALERT_NO_DETECT_HOLE,
    ENUM_ALERT_ID_COUNT
};
typedef BYTE ENUM_ALERT_ID;
    
typedef struct
{
	const char *SerialNo;
	const char *SoftVer;
	const char *SelfCheck;
	const char *LanguageSel;
	const char *LanguageOption[ENUM_LANGUAGE_COUNT];
	const char *PrintDensity;
	const char *DensityOption[15];
	const char *PrintSpeed;
	const char *PrintDistance;
	const char *TxPower;
//	const char *DistanceOption[11];
	const char *SpeedOption[5];
	const char *ShutdownMode;
	const char *ShutdownModeOption[5];
	const char *PaperType;
	const char *PaperTypeOption[5];
	const char *AutoCalibration;
	const char *ResetFactory;
    const char *ResetFactoryMsg[3];
	const char *MacAdd;
    const char *AlertMsg[ENUM_ALERT_ID_COUNT];
    const char *Printing[4];
    const char *Upgrading;
}LANGUAGE_CATEGORY;

extern LANGUAGE_CATEGORY *pLanguage;
void LanguageSwitch(ENUM_LANGUAGE lan);
ENUM_LANGUAGE CurrentLanguageGet(void);
#endif



















//                           main.c       




/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * This notice applies to any and all portions of this file
  * that are not between comment pairs USER CODE BEGIN and
  * USER CODE END. Other portions of this file, whether 
  * inserted by the user or by software development tools
  * are owned by their respective copyright owners.
  *
  * Copyright (c) 2020 STMicroelectronics International N.V. 
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
  * modification, are permitted, provided that the following conditions are met:
  *
  * 1. Redistribution of source code must retain the above copyright notice, 
  *    this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright notice,
  *    this list of conditions and the following disclaimer in the documentation
  *    and/or other materials provided with the distribution.
  * 3. Neither the name of STMicroelectronics nor the names of other 
  *    contributors to this software may be used to endorse or promote products 
  *    derived from this software without specific written permission.
  * 4. This software, including modifications and/or derivative works of this 
  *    software, must execute solely and exclusively on microcontroller or
  *    microprocessor devices manufactured by or for STMicroelectronics.
  * 5. Redistribution and use of this software other than as permitted under 
  *    this license is void and will automatically terminate your rights under 
  *    this license. 
  *
  * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" 
  * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT 
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 
  * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY
  * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT 
  * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include "usb_device.h"
#include "Types.h"
#include "hal.h"
#include "EscCommand.h"
#include "Printer.h"
#include "Version.h"
#include "UI.h"
/* USER CODE BEGIN Includes */
#include "hal_uhf_module.h"
#include "hal_hf_module.h"
#include "MFG.h"
#include "DeviceDB.h"
#include "Power.h"
#include "stdio.h"
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
ADC_HandleTypeDef hadc2;
DMA_HandleTypeDef hdma_adc1;

SPI_HandleTypeDef hspi1;
SPI_HandleTypeDef hspi2;
SPI_HandleTypeDef hspi3;

TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;
TIM_HandleTypeDef htim4;
TIM_HandleTypeDef htim5;
TIM_HandleTypeDef htim6;
TIM_HandleTypeDef htim7;

UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;

UART_HandleTypeDef huart4;
osThreadId defaultTaskHandle;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

#define APP_START_ADDRESS (0x08008000)
#define APP_INFO_ADDRESS  (0x08009000)
#define BL_INFO_ADDRESS   (0x08001000)

const ST_FW_INFO __attribute__((at(APP_INFO_ADDRESS))) FW_INFO = {
    .UpgradeFlag  = 0xFFFFFFFF,
    .ActiveBankNo = 0xFFFFFFFF,
    .Version    = {VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_BUILD_COUNT},
    .BuildTime  = VERSION_BUILD_TIME,
    .Builder    = VERSION_BUILDER,
    .Memo       = VERSION_MEMO,
};
const ST_BL_INFO *pBL_INFO = (const ST_BL_INFO *)(BL_INFO_ADDRESS);

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_ADC2_Init(void);
static void MX_SPI1_Init(void);
static void MX_SPI2_Init(void);
static void MX_SPI3_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_TIM5_Init(void);
static void MX_TIM6_Init(void);
static void MX_TIM3_Init(void);
static void MX_TIM2_Init(void);
static void MX_TIM4_Init(void);
static void MX_TIM7_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_UART4_Init(void);

void StartDefaultTask(void const * argument);

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
                                

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/

ENUM_ERROR_CODE Printer_RibbonCheck(UINT16 decLen, UINT16 *pLastLen);
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */
//uint8_t cardType[2];
//uint8_t cardID[10];
//uint8_t cardData[16]= {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11};
//uint8_t keyPass[6] = {0xff,0xff,0xff,0xff,0xff,0xff};
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  *
  * @retval None
  */
void delay_ms(UINT32 i)
{
    UINT32 temp;
    SysTick->LOAD=7500*i;
    SysTick->CTRL=0X01;
    SysTick->VAL=0;
    do
    {
        temp=SysTick->CTRL;
    }
    while((temp&0x01)&&(!(temp&(1<<16))));
    SysTick->CTRL=0;
    SysTick->VAL=0;
}
//struct __FILE 
//{ 
//	int handle; 
//}; 

//FILE __stdout;    

//int fputc(int ch, FILE *f)
//{ 	
//	while((UART4->SR&0X40)==0);//循环发送,直到发送完毕   
//	UART4->DR = (uint8_t)ch;      
//	return ch;
//}

int fputc(int ch,FILE*f)
{
//	while((UART4->SR&0x40)==0);
//	 UART4->DR = (uint8_t) ch ;
	HAL_UART_Transmit(&huart4,(char *)&ch,1,0xFFFF);
	return ch ;
}

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

#ifndef __DEBUG__
    FLASH_OBProgramInitTypeDef obInitR, obInitW;
    HAL_FLASH_Unlock();
    HAL_FLASH_OB_Unlock();
    HAL_FLASHEx_OBGetConfig(&obInitR);
    if(obInitR.RDPLevel == OB_RDP_LEVEL_0)
    {
        obInitW.OptionType = OPTIONBYTE_RDP;
        obInitW.RDPLevel = OB_RDP_LEVEL_1;
        HAL_FLASHEx_OBProgram(&obInitW);
        HAL_FLASH_OB_Launch(); 
        HAL_Delay(100);
        HAL_FLASH_OB_Lock();
        HAL_FLASH_Lock();
        HAL_Delay(100);
        HAL_NVIC_SystemReset();
    }
    HAL_FLASH_OB_Lock();
    HAL_FLASH_Lock();
#endif
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  MX_SPI1_Init();
  MX_SPI2_Init();
  MX_SPI3_Init();
  MX_USART2_UART_Init();
  MX_TIM5_Init();
  MX_TIM6_Init();
  MX_TIM3_Init();
  MX_TIM2_Init();
  MX_TIM4_Init();
  MX_TIM7_Init();
  MX_USART1_UART_Init();
  MX_UART4_Init();
  
  
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityBelowNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */
 

  /* Start scheduler */
  osKernelStart();
  
  /* We should never get here as control is now taken by the scheduler */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {

  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Initializes the CPU, AHB and APB busses clocks 
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC|RCC_PERIPHCLK_USB;
  PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV8;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
}

/* ADC1 init function */
static void MX_ADC1_Init(void)
{

  ADC_ChannelConfTypeDef sConfig;

    /**Common config 
    */
  hadc1.Instance = ADC1;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 4;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure Regular Channel 
    */
  sConfig.Channel = ADC_CHANNEL_15;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure Regular Channel 
    */
  sConfig.Channel = ADC_CHANNEL_13;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure Regular Channel 
    */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure Regular Channel 
    */
  sConfig.Channel = ADC_CHANNEL_12;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* ADC2 init function */
static void MX_ADC2_Init(void)
{

  ADC_ChannelConfTypeDef sConfig;

    /**Common config 
    */
  hadc2.Instance = ADC2;
  hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc2.Init.ContinuousConvMode = DISABLE;
  hadc2.Init.DiscontinuousConvMode = DISABLE;
  hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc2.Init.NbrOfConversion = 1;
  if (HAL_ADC_Init(&hadc2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    /**Configure Regular Channel 
    */
  sConfig.Channel = ADC_CHANNEL_11;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc2, &sConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* SPI1 init function */
static void MX_SPI1_Init(void)
{

  /* SPI1 parameter configuration*/
  hspi1.Instance = SPI1;
  hspi1.Init.Mode = SPI_MODE_MASTER;
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
  hspi1.Init.NSS = SPI_NSS_SOFT;
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi1.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* SPI2 init function */
static void MX_SPI2_Init(void)
{

  /* SPI2 parameter configuration*/
  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi2.Init.NSS = SPI_NSS_SOFT;
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* SPI3 init function */
static void MX_SPI3_Init(void)
{

  /* SPI3 parameter configuration*/
  hspi3.Instance = SPI3;
  hspi3.Init.Mode = SPI_MODE_MASTER;
  hspi3.Init.Direction = SPI_DIRECTION_2LINES;
  hspi3.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi3.Init.CLKPolarity = SPI_POLARITY_HIGH;//LOW;
  hspi3.Init.CLKPhase = SPI_PHASE_2EDGE;//1EDGE;
  hspi3.Init.NSS = SPI_NSS_SOFT;
  hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
  hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi3.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi3.Init.CRCPolynomial = 10;
  if (HAL_SPI_Init(&hspi3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* TIM1 init function */
static void MX_TIM5_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim5.Instance = TIM5;
  htim5.Init.Prescaler = 3600 - 1;
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim5.Init.Period = 1000 - 1;
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}
static void MX_TIM6_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim6.Instance = TIM6;
  htim6.Init.Prescaler = 3600 - 1;
  htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim6.Init.Period = 1000 - 1;
  htim6.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim6, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}
static void MX_TIM7_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim7.Instance = TIM7;
  htim7.Init.Prescaler = 3600 - 1;
  htim7.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim7.Init.Period = 1000 - 1;
  htim7.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim7.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim7) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim7, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim7, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}
/* TIM2 init function */
static void MX_TIM2_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 36 - 1;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 2000 - 1;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* TIM3 init function */
static void MX_TIM3_Init(void)
{

  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;

  htim3.Instance = TIM3;
  htim3.Init.Prescaler = 36 - 1;
  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim3.Init.Period = 1000 - 1;
  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 100;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  HAL_TIM_MspPostInit(&htim3);

}

/* TIM4 init function */
static void MX_TIM4_Init(void)
{

  TIM_ClockConfigTypeDef sClockSourceConfig;
  TIM_MasterConfigTypeDef sMasterConfig;

  htim4.Instance = TIM4;
  htim4.Init.Prescaler = 36 - 1;
  htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim4.Init.Period = 10 - 1;
  htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* USART1 init function */
static void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* USART2 init function */
static void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;//473933;//460800;//
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;//UART_HWCONTROL_CTS;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

/* UART4 init function */
static void MX_UART4_Init(void)
{

  huart4.Instance = UART4;
  huart4.Init.BaudRate = 115200;
  huart4.Init.WordLength = UART_WORDLENGTH_8B;
  huart4.Init.StopBits = UART_STOPBITS_1;
  huart4.Init.Parity = UART_PARITY_NONE;
  huart4.Init.Mode = UART_MODE_TX_RX;
  huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart4.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart4) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}
/** 
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  /* DMA1_Channel6_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 6, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
     PC1   ------> SharedAnalog_PC1
     PC2   ------> SharedAnalog_PC2
     PC3   ------> SharedAnalog_PC3
     PC5   ------> SharedAnalog_PC5
*/
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

 // HAL_GPIO_WritePin(GPIOE, POWER_EN_Pin, GPIO_PIN_SET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, UHF_POWER_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOA, FLASH_SPI1_CS_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOC, PH_LAT_Pin|HR8833_AIN1_Pin|HR8833_AIN2_Pin|HR8833_BIN1_Pin 
                          |HR8833_BIN2_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOE, UHF_EN_Pin|TEST_4_Pin|PH_STB6_Pin|PH_STB5_Pin 
                          |PH_STB4_Pin|PH_STB3_Pin|PH_STB2_Pin|PH_STB1_Pin , GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOE, RFID_SPI3_CS_Pin, GPIO_PIN_SET);
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, RESERVE_2_Pin|LCD_SPI2_CS_Pin|LCD_DC_Pin|RFID_RESET_Pin 
                          |TEST_6_Pin|TEST_5_Pin, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, LCD_RES_Pin|PH_VCC_EN_Pin|HR8833_nSLEEP_Pin| 
                          USB_ID_Pin|BT_RESET_Pin, GPIO_PIN_RESET);
  HAL_GPIO_WritePin(GPIOD, PAPER_DET_EN_Pin, GPIO_PIN_SET);
  /*Configure GPIO pin : BT_CONN_STATE_Pin */
  GPIO_InitStruct.Pin = BT_CONN_STATE_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(BT_CONN_STATE_GPIO_Port, &GPIO_InitStruct);

  /*Configure GPIO pins : HW_VERSION_1_Pin HW_VERSION_2_Pin */
  GPIO_InitStruct.Pin = HW_VERSION_1_Pin|HW_VERSION_2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PH_OPEN_DET_ADC_Pin PAPER_DET_ADC_Pin PH_TEMP_ADC_Pin BATTERY_ADC_Pin */
  GPIO_InitStruct.Pin = PH_OPEN_DET_ADC_Pin|PAPER_DET_ADC_Pin|PH_TEMP_ADC_Pin|BATTERY_ADC_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : FLASH_SPI1_CS_Pin UHF_POWER_Pin */
  GPIO_InitStruct.Pin = FLASH_SPI1_CS_Pin|UHF_POWER_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PH_LAT_Pin HR8833_AIN1_Pin HR8833_AIN2_Pin HR8833_BIN1_Pin 
                           HR8833_BIN2_Pin */
  GPIO_InitStruct.Pin = PH_LAT_Pin|HR8833_AIN1_Pin|HR8833_AIN2_Pin|HR8833_BIN1_Pin 
                          |HR8833_BIN2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : ADAPTER_IN_DET_Pin RFID_IRQ_Pin */
  GPIO_InitStruct.Pin = ADAPTER_IN_DET_Pin|RFID_IRQ_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : KEY_SETUP_Pin KEY_START_Pin */
  GPIO_InitStruct.Pin = KEY_SETUP_Pin|KEY_START_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : UHF_EN_Pin TEST_4_Pin PH_STB6_Pin PH_STB5_Pin 
                           PH_STB4_Pin PH_STB3_Pin PH_STB2_Pin PH_STB1_Pin 
                           POWER_EN_Pin RFID_SPI3_CS_Pin */
  GPIO_InitStruct.Pin = UHF_EN_Pin|TEST_4_Pin|PH_STB6_Pin|PH_STB5_Pin 
                          |PH_STB4_Pin|PH_STB3_Pin|PH_STB2_Pin|PH_STB1_Pin 
                          |POWER_EN_Pin|RFID_SPI3_CS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /*Configure GPIO pins : RESERVE_2_Pin LCD_SPI2_CS_Pin LCD_DC_Pin RFID_RESET_Pin 
                           TEST_6_Pin TEST_5_Pin */
  GPIO_InitStruct.Pin = RESERVE_2_Pin|LCD_SPI2_CS_Pin|LCD_DC_Pin|RFID_RESET_Pin 
                          |TEST_6_Pin|TEST_5_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : LCD_RES_Pin PH_VCC_EN_Pin HR8833_nSLEEP_Pin PAPER_DET_EN_Pin 
                           USB_ID_Pin BT_RESET_Pin */
  GPIO_InitStruct.Pin = LCD_RES_Pin|PH_VCC_EN_Pin|HR8833_nSLEEP_Pin 
                          |USB_ID_Pin|BT_RESET_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = PAPER_DET_EN_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
  
  /*Configure GPIO pins : POWER_CHARGE_STATE_Pin USB_VBUS_Pin */
  GPIO_InitStruct.Pin = POWER_CHARGE_STATE_Pin|USB_VBUS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*Configure GPIO pin : HR8833_nFAULT_Pin */
  GPIO_InitStruct.Pin = HR8833_nFAULT_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(HR8833_nFAULT_GPIO_Port, &GPIO_InitStruct);

  /* EXTI interrupt init*/
  HAL_NVIC_SetPriority(EXTI2_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(EXTI2_IRQn);

  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used 
  * @retval None
  */
ST_SYSTEM_STATUS SystemStatus;
/* USER CODE END Header_StartDefaultTask */
#include "ICON.h"
#ifdef __DEBUG__
    BYTE temprsp[256] = {0};
#endif
void SystemInfoRefresh(BOOL initFlag)
{
    static BOOL tempChargingFlag = 0;
    static UINT16 tempCount = 0;
    static UINT16 shutdownCounter = 0;    
    static BOOL updatedFlag = 0;
    static UINT16 NoDetectGapCount = 0;
    static UINT16 CaliFailCount = 0;
//    static UINT16 NoRibbonCount = 0;
    static UINT16 batteryLowCount = 0;
    UINT16 voltage = PaperSensorVoltageGet();
    BOOL temp = 0;
    SystemStatus.PaperSensorVoltage = voltage;
    switch(DeviceDB.PrintConfig.PaperType)
    {    
        case PAPER_TYPE_GAP:
#if defined(MODEL_PT68DC) || defined(MODEL_PT60DC)
        case PAPER_TYPE_RFID:
#endif
        case PAPER_TYPE_NORMAL:
            if(SystemStatus.NoPaper != (SystemStatus.PaperSensorVoltage > PAPER_ADC_THRESHOLD_EMPTY))
            {
                SystemStatus.NoPaper = (SystemStatus.PaperSensorVoltage > PAPER_ADC_THRESHOLD_EMPTY);
                if(!SystemStatus.NoPaper)
                {
                    Printer_ClearPaperStatus();
                }
                updatedFlag = 1;
            }
            break;
        case PAPER_TYPE_HOLE:
        case PAPER_TYPE_BLACK:
            if((SystemStatus.NoPaper == 1) && (SystemStatus.PaperSensorVoltage <= PAPER_ADC_THRESHOLD_EMPTY))
            {
                SystemStatus.NoPaper = 0;
                Printer_ClearPaperStatus();
                updatedFlag = 1;
            }
            break;
    }
    if(SystemStatus.NoDetectGap)
    {
        if(++NoDetectGapCount >= 500)
        {
            SystemStatus.NoDetectGap = 0;
            NoDetectGapCount = 0;
        }
    }
    else
    {
        NoDetectGapCount = 0;
    }
    if(SystemStatus.CalibrationFailed)
    {
        if(++CaliFailCount >= 200)
        {
            SystemStatus.CalibrationFailed = 0;
            CaliFailCount = 0;
        }
    }
    if(SystemStatus.BTConn != IORead(GPIO_BT_CONN_STATE))
    {
        SystemStatus.BTConn = IORead(GPIO_BT_CONN_STATE);
        updatedFlag = 1;
    }
    if(SystemStatus.USBConn != IORead(GPIO_USB_VBUS))
    {
        SystemStatus.USBConn = IORead(GPIO_USB_VBUS);
        if(SystemStatus.USBConn)
        {
            SystemStatus.BatteryLow = 0;
        }
        updatedFlag = 1;
    }
#ifdef MODEL_PT66DC
    static BYTE RibbonChkTime = 0;
    if((SystemStatus.RibbonNoDetect) || (SystemStatus.RibbonRunout))
    {
        if(RibbonChkTime++ > 200)
        {
            RibbonChkTime = 0;
            UINT16 lastRibbonLen = 0;
            ENUM_ERROR_CODE  sta = Printer_RibbonCheck(0, &lastRibbonLen);
            if(sta != NO_ERROR)
            {
                SystemStatus.RibbonNoDetect = 1;
            }
            else if(lastRibbonLen == 0)
            {
                SystemStatus.RibbonRunout = 1;
                SystemStatus.RibbonNoDetect = 0;
            }
            else
            {
                SystemStatus.RibbonRunout = 0;
                SystemStatus.RibbonNoDetect = 0;
            }
            if((!SystemStatus.RibbonNoDetect) && (!SystemStatus.RibbonRunout))
            {
                updatedFlag = 1;
            }
        }
    }
#endif
    temp = PH_GetOpenState();
    if(SystemStatus.PHOpen != temp)
    {
        SystemStatus.PHOpen = temp;
        SystemStatus.RibbonRunout = 0;
        SystemStatus.NoDetectGap = 0;
        NoDetectGapCount = 0;
#ifdef MODEL_PT66DC
         if(SystemStatus.PHOpen == 0)
         {
            UINT16 ribbonLen = 0;
            ENUM_ERROR_CODE ribbonSta = Printer_RibbonCheck(0, &ribbonLen);
            if(ribbonSta != NO_ERROR)
            {
                SystemStatus.RibbonNoDetect = 1;
            }
            else if(ribbonLen == 0)
            {
                SystemStatus.RibbonRunout = 1;
                SystemStatus.RibbonNoDetect = 0;
            }
            else
            {
                SystemStatus.RibbonRunout = 0;
                SystemStatus.RibbonNoDetect = 0;
            }
            if((SystemStatus.RibbonNoDetect) || (SystemStatus.RibbonRunout))
            {
                updatedFlag = 1;
            }
        }
#endif
        if(!initFlag)
        {
            UI_SendEvent((SystemStatus.PHOpen)?(UIEVENT_HEAT_OPEN):(UIEVENT_HEAT_CLOSE), NULL);
        }
        //flag = 1;
    }
    
    SystemStatus.RibbonVoltage  = RibbonSensorVoltageGet(); //
//    if(SystemStatus.NoRibbon)
//    {
//        if(SystemStatus.RibbonVoltage >= RIBBOM_DET_VOLTAGE_THRESHOLD)
//        {
//            SystemStatus.NoRibbon = 0;
//            NoRibbonCount = 0;
//            updatedFlag = 1;
//        }
//    }
//    else
//    {
//        if(SystemStatus.RibbonVoltage < RIBBOM_DET_VOLTAGE_THRESHOLD)
//        {
//            if(NoRibbonCount < 30)
//            {
//                NoRibbonCount++;
//            }
//            else
//            {
//                SystemStatus.NoRibbon = 1;
//                UI_SendEvent(UIEVENT_NO_RIBBON, NULL);
//            }            
//        }
//        else
//        {
//            NoRibbonCount = 0;
//        }
//    }
    if(SystemStatus.Charging != !IORead(GPIO_BAT_CHARGE_DET))
    {
        SystemStatus.Charging = !IORead(GPIO_BAT_CHARGE_DET);
        //updatedFlag = 1;
    }
    SystemStatus.Charging = !IORead(GPIO_BAT_CHARGE_DET);
    if(SystemStatus.DcConn != IORead(GPIO_ADAPTER_IN_DET))
    {
        SystemStatus.DcConn = IORead(GPIO_ADAPTER_IN_DET);
        updatedFlag = 1;
    }
    SystemStatus.BatVoltage = BatteryVoltageGet();
    if((!initFlag) && (!Printer_IsBusy()))
    {
        ENUM_BATTERY_LEVEL batLV = VoltageToBatLevel(SystemStatus.BatVoltage);
        if(SystemStatus.BatLevel != batLV)
        {
            SystemStatus.BatLevel = batLV;
            UI_SendEvent(UIEVENT_BATTERY_LV_CHANGE, NULL);
        }
        if(!SystemStatus.DcConn)
        {
            if(SystemStatus.BatLevel == BATTERY_LEVEL_0)
            {
                if(!SystemStatus.BatteryLow)
                {            
                    if(++batteryLowCount >= 300)
                    {
                        SystemStatus.BatteryLow = 1;
                        batteryLowCount = 0;
                        UI_SendEvent(UIEVENT_BATTERY_LOW, NULL);
                    }
                }
            }
            else
            {
                if(SystemStatus.BatteryLow)
                {
                    if(++batteryLowCount >= 300)
                    {
                        SystemStatus.BatteryLow = 0;
                        batteryLowCount = 0;
                        //updatedFlag = 1;
                        UI_SendEvent(UIEVENT_BATTERY_LOW_RESUME, NULL);
                    }
                }
                else
                {
                    batteryLowCount = 0;
                }
            }
        }
    }
    if((!initFlag) && (!SystemStatus.DcConn))
    {
        if(Printer_IsPrinting() || Printer_IsBusy())
        {
            shutdownCounter = 0;
        }
        else if(++shutdownCounter >= 300)
        {
            shutdownCounter = 300;
            if(SystemStatus.BatVoltage < BATTORY_SHUTDOWN_THRESHOLD)
            {
                UI_SendEvent(UIEVENT_SHUTDOWN, NULL);
            }
        }
    }
    if(SystemStatus.DcConn)
    {
        SystemStatus.BatteryLow = 0;
    }
//    ENUM_BATTERY_LEVEL lv = VoltageToBatLevel(SystemStatus.BatVoltage);
//    if(SystemStatus.BatLevel != lv)
//    {
//        SystemStatus.BatLevel = lv;
//        //UI_SendEvent(UIEVENT_BATTERY_LV_CHANGE, NULL);
//    }
#ifdef MODEL_PT66DC
    static UINT16 ribbonDecTime = 0;
    extern UINT32 DecRibbonLength;
    if(!Printer_IsPrinting())
    {
        if(ribbonDecTime++ >= 100)
        {
            if(DecRibbonLength > 0)
            {
                UINT16 ribbonLen = 0;
                ENUM_ERROR_CODE ribbonSta = Printer_RibbonCheck(DecRibbonLength / 8, &ribbonLen);
                SystemStatus.RibbonRunout = ((ribbonSta != NO_ERROR) || (ribbonLen == 0));
                DecRibbonLength = 0;
//                if(SystemStatus.RibbonRunout)
//                {
//                    PrintStatus.AbortFlag = 1;
//                }
                ribbonDecTime = 0;
            }
        }
    }
    else
    {
        ribbonDecTime = 0;
    }
#endif
    if((!initFlag) && (updatedFlag) && (!Printer_IsPrinting()))
    {
        updatedFlag = 0;
        UI_SendEvent(UIEVENT_SYSTEM_STATUS_CHANGE, NULL);
    }        
    SystemStatus.PHTempVoltage  = PHTemeVoltageGet();
//    SystemStatus.SysTemperature = SysTemeGet();
    if((!initFlag) && (tempCount++ > 50))
    {
        tempCount = 0;
        if(SystemStatus.Charging && (!Printer_IsPrinting()))
        {
            LCD_TitleBatLevelSet(tempChargingFlag?(MIN(BATTERY_LEVEL_4, SystemStatus.BatLevel + 1)):(MIN(BATTERY_LEVEL_3,SystemStatus.BatLevel)));
            tempChargingFlag = !tempChargingFlag;
        }
//        LCD_PutText(0,  0, 16, "%4d", SystemStatus.RibbonVoltage);
    }
//extern INT16 tempComp;
//extern INT16 warmComp;
//extern INT16 voltComp;
//extern INT16 rfidComp;
//extern INT16 bitCountComp;
//extern INT16 comp;
//static UINT16 tempCount3 = 0;
//    if(tempCount3++ > 100)
//    {
//        tempCount3 = 0;
//        LCD_PutText(0,  0, 16, "%04X%04X%04X%04X", tempComp,warmComp,voltComp,rfidComp);
//        LCD_PutText(0,  16, 16, "%04X%04X", bitCountComp,comp);
//    }
#ifdef __DEBUG__
    static UINT16 tempCount2 = 0;
    if(tempCount2++ > 30)
    {
        tempCount2 = 0;
        typedef struct
        {
            BYTE                State;
            UINT32              Count;
            UINT32              PrintIndex;
            BOOL                RecviveDone;
            BOOL                IsPrinting;
            BOOL                IsBusy;
            BOOL                AbortFlag;
            BYTE                RestPages;
            UINT32              IdleTime;
            BOOL                IdleFlag;
        }ST_PRINT_STATUS;
        extern ST_PRINT_STATUS PrintStatus;
//        LCD_PutText(64,  0, 16, "%d,%d,%d,%d", PrintStatus.State, PrintStatus.IsPrinting, PrintStatus.IsBusy, PrintStatus.AbortFlag);
//        LCD_PutText(64,  16, 16, "%d,%4d", PrintStatus.IdleFlag, PrintStatus.IdleTime);
        typedef struct
        {
            BYTE                DetectionState;
            UINT16              DetectionCount;
            UINT16              GapMap[10];
            BYTE                GapCount;
            ENUM_PAPER_STATE    LastRealState;
            UINT16              FallbackCount;
            UINT16              ForwardCount;
            UINT32              PaperMinVoltage;
            UINT32              PaperMaxVoltage;
            UINT32              PaperGapThresholdVoltage;
            UINT16              PaperVoltage;
            UINT32              PaperVoltageCount;
            ENUM_PAPER_STATE    PaperState_Real;
            ENUM_PAPER_STATE    PaperState_Cutter;
            ENUM_PAPER_STATE    PaperState_Heat;
            UINT16              PaperVoltage_Exist;
            UINT16              PaperVoltage_Gap;
            UINT16              PaperAntennaAddressStart;
            UINT16              PaperAntennaAddressEnd;
        }ST_PAPER_STATUS;
        extern ST_PAPER_STATUS PaperStatus;
//        tempCount = 0;
//        
extern UINT16 test_printRowCount;
extern UINT16 test_printRowCountLast;
extern BYTE GapStateFlag;
//        LCD_PutText(0,  16, 16, "%4d", SystemStatus.RibbonVoltage);
//        UINT16 PC;
//        BYTE EPC[32];
//        INT16 rssi;
//        ENUM_ERROR_CODE status = ISO18K6C_InventoryOnce(40, &PC, EPC, &rssi);
//        LCD_PutText(0,  0, 16, "%d", (status == NO_ERROR));
        
//        UINT16 rspLen = 0;
//        BYTE tagCount = 0;
//        ENUM_ERROR_CODE status =  ISO18K6C_CountInventory(20, temprsp, &rspLen, &tagCount);
//        
//        LCD_PutText(0,  16, 16, "%d", (status == NO_ERROR)?(tagCount):(0));
//        if(status == NO_ERROR)
//        {
//            break;
//        }
//        LCD_PutText(0,  0, 16, "%4d", SystemStatus.BatVoltage);
//        LCD_PutText(0,  0, 16, "%4d,%4d,%4d,%d", SystemStatus.RibbonVoltage, SystemStatus.PaperSensorVoltage, SystemStatus.BatVoltage, SystemStatus.PauseFlag);
//        LCD_PutText(0, 16, 16, "%4d,%4d,%4d,%d", PaperStatus.PaperMinVoltage, PaperStatus.PaperMaxVoltage, PaperStatus.PaperGapThresholdVoltage, PaperStatus.DetectionDone);
//        //LCD_PutText(0, 32, 16, "%4d", PaperStatus.PaperVoltage_Exist);
//        LCD_PutText(0, 16, 16, "%4d,%4d,%4d,%d", PaperStatus.PaperVoltage_Exist, PaperStatus.PaperVoltage_Gap, PaperStatus.PaperGapThresholdVoltage, PaperStatus.DetectionState);
       // LCD_PutText(0, 32, 16, "%3d,%3d,%3d,%3d", test_printRowCount, test_printRowCountLast, PaperStatus.FallbackCount, PaperStatus.ForwardCount);
//        LCD_PutText(0, 32, 16, "%4d,%4d,%d", PaperStatus.PaperMinVoltage, PaperStatus.PaperMaxVoltage, GapStateFlag);
//        LCD_PutText(0, 32, 16, "%d,%d ", PaperStatus.PaperAntennaAddressStart, PaperStatus.PaperAntennaAddressEnd);
//        LCD_PutText(0, 48, 16, "%d,%d,%d,%d,%d", PaperStatus.GapMap[0], PaperStatus.GapMap[1], PaperStatus.GapMap[2], PaperStatus.GapMap[3], PaperStatus.GapMap[4]);
//        //LCD_PutText(0, 0, 16, "%d", SystemStatus.BatVoltage);
         
//            extern ST_PRINT_LABEL_CONFIG PrintLabelConfig;
//            LCD_PutText(0,  32, 16, "%d,%d,%d ", PrintStatus.RestPages, PrintLabelConfig.LabelIndex, PrintLabelConfig.LabelCount);       
    }
#endif

//    ENUM_ERROR_CODE status = NO_ERROR;
//    BYTE CardType[2];
//    BYTE CardID[8];
//    status = ISO14443A_Get_CardType_ID(CardType, CardID);
//    LCD_PutText(0, 0, 16, "%02X", status);
    
//        LCD_PutText(0, 16, 16, "%.3f", SystemStatus.SysTemperature);
//        LCD_PutText(0, 32, 16, "%d", SystemStatus.PHTempVoltage);
//        LCD_PutImageR(96, 0, ICON_BatteryLevel[lv], 0);
//        LCD_PutText(0, 0, 16, "%d", SystemStatus.PaperSensorVoltage);
       // LCD_PutText(0, 0, 16, "%d", IORead(GPIO_HEAT_SWITCH_DET));
//typedef struct
//{
//    UINT32 StartIndex;
//    UINT32 Length;
//}ST_FLASH_BUFFER;
//extern ST_FLASH_BUFFER FlashBufDB;
//extern INT32 U2rxCount2;
//extern INT32 U2rxCount3;

//extern BYTE lastU2Rx[16];

//typedef struct
//{
//    BYTE  Interface;
//    BYTE  Mode;
//    BYTE  State;
//    BYTE  CmdID;
//    BYTE            DataBuffer[1030];
//    UINT16          DataLength;
//    BYTE            SubDataIndex;
//    UINT16          SubDataLength;
//    
//    UINT32          OtaAddrIndex;
//    char            OtaFilename[100];
//    char            OtaFilesize[10];
//    UINT32          IdleTime;
//    BOOL            SetupModeEn;
//}ST_CMD_DB;
//extern ST_CMD_DB CmdDB;

//extern UINT16 test_popCount;
//extern UINT16 test_popCount2;
//extern UINT16 test_popCount3;
//extern UINT16 test_popCount4;
//extern UINT16 test_popCount5;
//extern UINT16 test_popCount6;

//extern UINT32 rxtest;
//    LCD_PutText(0, 16, 16, "%d,%d ", rxtest, g_DeviceStatus.RealStatusFlag.Bits.DataReceived);
//A    LCD_PutText(0, 0, 16, "%d,%d,%d ", FlashBufDB.StartIndex, FlashBufDB.Length, g_DeviceStatus.RealStatusFlag.Value);
 //   LCD_PutText(0, 16, 16, "%d,%d,%d ", U2rxCount2, U2rxCount3, g_DeviceStatus.RealStatusFlag.Bits.DataReceived);
//    LCD_PutText(0, 32, 16, "%02X%02X%02X%02X%02X%02X%02X%02X",  lastU2Rx[15],
//                                                                lastU2Rx[14],
//                                                                lastU2Rx[13],
//                                                                lastU2Rx[12],
//                                                                lastU2Rx[11],
//                                                                lastU2Rx[10],
//                                                                lastU2Rx[9],
//                                                                lastU2Rx[8]);
//    LCD_PutText(0, 48, 16, "%02X%02X%02X%02X%02X%02X%02X%02X",  lastU2Rx[7],
//                                                                lastU2Rx[6],
//                                                                lastU2Rx[5],
//                                                                lastU2Rx[4],
//                                                                lastU2Rx[3],
//                                                                lastU2Rx[2],
//                                                                lastU2Rx[1],
//                                                                lastU2Rx[0]);
 //   LCD_PutText(0, 48, 16, "%d,%d,%d,%d ", test_popCount,test_popCount2,test_popCount3,test_popCount4);
   // LCD_PutText(0, 48, 16, "%d,%d ", test_popCount5,test_popCount6);
    //LCD_PutText(0, 48, 16, "%02X,%d,%d ", CmdDB.State,test_popCount,test_popCount2);
       
       
}
void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN 5 */
	printf("123456789...\n\r");
    HAL_Init2();
    ESC_Init();
    Printer_Init();
    

  /* init code for USB_DEVICE */
    IOWrite(GPIO_USB_ID, 0);
    vTaskDelay(100);
    IOWrite(GPIO_USB_ID, 1);
    MX_USB_DEVICE_Init();
    DeviceDB_Load();
    SystemInfoRefresh(1);
    UI_Init();
    Printer_Startup();
    UINT16 lastRibbonLen = 0;
#ifdef MODEL_PT66DC
    ENUM_ERROR_CODE  sta = Printer_RibbonCheck(0, &lastRibbonLen);
    SystemStatus.RibbonNoDetect = ((sta != NO_ERROR) || (lastRibbonLen == 0));
#endif
    /* Infinite loop */
    for(;;)
    {
        SystemInfoRefresh(0);
        osDelay(10);
    }
    /* USER CODE END 5 */ 
}

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  file: The file name as string.
  * @param  line: The line in file as a number.
  * @retval None
  */
void _Error_Handler(char *file, int line)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

void vApplicationStackOverflowHook( TaskHandle_t xTask, char *pcTaskName )
{
    char test[110];
#ifndef __DEBUG__
      NVIC_SystemReset();
#endif
    while(1)
    {
        sprintf(test, "%s", pcTaskName);
    }
}
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/



























//                 MFG.c





/****************************************************************************
 * File Name: MFG.c
 *
 * Description:
 *					Manufacturing
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/12/05		Original
 *
 *****************************************************************************/
#include "hal.h"
#include <string.h>
#include "MFG.h"
#include "Version.h"
#include "Structures.h"
#include "UI.h"

ST_MFG_INFO MfgInfo;
static void MFG_Read(ST_MFG_INFO *pMfg)
{
    ExtFlash_Read(FLASH_ADDRESS_MFG_INFO, (BYTE *)pMfg, sizeof(ST_MFG_INFO));
}

static void MFG_Write(ST_MFG_INFO *pMfg)
{
    ExtFlash_Erase4K(FLASH_ADDRESS_MFG_INFO); //flash地址0x00166000
    ExtFlash_Write(FLASH_ADDRESS_MFG_INFO,(BYTE *)pMfg, sizeof(ST_MFG_INFO));
}
char *MFG_GetFWVersion(char *buf)
{
//    const char *buildTime = VERSION_BUILD_TIME;
//#define VERSION_MAJOR       0
//#define VERSION_MINOR       8
//#define VERSION_PATCH       0
//#define VERSION_BUILD_COUNT 21
    //sprintf(buf, "02.001.%c%c%c%c%c%c", buildTime[2] + 17, buildTime[3] + 17, buildTime[5], buildTime[6], buildTime[8], buildTime[9]);
    sprintf(buf, "02.001.%02u%02u%02u", VERSION_MAJOR, VERSION_MINOR, VERSION_BUILD_COUNT);
    buf[strlen(buf)] = '\0';
    return buf;
}
void MFG_Save(void)
{
    MFG_Write(&MfgInfo);
}
BOOL MFG_BTNameSet(char *str)
{
    if(IORead(GPIO_BT_CONN_STATE))
    {
        return 0;
    }
    return BT_SetName(str);
}
BOOL MFG_BTPinSet(char *str)
{
    if(IORead(GPIO_BT_CONN_STATE))
    {
        return 0;
    }
    return BT_SetPin(str);
}
BOOL MFG_SerialNoSet(char *str)
{
    strncpy(MfgInfo.SerialNo, str, 20);
    MFG_Save();
    UI_Refresh();
    return 1;
}
BOOL MFG_ModelNameSet(char *str)
{
    strncpy(MfgInfo.ModelNo, str, 20);
    MFG_Save();
    UI_Refresh();
    return 1;
}
BOOL MFG_WriteInfo(ST_MFG_WRITE_INFO *pInfo)
{
    strncpy(MfgInfo.SerialNo, pInfo->SerialNo, 17);
    strncpy(MfgInfo.ModelNo, pInfo->ModelName, 17);
    strncpy(MfgInfo.BT.Name, pInfo->BTName, 17);
    strncpy(MfgInfo.BT.Pin, pInfo->BTPin, 9);
    MFG_Save();
    UI_Refresh();
    return MFG_BTFactoryDefault();
}
void MFG_Init(void)
{
    MFG_Read(&MfgInfo);
    
//    MfgInfo.Reserve1[0]  = 0x00;
//    MfgInfo.Reserve1[1]  = 0x83;
//    MfgInfo.Reserve1[2]  = 0x01;
//    MfgInfo.Reserve1[3]  = 0x00;
//    MfgInfo.Reserve1[4]  = 0x05;
//    MfgInfo.Reserve1[5]  = 0x0D;
//    MfgInfo.Reserve1[6]  = 0x20;
//    MfgInfo.Reserve1[7]  = 0x02;
//    MfgInfo.Reserve1[8]  = 0x00;
//    MfgInfo.Reserve1[9]  = 0x00;
//    MfgInfo.Reserve1[10] = 0x00;
//    MfgInfo.Reserve1[11] = 0x01;
//    MfgInfo.Reserve1[12] = 0x00;
//    MfgInfo.Reserve1[13] = 0x00;
//    MfgInfo.Reserve1[14] = 0x00;
//    MfgInfo.Reserve1[15] = 0x02;
//    MfgInfo.Reserve1[16] = 0x00;
//    MfgInfo.Reserve1[17] = 0x00;
//    memset(MfgInfo.Vender,   0, 33);
//    memset(MfgInfo.ModelNo,  0, 33);
//    memset(MfgInfo.SerialNo, 0, 33);
//    memcpy(MfgInfo.Vender,   "PUTY", 4);
//    memcpy(MfgInfo.ModelNo,  "PT-66DC", 7);
//    memcpy(MfgInfo.SerialNo, "11101800002", 11);
//    MfgInfo.Reserve2[0]  = 0x59;
//    MfgInfo.Reserve2[1]  = 0x5A;
//    MfgInfo.Reserve2[2]  = 0x4D;
//    MfgInfo.Reserve2[3]  = 0x04;
//    MfgInfo.Reserve2[4]  = 0x06;
//    MfgInfo.Reserve2[5]  = 0x80;
//    MfgInfo.Reserve2[6]  = 0x00;
//    MfgInfo.Reserve2[7]  = 0x31;
//    MfgInfo.Reserve2[8]  = 0x36;
//    MfgInfo.Reserve2[9]  = 0x30;
//    MfgInfo.Reserve2[10] = 0x31;
//    MfgInfo.Reserve2[11] = 0x31;
//    MfgInfo.Reserve2[12] = 0x37;
//    MfgInfo.Reserve2[13] = 0x00;
//    MfgInfo.Reserve2[14] = 0x00;
//    MfgInfo.Reserve2[15] = 0x52;
//    MfgInfo.Reserve2[16] = 0x65;
//    MfgInfo.Reserve2[17] = 0x69;
//    MfgInfo.Reserve2[18] = 0x6E;
//    MfgInfo.Reserve2[19] = 0x69;
//    MfgInfo.Reserve2[20] = 0x74;
//    MfgInfo.Reserve2[21] = 0x00;
//    MFG_Write(&MfgInfo);
//    char buf[32];
//    strcpy(MfgInfo.ModelNo, "PT-66DC");
//    //strcpy(MfgInfo.SerialNo, "12345678");
//    sprintf(buf, "%s_%s", MfgInfo.ModelNo, MfgInfo.SerialNo);
//    BT_SetName(buf);
//    MFG_Save();
    if((MfgInfo.BT.ValidCheck1 != VALID_CHECK_VALUE) || (MfgInfo.BT.ValidCheck2 != VALID_CHECK_VALUE) || (MfgInfo.BT.TableVersion != BT_INFO_TABLE_VERSION))
    {
        char buf[32];
        MfgInfo.BT.MacAddr[0] = 0;
        MfgInfo.BT.MacAddr[1] = 0;
        MfgInfo.BT.MacAddr[2] = 0;
        MfgInfo.BT.MacAddr[3] = 0;
        MfgInfo.BT.MacAddr[4] = 0;
        MfgInfo.BT.MacAddr[5] = 0;
        strcpy(MfgInfo.BT.Name, MODEL_NO);
        MfgInfo.BT.FWVersion[0] = '\0';
        strcpy(MfgInfo.BT.Pin, BT_PIN);
        strcpy(MfgInfo.ModelNo, MODEL_NO);
        strcpy(MfgInfo.SerialNo, "12345678");
        strcpy(MfgInfo.Vender, "PUTY");
        if(!IORead(GPIO_BT_CONN_STATE))
        {
            if(!BT_GetMac(MfgInfo.BT.MacAddr))
            {
                return;
            }
    //        if(!BT_GetName(MfgInfo.BT.Name))
    //        {
    //            return;
    //        }
            vTaskDelay(10);
            if(!BT_GetName(buf))
            {
                return;
            }
            for(BYTE i = 0; i < 16; i++)
            {
                if(buf[i] == '_')
                {
                    buf[i] = '\0';
                }
            }
            strncpy(MfgInfo.BT.Name, buf, 16);
            MfgInfo.BT.Name[16] = '\0';
            vTaskDelay(10);
            if(!BT_GetPin(MfgInfo.BT.Pin))
            {
                return;
            }
            vTaskDelay(10);
            if(!BT_GetVer(MfgInfo.BT.FWVersion))
            {
                return;
            }
            MfgInfo.BT.TableVersion = BT_INFO_TABLE_VERSION;
            MfgInfo.BT.ValidCheck1  = VALID_CHECK_VALUE;
            MfgInfo.BT.ValidCheck2  = VALID_CHECK_VALUE;
            MFG_Write(&MfgInfo);
        }
    }
}
BOOL MFG_BTFactoryDefault(void)
{
#ifndef DISABLE_BT
    if(!IORead(GPIO_BT_CONN_STATE))
    {
        char buf[32];
        char buf2[32];
        IOWrite(GPIO_BT_REST, 0);
        vTaskDelay(5);
#ifndef DISABLE_BT
        IOWrite(GPIO_BT_REST, 1);
#endif
        vTaskDelay(1000);
        sprintf(buf, "%s_%s", MfgInfo.BT.Name, MfgInfo.SerialNo);
//        if(!BT_GetName(MfgInfo.BT.Name))
//        {
//            return 0;
//        }
//        vTaskDelay(100);
        if(!BT_SetName(buf))
        {
            return 0;
        }
        vTaskDelay(10);
        if(!BT_SetPin(BT_PIN))
        {
            return 0;
        }
        
        vTaskDelay(10);
        if(!BT_GetMac(MfgInfo.BT.MacAddr))
        {
            return 0;
        }
        vTaskDelay(10);
        if(!BT_GetName(buf2))
        {
            return 0;
        }
        if(strcmp(buf, buf2))
        {
            return 0;
        }
        vTaskDelay(10);
        if(!BT_GetPin(MfgInfo.BT.Pin))
        {
            return 0;
        }
        vTaskDelay(10);
        if(!BT_GetVer(MfgInfo.BT.FWVersion))
        {
            return 0;
        }
        MfgInfo.BT.TableVersion = BT_INFO_TABLE_VERSION;
        MfgInfo.BT.ValidCheck1  = VALID_CHECK_VALUE;
        MfgInfo.BT.ValidCheck2  = VALID_CHECK_VALUE;
        MFG_Write(&MfgInfo);
        return 1;
    }
    return 0;
#else
    MfgInfo.BT.TableVersion = BT_INFO_TABLE_VERSION;
    MfgInfo.BT.ValidCheck1  = VALID_CHECK_VALUE;
    MfgInfo.BT.ValidCheck2  = VALID_CHECK_VALUE;
    MFG_Write(&MfgInfo);
    return 1;
#endif
}























//                                          MFG.h  


/****************************************************************************
 * File Name: MFG.h
 *
 * Description:
 *					Manufacturing
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/12/05		Original
 *
 *****************************************************************************/
#ifndef __MFG_H__
#define __MFG_H__
#include "hal.h"
#define BT_INFO_TABLE_VERSION 2
typedef struct
{
    BYTE Reserve1[18];
    char Vender[33];
    char ModelNo[33];
    char SerialNo[33];
    char Reserve2[22];
    struct
    {
        UINT32 ValidCheck1;
        UINT32 TableVersion;
        char FWVersion[32];
        char Name[26];
        BYTE MacAddr[6];
        char Pin[16];
        UINT32 ValidCheck2;
    }BT;
}ST_MFG_INFO;
extern ST_MFG_INFO MfgInfo;

typedef struct
{
    char BTName[17];
    char BTPin[9];
    char SerialNo[17];
    char ModelName[17];
}ST_MFG_WRITE_INFO;

void MFG_Init(void);
void MFG_Save(void);
char *MFG_GetFWVersion(char *buf);
BOOL MFG_BTFactoryDefault(void);

BOOL MFG_BTNameSet(char *str);
BOOL MFG_BTPinSet(char *str);
BOOL MFG_SerialNoSet(char *str);
BOOL MFG_ModelNameSet(char *str);
BOOL MFG_WriteInfo(ST_MFG_WRITE_INFO *pInfo);
#endif
























//                                          Power.c  


/****************************************************************************
 * File Name: Power.c
 *
 * Description:
 *					Power
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/12/03		Original
 *
 *****************************************************************************/
#include "hal.h"
#include <string.h>
/*
7.82 - 9    : 4
7.42 - 7.81 : 3
7.22 - 7.41 :2
7.02 - 7.21 : 1
6.82 - 7.01 : 0
0    - 6.81 : Shutdown
*/

const UINT16 BatLevelThreshold[5] = {7050, 7350, 7650, 7950, 8200};
ENUM_BATTERY_LEVEL VoltageToBatLevel(UINT16 volt)
{
    static UINT16 lastVoltage = 8200;
    for(BYTE i = 0; i < ENUM_BATTERY_LEVEL_COUNT; i++)
    {
        if(volt < BatLevelThreshold[i])
        {
            if(volt > (BatLevelThreshold[i] - BATTORY_LEVEL_DEBOUNCE))
            {
                if(lastVoltage < BatLevelThreshold[i])
                {
                    return i;
                }
                else
                {
                    return MIN(i + 1, ENUM_BATTERY_LEVEL_COUNT - 1);
                }
            }
            else
            {
                lastVoltage = volt;
            }
            return i;
        }
    }
    return BATTERY_LEVEL_4;
}
UINT16 Power_BatVoltageGet(void)
{
    extern uint32_t ADC1Value[3][3];
    return 3300 * (ADC1Value[0][0] & 0xFFF) * 95 / (20 * 4095);
//    UINT32 totallAdc = 0;
//    BYTE count = 0;
//    for(BYTE i = 0; i < 3; i++)
//    {
//        HAL_ADC_Start(&hadcBatPower);
//        if(HAL_ADC_PollForConversion(&hadcBatPower, 1000) != HAL_OK)
//        {
//            continue;
//        }
//        if(!HAL_IS_BIT_SET(HAL_ADC_GetState(&hadcBatPower), HAL_ADC_STATE_REG_EOC))
//        {
//            continue;
//        }
//        totallAdc += HAL_ADC_GetValue(&hadcBatPower) & 0xFFF;
//        count++;
//    }
//    return 3300 * totallAdc * 95 / (20 * 4095 * MAX(1, count));
}
void Power_Shutdown(void)
{
    BZR_SoundPowerOff();
    LCD_ShowShutdown();
    IOWrite(GPIO_POWER_9V_EN, 0);
    HAL_Uninit2();
    if(IORead(GPIO_ADAPTER_IN_DET))
    {
        while(1)
        {
//            for(UINT16 i = 0; i < 1000; i++)
//            {
//                if(IORead(GPIO_BTN_START))
//                {
//                    i = 0;
//                }
//                HAL_Delay(1);
//            }
            NVIC_SystemReset();
        }
    }
}





















//                                         Power.h  



/****************************************************************************
 * File Name: Power.h
 *
 * Description:
 *					Power
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/12/03		Original
 *
 *****************************************************************************/
#ifndef __POWER_H__
#define __POWER_H__
#include "hal.h"


ENUM_BATTERY_LEVEL VoltageToBatLevel(UINT16 volt);
void Power_Shutdown(void);

#endif



              


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值