PT606668DC\HAL:第1~12

/****************************************************************************
 * File Name: CRC16.c
 *
 * Description:
 *					CRC16
 *
 * --------------------------------------------------------------------
 * Revision	    Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong   2011/05/09 	Original
 *
 *****************************************************************************/

#include "Types.h"

const UINT16 CRC16_TABLE[256] = {
 	0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
    0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
    0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
    0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
    0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
    0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
    0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
    0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
    0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
    0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
    0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
    0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
    0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
    0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
    0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
    0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
    0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
    0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
    0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
    0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
    0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
    0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
    0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
    0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
    0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
    0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
    0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
    0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
    0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
    0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
    0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
    0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};




UINT16 CRC16(UINT16 init, BYTE *pData, UINT16 len)
{
    UINT16  i;
	BYTE	tmp, quotient;
	for(i=0; i < len; i++)
	{
		quotient = (BYTE)(init/256);
		init <<= 8;
		tmp = pData[i];
		init ^= CRC16_TABLE[quotient ^ tmp];
	}
    return init;
}








/****************************************************************************
 * File Name: CRC16.h
 *
 * Description:
 *					CRC16
 *
 * --------------------------------------------------------------------
 * Revision	    Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong   2011/05/09 	Original
 *
 *****************************************************************************/
#ifndef __CRC16_H__
#define __CRC16_H__
#include "Types.h"

UINT16 CRC16(UINT16 init, BYTE *pData, UINT16 len);
#endif










/****************************************************************************
 * File Name: hal.c
 *
 * Description:
 *					hal
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/02/13		Original
 *
 *****************************************************************************/
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include "hal.h"
#include "IODefines.h"
#include "MFG.h"
#include <string.h>
#define TIMEOUT 3000

SemaphoreHandle_t SPI1MutexHandle = NULL;
UINT32 ADC1Value[3][4];

void HAL_Init2(void)
{
    SPI1MutexHandle = xSemaphoreCreateMutex();
    ExtFlash_Init();
    Font_Init();
    BZR_Init();
    IOWrite(GPIO_PAPER_DET_EN, 1);
    HAL_ADC_Start_DMA(&hadc1, (uint32_t*)ADC1Value, 12);
    LCD_Init();
    BT_Init();
    MFG_Init();
    LCD_ShowBootup(MfgInfo.ModelNo);
    Key_Init();                              
//    osThreadDef(testTask, TestTask, osPriorityNormal, 0, 128);
//    osThreadCreate(osThread(testTask), NULL);
    PH_Init();
    Motor_Init();
#if defined(MODEL_PT60DC) || defined(MODEL_PT66DC)
    HF_Init();
#elif defined(MODEL_PT68DC)
    UHF_Init();
#endif
    
}
void HAL_Uninit2(void)
{
    IOWrite(GPIO_LCD_RST, 0);
    IOWrite(GPIO_HEAT_VCC_EN, 1);
    IOWrite(GPIO_HR8833_nSLEEP, 0);
    IOWrite(GPIO_USB_ID, 0);
    IOWrite(GPIO_BT_REST, 0);
    BT_Uninit();
    Key_Uninit();
}
UINT16 BatteryVoltageGet(void)
{
    UINT32 total = 0;
    for(BYTE i = 0; i < 3; i++)
    {
        total += (ADC1Value[i][0] & 0xFFF);
    }
    return total * 3300 * 95 / (20 * 4095 * 3);
}
UINT16 PHTemeVoltageGet(void)
{
    UINT32 total = 0;
    for(BYTE i = 0; i < 3; i++)
    {
        total += (ADC1Value[i][1] & 0xFFF);
    }
    return total * 3300 / (4095 * 3);
}
//float SysTemeGet(void)
//{
//    UINT32 total = 0;
//    for(BYTE i = 0; i < 3; i++)
//    {
//        total += (ADC1Value[i][2] & 0xFFF);
//    }
//    return (1430 - (total * 3300 / (3 * 4096))) / 4.3 + 25;
//}
void WriteFirmwareUpgrateFlag(void)
{
    HAL_FLASH_Unlock();
    if(HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, (UINT32)(&FW_INFO.UpgradeFlag), 0) != HAL_OK)
    {
    }
    HAL_FLASH_Lock();
}

UINT16 RibbonSensorVoltageGet(void)
{
    UINT32 total = 0;
    for(BYTE i = 0; i < 3; i++)
    {
        total += (ADC1Value[i][2] & 0xFFF);
    }
    return total * 3300 / (4095 * 3);
}
UINT16 PaperSensorVoltageGet(void)
{
    UINT32 total = 0;
    for(BYTE i = 0; i < 3; i++)
    {
        total += (ADC1Value[i][3] & 0xFFF);
    }
    return total * 3300 / (4095 * 3);
}
void RFID_Enable(BOOL en)
{
#if defined(MODEL_PT60DC) || defined(MODEL_PT66DC)
    HF_Enable(en);
#elif defined(MODEL_PT68DC)
    UHF_Enable(en);
#endif
}










/****************************************************************************
 * File Name: hal.h
 *
 * Description:
 *					hal
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/02/03		Original
 *
 *****************************************************************************/
#ifndef __HAL_H__
#define __HAL_H__
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include "Types.h"
#include "Errors.h"
#include "IODefines.h"
#define HAL_SPI1_TIMEOUT    3000

extern SemaphoreHandle_t SPI1MutexHandle;

void HAL_Init2(void);
void HAL_Uninit2(void);

enum
{
    PAPER_STATE_EMPTY,
    PAPER_STATE_GAP,
    PAPER_STATE_EXIST,
};
typedef BYTE ENUM_PAPER_STATE;

UINT16 PaperSensorVoltageGet(void);
UINT16 BatteryVoltageGet(void);
UINT16 PHTemeVoltageGet(void);
UINT16 RibbonSensorVoltageGet(void);
//float SysTemeGet(void);
void WriteFirmwareUpgrateFlag(void);
void HeatOpenISR(BOOL open);
void RFID_Enable(BOOL en);

//ENUM_ERROR_CODE HAL_SPI1_Send(BYTE *pData, UINT16 length);
//ENUM_ERROR_CODE HAL_SPI1_Receive(BYTE *pData, UINT16 length);
//ENUM_ERROR_CODE HAL_SPI1_SendAndReceive(BYTE *pTxData, BYTE *pRxData, UINT16 length);
#include "hal_spiflash.h"
#include "hal_font.h"
#include "hal_lcd.h"
#include "hal_keypad.h"
#include "hal_buzzer.h"
#include "hal_printHead.h"
#include "hal_stepperMotor.h"
#include "hal_bluetooth.h"
#include "hal_hf_module.h"
#include "hal_uhf_module.h"

#endif //__HAL_H__











/****************************************************************************
 * File Name: hal_bluetooth.c
 *
 * Description:
 *					hal bluetooth FSC-BT836
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2018/11/13		Original
 *
 *****************************************************************************/
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "Types.h"
#include "hal_bluetooth.h"
#include "IODefines.h"
#include "hal_spiflash.h"
#include "Image.h"

#define TIMEOUT             1000
#define AT_BUFFER_SIZE      48
#define BT_RECV_BUFFER_SIZE 256
#define BT_TX_BUFFER_SIZE   48

static BYTE rx_buffer = 0;
static BYTE tx_buffer = 0;
static BYTE tx_Flag = 0;
static QueueHandle_t UartReceiveQueueHandle = NULL;
static QueueHandle_t UartTXQueueHandle = NULL;
static QueueHandle_t AtReceiveQueueHandle = NULL;
static SemaphoreHandle_t UART2TMutexHandle = NULL;
static SemaphoreHandle_t UART2RMutexHandle = NULL;

//void USART2_IRQHandler(void)
//{
//    if(__HAL_UART_GET_FLAG(&huartBT, USART_SR_RXNE))
//    {
//        BYTE data = huartBT.Instance->DR;
//        portBASE_TYPE taskWoken = pdFALSE;
//        if(IORead(GPIO_BT_CONN_STATE) == 1)
//        {
//            xQueueSendFromISR(UartReceiveQueueHandle, &data, &taskWoken);
//        }
//        else
//        {
//            xQueueSendFromISR(AtReceiveQueueHandle, &data, &taskWoken);
//        }
//        portEND_SWITCHING_ISR(taskWoken);
//    }
//}
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    BYTE data = 0;
    portBASE_TYPE taskWoken = pdFALSE;
    if(huart->Instance == USART2)
    {
        if(xQueueReceiveFromISR(UartTXQueueHandle, &data, &taskWoken) == pdPASS)
        {
            HAL_UART_Transmit_IT(&huartBT, &data, 1);
            portEND_SWITCHING_ISR(taskWoken);
        }
        else
        {
            if(!tx_Flag)
            {
                __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
            }
 //           USART2->CR1 &= ~USART_CR1_TXEIE_TXFNFIE; // disable IRQ
        }
    }
}
//UINT32 rxtest = 0;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    BYTE data = rx_buffer;
    portBASE_TYPE taskWoken = pdFALSE;
    
//    rxtest = uxQueueMessagesWaitingFromISR(UartReceiveQueueHandle);
    if(IORead(GPIO_BT_CONN_STATE) == 1)
    {
        xQueueSendFromISR(UartReceiveQueueHandle, &data, &taskWoken);
        IOWrite(GPIO_BT_RTS, (uxQueueMessagesWaitingFromISR(UartReceiveQueueHandle) > (BT_RECV_BUFFER_SIZE - 50)));
    }
    else
    {
        xQueueSendFromISR(AtReceiveQueueHandle, &data, &taskWoken);
        IOWrite(GPIO_BT_RTS, 0);
    }
    HAL_UART_Receive_DMA(&huartBT, &rx_buffer, 1);
    portEND_SWITCHING_ISR(taskWoken);
}
static BYTE atDataReceive(BYTE *pData, BYTE len)
{
	BYTE i;
	for(i = 0; i < len; i++)
	{
		if(xQueueReceive(AtReceiveQueueHandle, &pData[i], TIMEOUT) != pdTRUE)
		{
			return i;
		}
	}
	return i;
}
static void atDataSend(BYTE *pData, BYTE len)
{
    HAL_UART_Transmit(&huartBT, pData, len, TIMEOUT);
}
static void atClearRxBuffer(void)
{	
	BYTE temp;
	while(xQueueReceive(AtReceiveQueueHandle, &temp, 0));
}


static BYTE AT_Transmit(char *pRecv, char *pSend, ...)
{
    BYTE i;
    char buf[AT_BUFFER_SIZE] = "";
    IOWrite(GPIO_BT_RTS, 0);
    HAL_UART_Receive_DMA(&huartBT, &rx_buffer, 1);
    va_list args;
    va_start(args, pSend);
    vsnprintf(buf, AT_BUFFER_SIZE, pSend, args);
    va_end(args);
	atClearRxBuffer();
	atDataSend((BYTE *)buf, strlen(buf));
    if(pRecv == NULL)
    {
        return 0;
    }
    for(i = 0; i < AT_BUFFER_SIZE; i++)
    {
		if(atDataReceive((BYTE *)&pRecv[i], 1) == 0)
		{
            //LCD_PutText(0,48,16,"3:%d,%d", i, IORead(GPIO_BT_CONN_STATE));
			return i;
		}
        if(i >= 2)
        {
            if((pRecv[i - 1] == '\r') && (pRecv[i] == '\n'))
            {
                //LCD_PutText(0,48,16,"4:%d", i + 1);
                //LCD_PutText(0,16,16,"%02X%02X%02X%02X%02X%02X", pRecv[0], pRecv[1], pRecv[2], pRecv[3], pRecv[4], pRecv[5]);
                return i + 1;
            }
        }
	}
    //LCD_PutText(0,48,16,"5:%d", i);
	return i;	
}
//static BYTE AT_Transmit(char *pRecv, char *pSend, ...)
//{
//    BYTE i;
//    char buf[AT_BUFFER_SIZE] = "";
//    va_list args;
//    va_start(args, pSend);
//    vsnprintf(buf, AT_BUFFER_SIZE, pSend, args);
//    va_end(args);
//    if(xSemaphoreTake(UART2MutexHandle, TIMEOUT) != pdTRUE)
//    {
//        return 0;
//    }
//	clearRxBuffer();
//	atDataSend((BYTE *)buf, strlen(buf));
//    if(pRecv == NULL)
//    {
//        return 0;
//    }
//    for(i = 0; i < AT_BUFFER_SIZE; i++)
//    {
//		if(atDataReceive((BYTE *)&pRecv[i], 1) == 0)
//		{
//            xSemaphoreGive(UART2MutexHandle);
//			return i;
//		}
//        if(i >= 2)
//        {
//            if((pRecv[i - 1] == '\r') && (pRecv[i] == '\n'))
//            {
//                xSemaphoreGive(UART2MutexHandle);
//                return i + 1;
//            }
//        }
//	}
//	return i;	
//}

static BOOL AT_Set(char *strName, char *strValue)
{	
    char buf[AT_BUFFER_SIZE]={0};
	
	if(AT_Transmit(buf, "AT+%s=%s\r\n", strName, strValue) > 0)
	{
        //LCD_PutText(0,32,16,"1:%02X%02X%02X%02X%02X%02X", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]);
		return !strcmp(buf, "\r\nOK\r\n");
	}
    //LCD_PutText(0,32,16,"2");
	return 0;
}
static BOOL AT_Get(char *strName, char *strValue)
{	
    BYTE i;
    char buf[AT_BUFFER_SIZE] = "";
    
	atClearRxBuffer();
    sprintf(buf, "AT+%s\r\n", strName);
	atDataSend((BYTE *)buf, strlen(buf));
    
    for(i = 0; i < AT_BUFFER_SIZE; i++)
    {
		if(atDataReceive((BYTE *)&strValue[i], 1) == 0)
		{
			return i;
		}
//        if(i >= 2)
//        {
//            if((strValue[i - 1] == '\r') && (strValue[i] == '\n'))
//            {
//                return i + 1;
//            }
//        }
        if(i >= 6)
        {
            if(!memcmp(&strValue[i - 5], "\r\nOK\r\n", 6))
            {
                return i + 1;
            }
        }
	}
	return i;
}
//#define mAT_DeviceNameSet(_value)       (AT_Set("NAME",_value))
//#define mAT_PinSet(_value)              (AT_Set("PIN",_value))

//#define mAT_MacAddrGet(_pValue)         (AT_Get("ADDR",_pValue))
//#define mAT_StatusGet(_pValue)          (AT_Transmit(_pValue, "AT\r\n"))

BOOL BT_GetMac(BYTE *pMac)
{
    char buf[AT_BUFFER_SIZE];
    if(AT_Get("ADDR",buf) > 20)
    {
        for(int i = 0; i < 6; i++)
        {
            sscanf(&buf[8 + i * 2], "%2hhx", &pMac[i]);
        }
        return 1;
    }
    return 0;
}
BOOL BT_GetName(char *pData)
{
    char buf[AT_BUFFER_SIZE] = {0};
    if(AT_Get("NAME",buf) > 8)
    {
        for(BYTE i = 0; i < 30; i++)
        {
            if((buf[8 + i] == '\0') || (buf[8 + i] == '\r') ||(buf[8 + i] == '\n'))
            {
                pData[i] = '\0';
                return 1;
            }
            pData[i] = buf[8 + i];
        }
        return 1;
    }
    return 0;
}

BOOL BT_GetPin(char *pData)
{
    char buf[AT_BUFFER_SIZE] = {0};
    if(AT_Get("PIN", buf) > 7)
    {
        for(BYTE i = 0; i < 30; i++)
        {
            if((buf[7 + i] == '\0') || (buf[7 + i] == '\r') ||(buf[7 + i] == '\n'))
            {
                pData[i] = '\0';
                return 1;
            }
            pData[i] = buf[7 + i];
        }
        return 1;
    }
    return 0;
}
BOOL BT_GetVer(char *pData)
{
    char buf[AT_BUFFER_SIZE] = {0};
    if(AT_Get("VER",buf) > 7)
    {
        for(BYTE i = 0; i < 30; i++)
        {
            if((buf[7 + i] == '\0') || (buf[7 + i] == '\r') ||(buf[7 + i] == '\n'))
            {
                pData[i] = '\0';
                return 1;
            }
            pData[i] = buf[7 + i];
        }
    }
    return 0;
}


BOOL BT_SetName(char *pValue)
{
    return AT_Set("NAME", pValue);
}
BOOL BT_SetPin(char *pValue)
{
    return AT_Set("PIN", pValue);
}
void BT_Init(void)
{
//    BYTE temp;
    UART2TMutexHandle        = xSemaphoreCreateMutex();
    UART2RMutexHandle        = xSemaphoreCreateMutex();
    UartReceiveQueueHandle  = xQueueCreate(BT_RECV_BUFFER_SIZE, sizeof(BYTE));
    UartTXQueueHandle       = xQueueCreate(BT_TX_BUFFER_SIZE, sizeof(BYTE));
    AtReceiveQueueHandle    = xQueueCreate(AT_BUFFER_SIZE, sizeof(BYTE)); 
    
//    HAL_NVIC_SetPriority(USART2_IRQn, 6, 0);
//    HAL_NVIC_EnableIRQ(USART2_IRQn);
//	if(HAL_UART_Receive_IT(&huartBT, &temp, 1)!=HAL_OK)
//	{
//		__HAL_UART_CLEAR_OREFLAG(&huartBT);
//	}
    IOWrite(GPIO_BT_REST, 0);
    vTaskDelay(5);
#ifndef DISABLE_BT
    IOWrite(GPIO_BT_REST, 1);
#endif
    IOWrite(GPIO_BT_RTS, 0);
	//__HAL_UART_ENABLE_IT(&huartBT, UART_IT_IDLE);
	HAL_UART_Receive_DMA(&huartBT,&rx_buffer,1);
//    BT_WriteString("AT+BAUD=%d\r\n", 115200);
}
void BT_Uninit(void)
{
    HAL_NVIC_DisableIRQ(USART2_IRQn);
}
void BT_ClearBuffer(void)
{
    BYTE dummy;
    if(xSemaphoreTake(UART2RMutexHandle, TIMEOUT) != pdTRUE)
    {
        return;
    }
    while(xQueueReceive(UartReceiveQueueHandle, &dummy, 0));
    xSemaphoreGive(UART2RMutexHandle);
}
void BT_WriteBuffer(BYTE *pData, UINT16 length, UINT32 timeout)
{
//    BYTE temp;
    if(length == 0)
    {
        return;
    }
    if(xSemaphoreTake(UART2TMutexHandle, timeout) != pdTRUE)
    {
        return;
    }   
    tx_Flag = 1;
    for(int i = 0; i < length; i++)
    {
        if(__HAL_UART_GET_FLAG(&huartBT, UART_FLAG_TXE) && __HAL_UART_GET_FLAG(&huartBT, UART_FLAG_TC) && (!__HAL_UART_GET_IT_SOURCE(&huartBT, UART_IT_TXE)) && (huart2.gState == HAL_UART_STATE_READY))
        //if(huart2.gState == HAL_UART_STATE_READY)
        {
//            if (xQueuePeek(UartTXQueueHandle, &temp, 0) != pdTRUE)
//            {
                tx_buffer = pData[i];
                if(HAL_UART_Transmit_IT(&huartBT, &tx_buffer, 1) == HAL_OK)
                {
                    
                }
//            }
//            else
//            {
//                
//                xQueueSend(UartTXQueueHandle, &pData[i], TIMEOUT);
//            }
        }
        else
        {
            xQueueSend(UartTXQueueHandle, &pData[i], TIMEOUT);
        }
    }
    tx_Flag = 0;
   
//    int i;    
//    if(!__HAL_UART_GET_IT_SOURCE(&huartBT, UART_IT_TXE))//huart2.gState == HAL_UART_STATE_READY)
//    {
//        HAL_UART_Transmit_IT(&huartBT, &pData[0], 1);
//        for(i = 1; i < length; i++)
//        {
//            xQueueSend(UartTXQueueHandle, &pData[i], TIMEOUT);
//        }
//    }
//    else
//    {
//        for(i = 0; i < length; i++)
//        {
//            xQueueSend(UartTXQueueHandle, &pData[i], TIMEOUT);
//        }
//    }
    //if(USART_GetFlagStatus(USART1,USART_FLAG_TXE)
    //HAL_UART_Transmit(&huartBT, pData, length, timeout);
    xSemaphoreGive(UART2TMutexHandle);
}
void BT_WriteByte(BYTE data, UINT32 timeout)
{
    BT_WriteBuffer(&data, 1, timeout);
//    if(xSemaphoreTake(UART2TMutexHandle, timeout) != pdTRUE)
//    {
//        return;
//    }
//    HAL_UART_Transmit(&huartBT, &data, 1, timeout);
//    xSemaphoreGive(UART2TMutexHandle);
}
void BT_WriteString(char *str, ...)
{
    char buf[50] = "";
    va_list args;
    va_start(args, str);
    vsnprintf(buf, 50, str, args);
    BT_WriteBuffer((BYTE *)buf, strlen(buf), TIMEOUT);
    va_end(args);
}
//BYTE UART2RxData;
//BYTE lastU2Rx[16];
BYTE BT_ReadBuffer(BYTE *pData, UINT16 length, UINT32 timeout)
{
    UINT16 i;
    if(xSemaphoreTake(UART2RMutexHandle, timeout) != pdTRUE)
    {
        return 0;
    }
    if(__HAL_UART_GET_FLAG(&huartBT,UART_FLAG_ORE) != RESET) 
    {
        __HAL_UART_CLEAR_OREFLAG(&huartBT);
        HAL_UART_Receive_DMA(&huartBT, &rx_buffer, 1);
    }
    for(i = 0; i < length; i++)
    {    
        if(uxQueueMessagesWaiting(UartReceiveQueueHandle) <= (BT_RECV_BUFFER_SIZE - 100))
        {
            IOWrite(GPIO_BT_RTS, 0);
        }
        if(xQueueReceive(UartReceiveQueueHandle, &pData[i], timeout) != pdTRUE)
        {
            xSemaphoreGive(UART2RMutexHandle);
            return i;
        }
//        U2rxCount3++;
//        if(U2rxCount3 + 100 < U2rxCount2)
//        {
//            IOWrite(GPIO_BT_RTS, 1);
//        }FlashBufQueueHandle
//        else //else if(U2rxCount3 + 50 < (U2rxCount2 ))
//        {
//            IOWrite(GPIO_BT_RTS, 0);
//        }
//        for(BYTE j = 0; j < 16; j++)
//        {
//            lastU2Rx[15 - j]= lastU2Rx[14 - j];
//        }
//        lastU2Rx[0]= pData[i];
    }
    xSemaphoreGive(UART2RMutexHandle);
    return i;
}
BOOL BT_ConnectState(void)
{
    return IORead(GPIO_BT_CONN_STATE);
}










/****************************************************************************
 * File Name: hal_bluetooth.h
 *
 * Description:
 *					hal bluetooth
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2018/11/13		Original
 *
 *****************************************************************************/
#ifndef __HAL_BLUETOOTH_H__
#define __HAL_BLUETOOTH_H__
#include "Types.h"
#include "Structures.h"
void BT_Init(void);
void BT_Uninit(void);
void BT_ClearBuffer(void);
BYTE BT_ReadBuffer(BYTE *pData, UINT16 length, UINT32 timeout);
void BT_WriteString(char *str, ...);
void BT_WriteBuffer(BYTE *pData, UINT16 length, UINT32 timeout);
void BT_WriteByte(BYTE data, UINT32 timeout);
BOOL BT_ConnectState(void);

BOOL BT_GetMac(BYTE *pMac);
BOOL BT_GetName(char *pData);
BOOL BT_GetPin(char *pData);
BOOL BT_GetVer(char *pData);
BOOL BT_SetName(char *pValue);
BOOL BT_SetPin(char *pValue);

#endif //__HAL_BLUETOOTH_H__












/****************************************************************************
 * File Name: hal_buzzer.c
 *
 * Description:
 *					Buzzer
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/02/10		Original
 *
 *****************************************************************************/
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "IODefines.h"
#include "Types.h"
#include "hal_buzzer.h"

#define     _L_DO1_HZ            262
#define     _L_RE2_HZ            294//286//294
#define     _L_MI3_HZ            330//311//330
#define     _L_FA4_HZ            349
#define     _L_SO5_HZ            392
#define     _L_LA6_HZ            440
#define     _L_SI7_HZ            494//523

#define     _M_DO1_HZ            523
#define     _M_RE2_HZ            587
#define     _M_MI3_HZ            659
#define     _M_FA4_HZ            698
#define     _M_SO5_HZ            784
#define     _M_LA6_HZ            880
#define     _M_SI7_HZ            988//987//988

#define     _H_DO1_HZ            1047//1046
#define     _H_RE2_HZ            1175//1174//1175
#define     _H_MI3_HZ            1319//1318
#define     _H_FA4_HZ            1397
#define     _H_SO5_HZ            1568//1567//1568
#define     _H_LA6_HZ            1760
#define     _H_SI7_HZ            1976//1975//1976

//static UINT8 gBootUPMusic[] = {16,0xFF,17,0xFF,18};;    // 3 4 5
//static UINT8 gBootUPTime[] = {8,16,8,16,24*3};
//static UINT8 gBootUPVole[] = {80,5,80,5,80};

typedef struct 
{
	UINT16 Freq;
	UINT16 Duration;
}ST_TONE;
const ST_TONE Tones_PowerOn[] = {
    {2100,400},
    {2300,400},
    {2400,1000},
    {0,0}
};
const ST_TONE Tones_PowerOff[] = {
    {2400,400},
    {2200,400},
    {2100,1000},
    {0,0}
};
typedef struct
{
    const ST_TONE *pTone;
    BOOL           Enable;
    UINT16         Index;
}ST_BUZZER_STATUS;
ST_BUZZER_STATUS BuzzerStatus = {
    .pTone = NULL,
    .Enable = 0,
};
void BZR_Sound(UINT16 freq)
{
    __HAL_TIM_SET_AUTORELOAD(&htimBUZZER, 1000000 / freq);
    HAL_TIM_PWM_Start(&htimBUZZER, TIM_CHANNEL_4);
}
void BZR_Stop(void)
{
    HAL_TIM_PWM_Stop(&htimBUZZER, TIM_CHANNEL_4);
}
void TIM3_IRQHandler(void)
{
//    portBASE_TYPE taskWoken = pdFALSE;    
    if(__HAL_TIM_GET_FLAG(&htimBUZZER, TIM_FLAG_UPDATE) != RESET)  
    {   
        __HAL_TIM_CLEAR_IT(&htimBUZZER, TIM_IT_UPDATE);
        if((BuzzerStatus.Enable) && (BuzzerStatus.pTone != NULL))
        {         
            if(BuzzerStatus.Index < BuzzerStatus.pTone->Duration)
            {
                BuzzerStatus.Index++;                
            }
            else
            {
                BuzzerStatus.pTone++;
                BuzzerStatus.Index = 0;
                if((BuzzerStatus.pTone->Freq == 0) && (BuzzerStatus.pTone->Duration == 0))
                {
                    BuzzerStatus.Enable = 0;
                    BuzzerStatus.pTone  = NULL;
                    HAL_TIM_PWM_Stop(&htimBUZZER, TIM_CHANNEL_4);
                    HAL_TIM_Base_Stop_IT(&htimBUZZER);
                }
                else
                {
                    __HAL_TIM_SET_AUTORELOAD(&htimBUZZER, 1000000 / BuzzerStatus.pTone->Freq);
                }
            }
        }
        else
        {
            HAL_TIM_Base_Stop_IT(&htimBUZZER);
        }
        //HAL_TIM_PWM_Stop(&htimBUZZER, TIM_CHANNEL_4);
//        if(MotorStatus.Enable)
//        {
//            if(MotorStatus.Counter >= MotorStatus.TargetCount)
//            {
//                MotorStatus.Enable  = 0;
//                HAL_TIM_Base_Stop_IT(&htimBUZZER);
//                IOWrite(GPIO_HR8833_nSLEEP, 0);
//                xSemaphoreGiveFromISR(MotorSemaphoreHandle, &taskWoken);
//                portEND_SWITCHING_ISR(taskWoken);
//                MotorStopISR();
//            }
//            else
//            {
//                // sync
//                MotorStatus.Counter++;
//                MotorStepPulse(MotorStatus.Direction);
//                MotorEncISR();
//            }
//        }
//        else
//        {
//            MotorStatus.AbortFlag = 1;
//            HAL_TIM_Base_Stop_IT(&htimMOTOR);
//            IOWrite(GPIO_HR8833_nSLEEP, 0);
//            xSemaphoreGiveFromISR(MotorSemaphoreHandle, &taskWoken);
//            portEND_SWITCHING_ISR(taskWoken);
//            MotorStopISR();
//        }
    }
}
void BZR_PlayTones(const ST_TONE* tones)
{
    BuzzerStatus.pTone  = tones;
	BuzzerStatus.Enable = 1;
    BuzzerStatus.Index  = 0;
    BZR_Sound(BuzzerStatus.pTone->Freq);
    __HAL_TIM_SET_COUNTER(&htimBUZZER, 0);
    HAL_TIM_Base_Start_IT(&htimBUZZER);
}
void BZR_SoundPowerOn(void)
{
    BZR_PlayTones(Tones_PowerOn);
//    BZR_Sound(2100);
//    vTaskDelay(200);
//    BZR_Sound(2300);
//    vTaskDelay(200);
//    BZR_Sound(2400);
//    vTaskDelay(500);
//    BZR_Stop();
}
void BZR_SoundPowerOff(void)
{
    BZR_PlayTones(Tones_PowerOff);
//    BZR_Sound(2400);
//    vTaskDelay(200);
//    BZR_Sound(2200);
//    vTaskDelay(200);
//    BZR_Sound(2100);
//    vTaskDelay(500);
//    BZR_Stop();
}
void BZR_Init(void)
{
    HAL_NVIC_SetPriority(TIM3_IRQn, 6, 1);
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
#ifndef __DEBUG__
    BZR_PlayTones(Tones_PowerOn);
#endif
}









/****************************************************************************
 * File Name: hal_buzzer.h
 *
 * Description:
 *					Buzzer
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2019/02/10		Original
 *
 *****************************************************************************/
#ifndef __HAL_BUZZER_H__
#define __HAL_BUZZER_H__
#include "Types.h"

void BZR_Sound(UINT16 freq);
void BZR_Stop(void);
void BZR_SoundPowerOn(void);
void BZR_SoundPowerOff(void);
void BZR_Init(void);
#endif //__HAL_BUZZER_H__














/****************************************************************************
 * File Name: hal_font.c
 *
 * Description:
 *					Font
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2018/03/14		Original
 *
 *****************************************************************************/
#include "stm32f1xx_hal.h"
#include "cmsis_os.h"
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "Types.h"
#include "hal.h"
#include "IODefines.h"
#include "Image.h"
#include "ICON.h"
#define TIMEOUT                 3000

static SemaphoreHandle_t _MutexHandle;
#ifdef BRAND_RU
typedef struct
{
	const UINT16 Code;
    const BYTE   Data5[5];
    const BYTE   Data16[10 * 2];
    const BYTE   Data24[16 * 3];
}ST_RU_FONT_INFO;
const ST_RU_FONT_INFO RuFontTable[] = {
    {0xA7A7, {0x7C,0x55,0x54,0x55,0x54,}, {0x00,0x00,0xFB,0x88,0x88,0x8B,0x88,0x88,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,},{0x00,0x00,0x00,0xE0,0xE7,0x67,0x60,0x60,0x60,0x67,0x67,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,0x00,}},
    {0xA7A1, {0x60,0x1C,0x12,0x1C,0x60,}, {0x00,0x00,0x80,0x78,0x08,0x78,0xC0,0x00,0x00,0x00,0x00,0x1C,0x07,0x04,0x04,0x04,0x07,0x1C,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0x20,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFC,0x9F,0x83,0x80,0x81,0x8F,0xFE,0xF0,0x80,0x00,0x00,0x00,0x00,0x00,0x0E,0x0F,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x03,0x0F,0x0E,0x00,0x00,}},
    {0xA7A2, {0xFE,0x8A,0x8A,0x8A,0x70,}, {0x00,0xF8,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x19,0x0F,0x00,0x00,0x00,},{0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x30,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x07,0x01,0x00,0x00,0x00,}},
    {0xA7A3, {0xFE,0x92,0x92,0x92,0x6C,}, {0x00,0xF8,0x88,0x88,0x88,0xC8,0x70,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x19,0x0F,0x00,0x00,0x00,},{0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x1C,0x37,0xF3,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x07,0x01,0x00,0x00,0x00,}},
    {0xA7A4, {0x7E,0x02,0x02,0x02,0x02,}, {0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7A5, {0x60,0x3C,0x22,0x22,0x7E,}, {0x00,0x00,0xF8,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x70,0x18,0x17,0x10,0x10,0x10,0x10,0x1F,0x70,0x00,},{0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xFC,0xFF,0x0F,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x7C,0x7E,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x7C,0x7C,0x00,0x00,}},
    {0xA7A6, {0x7C,0x54,0x54,0x54,0x54,}, {0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x88,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x00,0x00,},{0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x00,0x00,0x00,0x00,}},
    {0xA7A8, {0x24,0x18,0x3C,0x18,0x24,}, {0x08,0x10,0x60,0x80,0xF8,0x80,0x60,0x10,0x08,0x00,0x10,0x0C,0x02,0x01,0x1F,0x01,0x02,0x0C,0x10,0x00,},{0x00,0x20,0xE0,0xC0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xE0,0x20,0x00,0x00,0x00,0x00,0x83,0xE7,0x7C,0x18,0xFF,0xFF,0x18,0x7C,0xE7,0x83,0x00,0x00,0x00,0x00,0x08,0x0E,0x07,0x01,0x00,0x00,0x0F,0x0F,0x00,0x00,0x01,0x07,0x0E,0x08,0x00,}},
    {0xA7A9, {0x22,0x41,0x49,0x49,0x36,}, {0x00,0x10,0x88,0x88,0x88,0x88,0x70,0x00,0x00,0x00,0x00,0x08,0x10,0x10,0x10,0x19,0x0F,0x00,0x00,0x00,},{0x00,0x00,0xC0,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x1C,0x37,0xF3,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x07,0x01,0x00,0x00,0x00,0x00,}},
    {0xA7AA, {0x7C,0x20,0x10,0x08,0x7C,}, {0x00,0xF8,0x00,0x00,0x80,0xE0,0x30,0xF8,0x00,0x00,0x00,0x1F,0x0C,0x07,0x01,0x00,0x00,0x1F,0x00,0x00,},{0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0xC0,0x70,0x1C,0x0F,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7AB, {0x7C,0x21,0x12,0x09,0x7C,}, {0x00,0xF8,0x03,0x02,0x82,0xE1,0x30,0xF8,0x00,0x00,0x00,0x1F,0x0C,0x07,0x01,0x00,0x00,0x1F,0x00,0x00,},{0x00,0x00,0xE0,0xE0,0x06,0x0E,0x0C,0x08,0x08,0xCC,0xE6,0xE6,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x80,0xC0,0x70,0x1C,0x0F,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7AC, {0x7F,0x08,0x14,0x22,0x41,}, {0x00,0xF8,0x80,0xC0,0x60,0x30,0x08,0x00,0x00,0x00,0x00,0x1F,0x01,0x03,0x06,0x0C,0x10,0x00,0x00,0x00,},{0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x80,0xC0,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x10,0x38,0xEE,0xC7,0x83,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x01,0x03,0x07,0x0C,0x08,0x00,0x00,0x00,}},
    {0xA7AD, {0x40,0x70,0x0E,0x02,0x7E,}, {0x00,0x00,0xF8,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x10,0x1E,0x03,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFF,0x1F,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x0C,0x0E,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7AE, {0x7E,0x0C,0x70,0x0C,0x7E,}, {0xF8,0xF8,0x70,0xC0,0x00,0xC0,0x30,0xF8,0xF8,0x00,0x1F,0x1F,0x00,0x01,0x02,0x01,0x00,0x1F,0x1F,0x00,},{0x00,0x00,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x01,0x0F,0x3C,0x60,0x3C,0x0F,0x01,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x00,0x00,}},
    {0xA7AF, {0x7E,0x08,0x08,0x08,0x7E,}, {0x00,0xF8,0x80,0x80,0x80,0x80,0x80,0xF8,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,},{0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,}},
    {0xA7B0, {0x3C,0x42,0x42,0x42,0x3C,}, {0xE0,0x30,0x08,0x08,0x08,0x08,0x10,0xE0,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x10,0x0C,0x07,0x00,0x00,},{0x00,0x00,0x00,0x80,0xC0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0E,0x0C,0x0C,0x0C,0x0C,0x06,0x07,0x03,0x00,0x00,0x00,}},
    {0xA7B1, {0x7E,0x02,0x02,0x02,0x7E,}, {0x00,0xF8,0x08,0x08,0x08,0x08,0x08,0xF8,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,},{0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7B2, {0xFE,0x22,0x22,0x22,0x1C,}, {0x00,0xF8,0x08,0x08,0x08,0x98,0xF0,0x00,0x00,0x00,0x00,0x1F,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,},{0x00,0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x60,0x60,0x60,0x60,0x60,0x30,0x1F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7B3, {0x38,0x44,0x82,0x82,0x44,}, {0x00,0xC0,0x30,0x18,0x08,0x08,0x08,0x10,0x00,0x00,0x00,0x07,0x0C,0x10,0x10,0x10,0x10,0x08,0x00,0x00,},{0x00,0x00,0x00,0x80,0xC0,0xC0,0x60,0x60,0x60,0x60,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x00,0x00,0x00,0x00,}},
    {0xA7B4, {0x02,0x02,0x7E,0x02,0x02,}, {0x00,0x08,0x08,0x08,0xF8,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,},{0x00,0x00,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7B5, {0x86,0x48,0x30,0x08,0x06,}, {0x00,0x18,0x70,0xC0,0x00,0xC0,0x70,0x18,0x00,0x00,0x00,0x10,0x10,0x19,0x0F,0x01,0x00,0x00,0x00,0x00,},{0x00,0x00,0x60,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x3E,0xF8,0xE0,0xFC,0x1F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7B6, {0x18,0x24,0x7E,0x24,0x18,}, {0x00,0xC0,0x20,0x10,0xF8,0x10,0x30,0xC0,0x00,0x00,0x00,0x07,0x0C,0x08,0x1F,0x08,0x04,0x03,0x00,0x00,},{0x00,0x00,0x00,0x00,0x80,0xC0,0xC0,0xE0,0xE0,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFF,0x83,0x01,0x00,0xFF,0xFF,0x00,0x01,0x83,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x07,0x06,0x0F,0x0F,0x06,0x07,0x03,0x01,0x00,0x00,0x00,}},
    {0xA7B7, {0x44,0x28,0x10,0x28,0x44,}, {0x08,0x18,0x30,0xE0,0xC0,0x70,0x18,0x08,0x00,0x00,0x10,0x18,0x0E,0x03,0x01,0x07,0x0C,0x18,0x10,0x00,},{0x00,0x00,0x20,0x60,0xE0,0x80,0x00,0x00,0x00,0x00,0x80,0xE0,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xC7,0xFF,0x3C,0x7E,0xEF,0xC3,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x0C,0x0F,0x07,0x01,0x00,0x00,0x00,0x01,0x07,0x0F,0x0C,0x08,0x00,0x00,}},
    {0xA7B8, {0x3E,0x20,0x20,0x3E,0xE0,}, {0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x10,0x1F,0x70,0x00,},{0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x7F,0x7C,0x00,0x00,0x00,}},
    {0xA7B9, {0x0E,0x10,0x10,0x08,0x7E,}, {0x00,0xF8,0x80,0x00,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x1F,0x00,0x00,},{0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x07,0x1F,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,}},
    {0xA7BA, {0x7E,0x40,0x7E,0x40,0x7E,}, {0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x00,0x00,},{0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,0x00,}},
    {0xA7BB, {0x3E,0x20,0x3E,0x20,0x7E,}, {0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0xF8,0x00,0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x70,0x00,},{0x00,0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x7F,0x7C,0x00,0x00,}},
    {0xA7BC, {0x02,0x7E,0x48,0x48,0x30,}, {0x08,0x08,0xF8,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x19,0x0F,0x00,0x00,},{0x00,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x30,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x06,0x07,0x03,0x00,0x00,0x00,}},
    {0xA7BD, {0x7E,0x48,0x30,0x00,0x7E,}, {0x00,0xF8,0x80,0x80,0x80,0x00,0x00,0xF8,0x00,0x00,0x00,0x1F,0x10,0x10,0x18,0x0F,0x00,0x1F,0x00,0x00,},{0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x38,0xF0,0xE0,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x0F,0x0F,0x00,0x00,0x00,}},
    {0xA7BE, {0x7E,0x48,0x48,0x48,0x30,}, {0x00,0xF8,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x19,0x0F,0x00,0x00,0x00,},{0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0x18,0x18,0x18,0x30,0xF0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x07,0x01,0x00,0x00,0x00,}},
    {0xA7BF, {0x22,0x49,0x49,0x2A,0x1C,}, {0x00,0x10,0x88,0x88,0x88,0x88,0x90,0xE0,0x00,0x00,0x00,0x08,0x10,0x10,0x10,0x10,0x0C,0x07,0x00,0x00,},{0x00,0x00,0x00,0xC0,0x60,0x60,0x60,0x60,0x60,0xC0,0xC0,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x19,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x07,0x03,0x00,0x00,0x00,0x00,}},
    {0xA7C0, {0x7F,0x08,0x3E,0x41,0x3E,}, {0x00,0xF8,0x80,0xF0,0x18,0x08,0x08,0x18,0xF0,0x00,0x00,0x1F,0x00,0x07,0x18,0x10,0x10,0x18,0x07,0x00,},{0x00,0x00,0xE0,0xE0,0x00,0x00,0x00,0xC0,0xE0,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x18,0x18,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x01,0x07,0x0E,0x0C,0x0C,0x0E,0x07,0x01,0x00,0x00,}},
    {0xA7C1, {0x66,0x19,0x09,0x09,0x7F,}, {0x00,0x00,0xF0,0x88,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x18,0x1E,0x03,0x01,0x01,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xDF,0xF8,0x70,0x30,0x30,0x30,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0F,0x0F,0x01,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7D1, {0x34,0x52,0x4A,0x3C,0x40,}, {0x00,0x00,0x80,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x0C,0x12,0x12,0x12,0x0A,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC6,0xE3,0x63,0x63,0x63,0x63,0x67,0xFE,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07,0x0C,0x0C,0x0C,0x0C,0x06,0x06,0x0F,0x0F,0x00,0x00,0x00,}},
    {0xA7D2, {0x3C,0x4A,0x4A,0x31,0x01,}, {0x00,0xF0,0x48,0x24,0x24,0x24,0x64,0x80,0x00,0x00,0x00,0x07,0x08,0x10,0x10,0x10,0x08,0x07,0x00,0x00,},{0x00,0x00,0x00,0xC0,0xE0,0x30,0x30,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x0C,0x06,0x03,0x03,0x03,0x03,0x0E,0xFE,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x07,0x0E,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,}},
    {0xA7D3, {0x00,0x7C,0x54,0x54,0x38,}, {0x00,0xC0,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x1F,0x12,0x12,0x12,0x12,0x0D,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x63,0x63,0x63,0x63,0x77,0xDE,0xDE,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x00,0x00,}},
    {0xA7D4, {0x00,0x7C,0x04,0x04,0x04,}, {0x00,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7D5, {0x60,0x38,0x24,0x24,0x7C,}, {0x00,0x00,0xC0,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x70,0x1C,0x17,0x10,0x10,0x10,0x1F,0x70,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xFF,0x7F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x7E,0x0F,0x0D,0x0C,0x0C,0x0C,0x0C,0x0F,0x0F,0x7C,0x7C,0x00,0x00,0x00,}},
    {0xA7D6, {0x00,0x38,0x54,0x54,0x58,}, {0x00,0x00,0x80,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00,0x0F,0x0A,0x12,0x12,0x12,0x12,0x13,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0x66,0x63,0x63,0x63,0x63,0x66,0x7E,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7D8, {0x24,0x18,0x3C,0x18,0x24,}, {0x40,0x80,0x00,0x00,0xC0,0x00,0x00,0x80,0x40,0x00,0x10,0x18,0x0D,0x02,0x1F,0x02,0x0D,0x18,0x10,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x0E,0x9C,0xF0,0x60,0xFF,0xFF,0x60,0xF0,0x9C,0x0E,0x03,0x01,0x00,0x00,0x08,0x0C,0x0F,0x03,0x00,0x00,0x0F,0x0F,0x00,0x00,0x03,0x0F,0x0C,0x08,0x00,}},
    {0xA7D9, {0x00,0x28,0x44,0x54,0x38,}, {0x00,0x40,0x40,0x40,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x10,0x12,0x12,0x12,0x12,0x0D,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,0x63,0x63,0x63,0x63,0x67,0xFE,0xDE,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x00,0x00,}},
    {0xA7DA, {0x00,0x3C,0x10,0x08,0x3C,}, {0x00,0xC0,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,0x00,0x00,0x1F,0x0C,0x06,0x03,0x01,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0xC0,0xF0,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x07,0x01,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7DB, {0x00,0x7A,0x24,0x12,0x78,}, {0x00,0xC0,0x18,0x10,0x10,0x88,0xC0,0x00,0x00,0x00,0x00,0x1F,0x0C,0x06,0x03,0x01,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x18,0x38,0x20,0x20,0x20,0x38,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0xC0,0xF0,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x07,0x01,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7DC, {0x00,0x7C,0x10,0x28,0x44,}, {0x00,0xC0,0x00,0x00,0x80,0x80,0x40,0x00,0x00,0x00,0x00,0x1F,0x02,0x05,0x0C,0x18,0x10,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x20,0x70,0xD8,0x8C,0x06,0x03,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x01,0x03,0x06,0x0C,0x08,0x00,0x00,0x00,}},
    {0xA7DD, {0x00,0x20,0x1C,0x04,0x3C,}, {0x00,0x00,0xC0,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x10,0x18,0x07,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xFF,0x3F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7DE, {0x7C,0x08,0x30,0x08,0x7C,}, {0x00,0xC0,0x40,0x80,0x00,0x80,0x40,0xC0,0x00,0x00,0x00,0x1F,0x00,0x03,0x04,0x03,0x00,0x1F,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x1F,0x0F,0x3C,0xF0,0x80,0xF0,0x3C,0x0F,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,}},
    {0xA7DF, {0x00,0x7C,0x10,0x10,0x7C,}, {0x00,0xC0,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x1F,0x02,0x02,0x02,0x02,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x60,0x60,0x60,0x60,0x60,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7E0, {0x00,0x38,0x44,0x44,0x38,}, {0x00,0x00,0x80,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00,0x0F,0x18,0x10,0x10,0x10,0x08,0x07,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0xFE,0xF8,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x07,0x0E,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,}},
    {0xA7E1, {0x00,0x3C,0x04,0x04,0x3C,}, {0x00,0xC0,0x40,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7E2, {0x00,0xFC,0x24,0x24,0x18,}, {0x00,0xC0,0x80,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00,0xFF,0x10,0x10,0x10,0x10,0x08,0x07,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x0E,0x06,0x03,0x03,0x03,0x07,0xFE,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,}},
    {0xA7E3, {0x00,0x18,0x24,0x24,0x00,}, {0x00,0x00,0x80,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x0F,0x08,0x10,0x10,0x10,0x10,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0x0E,0x07,0x03,0x03,0x03,0x03,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x07,0x0E,0x0C,0x0C,0x0C,0x0C,0x06,0x00,0x00,0x00,0x00,}},
    {0xA7E4, {0x00,0x04,0x3C,0x04,0x00,}, {0x00,0x40,0x40,0x40,0xC0,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7E5, {0x04,0xC8,0x30,0x08,0x04,}, {0x00,0xC0,0x80,0x00,0x00,0x00,0x80,0xC0,0x00,0x00,0x80,0x80,0x83,0x7C,0x30,0x0E,0x03,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x1F,0x7C,0xE0,0x80,0x00,0x80,0xE0,0x7C,0x1F,0x03,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0xC0,0xE3,0x7F,0x3C,0x0F,0x01,0x00,0x00,0x00,0x00,0x00,0x00,}},
    {0xA7E6, {0x18,0x24,0xFE,0x24,0x18,}, {0x00,0x80,0x40,0x20,0xFC,0x20,0x60,0xC0,0x00,0x00,0x00,0x0F,0x18,0x10,0xFF,0x10,0x08,0x07,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0x0E,0x07,0x03,0xFF,0xFF,0x03,0x03,0x0E,0xFE,0xF8,0x00,0x00,0x00,0x00,0x01,0x07,0x06,0x0C,0x0C,0xFF,0xFF,0x0C,0x0E,0x07,0x03,0x01,0x00,0x00,}},
    {0xA7E7, {0x00,0x28,0x10,0x28,0x00,}, {0x00,0x40,0xC0,0x80,0x00,0x80,0xC0,0x40,0x00,0x00,0x00,0x10,0x18,0x0D,0x03,0x07,0x0C,0x18,0x10,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x0F,0x9E,0xF8,0x60,0xF8,0x9E,0x0F,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x0C,0x0F,0x07,0x01,0x00,0x01,0x07,0x0F,0x0C,0x08,0x00,0x00,0x00,}},
    {0xA7E8, {0x00,0x3C,0x20,0x3C,0x60,}, {0x00,0xC0,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x1F,0x10,0x10,0x10,0x10,0x1F,0x70,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0F,0x7F,0x7C,0x00,0x00,}},
    {0xA7E9, {0x00,0x1C,0x10,0x10,0x7C,}, {0x00,0xC0,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x02,0x02,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x70,0x60,0x60,0x60,0x60,0x60,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,}},
    {0xA7EA, {0x3C,0x20,0x3C,0x20,0x3C,}, {0x00,0xC0,0x00,0x00,0xC0,0x00,0x00,0xC0,0x00,0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x0F,0x00,0x00,}},
    {0xA7EB, {0x3E,0x20,0x3E,0x20,0x7E,}, {0x00,0xC0,0x00,0x00,0xC0,0x00,0x00,0xC0,0x00,0x00,0x00,0x1F,0x10,0x10,0x1F,0x10,0x10,0x1F,0x70,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x0F,0x0C,0x0C,0x0C,0x0F,0x7F,0x7C,0x00,0x00,}},
    {0xA7EC, {0x00,0x04,0x7C,0x50,0x20,}, {0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x12,0x12,0x12,0x0C,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x00,0x00,}},
    {0xA7ED, {0x7C,0x50,0x20,0x00,0x7C,}, {0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x1F,0x12,0x12,0x12,0x0C,0x00,0x1F,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x0F,0x0F,0x00,0x00,0x00,}},
    {0xA7EE, {0x00,0x7E,0x48,0x48,0x30,}, {0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x12,0x12,0x12,0x12,0x0C,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x30,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x00,0x00,}},
    {0xA7EF, {0x00,0x22,0x2A,0x2A,0x1C,}, {0x00,0x40,0x40,0x40,0x40,0xC0,0x80,0x00,0x00,0x00,0x00,0x12,0x12,0x12,0x12,0x0A,0x0F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x63,0x63,0x63,0x63,0x63,0x67,0x6E,0xFC,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x06,0x03,0x01,0x00,0x00,0x00,}},
    {0xA7F0, {0x7C,0x10,0x38,0x44,0x38,}, {0x00,0xC0,0x00,0x80,0xC0,0x40,0x40,0xC0,0x80,0x00,0x00,0x1F,0x02,0x0F,0x10,0x10,0x10,0x10,0x0F,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x60,0x60,0xFC,0xFE,0x07,0x03,0x03,0x07,0xFE,0xFC,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x03,0x07,0x0E,0x0C,0x0C,0x0E,0x07,0x03,0x00,0x00,}},
    {0xA7F1, {0x00,0x68,0x14,0x14,0x7C,}, {0x00,0x00,0x80,0x40,0x40,0x40,0xC0,0x00,0x00,0x00,0x00,0x10,0x1D,0x06,0x02,0x02,0x1F,0x00,0x00,0x00,},{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x0E,0x0F,0x01,0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00,0x00,0x00,}},
    {0xA7D7, {0x00,0x38,0x55,0x54,0x59,}, {0x00,0x00,0x8C,0x4C,0x40,0x4C,0xCC,0x80,0x00,0x00,0x00,0x0F,0x0A,0x12,0x12,0x12,0x12,0x13,0x00,0x00,},{0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x00,0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0xFC,0x66,0x63,0x63,0x63,0x63,0x66,0x7E,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x07,0x06,0x0C,0x0C,0x0C,0x0C,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,}},
};
typedef struct
{
    UINT16 Code;
    UINT16 Unicode;
}ST_RU_UNI;
const ST_RU_UNI RU_UNI_TABLE[] = {
    {0x003F, 0x0400 }, /* ? 0*/
    {0xA7A7, 0x0401 }, /* 壯 1*/
    {0x0080, 0x0402 }, /* ? 2*/
    {0x0081, 0x0403 }, /* ? 3*/
    {0x00AA, 0x0404 }, /* ? 4*/
    {0x00BD, 0x0405 }, /* ? 5*/
    {0x00B2, 0x0406 }, /* ? 6*/
    {0x00AF, 0x0407 }, /* ? 7*/
    {0x00A3, 0x0408 }, /* ? 8*/
    {0x008A, 0x0409 }, /* ? 9*/
    {0x008C, 0x040A }, /* ? 10*/
    {0x008E, 0x040B }, /* ? 11*/
    {0x008D, 0x040C }, /* ? 12*/
    {0x003F, 0x040D }, /* ? 13*/
    {0x00A1, 0x040E }, /* ? 14*/
    {0x008F, 0x040F }, /* ? 15*/
    {0xA7A1, 0x0410 }, /* 均 16*/
    {0xA7A2, 0x0411 }, /* 坎 17*/
    {0xA7A3, 0x0412 }, /* 圾 18*/
    {0xA7A4, 0x0413 }, /* 坐 19*/
    {0xA7A5, 0x0414 }, /* 坏 20*/
    {0xA7A6, 0x0415 }, /* 圻 21*/
    {0xA7A8, 0x0416 }, /* 夾 22*/
    {0xA7A9, 0x0417 }, /* 妝 23*/
    {0xA7AA, 0x0418 }, /* 妒 24*/
    {0xA7AB, 0x0419 }, /* 妨 25*/
    {0xA7AC, 0x041A }, /* 妞 26*/
    {0xA7AD, 0x041B }, /* 妣 27*/
    {0xA7AE, 0x041C }, /* 妙 28*/
    {0xA7AF, 0x041D }, /* 妖 29*/
    {0xA7B0, 0x041E }, /* 妍 30*/
    {0xA7B1, 0x041F }, /* 妤 31*/
    {0xA7B2, 0x0420 }, /* 妓 32*/
    {0xA7B3, 0x0421 }, /* 妊 33*/
    {0xA7B4, 0x0422 }, /* 妥 34*/
    {0xA7B5, 0x0423 }, /* 孝 35*/
    {0xA7B6, 0x0424 }, /* 孜 36*/
    {0xA7B7, 0x0425 }, /* 孚 37*/
    {0xA7B8, 0x0426 }, /* 孛 38*/
    {0xA7B9, 0x0427 }, /* 完 39*/
    {0xA7BA, 0x0428 }, /* 宋 40*/
    {0xA7BB, 0x0429 }, /* 宏 41*/
    {0xA7BC, 0x042A }, /* 尬 42*/
    {0xA7BD, 0x042B }, /* 局 43*/
    {0xA7BE, 0x042C }, /* 屁 44*/
    {0xA7BF, 0x042D }, /* 尿 45*/
    {0xA7C0, 0x042E }, /* 尾 46*/
    {0xA7C1, 0x042F }, /* 岐 47*/
    {0xA7D1, 0x0430 }, /* 忘 48*/
    {0xA7D2, 0x0431 }, /* 忌 49*/
    {0xA7D3, 0x0432 }, /* 志 50*/
    {0xA7D4, 0x0433 }, /* 忍 51*/
    {0xA7D5, 0x0434 }, /* 忱 52*/
    {0xA7D6, 0x0435 }, /* 快 53*/
    {0xA7D8, 0x0436 }, /* 忪 54*/
    {0xA7D9, 0x0437 }, /* 戒 55*/
    {0xA7DA, 0x0438 }, /* 我 56*/
    {0xA7DB, 0x0439 }, /* 抄 57*/
    {0xA7DC, 0x043A }, /* 抗 58*/
    {0xA7DD, 0x043B }, /* 抖 59*/
    {0xA7DE, 0x043C }, /* 技 60*/
    {0xA7DF, 0x043D }, /* 扶 61*/
    {0xA7E0, 0x043E }, /* 抉 62*/
    {0xA7E1, 0x043F }, /* 扭 63*/
    {0xA7E2, 0x0440 }, /* 把 64*/
    {0xA7E3, 0x0441 }, /* 扼 65*/
    {0xA7E4, 0x0442 }, /* 找 66*/
    {0xA7E5, 0x0443 }, /* 批 67*/
    {0xA7E6, 0x0444 }, /* 扳 68*/
    {0xA7E7, 0x0445 }, /* 抒 69*/
    {0xA7E8, 0x0446 }, /* 扯 70*/
    {0xA7E9, 0x0447 }, /* 折 71*/
    {0xA7EA, 0x0448 }, /* 扮 72*/
    {0xA7EB, 0x0449 }, /* 投 73*/
    {0xA7EC, 0x044A }, /* 抓 74*/
    {0xA7ED, 0x044B }, /* 抑 75*/
    {0xA7EE, 0x044C }, /* 抆 76*/
    {0xA7EF, 0x044D }, /* 改 77*/
    {0xA7F0, 0x044E }, /* 攻 78*/
    {0xA7F1, 0x044F }, /* 攸 79*/
    {0x003F, 0x0450 }, /* ? 80*/
    {0xA7D7, 0x0451 }, /* 忸 81*/
    {0x0090, 0x0452 }, /* ? 82*/
    {0x0083, 0x0453 }, /* ? 83*/
    {0x00BA, 0x0454 }, /* ? 84*/
    {0x00BE, 0x0455 }, /* ? 85*/
    {0x00B3, 0x0456 }, /* ? 86*/
    {0x00BF, 0x0457 }, /* ? 87*/
    {0x00BC, 0x0458 }, /* ? 88*/
    {0x009A, 0x0459 }, /* ? 89*/
    {0x009C, 0x045A }, /* ? 90*/
    {0x009E, 0x045B }, /* ? 91*/
    {0x009D, 0x045C }, /* ? 92*/
    {0x003F, 0x045D }, /* ? 93*/
    {0x00A2, 0x045E }, /* ? 94*/
    {0x009F, 0x045F }, /* ? 95*/
    {0x003F, 0x0460 }, /* ? 96*/
    {0x003F, 0x0461 }, /* ? 97*/
    {0x003F, 0x0462 }, /* ? 98*/
    {0x003F, 0x0463 }, /* ? 99*/
    {0x003F, 0x0464 }, /* ? 100*/
    {0x003F, 0x0465 }, /* ? 101*/
    {0x003F, 0x0466 }, /* ? 102*/
    {0x003F, 0x0467 }, /* ? 103*/
    {0x003F, 0x0468 }, /* ? 104*/
    {0x003F, 0x0469 }, /* ? 105*/
    {0x003F, 0x046A }, /* ? 106*/
    {0x003F, 0x046B }, /* ? 107*/
    {0x003F, 0x046C }, /* ? 108*/
    {0x003F, 0x046D }, /* ? 109*/
    {0x003F, 0x046E }, /* ? 110*/
    {0x003F, 0x046F }, /* ? 111*/
    {0x003F, 0x0470 }, /* ? 112*/
    {0x003F, 0x0471 }, /* ? 113*/
    {0x003F, 0x0472 }, /* ? 114*/
    {0x003F, 0x0473 }, /* ? 115*/
    {0x003F, 0x0474 }, /* ? 116*/
    {0x003F, 0x0475 }, /* ? 117*/
    {0x003F, 0x0476 }, /* ? 118*/
    {0x003F, 0x0477 }, /* ? 119*/
    {0x003F, 0x0478 }, /* ? 120*/
    {0x003F, 0x0479 }, /* ? 121*/
    {0x003F, 0x047A }, /* ? 122*/
    {0x003F, 0x047B }, /* ? 123*/
    {0x003F, 0x047C }, /* ? 124*/
    {0x003F, 0x047D }, /* ? 125*/
    {0x003F, 0x047E }, /* ? 126*/
    {0x003F, 0x047F }, /* ? 127*/
    {0x003F, 0x0480 }, /* ? 128*/
    {0x003F, 0x0481 }, /* ? 129*/
    {0x003F, 0x0482 }, /* ? 130*/
    {0x003F, 0x0483 }, /* ? 131*/
    {0x003F, 0x0484 }, /* ? 132*/
    {0x003F, 0x0485 }, /* ? 133*/
    {0x003F, 0x0486 }, /* ? 134*/
    {0x003F, 0x0487 }, /* ? 135*/
    {0x003F, 0x0488 }, /* ? 136*/
    {0x003F, 0x0489 }, /* ? 137*/
    {0x003F, 0x048A }, /* ? 138*/
    {0x003F, 0x048B }, /* ? 139*/
    {0x003F, 0x048C }, /* ? 140*/
    {0x003F, 0x048D }, /* ? 141*/
    {0x003F, 0x048E }, /* ? 142*/
    {0x003F, 0x048F }, /* ? 143*/
    {0x00A5, 0x0490 }, /* ? 144*/
    {0x00B4, 0x0491 }, /* ? 145*/
    {0x003F, 0x0492 }, /* ? 146*/
    {0x003F, 0x0493 }, /* ? 147*/
    {0x003F, 0x0494 }, /* ? 148*/
    {0x003F, 0x0495 }, /* ? 149*/
    {0x003F, 0x0496 }, /* ? 150*/
    {0x003F, 0x0497 }, /* ? 151*/
    {0x003F, 0x0498 }, /* ? 152*/
    {0x003F, 0x0499 }, /* ? 153*/
    {0x003F, 0x049A }, /* ? 154*/
    {0x003F, 0x049B }, /* ? 155*/
    {0x003F, 0x049C }, /* ? 156*/
    {0x003F, 0x049D }, /* ? 157*/
    {0x003F, 0x049E }, /* ? 158*/
    {0x003F, 0x049F }, /* ? 159*/
    {0x003F, 0x04A0 }, /* ? 160*/
    {0x003F, 0x04A1 }, /* ? 161*/
    {0x003F, 0x04A2 }, /* ? 162*/
    {0x003F, 0x04A3 }, /* ? 163*/
    {0x003F, 0x04A4 }, /* ? 164*/
    {0x003F, 0x04A5 }, /* ? 165*/
    {0x003F, 0x04A6 }, /* ? 166*/
    {0x003F, 0x04A7 }, /* ? 167*/
    {0x003F, 0x04A8 }, /* ? 168*/
    {0x003F, 0x04A9 }, /* ? 169*/
    {0x003F, 0x04AA }, /* ? 170*/
    {0x003F, 0x04AB }, /* ? 171*/
    {0x003F, 0x04AC }, /* ? 172*/
    {0x003F, 0x04AD }, /* ? 173*/
    {0x003F, 0x04AE }, /* ? 174*/
    {0x003F, 0x04AF }, /* ? 175*/
    {0x003F, 0x04B0 }, /* ? 176*/
    {0x003F, 0x04B1 }, /* ? 177*/
    {0x003F, 0x04B2 }, /* ? 178*/
    {0x003F, 0x04B3 }, /* ? 179*/
    {0x003F, 0x04B4 }, /* ? 180*/
    {0x003F, 0x04B5 }, /* ? 181*/
    {0x003F, 0x04B6 }, /* ? 182*/
    {0x003F, 0x04B7 }, /* ? 183*/
    {0x003F, 0x04B8 }, /* ? 184*/
    {0x003F, 0x04B9 }, /* ? 185*/
    {0x003F, 0x04BA }, /* ? 186*/
    {0x003F, 0x04BB }, /* ? 187*/
    {0x003F, 0x04BC }, /* ? 188*/
    {0x003F, 0x04BD }, /* ? 189*/
    {0x003F, 0x04BE }, /* ? 190*/
    {0x003F, 0x04BF }, /* ? 191*/
    {0x003F, 0x04C0 }, /* ? 192*/
    {0x003F, 0x04C1 }, /* ? 193*/
    {0x003F, 0x04C2 }, /* ? 194*/
    {0x003F, 0x04C3 }, /* ? 195*/
    {0x003F, 0x04C4 }, /* ? 196*/
    {0x003F, 0x04C5 }, /* ? 197*/
    {0x003F, 0x04C6 }, /* ? 198*/
    {0x003F, 0x04C7 }, /* ? 199*/
    {0x003F, 0x04C8 }, /* ? 200*/
    {0x003F, 0x04C9 }, /* ? 201*/
    {0x003F, 0x04CA }, /* ? 202*/
    {0x003F, 0x04CB }, /* ? 203*/
    {0x003F, 0x04CC }, /* ? 204*/
    {0x003F, 0x04CD }, /* ? 205*/
    {0x003F, 0x04CE }, /* ? 206*/
    {0x003F, 0x04CF }, /* ? 207*/
    {0x003F, 0x04D0 }, /* ? 208*/
    {0x003F, 0x04D1 }, /* ? 209*/
    {0x003F, 0x04D2 }, /* ? 210*/
    {0x003F, 0x04D3 }, /* ? 211*/
    {0x003F, 0x04D4 }, /* ? 212*/
    {0x003F, 0x04D5 }, /* ? 213*/
    {0x003F, 0x04D6 }, /* ? 214*/
    {0x003F, 0x04D7 }, /* ? 215*/
    {0x003F, 0x04D8 }, /* ? 216*/
    {0x003F, 0x04D9 }, /* ? 217*/
    {0x003F, 0x04DA }, /* ? 218*/
    {0x003F, 0x04DB }, /* ? 219*/
    {0x003F, 0x04DC }, /* ? 220*/
    {0x003F, 0x04DD }, /* ? 221*/
    {0x003F, 0x04DE }, /* ? 222*/
    {0x003F, 0x04DF }, /* ? 223*/
    {0x003F, 0x04E0 }, /* ? 224*/
    {0x003F, 0x04E1 }, /* ? 225*/
    {0x003F, 0x04E2 }, /* ? 226*/
    {0x003F, 0x04E3 }, /* ? 227*/
    {0x003F, 0x04E4 }, /* ? 228*/
    {0x003F, 0x04E5 }, /* ? 229*/
    {0x003F, 0x04E6 }, /* ? 230*/
    {0x003F, 0x04E7 }, /* ? 231*/
    {0x003F, 0x04E8 }, /* ? 232*/
    {0x003F, 0x04E9 }, /* ? 233*/
    {0x003F, 0x04EA }, /* ? 234*/
    {0x003F, 0x04EB }, /* ? 235*/
    {0x003F, 0x04EC }, /* ? 236*/
    {0x003F, 0x04ED }, /* ? 237*/
    {0x003F, 0x04EE }, /* ? 238*/
    {0x003F, 0x04EF }, /* ? 239*/
    {0x003F, 0x04F0 }, /* ? 240*/
    {0x003F, 0x04F1 }, /* ? 241*/
    {0x003F, 0x04F2 }, /* ? 242*/
    {0x003F, 0x04F3 }, /* ? 243*/
    {0x003F, 0x04F4 }, /* ? 244*/
    {0x003F, 0x04F5 }, /* ? 245*/
    {0x003F, 0x04F6 }, /* ? 246*/
    {0x003F, 0x04F7 }, /* ? 247*/
    {0x003F, 0x04F8 }, /* ? 248*/
    {0x003F, 0x04F9 }, /* ? 249*/
    {0x003F, 0x04FA }, /* ? 250*/
    {0x003F, 0x04FB }, /* ? 251*/
    {0x003F, 0x04FC }, /* ? 252*/
    {0x003F, 0x04FD }, /* ? 253*/
    {0x003F, 0x04FE }, /* ? 254*/
    {0x003F, 0x04FF }, /* ? 255*/
};
int GetFontIndexFromRu(UINT16 code)
{
	UINT32 i;
    for(i = 0; i < sizeof(RU_UNI_TABLE) / sizeof(ST_RU_UNI); i++)
    {
        if(RU_UNI_TABLE[i].Code == code)
        {
            return i;
        }
    }
    return -1;
}
int GetFontIndexFromUni(UINT16 code)
{
	UINT32 i;
    for(i = 0; i < sizeof(RU_UNI_TABLE) / sizeof(ST_RU_UNI); i++)
    {
        if(RU_UNI_TABLE[i].Unicode == code)
        {
            return i;
        }
    }
    return -1;
}
UINT16 ru2uni(UINT16 code)
{
    int idx = GetFontIndexFromRu(code);
	if(idx == -1)
	{
		return 0x0000; 
	}
    return RU_UNI_TABLE[idx].Unicode;
}
UINT16 uni2ru(UINT16 code)
{
    int idx = GetFontIndexFromUni(code);
	if(idx == -1)
	{
		return 0x0000; 
	}
    return RU_UNI_TABLE[idx].Code;
}
#elif defined(BRAND_ORVED)
const BYTE _BMP_A8A4_16[2][8] = 
{
    {0x00,0x00,0x44,0x4C,0x58,0xD0,0x80,0x00,},
    {0x00,0x0E,0x1F,0x11,0x11,0x0F,0x1F,0x10,},
};
const IMAGE_R BMP_A8A4_16 = {8, 16, (BYTE *)_BMP_A8A4_16};
const BYTE _BMP_A8A4_24[3][12] = 
{
    {0x00,0x00,0x80,0xC4,0xCC,0xD8,0xD0,0xC0,0x80,0x00,0x00,0x00,},
    {0x00,0xE0,0xF1,0x31,0x18,0x18,0x18,0x19,0xFF,0xFF,0x00,0x00,},
    {0x00,0x07,0x0F,0x18,0x18,0x18,0x18,0x0C,0x1F,0x1F,0x18,0x00,},
};
const IMAGE_R BMP_A8A4_24 = {12, 24, (BYTE *)_BMP_A8A4_24};
const BYTE _BMP_A8A8_16[2][8] = 
{
    {0x00,0x80,0xC4,0x4C,0x58,0x50,0xC0,0x80,},
    {0x00,0x0F,0x1F,0x11,0x11,0x11,0x19,0x09,},
};
const IMAGE_R BMP_A8A8_16 = {8, 16, (BYTE *)_BMP_A8A8_16};
const BYTE _BMP_A8A8_24[3][12] = 
{
    {0x00,0x00,0x80,0xC4,0xCC,0xD8,0xD0,0xC0,0xC0,0x80,0x00,0x00,},
    {0x00,0xFE,0xFF,0x31,0x30,0x30,0x30,0x30,0x31,0x3F,0x3E,0x00,},
    {0x00,0x03,0x0F,0x1C,0x18,0x18,0x18,0x18,0x1C,0x0E,0x06,0x00,},
};
const IMAGE_R BMP_A8A8_24 = {12, 24, (BYTE *)_BMP_A8A8_24};

const BYTE _BMP_A8AC_16[2][8] = 
{
    {0x00,0x00,0x44,0xCC,0xD8,0x10,0x00,0x00,},
    {0x00,0x00,0x10,0x1F,0x1F,0x10,0x00,0x00,},
};
const IMAGE BMP_A8AC_16 = {8, 16, (BYTE *)_BMP_A8AC_16};
const BYTE _BMP_A8AC_24[3][12] = 
{
    {0x00,0x00,0xC0,0xC4,0xCC,0xD8,0xD0,0x00,0x00,0x00,0x00,0x00,},
    {0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,},
    {0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,},
};
const IMAGE BMP_A8AC_24 = {12, 24, (BYTE *)_BMP_A8AC_24};

#endif


//计算一个字节中的有效像素点数
static BYTE BitReverse(BYTE x)
{
    x = (((x & 0xaa) >> 1) | ((x & 0x55) << 1));
    x = (((x & 0xcc) >> 2) | ((x & 0x33) << 2));
    x = (((x & 0xf0) >> 4) | ((x & 0x0f) << 4));
    return x;
}
static void FontDataConver(BYTE width, BYTE height, BYTE *src, BYTE *dst)
{
    for(BYTE h = 0; h < ((height + 7) / 8); h++)
    {
        for(BYTE w = 0; w < width; w++)
        {
            //dst[h * width + w] = src[h * width + w];
            dst[h * width + w] = BitReverse(src[w * ((height + 7) / 8) + h]);
        }
    }
}
static BYTE FontWidth(BYTE fontSize, UINT16 code)
{
    if(code < 0x7F)
    {
        if(fontSize == 16)
        {
            return 8;
        }
        else if(fontSize == 24)
        {
            return 12;
        }
    }
    else
    {
#if defined(BRAND_RU)
        BYTE temp[24*10 / 8];
        return ReadFont(fontSize, code, temp);
//        if(fontSize == 16)
//        {
//            return 10;
//        }
//        else if(fontSize == 24)
//        {
//            return 16;
//        }
#else
        if(fontSize == 16)
        {
            return 16;
        }
        else if(fontSize == 24)
        {
            return 24;
        }
#endif
    }
}
UINT16 StrFontWidth(BYTE fontSize, char *pStr)
{
    UINT16 code = 0;
    BYTE *ptr = (BYTE *)pStr;
    UINT16 width = 0;
    
    while((*ptr != '\0') && (*ptr != '\n'))
    {
        code = *ptr++;
        if(code >= 0x80)
        {
            code = (code << 8) | *ptr++;
        }
        width += FontWidth(fontSize, code);
    }
    return width;
}
BYTE RemoveBorder(BYTE width, BYTE height, BYTE *pData, BYTE *pOutData)
{
  
    BYTE *ptr = NULL;
    int leftBorder = 0, rightBorder = 0, newWidth = 0, offset = 0;
    leftBorder = width / 2;
    for(int i = 0; i < width;i++)
    {
        BYTE flag = 0;
        for(int j = 0; j < height / 8; j++)
        {
            if(pData[j * width + i] != 0)
            {
                flag = 1;
                break;
            }
        }
        if(flag)
        {
            leftBorder = i;
            break;
        }
    }
    rightBorder = width / 2;
    for(int i = 0; i < width ;i++)
    {
        BYTE flag = 0;
        for(int j = 0; j < height / 8; j++)
        {
            if(pData[(j + 1) * width - i - 1] != 0)
            {
                flag = 1;
                break;
            }
        }
        if(flag == 1)
        {
            rightBorder = width - i;
            break;
        }
    }
    newWidth = MAX(0, (rightBorder - leftBorder));
    if(newWidth < 4)
    {
        offset   = (4 - newWidth) / 2;
        newWidth = 4;
    }
    newWidth += 2;
    memset(pOutData, 0, newWidth * height / 8);
    for(int i = 0; i < height / 8; i++)
    {
        memcpy(&pOutData[i * newWidth + 1 + offset], &pData[i * width + leftBorder],  (rightBorder - leftBorder));
    }
    return newWidth;
}
UINT8 ReadFont(BYTE fontSize, UINT16 code, UINT8 *pData)
{
    BYTE buf[72];
    UINT16 fontIdx = 0;
    if(code < 0x7F)
    {
        fontIdx = MAX(0, (code - ' '));
        if(fontSize == 16)
        {
            ExtFlash_Read(EXTFLASH_ADDRESS_FONT_EN_16x8 + fontIdx * 16, buf, 16);
            FontDataConver(8, 16, buf, pData);
            return 8;
        }
        else if(fontSize == 24)
        {
            if(code < '{')
            {
                ExtFlash_Read(EXTFLASH_ADDRESS_FONT_EN_24x12_1 + fontIdx * 36, buf, 36);
            }
            else
            {
                fontIdx = MAX(0, (code - '{'));
                ExtFlash_Read(EXTFLASH_ADDRESS_FONT_EN_24x12_2 + fontIdx * 36, buf, 36);
            }
            FontDataConver(12, 24, buf, pData);
            return 12;
        }
        
    }
    else
    {
        
#if defined(BRAND_RU)
        if((code >= 0xA7A0) && (code <= 0xA7FF))
        {
            
            for(BYTE j = 0; j < (sizeof(RuFontTable) / sizeof(ST_RU_FONT_INFO)); j++)
            {
                if(RuFontTable[j].Code == code)
                {
                    UINT16 i, leftBorder = 0, rightBorder = 0;
                    if(fontSize == 16)
                    {
                        return RemoveBorder(10, 16, (BYTE *)RuFontTable[j].Data16, pData);
//                        memcpy(pData, RuFontTable[j].Data16, 10*2);
//                        return 10;
                    }
                    else if(fontSize == 24)
                    {
                        return RemoveBorder(16, 24, (BYTE *)RuFontTable[j].Data24, pData);
//                        memcpy(pData, RuFontTable[j].Data24, 16*3);
//                        return 16;
                    }
                    else if(fontSize == 8)
                    {
                        memcpy(pData, RuFontTable[j].Data5, 5);
                        return 5;
                    }
//                    for(i = 0; i < 2;i++)
//                    {
//                        if(RuFontTable8x5[j].Data[i] != 0)
//                        {
//                            break;
//                        }
//                    }
//                    leftBorder = i;
//                    for(i = 0; i < 2;i++)
//                    {
//                        if(RuFontTable8x5[j].Data[4 - i] != 0)
//                        {
//                            break;
//                        }
//                    }
//                    rightBorder = 4 - i;
//                    pImage = ImageCreate(rightBorder - leftBorder + 2, 16);
//                    for(i = 0; i < rightBorder - leftBorder + 1; i++)
//                    {
//                        pImage->Data[i]                  = RuFontTable8x5[j].Data[leftBorder + i] << 5;
//                        pImage->Data[pImage->Width + i]  = RuFontTable8x5[j].Data[leftBorder + i] >> 3;
//                    }
//                    break;
                }
            }
		
        }
#else
        #define FONT_CN1_OFFSET   (0)
        #define FONT_CN2_OFFSET   (FONT_CN1_OFFSET + (0xF7 - 0xB0 + 1) * (0xFE - 0xA1 + 1))
        #define FONT_CN3_OFFSET   (FONT_CN2_OFFSET + (0xA0 - 0x81 + 1) * ((0xFE - 0x80 + 1) + (0x7E - 0x40 + 1)))
        
        BYTE hh = (BYTE)(code >> 8);
        BYTE ll = (BYTE)code;
        if((hh >= 0xB0) && (hh <= 0xF7) && (ll >= 0xA1) && (ll <= 0xFE))
        {
            fontIdx = FONT_CN1_OFFSET + (hh - 0xB0) * (0xFE - 0xA1 + 1) + (ll - 0xA1);
        }
        else if((hh >= 0x81) && (hh <= 0xA0) && (ll >= 0x40) && (ll <= 0xFE))
        {
            fontIdx = FONT_CN2_OFFSET + (hh - 0x81) * (0xFE - 0x40) + (ll - 0x40 - (ll > 0x7F));
        }
        else if((hh >= 0xAA) && (hh <= 0xFE) && (ll >= 0x40) && (ll <= 0xA0))
        {
            fontIdx = FONT_CN3_OFFSET + (hh - 0xAA) * (0xA0 - 0x40 + 1) + (ll - 0x40);
        }
#ifdef BRAND_ORVED
        else if(hh == 0xA8)
        {
            if(ll == 0xA4)
            {
                if(fontSize == 16)
                {
                    memcpy(pData, BMP_A8A4_16.Data, 16);
                    return 8;
                }
                else if(fontSize == 24)
                {
                    memcpy(pData, BMP_A8A4_24.Data, 72);
                    return 12;
                }
            }
            else if(ll == 0xA8)
            {
                if(fontSize == 16)
                {
                    memcpy(pData, BMP_A8A8_16.Data, 16);
                    return 8;
                }
                else if(fontSize == 24)
                {
                    memcpy(pData, BMP_A8A8_24.Data, 72);
                    return 12;
                }
            }
            else if(ll == 0xAC)
            {
                if(fontSize == 16)
                {
                    memcpy(pData, BMP_A8AC_16.Data, 16);
                    return 8;
                }
                else if(fontSize == 24)
                {
                    memcpy(pData, BMP_A8AC_24.Data, 72);
                    return 12;
                }
                
            }
        }
#endif
#endif
        if(fontSize == 16)
        {
            ExtFlash_Read(EXTFLASH_ADDRESS_FONT_CN_16x16 + fontIdx * 32, buf, 32);
            FontDataConver(16, 16, buf, pData);
            return 16;
        }
        else if(fontSize == 24)
        {
            ExtFlash_Read(EXTFLASH_ADDRESS_FONT_CN_24x24 + fontIdx * 72, buf, 72);
            FontDataConver(24, 24, buf, pData); //字体数据转换器
            return 24;
        }
        
    }
    return 0;
}

const BYTE ascii_8x5[95][5] = {
		{0x00,0x00,0x00,0x00,0x00},   //   0x20 32
		{0x00,0x00,0x6f,0x00,0x00},   // ! 0x21 33
		{0x00,0x07,0x00,0x07,0x00},   // " 0x22 34
		{0x14,0x7f,0x14,0x7f,0x14},   // # 0x23 35
		{0x00,0x07,0x04,0x1e,0x00},   // $ 0x24 36
		{0x23,0x13,0x08,0x64,0x62},   // % 0x25 37
		{0x36,0x49,0x56,0x20,0x50},   // & 0x26 38
		{0x00,0x00,0x07,0x00,0x00},   // ' 0x27 39
		{0x00,0x1c,0x22,0x41,0x00},   // ( 0x28 40
		{0x00,0x41,0x22,0x1c,0x00},   // ) 0x29 41
		{0x14,0x08,0x3e,0x08,0x14},   // * 0x2a 42
		{0x08,0x08,0x3e,0x08,0x08},   // + 0x2b 43
		{0x00,0x50,0x30,0x00,0x00},   // , 0x2c 44
		{0x08,0x08,0x08,0x08,0x08},   // - 0x2d 45
		{0x00,0x60,0x60,0x00,0x00},   // . 0x2e 46
		{0x20,0x10,0x08,0x04,0x02},   // / 0x2f 47
		{0x3e,0x51,0x49,0x45,0x3e},   // 0 0x30 48
		{0x00,0x42,0x7f,0x40,0x00},   // 1 0x31 49
		{0x42,0x61,0x51,0x49,0x46},   // 2 0x32 50
		{0x21,0x41,0x45,0x4b,0x31},   // 3 0x33 51
		{0x18,0x14,0x12,0x7f,0x10},   // 4 0x34 52
		{0x27,0x45,0x45,0x45,0x39},   // 5 0x35 53
		{0x3c,0x4a,0x49,0x49,0x30},   // 6 0x36 54
		{0x01,0x71,0x09,0x05,0x03},   // 7 0x37 55
		{0x36,0x49,0x49,0x49,0x36},   // 8 0x38 56
		{0x06,0x49,0x49,0x29,0x1e},   // 9 0x39 57
		{0x00,0x36,0x36,0x00,0x00},   // : 0x3a 58
		{0x00,0x56,0x36,0x00,0x00},   // ; 0x3b 59
		{0x08,0x14,0x22,0x41,0x00},   // < 0x3c 60
		{0x14,0x14,0x14,0x14,0x14},   // = 0x3d 61
		{0x00,0x41,0x22,0x14,0x08},   // > 0x3e 62
		{0x02,0x01,0x51,0x09,0x06},   // ? 0x3f 63
		{0x3e,0x41,0x5d,0x49,0x4e},   // @ 0x40 64
		{0x7e,0x09,0x09,0x09,0x7e},   // A 0x41 65
		{0x7f,0x49,0x49,0x49,0x36},   // B 0x42 66
		{0x3e,0x41,0x41,0x41,0x22},   // C 0x43 67
		{0x7f,0x41,0x41,0x41,0x3e},   // D 0x44 68
		{0x7f,0x49,0x49,0x49,0x41},   // E 0x45 69
		{0x7f,0x09,0x09,0x09,0x01},   // F 0x46 70
		{0x3e,0x41,0x49,0x49,0x7a},   // G 0x47 71
		{0x7f,0x08,0x08,0x08,0x7f},   // H 0x48 72
		{0x00,0x41,0x7f,0x41,0x00},   // I 0x49 73
		{0x20,0x40,0x41,0x3f,0x01},   // J 0x4a 74
		{0x7f,0x08,0x14,0x22,0x41},   // K 0x4b 75
		{0x7f,0x40,0x40,0x40,0x40},   // L 0x4c 76
		{0x7f,0x02,0x0c,0x02,0x7f},   // M 0x4d 77
		{0x7f,0x04,0x08,0x10,0x7f},   // N 0x4e 78
		{0x3e,0x41,0x41,0x41,0x3e},   // O 0x4f 79
		{0x7f,0x09,0x09,0x09,0x06},   // P 0x50 80
		{0x3e,0x41,0x51,0x21,0x5e},   // Q 0x51 81
		{0x7f,0x09,0x19,0x29,0x46},   // R 0x52 82
		{0x46,0x49,0x49,0x49,0x31},   // S 0x53 83
		{0x01,0x01,0x7f,0x01,0x01},   // T 0x54 84
		{0x3f,0x40,0x40,0x40,0x3f},   // U 0x55 85
		{0x0f,0x30,0x40,0x30,0x0f},   // V 0x56 86
		{0x3f,0x40,0x30,0x40,0x3f},   // W 0x57 87
		{0x63,0x14,0x08,0x14,0x63},   // X 0x58 88
		{0x07,0x08,0x70,0x08,0x07},   // Y 0x59 89
		{0x61,0x51,0x49,0x45,0x43},   // Z 0x5a 90
		{0x3c,0x4a,0x49,0x29,0x1e},   // [ 0x5b 91
		{0x02,0x04,0x08,0x10,0x20},   // \ 0x5c 92
		{0x00,0x41,0x7f,0x00,0x00},   // ] 0x5d 93
		{0x04,0x02,0x01,0x02,0x04},   // ^ 0x5e 94
		{0x40,0x40,0x40,0x40,0x40},   // _ 0x5f 95
		{0x00,0x00,0x03,0x04,0x00},   // ` 0x60 96
		{0x20,0x54,0x54,0x54,0x78},   // a 0x61 97
		{0x7f,0x48,0x44,0x44,0x38},   // b 0x62 98
		{0x38,0x44,0x44,0x44,0x20},   // c 0x63 99
		{0x38,0x44,0x44,0x48,0x7f},   // d 0x64 100
		{0x38,0x54,0x54,0x54,0x18},   // e 0x65 101
		{0x08,0x7e,0x09,0x01,0x02},   // f 0x66 102
		{0x0c,0x52,0x52,0x52,0x3e},   // g 0x67 103
		{0x7f,0x08,0x04,0x04,0x78},   // h 0x68 104
		{0x00,0x44,0x7d,0x40,0x00},   // i 0x69 105
		{0x20,0x40,0x44,0x3d,0x00},   // j 0x6a 106
		{0x00,0x7f,0x10,0x28,0x44},   // k 0x6b 107
		{0x00,0x41,0x7f,0x40,0x00},   // l 0x6c 108
		{0x7c,0x04,0x18,0x04,0x78},   // m 0x6d 109
		{0x7c,0x08,0x04,0x04,0x78},   // n 0x6e 110
		{0x38,0x44,0x44,0x44,0x38},   // o 0x6f 111
		{0x7c,0x14,0x14,0x14,0x08},   // p 0x70 112
		{0x08,0x14,0x14,0x18,0x7c},   // q 0x71 113
		{0x7c,0x08,0x04,0x04,0x00},   // r 0x72 114		{0x7c,0x08,0x04,0x04,0x08},   // r 0x72 114
		{0x48,0x54,0x54,0x54,0x20},   // s 0x73 115
		{0x04,0x3f,0x44,0x40,0x00},   // t 0x74 116		{0x04,0x3f,0x44,0x40,0x20},   // t 0x74 116
		{0x3c,0x40,0x40,0x20,0x7c},   // u 0x75 117
		{0x1c,0x20,0x40,0x20,0x1c},   // v 0x76 118
		{0x3c,0x40,0x30,0x40,0x3c},   // w 0x77 119
		{0x44,0x28,0x10,0x28,0x44},   // x 0x78 120
		{0x0c,0x50,0x50,0x50,0x3c},   // y 0x79 121
		{0x44,0x64,0x54,0x4c,0x44},   // z 0x7a 122
		{0x00,0x08,0x36,0x41,0x41},   // { 0x7b 123
		{0x00,0x00,0x7f,0x00,0x00},   // | 0x7c 124
		{0x41,0x41,0x36,0x08,0x00},   // } 0x7d 125
		{0x04,0x02,0x04,0x08,0x04},   // ~ 0x7e 126
	};



IMAGE_R Font_GetAscii8x5(char code)
{
    IMAGE_R image = {5, 8, ascii_8x5[code - 0x20]};
    return image;
}

IMAGE *ImageCreateWord(UINT16 code, BYTE fontSize)
{
    IMAGE *pImage = NULL;    
    if(xSemaphoreTake(_MutexHandle, TIMEOUT) != pdTRUE)
    {
        return NULL;
    }
    if(code < 0x80)
    {
        pImage = ImageCreate(fontSize / 2, fontSize);
    }
    else
    {
        pImage = ImageCreate(fontSize, fontSize);
    }
    
    ReadFont(fontSize, code, pImage->Data);
    xSemaphoreGive(_MutexHandle);
    return pImage;
}
void Font_Init(void)
{
    _MutexHandle = xSemaphoreCreateMutex();
}
//__HAL_FONT_C__












/****************************************************************************
 * File Name: hal_font.h
 *
 * Description:
 *					Font
 *
 * --------------------------------------------------------------------
 * Revision	Author		Date		Comment
 * --------------------------------------------------------------------
 * 1.0          Junrong         2018/03/14		Original
 *
 *****************************************************************************/
#ifndef __HAL_FONT_H__
#define __HAL_FONT_H__
#include "Types.h"
#include "Image.h"
#include "Structures.h"

void Font_Init(void);
IMAGE_R Font_GetAscii8x5(char code);
IMAGE *ImageCreateWord(UINT16 code, BYTE size);
UINT8 ReadFont(BYTE fontSize, UINT16 code, UINT8 *pData);
UINT16 StrFontWidth(BYTE fontSize, char *pStr);

#endif //__HAL_FONT_H__












#include "hal_hf_module.h"
#include "string.h"
#include "hal.h"

#if defined(MODEL_PT60DC) || defined(MODEL_PT66DC)

#define HAL_SPI3_TIMEOUT    3000
#define RETRY_TIMES_MAX     10
extern SPI_HandleTypeDef    hspi3;

static void _SpiWrite(BYTE *pData, uint16_t length)
{
    HAL_SPI_Transmit(&hspi3, pData, length, 0xff);
}
static void _SpiRead(BYTE *pData, uint16_t length)
{
    BYTE *ptr = pvPortMalloc(length);
    memset(ptr, 0, length);
    HAL_SPI_TransmitReceive(&hspi3,ptr,pData,length,0xff);
    vPortFree(ptr);
//    HAL_SPI_Receive(&hspi3, pData, length, 0xff);
}


/*
* 功能: 读取RC522寄存器值
* 参数说明: 
* Address[IN]: 寄存器地址
* 返回: 读出的值
*/
BYTE ReadRawRC(BYTE Address)
{
    BYTE ucAddr = 0x00 ;
    BYTE res;
    IOWrite(GPIO_HF_SPI_CS, 0);
    ucAddr = ((Address<<1)&0x7E)|0x80;
    _SpiWrite(&ucAddr,1);
    _SpiRead(&res,1);
    IOWrite(GPIO_HF_SPI_CS, 1);
    return res;
}

/*
* 功能: 写RC522寄存器值
* 参数说明: 
* Address[IN]: 寄存器地址
* value : 写入的值
*/
void WriteRawRC(BYTE Address, BYTE value)
{
    BYTE ucAddr = 0x00 ;
    IOWrite(GPIO_HF_SPI_CS, 0);
    ucAddr = ((Address<<1)&0x7E);
    _SpiWrite(&ucAddr, 1);
    _SpiWrite(&value, 1);
    IOWrite(GPIO_HF_SPI_CS, 1);
}
void WriteRawRCs(BYTE Address, BYTE *pValues, BYTE len)
{
    BYTE ucAddr = 0x00 ;
    IOWrite(GPIO_HF_SPI_CS, 0);
    ucAddr = ((Address<<1)&0x7E);
    _SpiWrite(&ucAddr, 1);
    _SpiWrite(pValues, len);
    IOWrite(GPIO_HF_SPI_CS, 1);
}

/*
* 功能: 置RC522寄存器位
* 参数说明: 
* reg[IN] : 寄存器地址
* mask[IN] : 置位值
*/
void SetBitMask(BYTE reg, BYTE mask)  
{
    char tmp = 0x0;
    tmp = ReadRawRC(reg);
    WriteRawRC(reg,tmp | mask);  // set bit mask
}

/*
* 功能: 清RC522寄存器位
* 参数说明: 
* reg[IN] : 寄存器地址
* mask[IN] : 清位值
*/
void ClearBitMask(BYTE reg, BYTE mask)  
{
    BYTE tmp = ReadRawRC(reg);
    WriteRawRC(reg, tmp & ~mask);  // clear bit mask
}

/*
* 功能: 通过RC522和ISO14443卡通讯
* 参数说明: 
* Command[IN]: RC522命令字
* pInData[IN]: 通过RC522发送到卡片的数据
* InLenByte[IN]: 发送数据的字节长度
* pOutData[OUT]: 接收到的卡片返回数据
* pOUtLenBit[OUT]: 返回数据的位长度
*/
ENUM_ERROR_CODE PcdComMF522(BYTE Command, BYTE *pInData, BYTE InLenByte, BYTE *pOutData, UINT16 *pOutLenBit)
{
    BYTE err;
    ENUM_ERROR_CODE status = ERROR_TIMEOUT;
    BYTE irqEn   = 0x00;
    BYTE waitFor = 0x00;
    BYTE lastBits;
    BYTE n;
    UINT16 i;
    switch (Command)
    {
        case PCD_AUTHENT:
            irqEn   = 0x12;
            waitFor = 0x10;
            break;
        case PCD_TRANSCEIVE:
            irqEn   = 0x77;
            waitFor = 0x30;
            break;
        default:
            break;
    }
    WriteRawRC(ComIEnReg, irqEn | 0x80);
    ClearBitMask(ComIrqReg, 0x80);
    WriteRawRC(CommandReg, PCD_IDLE);
    SetBitMask(FIFOLevelReg, 0x80);

    for (i = 0; i < InLenByte; i++)
    {   
        WriteRawRC(FIFODataReg, pInData[i]); 
    }
//    WriteRawRCs(FIFODataReg, pInData, InLenByte); 
    WriteRawRC(CommandReg, Command);

    if (Command == PCD_TRANSCEIVE)
    {    
        SetBitMask(BitFramingReg, 0x80);  
    }

    i = 6000;
    do 
    {
        n = ReadRawRC(ComIrqReg);
        i--;
    }
    while ((i != 0) && !(n & 0x01) && !(n & waitFor));
    ClearBitMask(BitFramingReg, 0x80);
    if(i != 0)
    {
        err = ReadRawRC(ErrorReg);
        
//        LCD_PutText(0, 48, 16,"%u,%u,%02X,%02X,%02X ", i, err, n, irqEn, Command);
        if(!(err & 0x1B))
        {
            status = NO_ERROR;
            if(n & irqEn & 0x01)
            {   
                status = ERROR_NO_TAG; 
            }
            if(Command == PCD_TRANSCEIVE)
            {
                n = ReadRawRC(FIFOLevelReg);
                lastBits = ReadRawRC(ControlReg) & 0x07;
                if(lastBits)
                {
                    *pOutLenBit = (n - 1) * 8 + lastBits;
                }
                else
                {
                    *pOutLenBit = n * 8;
                }
                if(n == 0)
                {
                    n = 1;
                }
                if(n > MAXRLEN)
                {
                    n = MAXRLEN;
                }
                for (i=0; i<n; i++)
                {
                    pOutData[i] = ReadRawRC(FIFODataReg);
                }
            }
        }
        else
        {
            status = ERROR_TIMEOUT;
        }
    }
    SetBitMask(ControlReg, 0x80);           // stop timer now
    WriteRawRC(CommandReg, PCD_IDLE); 
    return status;
}

static void PcdAntennaOn(void)
{
    BYTE i = 0x00;
    i = ReadRawRC(TxControlReg);
    if (!(i & 0x03))
    {
        SetBitMask(TxControlReg, 0x03);
    }
}

static void PcdAntennaOff(void)
{
    ClearBitMask(TxControlReg, 0x03);
}


/*
* FM1750 与 RC522兼容
* 功能: 寻卡
* 参数说明:
* req_code[IN] : 寻卡方式, 0x52->寻感应区内所有符合1444A标准的卡
*                                                     0x26->寻进入休眠状态的卡
* pTagType[OUT] : 卡片类型代码
*                                    0x4400 = Mifare_UltraLight
*                                    0x0400 = Mifare_One(S50)
*                                    0x0200 = Mifare_One(S70)
*                                    0x0800 = Mifare_Pro(X)
*                                    0x4403 = Mifare_DESFire
* 返回:成功返回NO_ERROR
*/
ENUM_ERROR_CODE PcdRequest(BYTE req_code, BYTE *pTagType)
{
    ENUM_ERROR_CODE status;  
    UINT16  unLen;
    BYTE ucComMF522Buf[MAXRLEN]; 

    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(BitFramingReg,0x07);
    SetBitMask(TxControlReg,0x03);

    ucComMF522Buf[0] = req_code;

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen);

    if(status == NO_ERROR)
    {   
        if(unLen != 0x10)
        {
            return ERROR_UNKNOW;
        }
        *pTagType     = ucComMF522Buf[0];
        *(pTagType+1) = ucComMF522Buf[1];
    }    
    return status;
}

/*
* 功能:防冲撞
* 参数说明:
* anticollMode[In] : 防冲撞模式,用于获取Snr
* pSnr[OUT] : 卡片SN
*
* 返回:成功返回NO_ERROR
*/
ENUM_ERROR_CODE PcdAnticoll(BYTE anticollMode, BYTE *pSnr)
{
    ENUM_ERROR_CODE status;
    BYTE i,snr_check=0;
    UINT16 unLen;
    BYTE ucComMF522Buf[MAXRLEN]; 
    
    ClearBitMask(Status2Reg,0x08);
    WriteRawRC(BitFramingReg,0x00);
    ClearBitMask(CollReg,0x80);

    ucComMF522Buf[0] = anticollMode;
    ucComMF522Buf[1] = 0x20;

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2,ucComMF522Buf,&unLen);

//    LCD_PutText(0, 32, 16,"%u,%02X%02X%02X%02X%02X%02X ", status, unLen, ucComMF522Buf[0], ucComMF522Buf[1], ucComMF522Buf[2], ucComMF522Buf[3], ucComMF522Buf[4]);
    if (status == NO_ERROR)
    {
        for(i = 0; i < 4; i++)
        {   
            *(pSnr+i)  = ucComMF522Buf[i];
            snr_check ^= ucComMF522Buf[i];
        }
        if(snr_check != ucComMF522Buf[i])
        {   
            status = ERROR_UNKNOW;
        }
    }
//    LCD_PutText(128-16, 32, 16,"%02X", snr_check);
    
    SetBitMask(CollReg,0x80);
    return status;
}

/*
* 功能 : 计算CRC16
*/
void CalulateCRC(BYTE *pIndata, BYTE len, BYTE *pOutData)
{
    BYTE i,n;
    ClearBitMask(DivIrqReg,0x04);
    WriteRawRC(CommandReg,PCD_IDLE);
    SetBitMask(FIFOLevelReg,0x80);
    for (i=0; i<len; i++)
    {
        WriteRawRC(FIFODataReg, *(pIndata+i));   
    }
    WriteRawRC(CommandReg, PCD_CALCCRC);
    i = 0xFF;
    do 
    {
        n = ReadRawRC(DivIrqReg);
        i--;
    }
    while ((i!=0) && !(n&0x04));
    pOutData[0] = ReadRawRC(CRCResultRegL);
    pOutData[1] = ReadRawRC(CRCResultRegM);
}

/*
* 选定卡片
* 参数:
* anticollMode[In] : 防冲撞模式
* pSnr[IN],卡片序列号
* 返回:成功返回 NO_ERROR
*/
ENUM_ERROR_CODE PcdSelect(BYTE anticollMode, BYTE *pSnr)
{
    ENUM_ERROR_CODE status;
    BYTE i;
    UINT16 unLen;
    BYTE ucComMF522Buf[MAXRLEN]; 
    
    ucComMF522Buf[0] = anticollMode;
    ucComMF522Buf[1] = 0x70;
    ucComMF522Buf[6] = 0;
    for (i=0; i<4; i++)
    {
        ucComMF522Buf[i+2] = *(pSnr+i);
        ucComMF522Buf[6]  ^= *(pSnr+i);
    }
    CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);

    ClearBitMask(Status2Reg,0x08);

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen);
    
    if((status == NO_ERROR) && (unLen != 0x18))
    {
        status = ERROR_UNKNOW;    
    }

    return status;
}
/*
* 功能: 验证卡片密码
* 参数说明:
* auth_mode[IN] : 密码验证模式
*                             0x60 = 验证A密钥
*                                0x61 = 验证B密钥
* addr[IN] : 块地址
* pKey[IN] : 密码
* pSnr[IN] : 卡片序列号
* 返回: 成功返回 NO_ERROR
*/
ENUM_ERROR_CODE PcdAuthState(BYTE auth_mode, BYTE addr, BYTE *pKey, BYTE *pSnr)
{
    ENUM_ERROR_CODE status;
    UINT16 unLen;
    BYTE ucComMF522Buf[MAXRLEN]; 

    ucComMF522Buf[0] = auth_mode;
    ucComMF522Buf[1] = addr;
    memcpy(&ucComMF522Buf[2], pKey, 6); 
    memcpy(&ucComMF522Buf[8], pSnr, 4); 

    status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen);
    if ((status == NO_ERROR) && (!(ReadRawRC(Status2Reg) & 0x08)))
    {   
        status = ERROR_UNKNOW;   
    }

    return status;
}

/*
* 功能: 读取M1卡一块数据
* 参数说明: 
*    addr[IN] : 块地址
* pData[OUT] : 读出的数据, 16字节
* 返回: 成功返回 NO_ERROR
*/
ENUM_ERROR_CODE PcdRead(BYTE addr, BYTE *pData)
{
    ENUM_ERROR_CODE status;
    UINT16 unLen = 0;
    BYTE ucComMF522Buf[MAXRLEN]; 

    ucComMF522Buf[0] = PICC_READ;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf, 2, &ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE, ucComMF522Buf, 4, ucComMF522Buf, &unLen);
    if(status == NO_ERROR)
    {
        if(unLen != 0x90)
        {
            return ERROR_UNKNOW;
        }
        memcpy(pData, ucComMF522Buf, 16);   
    }
    return status;
}

/*
* 功能: 写数据到M1卡一块
* 参数说明:
* addr[IN] : 块地址
* pData[In] : 写入的数据, 16字节
* 返回: 成功返回 NO_ERROR
*/
ENUM_ERROR_CODE PcdWrite(BYTE addr, BYTE *pData)
{
    ENUM_ERROR_CODE status;
    UINT16 unLen;
    BYTE ucComMF522Buf[MAXRLEN]; 

    ucComMF522Buf[0] = PICC_WRITE;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

    if ((status != NO_ERROR) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {   
        status = ERROR_UNKNOW;   
    }

    if (status == NO_ERROR)
    {
        memcpy(ucComMF522Buf, pData, 16);
        CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);

        status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);
        if ((status == NO_ERROR) && ((unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A)))
        {   
            status = ERROR_UNKNOW;   
        }
    }

    return status;
}

ENUM_ERROR_CODE PcdValue(BYTE dd_mode,BYTE addr, BYTE *pValue)
{
    ENUM_ERROR_CODE status;
    UINT16  unLen;
    BYTE i,ucComMF522Buf[MAXRLEN]; 
    
    ucComMF522Buf[0] = dd_mode;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
 
    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf, &unLen);
 
    if ((status != NO_ERROR) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {
        status = ERROR_UNKNOW;   
    }
        
    if (status == NO_ERROR)
    {
       // memcpy(ucComMF522Buf, pValue, 4);
        for (i = 0; i < 16; i++)
        {
            ucComMF522Buf[i] = *(pValue+i);   
        }
        CalulateCRC(ucComMF522Buf, 4, &ucComMF522Buf[4]);
        unLen = 0;
        status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen);
//        if (status != MI_ERR)
//        {
//            status = MI_OK;
//        }
    }
    
    if (status == NO_ERROR)
    {
        ucComMF522Buf[0] = PICC_TRANSFER;
        ucComMF522Buf[1] = addr;
        CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); 
   
        status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);
 
        if ((status != NO_ERROR) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {
            status = ERROR_UNKNOW;   
        }
    }
    return status;
}
/*
* 功能: 命令卡片进入休眠状态
* 返回 : 成功返回 NO_ERROR
*/
ENUM_ERROR_CODE PcdHalt(void)
{
    ENUM_ERROR_CODE status;
    UINT16 unLen;
    BYTE ucComMF522Buf[MAXRLEN]; 

    ucComMF522Buf[0] = PICC_HALT;
    ucComMF522Buf[1] = 0;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

    return status;
}
BYTE tmp11111 = 0;
/*
* 功能: 软件复位RC522
* 返回: 成功返回NO_ERROR
*/
ENUM_ERROR_CODE PcdReset(void)
{
    WriteRawRC(CommandReg,PCD_RESETPHASE);    //软件复位
    HAL_Delay(1);
    WriteRawRC(ModeReg,0x3D);
    tmp11111 = ReadRawRC( ModeReg );
    WriteRawRC(TReloadRegL,30);
    tmp11111 = ReadRawRC( TReloadRegL );
    WriteRawRC(TReloadRegH,0);
    tmp11111 = ReadRawRC( TReloadRegH );
    WriteRawRC(TModeReg,0x00);//0x8D);
    tmp11111 = ReadRawRC( TModeReg );
    WriteRawRC(TPrescalerReg,0x00);//0x3E);
    tmp11111 = ReadRawRC( TPrescalerReg );
    WriteRawRC(TxAutoReg,0x40);
    tmp11111 = ReadRawRC( TxAutoReg );
    return NO_ERROR;
}

void PcdConfigISOType(void)
{
    ClearBitMask(Status2Reg, 0x08);
    WriteRawRC( ModeReg , 0x3D);
    WriteRawRC( RxSelReg, 0x86);
    WriteRawRC( RFCfgReg, 0x7F);

    WriteRawRC(RxThresholdReg,0xFF); 

    WriteRawRC( TReloadRegL, 30 );    
    WriteRawRC( TReloadRegH, 0x00 );
    WriteRawRC( TModeReg , 0x00);//0x8D);
    WriteRawRC( TPrescalerReg , 0x00);//0x3E);
    PcdAntennaOn();
}

ENUM_ERROR_CODE ISO14443A_Get_CardType_ID(BYTE *CardType, BYTE *CardID)
{
    ENUM_ERROR_CODE status = NO_ERROR;
    for(BYTE i = 0; i < RETRY_TIMES_MAX; i++)
    {
        status = PcdRequest(PICC_REQALL,CardType); 
//        LCD_PutText(0, 0, 16,"%d,%u,%02X%02X ", i, status, CardType[0], CardType[1]);
        if(status != NO_ERROR)
        {
            continue;
        }
        switch (CardType[0] & 0xC0)
        {
            case 0x00:
            {
                status = PcdAnticoll(PICC_ANTICOLL1, CardID);
//                LCD_PutText(0, 16, 16,"%d,%u,%02X%02X%02X%02X ", i, status, CardID[0], CardID[1],CardID[2], CardID[3]);
                if(status != NO_ERROR)
                {
                    continue;
                }
                status = PcdSelect(PICC_ANTICOLL1, CardID);
                if(status != NO_ERROR)
                {
                    continue;
                }                
                return NO_ERROR;
            }
            case 0x40:
            {
                status = PcdAnticoll(PICC_ANTICOLL1, CardID);
                if(status != NO_ERROR)
                {
                    continue;
                }
                status = PcdSelect(PICC_ANTICOLL1, CardID);
                if(status != NO_ERROR)
                {
                    continue;
                }                
                memcpy(CardID, &CardID[1],3);
                status = PcdAnticoll(PICC_ANTICOLL2, &CardID[3]);
                if(status != NO_ERROR)
                {
                    continue;
                }
                status = PcdSelect(PICC_ANTICOLL2, &CardID[3]);
                if(status != NO_ERROR)
                {
                    continue;
                }                
                return NO_ERROR;
            }
        }
    }
    return status;
}
ENUM_ERROR_CODE ISO14443A_Read_Block(BYTE keyType, BYTE * passwd, BYTE blockNO, BYTE *pOutbuff)
{
    ENUM_ERROR_CODE status = NO_ERROR;
    BYTE CardType[2] = {0};
    BYTE CardID[8];
    for(BYTE i = 0; i < RETRY_TIMES_MAX; i++)
    {
        status = ISO14443A_Get_CardType_ID(CardType, CardID);
//        LCD_PutText(0, 16, 16,"%d,%u,%02X%02X ", i, status, CardType[0], CardType[1] );
        if(status != NO_ERROR)
        {
            return status;
        }
        if((CardType[0] & 0xC0) == 0)
        {
            status = PcdAuthState(keyType, blockNO, passwd, CardID);
//            LCD_PutText(0, 32, 16,"%d,%u", i, status);
            if (status != NO_ERROR) 
            {
                continue;
            }
        }
        status = PcdRead(blockNO, pOutbuff);
//        LCD_PutText(0,48, 16,"%d,%u", i, status);
        if(status != NO_ERROR) 
        {
            continue;
        }
        break;
    }
    return status;
}

ENUM_ERROR_CODE ISO14443A_Write_Block(BYTE keyType, BYTE *passwd, BYTE blockNO, BYTE *pInbuff)
{
    ENUM_ERROR_CODE status = NO_ERROR;
    BYTE CardType[2];
    BYTE CardID[8];
    for(BYTE i = 0; i < RETRY_TIMES_MAX; i++)
    {
        status = ISO14443A_Get_CardType_ID(CardType, CardID);
        if(status != NO_ERROR)
        {
            return status;
        }
        if((CardType[0] & 0xC0) == 0)
        {
            status = PcdAuthState(keyType, blockNO, passwd, CardID);
            if (status != NO_ERROR) 
            {
                continue;
            }
        }
        status = PcdWrite(blockNO, pInbuff);
        if(status != NO_ERROR) 
        {
            continue;
        }
        break;
    }
    return status;
}

ENUM_ERROR_CODE ISO14443A_Decrement(BYTE keyType, BYTE *passwd, BYTE blockNO, BYTE *pInbuff)
{
    ENUM_ERROR_CODE status = NO_ERROR;
    BYTE CardType[2];
    BYTE CardID[8];
    for(BYTE i = 0; i < RETRY_TIMES_MAX; i++)
    {
        status = ISO14443A_Get_CardType_ID(CardType, CardID);
        if(status != NO_ERROR)
        {
            return status;
        }
        if((CardType[0] & 0xC0) == 0)
        {
            status = PcdAuthState(keyType, blockNO, passwd, CardID);
            if (status != NO_ERROR) 
            {
                continue;
            }
        }
        status = PcdValue(PICC_DECREMENT, blockNO, pInbuff);
        if(status != NO_ERROR) 
        {
            continue;
        }
        break;
    }
    return status;
}
static void fm17520Reset(void)
{
    IOWrite(GPIO_HF_RST, 1);
    HAL_Delay(1);
    IOWrite(GPIO_HF_RST, 0);
    HAL_Delay(1);
    IOWrite(GPIO_HF_RST, 1);
    HAL_Delay(1);
}
//ENUM_ERROR_CODE ISO14443A_Ultralight_Write(BYTE page,///< The page (2-15) to write to.
//                             BYTE *buffer,	///< The 4 bytes to write to the PICC
//                             BYTE bufferSize	///< Buffer size, must be at least 4 bytes. Exactly 4 bytes are written.
//                            ) 
//{
//    ENUM_ERROR_CODE status;
//	
	// Sanity check
	if (buffer == nullptr || bufferSize < 4) {
		return STATUS_INVALID;
	}
//	
//	// Build commmand buffer
//	BYTE cmdBuffer[6];
//    UINT16 unLen;
//    BYTE ucComMF522Buf[MAXRLEN]; 
//	cmdBuffer[0] = PICC_CMD_UL_WRITE;
//	cmdBuffer[1] = page;
//	memcpy(&cmdBuffer[2], buffer, 4);
//	
//	// Perform the write
//    status = PcdComMF522(PCD_TRANSCEIVE, cmdBuffer, 6, ucComMF522Buf,&unLen); // Adds CRC_A and checks that the response is MF_ACK.
//	return (status == NO_ERROR);
//        
    char status;
    unsigned int unLen;
    BYTE ucComMF522Buf[MAXRLEN]; 

    ucComMF522Buf[0] = PICC_WRITE;
    ucComMF522Buf[1] = addr;
    CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);

    status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen);

    if ((status != NO_ERROR) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
    {   
        status = MI_ERR;   
    }

    if (status == NO_ERROR)
    {
        memcpy(ucComMF522Buf, pData, 16);
        CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);

        status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen);
        if ((status != NO_ERROR) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
        {   
            status = MI_ERR;   
        }
    }

    return status;
//} // End MIFARE_Ultralight_Write()
BOOL aStatus = 0;
void HF_Init(void)
{
    extern BYTE cardType[2];
    extern BYTE cardID[10];
    extern BYTE cardData[16]; //= {0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11};
    extern BYTE keyPass[6];   //= {0xff,0xff,0xff,0xff,0xff,0xff};
//    BYTE cardWData[16] = {0x11,0x00,0x22,0x22,0x33,0x33,0x44,0x44,0x55,0x55,0x66,0x66,0x77,0x77,0x88,0x88};
//    BYTE keyPass1[6] = {0};
    IOWrite(GPIO_HF_SPI_CS, 1);
    fm17520Reset();
    PcdReset();
    PcdAntennaOff();
    HAL_Delay(2);
    PcdAntennaOn();
    PcdConfigISOType();
//    aStatus = ISO14443A_Get_CardType_ID(cardType, cardID);
// aStatus = ISO14443A_Write_Block(0x60, keyPass, 4, cardWData);
 aStatus = ISO14443A_Read_Block(0x60, keyPass, 1, cardData);
    aStatus = ISO14443A_Ultralight_Write(5, cardData, 4);
    aStatus = ISO14443A_Read_Block(0x60, keyPass, 3, cardData);
//    
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 0, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 1, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 2, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 3, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 4, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 5, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 6, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 7, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 8, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 9, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 10, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 11, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 12, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 13, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 14, cardData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 15, cardData);
// aStatus = ISO14443A_Write_Block(0x60, keyPass, 1, cardWData);
//    aStatus = ISO14443A_Read_Block(0x60, keyPass, 6, cardData);
//    aStatus = ISO14443A_Read_Block(0x61, keyPass, 7, cardData);
}

void HF_Enable(BOOL en)
{
}

#endif














#ifndef	__HAL_HF_MODULE_H__
#define	__HAL_HF_MODULE_H__
#include "stm32f1xx_hal.h"
#include "hal.h"



//#define	SPI3_CS_PIN		GPIO_PIN_0
//#define	SPI3_CS_PORT	GPIOE

//#define	HF_RST_PIN		GPIO_PIN_6
//#define	HF_RST_PORT		GPIOB



//#define	SPI3_CS_H       IOWrite(GPIO_RFID_SPI_CS, 1) //	 	HAL_GPIO_WritePin(SPI3_CS_PORT, SPI3_CS_PIN, GPIO_PIN_SET);
//#define	SPI3_CS_L		IOWrite(GPIO_RFID_SPI_CS, 0) //     HAL_GPIO_WritePin(SPI3_CS_PORT, SPI3_CS_PIN, GPIO_PIN_RESET);


//#define	HF_RST_H		HAL_GPIO_WritePin(HF_RST_PORT, HF_RST_PIN, GPIO_PIN_SET);
//#define	HF_RST_L		HAL_GPIO_WritePin(HF_RST_PORT, HF_RST_PIN, GPIO_PIN_RESET);



#define		Mifare_UltraLight		0x4400
#define		Mifare_One_S50			0x0400
#define		Mifare_One_S70			0x0200
#define		Mifare_Pro					0x0800
#define		Mifare_DESFire			0x4430

/
//MF522命令字
/
#define PCD_IDLE              0x00               //取消当前命令
#define PCD_AUTHENT           0x0E               //验证密码
#define PCD_RECEIVE           0x08               //接收数据
#define PCD_TRANSMIT          0x04               //发送数据
#define PCD_TRANSCEIVE        0x0C               //发送并接收数据
#define PCD_RESETPHASE        0x0F               //复位
#define PCD_CALCCRC           0x03               //CRC计算

/
//Mifare_One卡片命令字
/
#define PICC_REQIDL           0x26               //寻天线区内未进入休眠的卡
#define PICC_REQALL           0x52               //寻天线内全部卡
#define PICC_ANTICOLL1        0x93               //防冲撞
#define PICC_ANTICOLL2        0x95               //防冲撞
#define PICC_ANTICOLL3        0x97               //防冲撞
#define PICC_AUTHENT1A        0x60               //验证A密钥
#define PICC_AUTHENT1B        0x61               //验证B密钥
#define PICC_READ             0x30               //读块
#define PICC_WRITE            0xA0               //写块
#define PICC_DECREMENT        0xC0               //扣款
#define PICC_INCREMENT        0xC1               //充值
#define PICC_RESTORE          0xC2               //调数据到缓冲区
#define PICC_TRANSFER         0xB0               //保存缓冲区中数据
#define PICC_HALT             0x50               //休眠
#define PICC_CMD_UL_WRITE	  0xA2		         // Writes one 4 byte page to the PICC.

/
//MF522 FIFO长度定义
/
#define DEF_FIFO_LENGTH       64                 //FIFO size=64byte
#define MAXRLEN 		64

/
//MF522寄存器定义
/
// PAGE 0
#define     RFU00                 0x00    
#define     CommandReg            0x01    
#define     ComIEnReg             0x02    
#define     DivlEnReg             0x03    
#define     ComIrqReg             0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08    
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D
#define     CollReg               0x0E
#define     RFU0F                 0x0F
// PAGE 1     
#define     RFU10                 0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     RFU1A                 0x1A
#define     RFU1B                 0x1B
#define     MifareReg             0x1C
#define     RFU1D                 0x1D
#define     RFU1E                 0x1E
#define     SerialSpeedReg        0x1F
// PAGE 2    
#define     RFU20                 0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     RFU23                 0x23
#define     ModWidthReg           0x24
#define     RFU25                 0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsCfgReg            0x28
#define     ModGsCfgReg           0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F
// PAGE 3      
#define     RFU30                 0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     RFU3C                 0x3C   
#define     RFU3D                 0x3D   
#define     RFU3E                 0x3E   
#define     RFU3F		  						0x3F

/
//MF522通讯时返回的错误代码
/
//#define MI_OK                          0
//#define MI_NOTAGERR                    1
//#define MI_ERR                         2



void HF_Init(void);
void HF_Enable(BOOL en);
ENUM_ERROR_CODE ISO14443A_Get_CardType_ID(uint8_t *CardType, uint8_t *CardID);
ENUM_ERROR_CODE ISO14443A_Read_Block(uint8_t keyType, uint8_t * passwd, uint8_t blockNO, uint8_t *pOutbuff);
ENUM_ERROR_CODE ISO14443A_Write_Block(uint8_t keyType, uint8_t * passwd, uint8_t blockNO, uint8_t *pInbuff);

#endif












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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值