YC3121_PT26\Source:PrtBuf.c开始

//                         PrtBuf.c


/*******************************************************************************
* File Name   : PrtBuf.c
* Date        : 2010.12.18
* Description : PrtBuf  Operation
* Designer    : XXXXXXXXXXXXXX
*******************************************************************************/
#include "yc3121.h"

#include "type.h"
#include "Interface.h"
#include "PrtHead.h"
#include "RcvBuf.h"
#include "string.h"
#include "CmdSet.h"
#include "PrtBuf.h"
#include "yc_timer.h"
#include "yc_bt.h"
#include "yc_wdt.h"
#include "Sensor.h"
#include "Interface.h"
#include "LcdMenu.h"
//增加一个变量,这个变量决定步进电机步进几步然后打印一行.
//因为这个量在打印APP图片和汉字的时候并不一致,所以用一个常量并不合适,这里用一个变量以兼容多种打印的需求
volatile unsigned char one_dotline_lfstep_num; 
volatile unsigned char one_dotline_lfstep_num_change_flage; 




unsigned char cAsciiHightMultiple_Prt=0;

unsigned char cAsciiWidthMultiple;//字符倍宽倍数
unsigned char cAsciiHightMultiple;//字符倍高倍数
unsigned char cAsciiRightSpace;//字符右边距
unsigned int  iLineSpaceNumber;//字符行之间点行数
unsigned char cChineseWidthMultiple;//汉字倍宽倍数
unsigned char cChineseHightMultiple;//汉字倍高倍数
unsigned char cChineseRightSpace;//汉字右边距
unsigned char cChineseLeftSpace;//汉字左边距
unsigned int  iCurrentFillColumn;//当前填充位置计数
volatile unsigned char cCurrentFillRow;//填充行
volatile unsigned char cCurrentPrtCharLine;//打印行
volatile unsigned char bTimer2Prt;//打印标志位
unsigned char bTimer2FeedLine;//走行间距标志位
unsigned char bTimer2KeyFeed;//按键进纸标志位             feed仅仅是走纸的意思
unsigned char bChinese;//汉字模式
unsigned char bHexDump;//16进制模式
unsigned char bSelfTest;//自检模式
unsigned char bCharacterSel;//进入字符模式选择模式
unsigned char bDensitySel;//进入打印浓度设置模式
unsigned char bHaveFilledAscii;//字符行填充ASCII标志
unsigned char bHaveFilledChinese;//字符行填充汉字标志
unsigned char bHaveFilledBarCode;//字符行条码标志
unsigned char bHaveFilledRasterDot;//字符行填充光栅位图标志
unsigned char bHaveFilledImageDot;//字符行填充下载位图标志
unsigned char bFont12x24;//字符字体
unsigned char bPrtAdverse;//反白打印标志位
unsigned char bAsciiUnderLine;//ascii下划线标志位
unsigned char bChineseUnderLine;//chinese下划线标志位
unsigned char bUnderLineEffect;//下划线有效标志位
unsigned char bAlign;//打印对齐模式
unsigned char bBold;//粗体打印
unsigned int  iPrtLeftMargin;//左边距设置
unsigned int  iPrtRightMargin;//左边距加打印区域等于右边距
unsigned int  iRasterDotHight;//光栅位图的高度
unsigned char bUserChar;//用户自定义字符
unsigned int  iImageDotHight;//打印图形的高度 如下载LOGE和下装点图GS *
unsigned char cCodePage;//字符代码页
unsigned char bPart1;//转换表1
unsigned char bPart2;//转换表2
unsigned char bPart3;//转换表3
unsigned char bPart4;//转换表4
unsigned char bFontBig5;//繁体
unsigned char bClearBarCode;
unsigned char bPrintBmp;
unsigned char SelfTestPrinting_flag ;    //打印自检标志

enum enumInterCharSet cInternationalCharSet;
unsigned char bPrt_Statu_flag;    //打印状态标志_  
volatile struct structCharLine PrtBuf[NumOfCharLine];


struct StructBarCode BarCode;

EEPROM_STRUCT EEPROM;


extern const unsigned char apk_ver[];
extern const unsigned char hard_ver[];
extern const unsigned char soft_ver[];

#if(GB2312 == 1)
	const unsigned char Decode_Part1[256] = 
	{
		0x8D,0x48,0x49,0x4A,0x4B,0xC7,0x67,0x73,0x74,0x64,0x60,0x61,0x83,0x77,0x00,0x01,
		0x02,0x03,0x04,0x05,0x7D,0x53,0x4C,0x4D,0xFE,0x7A,0x7B,0x7C,0x06,0x07,0x08,0x09,
		0x0A,0x0B,0x0C,0x0D,0x47,0x33,0x2A,0x2B,0x2C,0x5B,0x35,0x36,0x37,0x38,0x66,0x30,
		0x39,0x56,0x2D,0x2E,0x2F,0x3A,0x3B,0x41,0x42,0x43,0x31,0x32,0x50,0x3F,0x40,0x44,
		0x68,0x69,0x6A,0x6B,0x6C,0xFF,0x45,0x46,0x51,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,
		0x1D,0x1E,0x58,0x59,0x3C,0x3D,0x3E,0x57,0x4E,0x4F,0x1F,0x20,0x21,0x22,0x53,0x55,
		0x62,0x63,0x65,0x91,0x5C,0x5D,0x5E,0x6D,0x6E,0x6F,0x0E,0x0F,0x10,0x11,0x12,0x13,
		0x14,0x15,0x52,0x5F,0xAF,0xB0,0xB1,0x5A,0x70,0x71,0x72,0x75,0x76,0x8A,0x8B,0x23,
		0x24,0x25,0x26,0x27,0x28,0x29,0x84,0x85,0x88,0x98,0x99,0x9A,0x9B,0x9C,0x86,0x87,
		0x9D,0x89,0x8E,0x8F,0xA1,0xA2,0xA3,0x9E,0x78,0x79,0x9F,0xA0,0xBD,0xA5,0xA6,0xA7,
		0x88,0x89,0xAA,0xAB,0xAC,0xAD,0xAE,0xA4,0xCE,0x8C,0x92,0x93,0xC4,0xC5,0x82,0xB2,
		0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,0xCB,0x7E,0x7F,0x80,0x81,0xF6,0xC6,0x94,0x95,
		0x96,0x97,0xC2,0xC3,0xBA,0xBB,0xBC,0xC8,0xCC,0xE2,0xE3,0xE4,0xE5,0xE6,0xD0,0xD1,
		0xCD,0xBE,0xBF,0xC0,0xD6,0xC9,0xCA,0xD7,0xD8,0xD9,0xDA,0xDB,0x90,0xFB,0xFC,0xCF,
		0xDC,0xDD,0xDE,0xDF,0xE0,0xE1,0xEA,0xF7,0xF8,0xF9,0xFA,0xC1,0x34,0xEB,0xEC,0xED,
		0xEE,0xEF,0xD3,0xD4,0xFD,0xD5,0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xD2,0xE7,0xE8,0xE9,
	};
	const unsigned char Decode_Part2[256] = 
	{
		0x17,0x18,0xE2,0x0F,0x1B,0xB4,0x25,0x22,0x29,0x2A,0xAB,0x48,0x49,0x4A,0x4B,0x4C,
		0x10,0x1A,0x28,0x02,0x44,0x60,0x09,0x0A,0x0B,0x0C,0x42,0x23,0x34,0x35,0x36,0x37,
		0x38,0x39,0x3D,0x03,0x04,0x05,0x06,0x07,0x21,0x12,0x13,0x14,0x45,0x46,0x47,0x1C,
		0x1D,0x1E,0x1F,0x20,0x26,0x27,0x55,0x7F,0x80,0x81,0x82,0x83,0x56,0x57,0x58,0x84,
		0x85,0x86,0x87,0x88,0x5F,0x67,0x68,0x69,0x6A,0x6B,0x7D,0x3A,0x3B,0x3C,0x43,0x3E,
		0x3F,0x40,0x41,0x4D,0x4E,0x4F,0x65,0x66,0x61,0x62,0x63,0x64,0x2F,0x30,0x31,0x32,
		0x33,0x7C,0x50,0x51,0x52,0x53,0x54,0x75,0x89,0x8A,0x8B,0xB3,0x6F,0x00,0x01,0x98,
		0x5C,0x70,0x71,0x72,0x73,0x74,0x7B,0xBE,0xBF,0xC0,0xC1,0xC2,0x7E,0x5D,0x5E,0xAA,	
		0xAB,0x94,0x95,0x96,0xC9,0xB0,0x59,0x5A,0x5B,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
		0xA0,0xA1,0xB1,0xE6,0xE2,0x0D,0xFE,0x97,0xCE,0xC5,0xC6,0xC7,0xC8,0xD9,0xDA,0xDB,
		0x76,0x77,0x78,0x79,0x7A,0xF0,0x8C,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0xBA,0xBB,
		0xB5,0xE7,0xE8,0xDF,0xBC,0xBD,0xD7,0xD8,0x15,0x16,0xEC,0xF6,0xCA,0xCB,0xCC,0xFA,
		0xB6,0xB7,0xB8,0xB9,0x6C,0x6D,0x6E,0xEE,0xED,0xDC,0xDD,0xDE,0xF4,0xCD,0xCE,0xCF,
		0xD0,0x24,0xFF,0xF8,0xF5,0xFB,0xEB,0xAC,0xAD,0xAE,0xAF,0x0E,0xE9,0xEA,0x08,0xD1,
		0xD2,0xD3,0xD4,0xD5,0xD6,0xC3,0x2C,0x2D,0x2E,0xF9,0xE0,0xE1,0xF1,0xF2,0xF3,0xE3,
		0xE4,0xE5,0xFC,0xA2,0xA3,0xA4,0x19,0xFD,0xA5,0xA6,0xA7,0xA8,0xA9,0xEF,0xF7,0xAA,
	};
	const unsigned char Decode_Part3[256] = 
	{
		0xDC,0xFE,0x64,0x1B,0x1C,0x1D,0x1E,0x70,0x51,0xF5,0xF6,0x6A,0xD2,0xD3,0x7C,0xF3,
		0xCC,0xFF,0x20,0x21,0x22,0x23,0x5D,0x2A,0x45,0xEA,0xEB,0x1F,0x7D,0x7E,0x7F,0x80,
		0x2D,0x2B,0x2C,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x28,0x29,0x24,0x25,0x26,
		0x27,0x58,0x59,0x5E,0x5F,0x35,0x52,0x53,0x54,0x55,0x56,0x57,0x62,0x63,0x00,0x01,
		0x02,0x03,0x04,0x05,0x36,0x37,0x38,0x39,0x3A,0x3B,0x95,0x96,0x97,0x98,0x99,0x9A,
		0x81,0x8D,0x8E,0x8F,0x90,0x91,0x92,0x93,0x71,0x72,0x2E,0x2F,0x30,0x31,0x32,0x33,
		0x34,0x42,0x43,0x44,0x5A,0x5B,0x5C,0x46,0x47,0x48,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
		0x60,0xBC,0xBD,0xBE,0xBF,0xC0,0xC0,0x61,0xC7,0xB3,0xC2,0x66,0x67,0x68,0x69,0x7B,
		0x85,0x86,0x94,0x83,0x84,0x82,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7A,0x6B,0x6C,
		0x6D,0x6E,0x9D,0x9E,0x9F,0xA0,0xA1,0x88,0x89,0x8A,0x65,0x06,0x07,0x08,0x09,0x0A,
		0x0B,0x0C,0x0D,0x0E,0x0F,0x10,0x3C,0xAC,0xAD,0xA2,0xA3,0xA4,0x9B,0x9C,0x87,0x6F,
		0xC3,0xC4,0xC5,0xC6,0xCA,0xCB,0x3D,0x3E,0x3F,0x40,0x41,0x8B,0x8C,0xCD,0xCE,0xCF,
		0xD0,0xD1,0xDD,0xA8,0xA9,0xAA,0xAB,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,
		0x1A,0xBA,0xBB,0xAE,0xAF,0xB0,0xB1,0xB2,0xDA,0xDB,0xA5,0xA6,0xA7,0xF2,0xF7,0xF8,
		0xF9,0xFA,0xFB,0xFC,0xFD,0xDE,0xDF,0xE0,0xE1,0xE2,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,
		0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,0xEC,0xED,0xEE,0xEF,0xF0,0xE3,0xF1,0xF4,0xC8,0xC9,
	};
	const unsigned char Decode_Part4[256] = 
	{
		0xFC,0xAD,0x6A,0x40,0x43,0x3C,0x33,0x21,0xF2,0x23,0xFB,0x1E,0x84,0x1D,0xC6,0xA9,
		0xC9,0xB0,0xD0,0x57,0xC7,0x20,0x00,0xD4,0xEA,0xD9,0xB5,0x1A,0x3E,0x3F,0x14,0xBD,
		0xFD,0x2B,0x2C,0x9E,0x22,0xB7,0xBB,0x3D,0x94,0x26,0xDC,0xC0,0x27,0x9B,0x15,0x71,
		0x2F,0x01,0x45,0x48,0x49,0x4A,0x56,0x8D,0x1F,0x9F,0x34,0x35,0x36,0x37,0x38,0x41,
		0x42,0x58,0x0F,0xE7,0x44,0x46,0x8C,0x6D,0x6C,0x16,0xCA,0x4E,0x4B,0x19,0x2A,0xC1,
		0x3A,0x76,0x04,0xB1,0x18,0x7B,0x25,0x5B,0x6F,0x03,0x59,0x53,0x2D,0x32,0x5C,0x8E,
		0x54,0xE0,0x8A,0x99,0x72,0x92,0x50,0x4D,0x7E,0x88,0x55,0x69,0x51,0x02,0x6E,0x89,
		0x5D,0x3B,0x7D,0x87,0xC3,0x66,0x0E,0x80,0x77,0x81,0x28,0x85,0x70,0x83,0xC2,0x95,
		0xFF,0x8B,0x67,0x17,0xAA,0x5E,0x93,0x9C,0x91,0x90,0x29,0xB9,0xB4,0xB8,0xA3,0x7F,
		0x5F,0xA7,0x30,0x31,0xA0,0xA1,0xE3,0xE4,0x05,0x06,0x07,0x08,0x09,0xD3,0xAC,0x9A,
		0x82,0x74,0xFE,0x47,0x1B,0x1C,0x8F,0xF1,0x6B,0xA2,0x5A,0x10,0xD1,0xCB,0xA6,0xCF,
		0x0A,0x61,0x62,0x63,0x64,0x65,0xBC,0x78,0x79,0xC5,0x11,0xD5,0xE1,0xE5,0x0B,0xDE,
		0xCC,0xB3,0xEE,0xA8,0xED,0xB6,0xC4,0x96,0xD2,0x7C,0xDA,0xD7,0xB2,0x86,0xFA,0xD8,
		0xCD,0xDB,0xF6,0x97,0xEB,0x0D,0xF9,0x7A,0xF5,0xAF,0xDF,0xF3,0x12,0x98,0x2E,0xE8,
		0xE9,0xAE,0xEC,0x39,0x52,0x4C,0xF7,0xF8,0x9D,0xE2,0x60,0xDD,0xF4,0xA4,0xA5,0xBE,
		0xBF,0xE6,0xBA,0xD6,0xF0,0xEF,0x0C,0x24,0xCE,0x13,0x68,0x4F,0xC8,0x73,0x75,0xAB,
	};
#endif
//InterCharSearchTab:区分ASCII常用字符和特殊字符的数组,当字符值不等于0xff时,为特殊字符
const unsigned char  InterCharSearchTab[]={
	0xff,	0xff,	0xff,	0,		1,		0xff,	0xff,	0xff,
	//0x20,	0x21,	0x22,	0x23,	0x24,	0x25,	0x26,	0x27
	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x28,	0x29,	0x2a,	0x2b,	0x2c,	0x2d,	0x2e,	0x2f
	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x30,	0x31,	0x32,	0x33,	0x34,	0x35,	0x36,	0x37
	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x38,	0x39,	0x3a,	0x3b,	0x3c,	0x3d,	0x3e,	0x3f
	2,		0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x40,	0x41,	0x42,	0x43,	0x44,	0x45,	0x46,	0x47
	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x48,	0x49,	0x4a,	0x4b,	0x4c,	0x4d,	0x4e,	0x4f
	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x50,	0x51,	0x52,	0x53,	0x54,	0x55,	0x56,	0x57
	0xff,	0xff,	0xff,	3,		4,		5,		6,		0xff,
	//0x58,	0x59,	0x5a,	0x5b,	0x5c,	0x5d,	0x5e,	0x5f
	7,		0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x60,	0x61,	0x62,	0x63,	0x64,	0x65,	0x66,	0x67
	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x68,	0x69,	0x6a,	0x6b,	0x6c,	0x6d,	0x6e,	0x6f
	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,	0xff,
	//0x70,	0x71,	0x72,	0x73,	0x74,	0x75,	0x76,	0x77
	0xff,	0xff,	0xff,	8,		9,		10,		11,		0xff,
	//0x78,	0x79,	0x7a,	0x7b,	0x7c,	0x7d,	0x7e,	0x7f
};
//在代码页2中找点阵 (page 0)0->0X9E (Pt)
const unsigned char  InterCharExchangeTab[14][12]={
	{0x23,0x24,0x40,0x5B,0x5C,0x5D,0x5E,0x60,0x7B,0x7C,0x7D,0x7E},  // 0 U.S.A.
	{0x23,0x24,0x85,0xF8,0x87,0xF5,0x5E,0x60,0x82,0x97,0x8A,0xF9},	// 1 France
	{0x23,0x24,0xF5,0x8E,0x99,0x9A,0x5E,0x60,0x84,0x94,0x81,0xE1},	// 2 Germany
	{0x9C,0x24,0x40,0x5B,0x5C,0x5D,0x5E,0x60,0x7B,0x7C,0x7D,0x7E},	// 3 U.K.
	{0x23,0x24,0x40,0x93,0x9C,0x8F,0x5E,0x60,0x91,0x9B,0x86,0x7E},	// 4 Denmark I
	{0x23,0xCF,0x90,0x8E,0x99,0x8F,0x9A,0x82,0x84,0x94,0x86,0x81},	// 5 Sweden
	{0x23,0x24,0x40,0xF8,0x5C,0x82,0x5E,0x97,0x85,0x95,0x8A,0x8D},	// 6 Italy
	{0,   0x24,0x40,0xAD,0xA5,0xA8,0x5E,0x60,0xF9,0xA4,0x7D,0x7E},	// 7 Spain  I
	{0x23,0x24,0x40,0x5B,0xBE,0x5D,0x5E,0x60,0x7B,0x7C,0x7D,0x7E},	// 8 Janan
	{0x23,0xCF,0x90,0x93,0x9C,0x8F,0x9A,0x82,0x91,0x9B,0x86,0x81},	// 9 Norway
	{0x23,0x24,0x90,0x93,0x9C,0x8F,0x9A,0x82,0x91,0x9B,0x86,0x81},	// A Denmark II
	{0x23,0x24,0x96,0xAD,0xA5,0xA8,0x82,0x60,0xA1,0xA4,0xA2,0xA3},	// B Spain  II
	{0x23,0x24,0x96,0xAD,0xA5,0xA8,0x82,0x81,0xA1,0xA4,0xA2,0xA3},	// C Latin America
	{0x23,0x24,0x40,0x5B, 1 , 0x5D,0x5E,0x60,0x7B,0x7C,0x7D,0x7E},	// D Korea
};



/******************************************************************************************************/

/*******************************************************************************
** Function name   :      CalculateChineseAddr    
**
** Descriptions    :      获取指定汉字地址
** input parameters:      cByte1  first byte  cByte2 second byte
**
** Returned value  :      返回指定地址   
**
******************************************************************************/
unsigned int CalculateChineseAddr(unsigned char cByte1,unsigned char cByte2,unsigned char cByte3,unsigned char cByte4)//yxm add
{
	unsigned int Address = 0;
	if(cByte1==0xfe && cByte2>=0xa1 && cByte2<=0xfe)//user defined char 
	{
		if(SPI_Read_Byte(UserCharAddr_24x24 |((cByte2-0xa1)<<12)))
		{
			Address = UserCharAddr_24x24 |((cByte2-0xa1)<<12)|1;
		}
	}
	else if(cByte1>=0xA1 && cByte1<=0xA9)
	{
		bPart1 = 1;
		Address =((cByte1 - 0xA1) * 94 + (cByte2 - 0xA1))*72+ BaseAddr1_24x24;
	}
	else// 汉字 B0~F7区
	{
		bPart3 = 1;
		Address =((cByte1 - 0xB0) * 94 + (cByte2 - 0xA1))*72+ BaseAddr2_24x24;
	}
	return Address;
}



unsigned int CalculatePty860Addr(unsigned char cByte1)//yxm add
{
	unsigned int Address = 0;

	
	Address =(cByte1 * HZ_WIDTH*3)+ Pty860Addr;


	return Address;
}


/*******************************************************************************
** Function name   :     CalculateAsciiAddr    
**
** Descriptions    :     获取指定字符地址
** input parameters:     cByte  Ascii Code
**
** Returned value  :     返回指定地址   
**
******************************************************************************/
u32 CalculateAsciiAddr(unsigned char cByte) //yxm add
{
	unsigned int Address;
	unsigned char cTemp;
	if(cByte > 0x7F)//高128位Ascii码 需要判断代码页     //自测打印不进来
	{
	//	MyPrintf("CB_1! ");
		if(bFont12x24)//12X24代码页
		{
			if((cCodePage < 33)||(cCodePage == 255))
			{
				switch(cCodePage)
				{
					case 0:
					case 1:
					case 2:
					case 3:
					case 4:
					case 5:
					case 6:
					case 7:
					case 8:
					case 9:				   
					case 10:
						bPart4 = 1;
						Address = (cByte-0x80)*(ASCII_WIDTH*3) + ExtendedBaseAddr1_12x24 + cCodePage*(unsigned long)ZKBlockSize_12x24;
						break;
					case 16:
					case 17:
					case 18:
					case 19:
					case 20:
					case 21:
					case 22:
					case 23:
					case 24:
					case 25:
					case 26:      
					case 27:
					case 28:
					case 29:
					case 30:
					case 31:
					case 32:
						bPart4 = 1;
						Address = (cByte-0x80)*(ASCII_WIDTH*3) + ExtendedBaseAddr1_12x24 + (cCodePage-5)*(unsigned long)ZKBlockSize_12x24;
						break;
					case 255:
					{
						unsigned char temp_codepage;
						bPart4 = 1;
						temp_codepage = 33;
						Address = (cByte-0x80)*(ASCII_WIDTH*3) + ExtendedBaseAddr1_12x24 + (temp_codepage-5)*(unsigned long)ZKBlockSize_12x24;
						break;
					}
				    default:
						bPart4 = 1;
						Address = (cByte-0x80)*(ASCII_WIDTH*3) + ExtendedBaseAddr1_12x24;
					    break;
				}
			}
			else if((cCodePage)>49&&(cCodePage<100))
			{
				bPart3 = 1;
				Address = (cByte-0x80)*(ASCII_WIDTH*3) + ExtendedBaseAddr2_12x24+ (cCodePage-50)*(unsigned long)ZKBlockSize_12x24;	
			}
			else
			{
				bPart4 = 1;
				Address = (cByte-0x80)*(ASCII_WIDTH*3) + ExtendedBaseAddr1_12x24;
			}
		}
		else//9X24代码页
		{
			if((cCodePage < 20)||(cCodePage == 255))
			{
				switch(cCodePage)
				{
					case 0:
					case 1:
					case 2:
					case 3:
					case 4:
					case 5:
					case 6:
						bPart2 = 1;
						Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24 + cCodePage*(unsigned long)ZKBlockSize_9x24;
						break;
					case 16:
						bPart2 = 1;
						Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24 + (cCodePage-9)*(unsigned long)ZKBlockSize_9x24;
						break;
					case 17:
						bPart2 = 1;
						Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24 + (cCodePage-11)*(unsigned long)ZKBlockSize_9x24;
						break;
					case 18:
					case 19:
						bPart2 = 1;
						Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24 + (cCodePage-10)*(unsigned long)ZKBlockSize_9x24;
						break;
					case 255:
					{
						unsigned char temp_codepage;
						bPart2 = 1;
						temp_codepage = 20;
						Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24 + (temp_codepage-10)*(unsigned long)ZKBlockSize_9x24;
						break;
					}
				    default:
						bPart2 = 1;
						Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24;
					    break;
				}
			}
			else
			{
				bPart2 = 1;
				Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24;
			}
		}
	}
	else//低128位ascii码     //自测打印时循环进来
	{
	//	MyPrintf("cByte= %d ",cByte);
		cTemp = InterCharSearchTab[cByte-0x20];
		if(cTemp != 0xff)      //处理特殊字符部分
		{
			//MyPrintf("aaa! ");
			cByte = InterCharExchangeTab[cInternationalCharSet][cTemp];
			if(cByte == 0)
			{
			//	MyPrintf("aaa_111! ");
				if(bFont12x24)
				{
					bPart4 = 1;
					//Address = (u32)(0x9e-0x80)*(SFONT_WIDTH*3)+ExtendedBaseAddr1_12x24;
					Address = (u32)0x1e*(ASCII_WIDTH*3)+ExtendedBaseAddr1_12x24;					
				
				}
				else
				{
					bPart2 = 1;
					//Address = (u32)(0x9e-0x80)*(SFONT_WIDTH*3)+ExtendedBaseAddr_9x24;
					Address = (u32)0x1e*(ASCII_WIDTH*3)+ExtendedBaseAddr_9x24;
				}
			}
			//else if(cByte == 1)
			//{
				//没找到韩国的一个字符类似W的一个字符
			//}
			else if(cByte >0x7F)
			{
			//	MyPrintf("aaa_222! ");
				if(bFont12x24)
				{
					bPart4 = 1;
					Address = (cByte-0x80)*(ASCII_WIDTH*3) + ExtendedBaseAddr1_12x24 + 2*ZKBlockSize_12x24;
				}
				else
				{
					bPart2 = 1;
					Address = (cByte-0x80)*(SFONT_WIDTH*3) + ExtendedBaseAddr_9x24 + 2*ZKBlockSize_9x24;
				}
			}
			else
			{
			//	MyPrintf("aaa_333! ");
				if(bFont12x24)
				{
					bPart2 = 1;
					Address = (cByte - 0x20)*(ASCII_WIDTH*3) + BaseAddr_12x24;
				}
				else
				{
					bPart2 = 1;
					Address = (cByte - 0x20)*(SFONT_WIDTH*3) + BaseAddr_9x24;
				}
			}
		}
		else
		{
			if(bFont12x24)       //自测打印循环进来
			{
			//	MyPrintf("BBB! ");
				bPart2 = 1;
				Address = (cByte - 0x20)*(ASCII_WIDTH*3) + BaseAddr_12x24;             //#define ASCII_WIDTH			  12 //ascii横向占得点数
			}
			else
			{
			//	MyPrintf("BBB_1111! ");
				bPart2 = 1;
				Address = (cByte - 0x20)*(SFONT_WIDTH*3) + BaseAddr_9x24;
			}
		}
	}
	return Address;
}
/*******************************************************************************
** Function name   :       CalculateAsciiAddr    
**
** input parameters:       Chinese Addr
** Descriptions    :       获取指定汉字字模
**  
******************************************************************************/
void GetChineseZimo(unsigned int Addr)
{
	unsigned char i;
	unsigned char cTempBuf[HZ_WIDTH*3];	
	SPI_FastRead_nBytes(Addr,cTempBuf,HZ_WIDTH*3);
	if(bPart1 == 1) //A0~A9
	{
		bPart1 = 0;
		for(i = 0;i < HZ_WIDTH*3;i ++)
		{
			Zimotemp[i] = Decode_Part1[cTempBuf[i]];
		}
	}
	else if(bPart3 == 1)//B0~B7
	{
		bPart3 = 0;
		for(i = 0;i < HZ_WIDTH*3;i ++)
		{
			Zimotemp[i] = Decode_Part3[cTempBuf[i]];
		}
	}
	else//User defiened   char
	{
		for(i = 0;i < HZ_WIDTH*3;i ++)
		{
			Zimotemp[i] = cTempBuf[i];
		}
	}
}
/*******************************************************************************
** Function name   :      GetAsciiZimo    
**
** input parameters:      ASCII Addr
** Descriptions    :      获取指定字符字模  
**
******************************************************************************/
void GetAsciiZimo(u32 Addr)
{
	unsigned char i;
	unsigned char cTempBuf[ASCII_WIDTH*3];
	if(bUserChar)
	{
		/*if(bFont12x24)
		{
			//(Addr-AsciiBaseAddr)/(ASCII_WIDTH*3) 字符首地址
			if(UserDefinedBuf[(Addr-BaseAddr_12x24)/(ASCII_WIDTH*3)*(ASCII_WIDTH*3+1)] == 0x01)//还原地址看是否被定义
			{
				for(i = 0;i<(ASCII_WIDTH*3);i++)//读出(ASCII_WIDTH*3)个字节
				{
					Zimotemp[i]=UserDefinedBuf[(Addr-BaseAddr_12x24)/(ASCII_WIDTH*3)*(ASCII_WIDTH*3+1)+1+i];
				}
				return;
			}
		}
		else
		{
			if(UserDefinedBuf[(Addr-BaseAddr_12x24)/(SFONT_WIDTH*3)*(SFONT_WIDTH*3+1)+MaxDotPos*ASCII_WIDTH] == 0x01)
			{
				for(i = 0;i<SFONT_WIDTH*3;i++)
				{
					Zimotemp[i]=UserDefinedBuf[(Addr-BaseAddr_12x24)/(SFONT_WIDTH*3)*(SFONT_WIDTH*3+1)+MaxDotPos*ASCII_WIDTH+1+i];
				}
				return;
			}
		}*/
	}
	if(bFont12x24)
	{
		SPI_FastRead_nBytes(Addr,cTempBuf,(ASCII_WIDTH*3));    
		//bERLED_OFF;
		if(bPart2 == 1)//ASCII 0x20~0x7F  12X24
		{
			bPart2 = 0;
			for(i = 0;i<ASCII_WIDTH*3;i ++)
			{
				Zimotemp[i] = Decode_Part2[cTempBuf[i]];
			}
		}
		else if(bPart3 == 1)// code page 50~code page 96 12x24
		{
			bPart3 = 0;
			for(i = 0;i<ASCII_WIDTH*3;i ++)
			{
				Zimotemp[i] = Decode_Part3[cTempBuf[i]];
			}
		}
		else if(bPart4 == 1)//code page 0~code page 32, page 255   12x24
		{
			bPart4 = 0;
			for(i = 0;i<ASCII_WIDTH*3;i ++)
			{
				Zimotemp[i] = Decode_Part4[cTempBuf[i]];
			}
		}
		else//others
		{
			for(i = 0;i<ASCII_WIDTH*3;i ++)
			{
				Zimotemp[i] = cTempBuf[i];
			}
		}
	}
	else
	{
		SPI_FastRead_nBytes(Addr,cTempBuf,(SFONT_WIDTH*3));
		if(bPart2 == 1)//FontB 9x24
		{
			bPart2 = 0;
			for(i = 0;i<SFONT_WIDTH*3;i ++)
			{
				Zimotemp[i] = Decode_Part2[cTempBuf[i]];
			}
		}
		else//other
		{
			for(i = 0;i<SFONT_WIDTH*3;i ++)
			{
				Zimotemp[i] = cTempBuf[i];
			}
		}
	}
}
/*******************************************************************************
** Function name:     FillPrtBufChinese    
**
** Descriptions :     填充汉字字模
**  
******************************************************************************/
void FillPrtBufChinese(void)
{
	unsigned int  iTemp;
	unsigned char cSpaceTemp;
	unsigned char cLoop;
	unsigned char cLoop1;
	unsigned char cCount;
	unsigned char cWidth;
	unsigned char *pChinesePattern;
	unsigned char *pChineseHightPattern;
	unsigned char ChineseZimotempHight[HZ_WIDTH*3*4];

	bUnderLineEffect = 1;
	cWidth = HZ_WIDTH;
	iTemp = cWidth* cChineseWidthMultiple;//chinese width	
	cChineseLeftSpace = cChineseLeftSpace << (cChineseWidthMultiple - 1);//Left spase
	cChineseRightSpace = cChineseRightSpace << (cChineseWidthMultiple - 1);//righ tspase
	iTemp += (cChineseLeftSpace+cChineseRightSpace);//chinese width ++leftspase+rightspace
	if(iTemp > (iPrtRightMargin - iPrtLeftMargin))//打印区域 默认是MaxDotPos - 0
	{
        iTemp = (iPrtRightMargin - iPrtLeftMargin);
	}
	JudgeExceedByteLine(iTemp);
//	MyPrintf("h111");
	if(bPrtAdverse)//反白打印处理
	{
		for(cLoop = 0;cLoop<HZ_WIDTH*3;cLoop ++)//按位取反
		{
			Zimotemp[cLoop] = ~Zimotemp[cLoop];
		}
		cSpaceTemp = 0xff;//边距填充值
		bUnderLineEffect = 0;//下划线失效
	}
	else
	{
		cSpaceTemp = 0;//边距填充值
	}
	pChinesePattern = &Zimotemp[0];


	bHaveFilledChinese = 1;
	one_dotline_lfstep_num=ONEDOTSTEPNUM;

	if(cChineseHightMultiple > 1)//有倍高
	{		
		unsigned char *p;
		unsigned int Temp1;
		unsigned int Temp2;
		memset(&ChineseZimotempHight, 0, sizeof(ChineseZimotempHight)); 
		ChineseHightMultiple(pChinesePattern,ChineseZimotempHight,cWidth);//倍高处理
		pChineseHightPattern = &ChineseZimotempHight[0];
		p = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[0].BasePrtLine[iCurrentFillColumn]; 
		for(cCount = 0;cCount<cChineseLeftSpace;cCount++)//左边距
		{
	
			for(cLoop1= 0;cLoop1<cChineseHightMultiple;cLoop1++)//每次循环填充3个字节行
			{
				Temp1 = 3*(cChineseHightMultiple-cLoop1-1)*MaxDotPos;
				*(p+2*MaxDotPos+Temp1)//
					= cSpaceTemp;
				*(p+MaxDotPos+Temp1)//
					= cSpaceTemp;
				*(p+Temp1)//
					= cSpaceTemp;
			}
			p++;
			iCurrentFillColumn ++;
		}
		for(cCount = 0;cCount<cWidth;cCount++)
		{
	
			for(cLoop = 0;cLoop<cChineseWidthMultiple;cLoop ++)//填充字模
			{
				for(cLoop1= 0;cLoop1<cChineseHightMultiple;cLoop1++)//每次循环填充3个字节行
				{
					Temp1 = 3*(cChineseHightMultiple-cLoop1-1)*MaxDotPos;
					Temp2 = cLoop1*3*cWidth;
					*(p+2*MaxDotPos+Temp1)//
						= *(pChineseHightPattern+Temp2);
					*(p+MaxDotPos+Temp1)//
						= *(pChineseHightPattern+Temp2+cWidth);
					*(p+Temp1)//
						= *(pChineseHightPattern+Temp2+2*cWidth);
				}
				p++;
				iCurrentFillColumn ++;
			}
			pChineseHightPattern++;
	
		}
		for(cCount = 0;cCount<cChineseRightSpace;cCount++)//右边距
		{
	
			for(cLoop1= 0;cLoop1<cChineseHightMultiple;cLoop1++)//每次循环填充3个字节行
			{
				Temp1 = 3*(cChineseHightMultiple-cLoop1-1)*MaxDotPos;
				Temp2 = (int)pChineseHightPattern+cLoop1*3*cWidth;
				*(p+2*MaxDotPos+Temp1)//
					= cSpaceTemp;
				*(p+MaxDotPos+Temp1)//
					= cSpaceTemp;
				*(p+Temp1)//
					= cSpaceTemp;
			}
			p++;
			iCurrentFillColumn ++;
		}
	}
	else
	{
		unsigned char *p1;
		unsigned char *p2;
		unsigned char *p3;
		p1 = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[0].BasePrtLine[iCurrentFillColumn];
		p2 = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[1].BasePrtLine[iCurrentFillColumn];
		p3 = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[2].BasePrtLine[iCurrentFillColumn];
		for(cCount = 0;cCount<cChineseLeftSpace;cCount++)//左边距
		{
			// 
			*p3++ = cSpaceTemp;
			//
			*p2++ = cSpaceTemp;
			//
			*p1++ = cSpaceTemp;
			//p ++;
			iCurrentFillColumn ++;
		}
		
		for(cCount = 0;cCount<cWidth;cCount++)
		{
			//SerialSendByte(0X11);//TEST
			for(cLoop = 0;cLoop<cChineseWidthMultiple;cLoop ++)//填充字模
			{
				//
				*p3++ = *(pChinesePattern);
				// 
				*p2++ = *(pChinesePattern+cWidth);
				//
				*p1++ = *(pChinesePattern+2*cWidth);
				iCurrentFillColumn ++;
			}
			pChinesePattern++;
			//SerialSendByte(0X13);//TEST
		}
		for(cCount = 0;cCount<cChineseRightSpace;cCount++)//右边距
		{
			//
			*p3++ = cSpaceTemp;
			//
			*p2++ = cSpaceTemp;
			//
			*p1++ = cSpaceTemp;
			iCurrentFillColumn ++;
		}
	}
	AddBlod(cCurrentFillRow,iTemp,cChineseHightMultiple);//粗体打印
	AddUnderLine(cCurrentFillRow,iTemp,bChineseUnderLine);//下划线打印设置
}
/*******************************************************************************
** Function name:     ChineseHightMultiple    
**
** Descriptions :     汉字多倍高处理最多4倍
**  
******************************************************************************/
void ChineseHightMultiple(unsigned char *pChinesePattern,unsigned char *pChineseHightPattern,unsigned char ChineseWidth)
{
	unsigned char cLoop;
	unsigned char cLoop1;
	unsigned char cLoop2;
	unsigned char cLoop3;
	unsigned int  iTemp[HZ_WIDTH];
	unsigned char cTemp[PRTLINEHIGHT*4];
	for(cLoop =0;cLoop<ChineseWidth;cLoop++)//合并成24个int型数组
	{
		iTemp[cLoop] = (unsigned int)(*pChinesePattern<<16)|(unsigned int)(*(pChinesePattern+ChineseWidth)<<8)|(unsigned int)*(pChinesePattern+2*ChineseWidth);
		pChinesePattern ++;
	}
	for(cLoop =0;cLoop<ChineseWidth;cLoop++)//处理宽度个int数组
	{
		cLoop3 = 0;
		for(cLoop2 =0;cLoop2 < PRTLINEHIGHT;cLoop2++)//取出24*cChineseHightMultiple个cTemp的数组
		{
			for(cLoop1 = 0;cLoop1 < cChineseHightMultiple;cLoop1++)//相同的cChineseHightMultiple 个
			{
				cTemp[cLoop3++] = (iTemp[cLoop] >>(23-cLoop2))&0x01;
			}
		}
		cLoop3 = 0;
		for(cLoop2 =0;cLoop2 < cChineseHightMultiple*3;cLoop2++)//重新组成cChineseHightMultiple*3个字节
		{
			for(cLoop1 = 0;cLoop1 < 8;cLoop1++)//8个cTemp组成一个字节
			{
				*(pChineseHightPattern+cLoop+cLoop2*ChineseWidth) |= (cTemp[cLoop3++]<<(7-cLoop1));
			}
		}
	}
}

/*******************************************************************************
** Function name:     FillPrtBufAscii    
**
** Descriptions :     填充字符字模
**  
******************************************************************************/
void FillPrtBufAscii(void)                //CPCL指令打印位图时循环进来
{
	unsigned int  iTemp;//ascii width +rightspace
	unsigned char cSpaceTemp;
	unsigned char cLoop;
	unsigned char cLoop1;
	unsigned char cCount;
	unsigned char cWidth;//字符宽度
	unsigned char *pAsciiPattern;
	unsigned char *pAsciiHightPattern;
	unsigned char AsciiZimotempHight[ASCII_WIDTH*3*4];
	bUnderLineEffect = 1;
//	MyPrintf("FillPrtBufAscii\n");
	if(bFont12x24)
	{
		cWidth = ASCII_WIDTH;
		iTemp = cWidth * cAsciiWidthMultiple;//ascii width
	}
	else
	{
		cWidth = SFONT_WIDTH;
		//添加小字体顺时针旋转90度处理函数
		iTemp = cWidth * cAsciiWidthMultiple;//ascii width
	}
	 cAsciiRightSpace = cAsciiRightSpace << (cAsciiWidthMultiple - 1);//rightspace
	iTemp += cAsciiRightSpace ;//ascii width +rightspace
	if(iTemp > (iPrtRightMargin - iPrtLeftMargin))//打印区域 默认是MaxDotPos - 0
	{
        iTemp = (iPrtRightMargin - iPrtLeftMargin);
	}

	JudgeExceedByteLine(iTemp);
//	MyPrintf("h222");
	if(bPrtAdverse)//反白打印处理
	{
		for(cLoop = 0;cLoop<cWidth*3;cLoop ++)//按位取反
		{
			Zimotemp[cLoop] = ~Zimotemp[cLoop];
		}
		cSpaceTemp = 0xff;
		bUnderLineEffect = 0;//UnderLine not Effect
		//RightSpace 处理
	}
	else
	{

		cSpaceTemp = 0;
	}
	pAsciiPattern = &Zimotemp[0];

	bHaveFilledAscii = 1;
	one_dotline_lfstep_num=ONEDOTSTEPNUM;//
	
	if(cAsciiHightMultiple > 1)//有倍高
	{
		unsigned char *p;
		unsigned int Temp1;
		unsigned int Temp2;
		memset(&AsciiZimotempHight, 0, sizeof(AsciiZimotempHight)); 
		AsciiHightMultiple(pAsciiPattern,AsciiZimotempHight,cWidth);//倍高处理,保存到AsciiZimotempHight里面
		pAsciiHightPattern = &AsciiZimotempHight[0];
		p = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[0].BasePrtLine[iCurrentFillColumn];
		for(cCount = 0;cCount<cWidth;cCount++)
		{
			for(cLoop = 0;cLoop<cAsciiWidthMultiple;cLoop ++)//填充字模
			{
				for(cLoop1= 0;cLoop1<cAsciiHightMultiple;cLoop1++)//每次循环填充3个字节行
				{
					Temp1 = 3*(cAsciiHightMultiple-cLoop1-1)*MaxDotPos;
					Temp2 = cLoop1*3*cWidth;
					*(p+2*MaxDotPos+Temp1)//
						= *(pAsciiHightPattern+Temp2);
					*(p+MaxDotPos+Temp1)//
						= *(pAsciiHightPattern+Temp2+cWidth);
					*(p+Temp1)//
						= *(pAsciiHightPattern+Temp2+2*cWidth);
				}
				p++;
				iCurrentFillColumn ++;
			}
			pAsciiHightPattern++;

		}
		for(cCount = 0;cCount<cAsciiRightSpace;cCount++)//右边距
		{
			for(cLoop1= 0;cLoop1<cAsciiHightMultiple;cLoop1++)//每次循环填充3个字节行
			{
				Temp1 = 3*(cAsciiHightMultiple-cLoop1-1)*MaxDotPos;
				*(p+2*MaxDotPos+Temp1)//
					= cSpaceTemp;
				*(p+MaxDotPos+Temp1)//
					= cSpaceTemp;
				*(p+Temp1)//
					= cSpaceTemp;
			}
			p++;
			iCurrentFillColumn ++;
		}		
	}
	else
	{
		unsigned char *p1;
		unsigned char *p2;
		unsigned char *p3;
		p1 = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[0].BasePrtLine[iCurrentFillColumn];
		p2 = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[1].BasePrtLine[iCurrentFillColumn];
		p3 = (unsigned char *)&PrtBuf[cCurrentFillRow].ByteLine[2].BasePrtLine[iCurrentFillColumn];
		for(cCount = 0;cCount<cWidth;cCount++)//填充字模
		{
			for(cLoop = 0;cLoop<cAsciiWidthMultiple;cLoop ++)
			{
				// 
				*p3++ = *(pAsciiPattern);
				//
				*p2++ = *(pAsciiPattern+cWidth);
				//
				*p1++ = *(pAsciiPattern+2*cWidth);
				 
				iCurrentFillColumn ++;
			}
			pAsciiPattern++;
		}
		for(cCount = 0;cCount<cAsciiRightSpace;cCount++)//右边距
		{
			//
			*p3++ = cSpaceTemp;
			//
			*p2++ = cSpaceTemp;
			//
			*p1++ = cSpaceTemp;
			 
			iCurrentFillColumn ++;
		}
	}
	AddBlod(cCurrentFillRow,iTemp,cAsciiHightMultiple);//粗体打印设置
	AddUnderLine(cCurrentFillRow,iTemp,bAsciiUnderLine);//下划线打印设置
}
/*******************************************************************************
** Function name:    AsciiHightMultiple    
**
** Descriptions :    字符多倍高处理    最多4倍
**  
******************************************************************************/
void AsciiHightMultiple(unsigned char *pAsciiPattern,unsigned char *pAsciiHightPattern,unsigned char AsciiWidth)
{
	unsigned char cLoop;
	unsigned char cLoop1;
	unsigned char cLoop2;
	unsigned char cLoop3;
	unsigned int  iTemp[ASCII_WIDTH];
	unsigned char cTemp[PRTLINEHIGHT*4];
	for(cLoop =0;cLoop<AsciiWidth;cLoop++)//合并成AsciiWidth 个int型数组
	{
		iTemp[cLoop] = (unsigned int)(*pAsciiPattern<<16)|(unsigned int)(*(pAsciiPattern+AsciiWidth)<<8)|(unsigned int)*(pAsciiPattern+2*AsciiWidth);
		pAsciiPattern ++;
	}
	for(cLoop =0;cLoop<AsciiWidth;cLoop++)//处理宽度个int数组
	{
		cLoop3 = 0;
		for(cLoop2 =0;cLoop2 < PRTLINEHIGHT;cLoop2++)//取出24*cAsciiHightMultiple个cTemp的数组
		{
			for(cLoop1 = 0;cLoop1 < cAsciiHightMultiple;cLoop1++)//相同的cAsciiHightMultiple 个
			{
				cTemp[cLoop3++] = (iTemp[cLoop] >>(23-cLoop2))&0x01;
			}
		}
		cLoop3 = 0;
		for(cLoop2 =0;cLoop2 < cAsciiHightMultiple*3;cLoop2++)//重新组成cAsciiHightMultiple*3个字节
		{
			for(cLoop1 = 0;cLoop1 < 8;cLoop1++)//8个cTemp组成一个字节
			{
				*(pAsciiHightPattern+cLoop+cLoop2*AsciiWidth) |= (cTemp[cLoop3++]<<(7-cLoop1));
			}
		}
	}
}

/*******************************************************************************
** Function name:     JudgeExceedByteLine    
**
** Descriptions :     Judg  打印buffer是否填满
**  
*******************************************************************************/
unsigned char JudgeExceedByteLine(unsigned int iDotWillAdd)
{
	if(iDotWillAdd <= (iPrtRightMargin- iCurrentFillColumn))
	{	
		// the byte line is not full
		return 0;
	}
	else
	{
		// the line is full
//		MyPrintf("!111"); 
		StartupPrint(1);
		return 1;
	}
}
/*******************************************************************************
** Function name:     StartupPrint    
**
** Descriptions :     准备打印函数
**  
*******************************************************************************/
void StartupPrint(unsigned char cNeedFeedLineSpace)  //
{
   unsigned char cNextLine;
	unsigned char cTempStatus;
	unsigned char cTempStep;
	unsigned char bNeedFeedLineSpace;
	unsigned int  iStepNum;

	//scan err and test
	//TestBatteryQuantity();
	//SerialSendByte(0x11);

//	MyPrintf("StartupPrint_\n");	
	if(f_error_no_paper)  //
	{
		//MyPrintf("no paper  \n"); 
		return;
	}
   
	if(cNeedFeedLineSpace)//是否需要走行间距   CPCL指令打印时会进来
	{
//		MyPrintf("b11\n");
		bNeedFeedLineSpace	= 1;
	}
	else
	{
//		MyPrintf("b22\n");
		bNeedFeedLineSpace	= 0;
	}

	if(iCurrentFillColumn == iPrtLeftMargin)   /*||((iCurrentFillColumn == iLeftMargin)&&(!iLeftMargin)))*///have nothing prt data
	{
		if(bNeedFeedLineSpace)
		{
			cTempStatus = PrtBuf[cCurrentPrtCharLine].Status;//打印buffer状态
			switch(cTempStatus)
			{
				case Empty:
				case Filling:
				//case Printing:

					WaitMotorStop();
					iStepNum = (iLineSpaceNumber+PRTLINEHIGHT)*one_dotline_lfstep_num;
					FeedPaper(iStepNum);//走一字符行
//				    MyPrintf("b33\n");
					break;
				case Printing://有问题 待解决
//					MyPrintf("b44\n");
					do
					{

						//MyPrintf("PrtBuf[cCurrentPrtCharLine].Status = %d \n", PrtBuf[cCurrentPrtCharLine].Status );
					}
					while(PrtBuf[cCurrentPrtCharLine].Status !=FeedLine);

					//MyPrintf("PrtBuf[cCurrentPrtCharLine].Status = %d \n", PrtBuf[cCurrentPrtCharLine].Status );

					CloseAllInt;
					cTempStatus = PrtBuf[cCurrentPrtCharLine].Status;
					if(cTempStatus == FeedLine)
					{
						// state have not changed
						if(MOTOR.iLFStepNum < LashStop_Nums + 1)//(const hlod stop)
						{
							OpenAllInt;
							WaitMotorStop();
							iStepNum = (iLineSpaceNumber+PRTLINEHIGHT)*one_dotline_lfstep_num;
							FeedPaper(iStepNum);
						}
						else
						{
							OpenAllInt;
							// in the period of acceleration of constant speed
							CountinueLineFeed((iLineSpaceNumber+PRTLINEHIGHT)*one_dotline_lfstep_num);
						}
					}
					else
					{
						// state have changed
						OpenAllInt;
						WaitMotorStop();
						iStepNum = (iLineSpaceNumber+PRTLINEHIGHT)*one_dotline_lfstep_num;
						FeedPaper(iStepNum);
					}

				    break;
				case FeedLine:
//					MyPrintf("b55\n");
					CloseAllInt;

					cTempStatus = PrtBuf[cCurrentPrtCharLine].Status;
					if(cTempStatus == FeedLine)
					{
						// state have not changed
						if(MOTOR.iLFStepNum < LashStop_Nums + 1)//(const hlod stop)
						{
							OpenAllInt;
							WaitMotorStop();
							iStepNum = (iLineSpaceNumber+PRTLINEHIGHT)*one_dotline_lfstep_num;
							FeedPaper(iStepNum);
						}
						else
						{
							OpenAllInt;
							// in the period of acceleration of constant speed
							CountinueLineFeed((iLineSpaceNumber+PRTLINEHIGHT)*one_dotline_lfstep_num);
						}
					}
					else
					{
						// state have changed
						OpenAllInt;
						WaitMotorStop();
						iStepNum = (iLineSpaceNumber+PRTLINEHIGHT)*one_dotline_lfstep_num;
						FeedPaper(iStepNum);
					}
					break;
				case WaitForPrint:
					break;
				default:
					break;
			}
		}
		else
		{
			//do nothing
		}
	}
	else
	{
		// have print data
		cNextLine = cCurrentFillRow + 1;
		
		//MyPrintf("cCurrentFillRow = %d \n", cCurrentFillRow ); //在[0,1]之变化的一个数据
		if(cNextLine == NumOfCharLine)
		{
			cNextLine = 0;
		}
		else
		{
			;
		}
		
		//MyPrintf("cNextLine = %d \n", cNextLine );     // 在[0,1]之变化的一个数据

		// fill the line attribute
		PrtBuf[cCurrentFillRow].cNextCharLine = cNextLine;
		if(bNeedFeedLineSpace)    //自测打印时循环执行,CPCL指令打印位图时循环执行
		{
//			MyPrintf("b66\n");
			PrtBuf[cCurrentFillRow].iFeedStep = iLineSpaceNumber*one_dotline_lfstep_num;//feed line
//			MyPrintf("have feed line  \n"); 		
		}
		else
		{
			PrtBuf[cCurrentFillRow].iFeedStep = 0;//feed line = 0
			MyPrintf("have no feed  line  \n"); 
		}
		
		if((cAsciiHightMultiple >= cChineseHightMultiple)&&bHaveFilledAscii)//计算打印走纸步数Prtfeed
		{
			PrtBuf[cCurrentFillRow].iPrtStep = cAsciiHightMultiple_Prt*PRTLINEHIGHT*one_dotline_lfstep_num;
			PrtBuf[cCurrentFillRow].iCurrentPrtDot = cAsciiHightMultiple_Prt*PRTLINEHIGHT;	
		}
		else if((cChineseHightMultiple >= cAsciiHightMultiple)&&bHaveFilledChinese)
		{
			PrtBuf[cCurrentFillRow].iPrtStep = cChineseHightMultiple*PRTLINEHIGHT*one_dotline_lfstep_num;
			PrtBuf[cCurrentFillRow].iCurrentPrtDot = cChineseHightMultiple*PRTLINEHIGHT;
		}
		else if(bHaveFilledImageDot)//打印图形 NV  GS *图
		{
            MyPrintf("打印图片\n"); 
			PrtBuf[cCurrentFillRow].iPrtStep = iImageDotHight*one_dotline_lfstep_num;
			PrtBuf[cCurrentFillRow].iCurrentPrtDot = iImageDotHight;
		}
		else if(bHaveFilledRasterDot)//打印光栅图
		{
		    MyPrintf("打印光栅图\n"); 
			PrtBuf[cCurrentFillRow].iPrtStep = iRasterDotHight*one_dotline_lfstep_num;
			PrtBuf[cCurrentFillRow].iCurrentPrtDot = iRasterDotHight;
			PrtBuf[cCurrentFillRow].bPrtRaster = 1;//中断中取数据不同寻常
		}
		else if(bHaveFilledBarCode)//打印条码
		{
            
			MyPrintf("打印条码\n"); 
			PrtBuf[cCurrentFillRow].iPrtStep = BarCode.cHight*one_dotline_lfstep_num;
			PrtBuf[cCurrentFillRow].iCurrentPrtDot = BarCode.cHight;
			PrtBuf[cCurrentFillRow].bPrtBarCode = 1;//中断中取数据不同寻常
		}
		else//打印ESC *  图
		{
		    	MyPrintf("打印ESC *  图\n"); 
			PrtBuf[cCurrentFillRow].iPrtStep = PRTLINEHIGHT*one_dotline_lfstep_num;
			PrtBuf[cCurrentFillRow].iCurrentPrtDot = PRTLINEHIGHT;
		}
		switch(bAlign)//对齐方式
		{

			
			case Align_Left:
				break;
			case Align_Middle:
				CharPrtMiddle(cCurrentFillRow,PrtBuf[cCurrentFillRow].iCurrentPrtDot,iCurrentFillColumn);
				break;
			case Align_Right:
				CharPrtRight(cCurrentFillRow,PrtBuf[cCurrentFillRow].iCurrentPrtDot,iCurrentFillColumn);
				break;
			default:
				break;
		}
		PrtBufferVToH(cCurrentFillRow);//打印缓冲字模由纵向变成横向
		// start up print
		CloseAllInt;
		if(PrtBuf[cCurrentPrtCharLine].Status == Empty)
		{
			OpenAllInt;
		
			cCurrentPrtCharLine	= cCurrentFillRow;

			
			MOTOR.iLFStepNum += (PrtBuf[cCurrentPrtCharLine].iPrtStep + PrtBuf[cCurrentPrtCharLine].iFeedStep + LashStop_Nums);

//			MyPrintf("!aa_ \n");
			StartLFMotor();
			bTimer2Prt = 1;
			
		}
		else
		{
			// printing is continued don't need restart
			PrtBuf[cCurrentFillRow].Status = WaitForPrint;
			cTempStep = cCurrentPrtCharLine;
			OpenAllInt;
			do
			{
				CloseAllInt;
				cTempStatus = PrtBuf[cTempStep].Status;
				BT_Progress();
				usb_main();
				OpenAllInt;
				
			}while(cTempStatus != Empty);
		}
		cCurrentFillRow = cNextLine;
		bHaveFilledAscii = 0;
		bHaveFilledChinese = 0;		
		bHaveFilledRasterDot = 0;
		bHaveFilledImageDot = 0;
		InitCharLine(cCurrentFillRow);//准备重新填充字模
		if(bHaveFilledBarCode)
		{
			BarCodeInit();
			bClearBarCode = 1;//下次清打印条码的buf
			bHaveFilledBarCode = 0;
		}
		else
		{
			;
		}
	}	
	
	cAsciiHightMultiple_Prt=cAsciiHightMultiple;
}
/*******************************************************************************
** Function name:     InitCharLine    
**
** Descriptions :     清空打印BUFFER状态,准备重新填充字模
**  
*******************************************************************************/
void InitCharLine(unsigned char Line)
{
	unsigned int  iLoop;
	unsigned char *p;
	unsigned char cLoopByteLine;
	unsigned char cPrtByteLine;
	if(bClearBarCode)//清空打印条码的buf
	{
		PrtBuf[Line].iPrtStep = (PRTLINEHIGHT*one_dotline_lfstep_num);
		bClearBarCode = 0;
	}
	if(PrtBuf[Line].iPrtStep%(8*one_dotline_lfstep_num))
	{
		cPrtByteLine = PrtBuf[Line].iPrtStep/(8*one_dotline_lfstep_num)+1;//用到的字节行
	}
	else
	{
		cPrtByteLine = PrtBuf[Line].iPrtStep/(8*one_dotline_lfstep_num);//用到的字节行
	}
	for(cLoopByteLine=0; cLoopByteLine<cPrtByteLine; cLoopByteLine++)//用到的字节行数据都清零
	{
		p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoopByteLine].BasePrtLine[0];
		for(iLoop=0; iLoop<MaxDotPos; iLoop++)
		{
		    *p++ = 0;
		}
	}
	PrtBuf[Line].Status = Empty;
	PrtBuf[Line].iFeedStep = 0;
	PrtBuf[Line].iPrtStep = 0;
	PrtBuf[Line].iCurrentPrtDot = 0;
	PrtBuf[Line].bPrtRaster = 0;
	PrtBuf[Line].bPrtBarCode= 0;
	iCurrentFillColumn = iPrtLeftMargin;
}
/*******************************************************************************
** Function name:      
**
** Descriptions :     开机初始化BUFFER状态
**  
*******************************************************************************/
void ClrCharPrtBuf(unsigned char Line)
{
	unsigned int iLoop;
	unsigned char *p;
	unsigned char cLoopByteLine;
	for(cLoopByteLine=0; cLoopByteLine<PRTBUFHIGHT; cLoopByteLine++)//所有字节行全部清零
	{
		p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoopByteLine].BasePrtLine[0];
		for(iLoop=0; iLoop<MaxDotPos; iLoop++)
		{
			*p++ = 0;
		}
	}
	PrtBuf[Line].Status = Empty;
	PrtBuf[Line].iFeedStep = 0;
	PrtBuf[Line].bPrtRaster = 0;
	PrtBuf[Line].bPrtBarCode= 0;
	PrtBuf[Line].bPrtRleBmp= 0;	
	PrtBuf[Line].iFeedStep = 0;
	PrtBuf[Line].iCurrentPrtDot = 0;
	iCurrentFillColumn = 0;
}
/*******************************************************************************
** Function name:     BarCodeInit   
**
** Descriptions :     条码设置初始化
**  
*******************************************************************************/
void BarCodeInit(void)
{
	BarCode.cFont = 0;
	BarCode.cFontPosition = 0;
	BarCode.cHight = 162;
	BarCode.cWidth = 3;
}

/*******************************************************************************
** Function name:     PrintStr    
**
** Descriptions :     打印ASCii字符串
**  
*******************************************************************************/
void PrintStr(unsigned char *pPrintData,unsigned char fPrint)
{
	unsigned int iAddrtemp;
	while(*pPrintData!=0x00)
	{
		if(*pPrintData > 0x80)               //自测打印不进来
		{
			// cData>0x80
			unsigned char cByteN1,cByteN2;
			cByteN1 = *pPrintData++;
			//MyPrintf("bChinese= %d ",bChinese);
			if(bChinese)
			{
				// chinese
				cByteN2 = *pPrintData++;;
				// cByteN2>=0x40 two bytes chinese
				iAddrtemp = CalculateChineseAddr(cByteN1, cByteN2, 0, 0); //yxm add
				GetChineseZimo(iAddrtemp);
				FillPrtBufChinese();
				//MyPrintf("11! ");
			}
			else
			{
				// not chinese		--- Ascii character
				iAddrtemp = CalculateAsciiAddr(*pPrintData++);
				GetAsciiZimo(iAddrtemp);
				FillPrtBufAscii();
//				MyPrintf("fill_1");
				//MyPrintf("22! ");
			}
		}
		else     //自测打印进来14次之后执行1次MyPrintf("44! "); 然后再执行14次这里再执行1次MyPrintf("44! ");
		{
	//		MyPrintf("33! ");
			// 0x20<=cData<=0x80
			iAddrtemp = CalculateAsciiAddr(*pPrintData++);
			GetAsciiZimo(iAddrtemp);
			FillPrtBufAscii();
//			MyPrintf("fill_2");
		}
	}
	if(fPrint)
	{
//		MyPrintf("44! ");
		StartupPrint(1);//打印
	}
	else
	{
		;
	}
}

extern void ESC_ATInit(void);
/*******************************************************************************
** Function name:     SelfTestPrint    
**
** Descriptions :     自检页打印数据
**  
*******************************************************************************/

static uint8_t dec_lookup[10] = { '0', '1', '2', '3', '4', '5', '6', '7','8','9'};
static void array2dec(uint8_t dec, uint8_t* out)
{
	
	if(dec >9 && dec<100){
		out[0] = dec_lookup[(u8)(dec/10)];
		out[1] = dec_lookup[(u8)(dec%10)];
	}
	else{
		out[0] = dec_lookup[dec];
	}

}
//----------------------------打印汉字
void printf_hz(u8 *pdata){

	u8 *push_data_index = pdata;
	
	do{
		FillRcvBuf(*push_data_index);

		MyPrintf("%02x ",*push_data_index);
		push_data_index++;

	}while(*push_data_index != 0);
}

extern uint8_t bt_name[14];
//----------------------------------------------------------打印自检_中文-------
void SelfTestPrint_Chiness(void)
{
 //   MyPrintf("start self print chinese \n");

//	unsigned char cByteN1,cByteN2;
	unsigned char cLoop;
	//unsigned char tt;
//	unsigned int iAddrtemp;
	unsigned char dec_buff[3] = {0};
	
	static const char strSelModel[] 	= {">>>Selftest<<<"};
	static const char strModel58[] 		= {"PT26   Printer"};
//	static const char strend[] 			= {">>>>>END<<<<<"};

	//static const char BARCODE[5][32] = 
	static const char BARCODE[5][33] = 
	{
		"1.UPC-A        2.UPC-E     ",
		"3.JAN13(EAN13) 4.JAN8(EAN8)",
		"5.CODE39       6.ITF       ",
		"7.CODE93       8.CODE128   ",
		"9.CODABAR",
	};

	ESC_ATInit();	           //可以不要
//  LCD_DispPrintTestPage(1);
    //自打印的时候速度都调整成                最大挡位。
	

    //os_type=0;
	SetMotorSpeedTime();      //可以不要

	/**************************************************************/
	bAlign = Align_Middle;//居中
	cAsciiHightMultiple = 1;//
	cAsciiWidthMultiple = 2;//两倍宽
	PrintStr((unsigned char*)strSelModel,1);       //可以不要
	
	cAsciiHightMultiple = 1;
	cAsciiWidthMultiple = 1;
//	StartupPrint(1);             //准备打印   //可以不要
	
	cAsciiHightMultiple = 1;//两倍高
	cAsciiWidthMultiple = 2;
	bAlign = Align_Middle;//居中

	PrintStr((unsigned char*)strModel58,1);    
//	StartupPrint(1);                           //可以不要
	cAsciiHightMultiple = 1;
	cAsciiWidthMultiple = 1;
	
	bAlign = Align_Left;//居左 正常模式
	
	printf_hz("版本信息:");
	printf_hz((u8 *)soft_ver);
	printf_hz("\n");

	printf_hz("蓝牙名称:");
	printf_hz(bt_name);
	printf_hz("\n");
	

//	printf_hz("生产日期:2021年4月25日\n");
	printf_hz("打印指令:ESC/POS\n");
	printf_hz("打印方法:从左至右打印\n");
	printf_hz("打印宽度:384点/行\n");

	printf_hz("打印速度:");	
	array2dec(PAPER.print_speed+1,dec_buff);
	printf_hz(dec_buff);
	printf_hz("\n");
	

	printf_hz("打印浓度:");	
	//array2dec(PAPER.print_density,dec_buff);
	array2dec(PAPER.print_density+1,dec_buff);
	printf_hz(dec_buff);
	printf_hz("\n");
	

	if(PAPER.type == E_PAPER_TYPE_CONTINUE)
	{
		printf_hz("纸张类型:连续纸\n");
	}
	else if(PAPER.type == E_PAPER_TYPE_GAP)
	{

		printf_hz("纸张类型:间隙纸\n");
	}
	else if(PAPER.type == E_PAPER_TYPE_HOLD)
	{
		printf_hz("纸张类型:定位孔纸\n");
	}
	
	if(EXT_DEV.power_off_mode ==0)
		printf_hz("关机模式:从不\n");
	else if (EXT_DEV.power_off_mode ==1)
		printf_hz("关机模式:5分钟\n");
	else if (EXT_DEV.power_off_mode ==2)
		printf_hz("关机模式:10分钟\n");
	else if (EXT_DEV.power_off_mode ==3)
		printf_hz("关机模式:20分钟\n");
	else if (EXT_DEV.power_off_mode ==4)
		printf_hz("关机模式:30分钟\n");

	if(LCD.language)
		printf_hz("语言:中文\n");

	printf_hz("通讯接口:USB&蓝牙\n");
	printf_hz("条码类型:\n");
	
	for(cLoop=0; cLoop< 5; cLoop++)//打印DIP功能
	{
		printf_hz((unsigned char*)BARCODE[cLoop]);
		printf_hz("\n");
	}

	printf_hz("\n\n\n\n\n\n\n\n");
	
	SelfTestPrinting_flag = 0;
 
    
}

//--------------------------------------------------
void SelfTestPrint(void)
{

//    MyPrintf("start self print english \n");
	
#if 1
    unsigned char mm=0;


//	unsigned char cByteN1,cByteN2;
	unsigned char cLoop;
	
	unsigned int iAddrtemp;
	unsigned char dec_buff[3] = {0};
	
	static const char strSelModel[] 	= {">>>Selftest<<<"};
	static const char strModel58[] 		= {"PT26   Printer"};
 	static const char strVersion[] 		= {"Version      : "};//s:Interface  t:Test
// 	static const char strData[] 		= {"Revised date : 2021-04-15"};	
	static const char strBlueName[] 	= {"BluetoothName: "};
	static const char strCommand[]		= {"Command      : EPSON(ESC/POS)"};
	static const char strCodePage[] 	= {"CodePage     : "};
	static const char strPrtMode[] 		= {"Print mode   : Normal&Hex"};
	static const char strPrtMethod[] 	= {"Print method : line thermal"};

	static const char strPrtWidth[] 	= {"Print width  : "};
	static const char strPrtSpeed[] 	= {"Print speed  : "};
	static const char strPrtdensity[] 	= {"Print density: "};
	

	
	static const char strInterface[] 	= {"InterfaceType: BT&USB"};
    static const char strBarCodeType[] 	= {"BarCodeType  : "};

	static const char BARCODE[5][33] = 
	{
		"1.UPC-A        2.UPC-E     ",
		"3.JAN13(EAN13) 4.JAN8(EAN8)",
		"5.CODE39       6.ITF       ",
		"7.CODE93       8.CODE128   ",
		"9.CODABAR",
		//"9.CODABARCODABARCODABARCODABARCO",
	};

	ESC_ATInit();
//	LCD_DispPrintTestPage(1);

    //自打印的时候速度都调整成最大挡位。

    //os_type=0;
	SetMotorSpeedTime();

	
	/**************************************************************/
	bAlign = Align_Middle;//居中
	cAsciiHightMultiple = 1;//
	cAsciiWidthMultiple = 2;//两倍宽
	PrintStr((unsigned char*)strSelModel,1);
	
	cAsciiHightMultiple = 1;   //走纸的
	cAsciiWidthMultiple = 1;
	StartupPrint(1);
	
	cAsciiHightMultiple = 1;//两倍高
	cAsciiWidthMultiple = 2;
	bAlign = Align_Middle;//居中

	PrintStr((unsigned char*)strModel58,1);
	StartupPrint(1);
	cAsciiHightMultiple = 1;
	cAsciiWidthMultiple = 1;
	
	bAlign = Align_Left;//居左 正常模式
	PrintStr((unsigned char*)strVersion,0);

	//PrintStr((uint8_t *)apk_ver,1);
	//PrintStr((uint8_t *)hard_ver,1);
	PrintStr((uint8_t *)soft_ver,1);
	bAlign = Align_Left;//居左 正常模式
	PrintStr((unsigned char*)strBlueName,0);
//	bAlign = Align_Right;//
	PrintStr((uint8_t *)bt_name,1);
	
	bAlign = Align_Left;//居左 正常模式
	
//	PrintStr((unsigned char*)strData,1);
	PrintStr((unsigned char*)strCommand,1);
	PrintStr((unsigned char*)strPrtMode,1);
	PrintStr((unsigned char*)strPrtMethod,1);
	PrintStr((unsigned char*)strPrtWidth,0);	
	PrintStr((unsigned char*)"384dots/line",1);


	
	memset(dec_buff, 0, sizeof(dec_buff));
	PrintStr((unsigned char*)strPrtSpeed,0);
	array2dec(PAPER.print_speed+1,dec_buff);
	PrintStr(dec_buff,1);
//	MyPrintf("PAPER.print_speed=0x%02x \n",PAPER.print_speed);
//	MyPrintf("PAPER.print_speed_time_multiple=0x%02x \n",PAPER.print_speed_time_multiple); 
	
	memset(dec_buff, 0, sizeof(dec_buff));
	PrintStr((unsigned char*)strPrtdensity,0);//打印当前浓度级别
	//array2dec(PAPER.print_density,dec_buff);
	array2dec(PAPER.print_density+1,dec_buff);
	PrintStr(dec_buff,1);
	
	if(PAPER.type == E_PAPER_TYPE_CONTINUE)
	{
		static const char strPrtPaperType[] = {"Paper Type:continuous"};
		PrintStr((unsigned char*)strPrtPaperType,1);
	}
	else if(PAPER.type == E_PAPER_TYPE_GAP)
	{
		static const char strPrtPaperType[] = {"Paper Type:Gap Paper"};
		PrintStr((unsigned char*)strPrtPaperType,1);
	}
	else if(PAPER.type == E_PAPER_TYPE_HOLD)
	{
		static const char strPrtPaperType[] = {"Paper Type:Locat Hole"};
		PrintStr((unsigned char*)strPrtPaperType,1);
	}
	//Shutdown mode
	if(EXT_DEV.power_off_mode ==0)
	{
		static const char strPrtShutdownType[] = {"Shutdown:Never"};
		PrintStr((unsigned char*)strPrtShutdownType,1);
	}
	else if (EXT_DEV.power_off_mode ==1)
	{
		static const char strPrtShutdownType[] = {"Shutdown:5 Min"};
		PrintStr((unsigned char*)strPrtShutdownType,1);
	}
	else if (EXT_DEV.power_off_mode ==2)
	{
		static const char strPrtShutdownType[] = {"Shutdown:10 Min"};
		PrintStr((unsigned char*)strPrtShutdownType,1);
	}		
	else if (EXT_DEV.power_off_mode ==3)
	{
		static const char strPrtShutdownType[] = {"Shutdown:20 Min"};
		PrintStr((unsigned char*)strPrtShutdownType,1);
	}
	else if (EXT_DEV.power_off_mode ==4)
	{
		static const char strPrtShutdownType[] = {"Shutdown:30 Min"};
		PrintStr((unsigned char*)strPrtShutdownType,1);
	}

	if(!(LCD.language))
	{
		static const char strPrtLanguage[] = {"Language:English"};
		PrintStr((unsigned char*)strPrtLanguage,1);
	}
	/**************************************************************/
	if(!bChinese)
	{
		PrintStr((unsigned char*)strCodePage,0);//打印当前代码页
		if(cCodePage/100)//计算
		{
			iAddrtemp = CalculateAsciiAddr(cCodePage/100+'0');//yxm add
			GetAsciiZimo(iAddrtemp);
//			MyPrintf("fill_3");
			FillPrtBufAscii();
			iAddrtemp = CalculateAsciiAddr((cCodePage%100)/10+'0');//yxm add
			GetAsciiZimo(iAddrtemp);
			FillPrtBufAscii();
			iAddrtemp = CalculateAsciiAddr(cCodePage%10+'0');//yxm add
			GetAsciiZimo(iAddrtemp);
			FillPrtBufAscii();
			StartupPrint(1);
		}
		else
		{
			if(cCodePage/10)
			{
				iAddrtemp = CalculateAsciiAddr(cCodePage/10+'0');//yxm add
				GetAsciiZimo(iAddrtemp);
//				MyPrintf("fill_4");
				FillPrtBufAscii();
				iAddrtemp = CalculateAsciiAddr(cCodePage%10+'0');//yxm add
				GetAsciiZimo(iAddrtemp);
				FillPrtBufAscii();
				StartupPrint(1);
			}
			else
			{
				iAddrtemp = CalculateAsciiAddr(cCodePage+'0');//yxm add
				GetAsciiZimo(iAddrtemp);
//				MyPrintf("fill_5");
				FillPrtBufAscii();
				StartupPrint(1);
			}
		}
	}
	/**************************************************************/
	PrintStr((unsigned char*)strInterface,1);//打印接口类型	
	PrintStr((unsigned char*)strBarCodeType,1);

	//PrintStr((unsigned char*)strCodeBar,1);//打印条码类别
	for(cLoop=0; cLoop< 5; cLoop++)//打印DIP功能
	{
		PrintStr((unsigned char*)BARCODE[cLoop], 1);
	}

	
    for(mm=0;mm<6;mm++)  
   	{
		StartupPrint(1);   //没有数据的时候就是仅仅走纸
	  }


	SelfTestPrinting_flag = 0;
	WaitMotorStop();

#endif




}
/*******************************************************************************
** Function name:     HexPrint    
**
** Descriptions :     进入16进制模式打印
**  
*******************************************************************************/
unsigned char HalfHex2Ascii(unsigned char cHalfHex)
{
	if(cHalfHex<10)
	{
		cHalfHex += 0x30;
	}
	else
	{
		cHalfHex = cHalfHex-10+'A';
	}
	return cHalfHex;
}

unsigned char Hex2Ascii(unsigned char *pHex)
{
	unsigned char cResult;
	cResult	= HalfHex2Ascii((*pHex & 0xf0)>>4);
	*pHex	= HalfHex2Ascii(*pHex & 0x0f);
	return cResult;
}

void HexPrint(void)            //PT26没用到
{
	unsigned char cByte;
	unsigned char cLoop;
	unsigned char cBufTemp[4] = {0x20,0x20,0x20,0x20};
	unsigned int  iZimoAddr;
	unsigned char cHexDumpCounter = 0;
	const unsigned char  strFirstLine[]	= {"The Printer is  under hex  mode now..."};
	const unsigned char  strEndLine[]		= {"        ***completed***"};

//	MyPrintf("!222");
	WaitMotorStop();
	InitRcvBuf();
	ESC_ATInit();
	StartupPrint(1);
	PrintStr((unsigned char *)strFirstLine,1);
	StartupPrint(1);
	while(cHexDumpCounter < 2)
	{
		if(cHexDumpCounter > 2)
		{
			break;
		}
		else
		{
			;
		}
		if(f_rcv_data)//接收BUFFER 有数据
		{
			// have data
			cByte = GetDataFromRcvBuf();
			cBufTemp[1] =Hex2Ascii(&cByte); //高低4位都得到对应的ASCII码字符
			cBufTemp[2] =cByte;
			for(cLoop = 0;cLoop<4;cLoop++)//每个数据转换成4个字节 两个是空格
			{
				iZimoAddr = CalculateAsciiAddr(cBufTemp[cLoop]);
				GetAsciiZimo(iZimoAddr);
				FillPrtBufAscii();
//				MyPrintf("fill_6");
			}
		}
		else
		{
			// no data scan key
		}
	}
	StartupPrint(1);
	PrintStr((unsigned char *)strEndLine,1);
	StartupPrint(1);
	ESC_ATInit();
}
/*******************************************************************************
** Function name:     CharPrtMiddle    
**
** Descriptions :     居中打印处理函数
**  
*******************************************************************************/
void CharPrtMiddle(unsigned char Line,unsigned char cHight,unsigned int iRightPos)
{
	unsigned int iLoop;
	unsigned char *p;
	unsigned char cLoopByteLine;
	unsigned char TempBuf[MaxDotPos];
	if(bHaveFilledRasterDot)//||bHaveFilledImageDot)//光栅和位图暂时不做居中处理
	{
		return;
	}
	if(bHaveFilledBarCode)//解决条码居中变化计算超出buf
	{
		cHight = PRTLINEHIGHT;
	}
	for(cLoopByteLine=0; cLoopByteLine<((cHight-1)/8+1); cLoopByteLine++)//所有字节行
	{
		p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoopByteLine].BasePrtLine[iPrtLeftMargin];
		for(iLoop=iPrtLeftMargin; iLoop<iPrtRightMargin; iLoop++)
		{
			TempBuf[iLoop] = *p;
		
			*p++ = 0;//字节行清零
			
		}
		p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoopByteLine].BasePrtLine[(iPrtRightMargin-iRightPos)/2+iPrtLeftMargin];
		for(iLoop=iPrtLeftMargin; iLoop<iRightPos; iLoop++)//重新排列成新的字节行居中
		{
			*p++ = TempBuf[iLoop];
		}
	}
}
/*******************************************************************************
** Function name:     CharPrtRight    
**
** Descriptions :     居右打印处理函数
**  
*******************************************************************************/
void CharPrtRight(unsigned char Line,unsigned char cHight,unsigned int iRightPos)
{
	unsigned int iLoop;
	unsigned char *p;
	unsigned char cLoopByteLine;
	unsigned char TempBuf[MaxDotPos];
	if(bHaveFilledRasterDot)
	{
		return;
	}
	if(bHaveFilledBarCode)//解决条码居中变化计算超出buf
	{
		cHight = PRTLINEHIGHT;
	}
	for(cLoopByteLine=0; cLoopByteLine<((cHight-1)/8+1); cLoopByteLine++)//所有字节行
	{
		p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoopByteLine].BasePrtLine[iPrtLeftMargin];
		for(iLoop=iPrtLeftMargin; iLoop<iPrtRightMargin; iLoop++)
		{
			TempBuf[iLoop]= *p;
			*p++ = 0;
		}
		p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoopByteLine].BasePrtLine[(iPrtRightMargin-iRightPos)];
		for(iLoop=iPrtLeftMargin; iLoop<iRightPos; iLoop++)//重新排列成新的字节行居右
		{
			*p++= TempBuf[iLoop];
		}
	}
}
/*******************************************************************************
** Function name:     AddUnderLine    
**
** Descriptions :     下划线处理
**  
*******************************************************************************/
void AddUnderLine(unsigned char Line,unsigned int width,unsigned char underline)
{
	unsigned int iLoop;
	unsigned char *p;
	if(bUnderLineEffect)//下划线有效
	{
		p = (unsigned char *)&PrtBuf[Line].ByteLine[0].BasePrtLine[iCurrentFillColumn];
		if(underline == 1)//下划线一点行
		{
			for(iLoop = width;iLoop > 0;iLoop--)
			{
				*(p -iLoop) |= 0x01;
			}
		}
		else if(underline == 2)//下划线两点行
		{
			for(iLoop = width;iLoop > 0;iLoop--)
			{
				*(p-iLoop) |= 0x03;
			}
		}
		else
		{
			;
		}
	}
}
/*******************************************************************************
** Function name:     AddBlod
**
** Descriptions :     粗体模式处理
**  
*******************************************************************************/
void AddBlod(unsigned char Line,unsigned int width,unsigned char hight)
{
	unsigned int iLoop;
	unsigned char cLoop;
	unsigned char cTemp;
	unsigned char *p;
	if(bBold)//粗体模式
	{
		for(cLoop = 0;cLoop < hight*3;cLoop ++)//hight*3个字节行
		{
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[iCurrentFillColumn-width];
			for(iLoop = 0;iLoop < width;iLoop++)//纵向粗体设置
			{
				//cTemp = (PrtBuf[Line].ByteLine[cLoop].BasePrtLine[iCurrentFillColumn-width+iLoop]>>1);
				//PrtBuf[Line].ByteLine[cLoop].BasePrtLine[iCurrentFillColumn-width+iLoop] |= cTemp;
				cTemp = *(p+iLoop)>>1;
				*(p+iLoop)|=cTemp;
			}
			for(iLoop = 1;iLoop < width;iLoop=iLoop+2)//横向粗体设置 处理width-1个字节
			{
				//cTemp = PrtBuf[Line].ByteLine[cLoop].BasePrtLine[iCurrentFillColumn-width+iLoop-1];//前一个字节
				//PrtBuf[Line].ByteLine[cLoop].BasePrtLine[iCurrentFillColumn-width+iLoop] |= cTemp;//后一个字节与前一个字节或
				cTemp = *(p+iLoop-1);
				*(p+iLoop)|=cTemp;
			}
		}
	}
	else
	{
		;
	}
}
/*******************************************************************************
** Function name:     
**
** Descriptions :     打印缓冲区字模排放方式变换由纵向变成横向排列
**  
*******************************************************************************/
void PrtBufferVToH(unsigned char Line)
{
	unsigned char TempBuf[MaxDotPos];
	unsigned char cPrtByteLine;
	unsigned char cLoop;
	unsigned char *p;
	unsigned int  iLoop;
	if(!bHaveFilledRasterDot)//光栅图形不用变换
	{
		cPrtByteLine = PrtBuf[Line].iPrtStep/(8*one_dotline_lfstep_num);//用到的字节
		if(bHaveFilledBarCode)
		{
			cPrtByteLine = 1;
		}
		for(cLoop = 0;cLoop<cPrtByteLine;cLoop++)
		{
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(iLoop = 0;iLoop<MaxDotPos/8;iLoop++)//生成第1一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x80)>>0;p++;
				TempBuf[iLoop] |= (*p&0x80)>>1;p++;
				TempBuf[iLoop] |= (*p&0x80)>>2;p++;
				TempBuf[iLoop] |= (*p&0x80)>>3;p++;
				TempBuf[iLoop] |= (*p&0x80)>>4;p++;
				TempBuf[iLoop] |= (*p&0x80)>>5;p++;
				TempBuf[iLoop] |= (*p&0x80)>>6;p++;
				TempBuf[iLoop] |= (*p&0x80)>>7;p++;
			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(;iLoop<MaxDotPos/4;iLoop++)//生成第2一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x40)<<1;p++;
				TempBuf[iLoop] |= (*p&0x40)>>0;p++;
				TempBuf[iLoop] |= (*p&0x40)>>1;p++;
				TempBuf[iLoop] |= (*p&0x40)>>2;p++;
				TempBuf[iLoop] |= (*p&0x40)>>3;p++;
				TempBuf[iLoop] |= (*p&0x40)>>4;p++;
				TempBuf[iLoop] |= (*p&0x40)>>5;p++;
				TempBuf[iLoop] |= (*p&0x40)>>6;p++;
			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(;iLoop<MaxDotPos*3/8;iLoop++)//生成第3一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x20)<<2;p++;
				TempBuf[iLoop] |= (*p&0x20)<<1;p++;
				TempBuf[iLoop] |= (*p&0x20)>>0;p++;
				TempBuf[iLoop] |= (*p&0x20)>>1;p++;
				TempBuf[iLoop] |= (*p&0x20)>>2;p++;
				TempBuf[iLoop] |= (*p&0x20)>>3;p++;
				TempBuf[iLoop] |= (*p&0x20)>>4;p++;
				TempBuf[iLoop] |= (*p&0x20)>>5;p++;
			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(;iLoop<MaxDotPos/2;iLoop++)//生成第4一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x10)<<3;p++;
				TempBuf[iLoop] |= (*p&0x10)<<2;p++;
				TempBuf[iLoop] |= (*p&0x10)<<1;p++;
				TempBuf[iLoop] |= (*p&0x10)>>0;p++;
				TempBuf[iLoop] |= (*p&0x10)>>1;p++;
				TempBuf[iLoop] |= (*p&0x10)>>2;p++;
				TempBuf[iLoop] |= (*p&0x10)>>3;p++;
				TempBuf[iLoop] |= (*p&0x10)>>4;p++;
			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(;iLoop<MaxDotPos*5/8;iLoop++)//生成第5一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x08)<<4;p++;
				TempBuf[iLoop] |= (*p&0x08)<<3;p++;
				TempBuf[iLoop] |= (*p&0x08)<<2;p++;
				TempBuf[iLoop] |= (*p&0x08)<<1;p++;
				TempBuf[iLoop] |= (*p&0x08)>>0;p++;
				TempBuf[iLoop] |= (*p&0x08)>>1;p++;
				TempBuf[iLoop] |= (*p&0x08)>>2;p++;
				TempBuf[iLoop] |= (*p&0x08)>>3;p++;
			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(;iLoop<MaxDotPos*3/4;iLoop++)//生成第6一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x04)<<5;p++;
				TempBuf[iLoop] |= (*p&0x04)<<4;p++;
				TempBuf[iLoop] |= (*p&0x04)<<3;p++;
				TempBuf[iLoop] |= (*p&0x04)<<2;p++;
				TempBuf[iLoop] |= (*p&0x04)<<1;p++;
				TempBuf[iLoop] |= (*p&0x04)>>0;p++;
				TempBuf[iLoop] |= (*p&0x04)>>1;p++;
				TempBuf[iLoop] |= (*p&0x04)>>2;p++;
			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(;iLoop<MaxDotPos*7/8;iLoop++)//生成第7一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x02)<<6;p++;
				TempBuf[iLoop] |= (*p&0x02)<<5;p++;
				TempBuf[iLoop] |= (*p&0x02)<<4;p++;
				TempBuf[iLoop] |= (*p&0x02)<<3;p++;
				TempBuf[iLoop] |= (*p&0x02)<<2;p++;
				TempBuf[iLoop] |= (*p&0x02)<<1;p++;
				TempBuf[iLoop] |= (*p&0x02)>>0;p++;
				TempBuf[iLoop] |= (*p&0x02)>>1;p++;
			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(;iLoop<MaxDotPos;iLoop++)//生成第8一点行的字节
			{
				TempBuf[iLoop]  = (*p&0x01)<<7;p++;
				TempBuf[iLoop] |= (*p&0x01)<<6;p++;
				TempBuf[iLoop] |= (*p&0x01)<<5;p++;
				TempBuf[iLoop] |= (*p&0x01)<<4;p++;
				TempBuf[iLoop] |= (*p&0x01)<<3;p++;
				TempBuf[iLoop] |= (*p&0x01)<<2;p++;
				TempBuf[iLoop] |= (*p&0x01)<<1;p++;
				TempBuf[iLoop] |= (*p&0x01)>>0;p++;

			}
			p = (unsigned char *)&PrtBuf[Line].ByteLine[cLoop].BasePrtLine[0];
			for(iLoop = 0;iLoop<MaxDotPos;iLoop++)//生成的数据重新放大打印BUFFER中
			{
				*p = TempBuf[iLoop];
				p++;
			}
		}
		//bERLED_OFF;
	}
}

/*******************************************************************************
** Function name:     SendStr    
**
** Descriptions :     蓝牙串口发送字符串
**  
*******************************************************************************/
void SendStr(unsigned char *pStr)
{
//	while(*pStr != 0x00)
//	{
//		SerialSendByte(*pStr++);
//	}
}

/*******************************************************************************
** Function name:     ExecuteData    
**
** Descriptions :     打印数据处理函数
**  
*******************************************************************************/
void ExecuteData(unsigned char data)         //CPCL指令打印位图时进来
{	
	unsigned int Laddrtemp;

#if 1
//	MyPrintf("Date1111=0x%02x\n",data);
	if(data > 0x80)      //CPCL指令打印位图不进来  IOS打印一维码不进来
	{

		// cData>0x80
//		MyPrintf("12345");
		unsigned char cByteN1,cByteN2;
		cByteN1 = data;
		if(bChinese)
		{
			//MyPrintf("chinese area \n"); 
			// chinese
			cByteN2 = GetDataFromRcvBuf();
			Laddrtemp = CalculateChineseAddr(cByteN1, cByteN2, 0, 0); //yxm add
			GetChineseZimo(Laddrtemp);
			FillPrtBufChinese();
		}
		else
		{
			//MyPrintf(" not chinese area \n"); 

		
			// not chinese		--- Ascii character
			Laddrtemp = CalculateAsciiAddr(data);
			GetAsciiZimo(Laddrtemp);              //获取字模
			
			FillPrtBufAscii();
//			MyPrintf("fill_7");
		}

	}
	else                // //CPCL指令打印位图时循环执行这部分
	{
		//MyPrintf(" third area \n"); 
		// 0x20<=cData<=0x80
		Laddrtemp = CalculateAsciiAddr(data);     //获取指定字符地址
		GetAsciiZimo(Laddrtemp);

//		MyPrintf("fill_8");
		FillPrtBufAscii();
	}
#else

	bPart1 = 0;
	bPart3 = 0;


	Laddrtemp = CalculatePty860Addr(data);
	GetChineseZimo(Laddrtemp);
	FillPrtBufChinese();

#endif
}
/**********************************END*****************************************/


























 //                       PrtBuf.h


// PrtBuf.h
#ifndef _PRTBUF_H_
#define _PRTBUF_H_

#include "PrtConfig.h"
#include "type.h"
#if(PRT_WIDTH_80mm == 1)
	#define	MaxDotPos            576
#else
	#define	MaxDotPos            384
#endif

#define NumOfCharLine          2  //
#define PRTBUFHIGHT           12 
#define PRTLINEHIGHT          24
#define ONEDOTSTEPNUM          4  //一点行步进数
#define ONEDOTSTEPNUM1         3

#define HZ_WIDTH              24 //汉字横向占得点数
#define ASCII_WIDTH			  12 //ascii横向占得点数
#define SFONT_WIDTH            9 //small FONT横向占得点数
#define BIT_IMAGE_SIZE         5


extern volatile unsigned char one_dotline_lfstep_num; 
extern volatile unsigned char one_dotline_lfstep_num_change_flage; 

extern unsigned char cAsciiHightMultiple_Prt;
extern unsigned char cAsciiRightSpace;
extern unsigned char cChineseLeftSpace;
extern unsigned char cChineseRightSpace;
extern unsigned char cAsciiWidthMultiple;
extern unsigned char cAsciiHightMultiple;
extern unsigned char cChineseWidthMultiple;
extern unsigned char cChineseHightMultiple;
extern unsigned int  iCurrentFillColumn;
extern unsigned int  iLineSpaceNumber;
extern unsigned char bFont12x24;
extern volatile unsigned char cCurrentPrtCharLine;
extern volatile unsigned char cCurrentFillRow;
extern volatile unsigned char bTimer2Prt ;
extern unsigned char bTimer2FeedLine;
extern unsigned char bTimer2KeyFeed;
extern unsigned char bChinese;
extern unsigned char bHexDump;
extern unsigned char bSelfTest;
extern unsigned char bCharacterSel;
extern unsigned char bDensitySel;
extern unsigned char bHaveFilledAscii;
extern unsigned char bHaveFilledChinese;
extern unsigned char bHaveFilledBarCode;
extern unsigned char bHaveFilledRasterDot;
extern unsigned char bHaveFilledImageDot;
extern unsigned char bPrtAdverse;
extern unsigned char bAsciiUnderLine;
extern unsigned char bChineseUnderLine;
extern unsigned char bAlign;
extern unsigned char bBold;
extern unsigned int  iPrtLeftMargin;
extern unsigned int  iPrtRightMargin;
extern unsigned int  iRasterDotHight;
extern unsigned int  iImageDotHight;
extern unsigned char bUserChar;
extern unsigned char cCodePage;
extern unsigned char bPart1;//转换表1
extern unsigned char bPart2;//转换表2
extern unsigned char bPart3;//转换表3
extern unsigned char bPart4;//转换表4
extern unsigned char bFontBig5;
extern unsigned char bClearBarCode;
extern unsigned char bPrt_Statu_flag;    //打印状态标志 
extern unsigned char HT_TAB[16];
extern unsigned char SelfTestPrinting_flag;    //打印自检标志_

enum enumCharLineStatus{
	Empty,Filling,Printing,FeedLine,WaitForPrint
};
enum ALIGN  
{
    Align_Left,Align_Middle,Align_Right,
};
enum enumInterCharSet{
	USA,France,Germany,UK,DenmarkI,Sweden,Italy,SpainI,Japan,Norway,DenmarkII,
	//0,	    1,	         2,		3,	   4,		5,		6,		7,	  8,		9,	     10
	SpainII,Latin,Korea,Croatia,China
	//11,     12 ,      13,      14,         15
};
extern enum enumInterCharSet cInternationalCharSet;

struct structByteLine{
	unsigned char BasePrtLine[MaxDotPos];
	//unsigned char cHaveData;
};
struct structCharLine{
	struct structByteLine ByteLine[PRTBUFHIGHT];
	unsigned char cNextCharLine;
	unsigned char bPrtRaster;
	unsigned char bPrtBarCode;
	unsigned char bPrtRleBmp;            //打印压缩位图
	unsigned int  iFeedStep;
	unsigned int  iPrtStep;          //打印一点行的步进数
	unsigned int  iCurrentPrtDot;
	enum enumCharLineStatus Status;
};

extern volatile struct structCharLine  PrtBuf[NumOfCharLine];

struct StructBarCode{
	unsigned char cHight;
	unsigned char cWidth;
	unsigned char cFont;
	unsigned char cFontPosition;
};
extern struct StructBarCode BarCode;

typedef struct  
{
	uint8_t save_flag;
	uint8_t SerialBauRate;
	uint8_t CharacterMode;
	uint8_t DensitySelect;
	uint8_t SpeedSelect;
	uint8_t CodePage;

	uint8_t language;
	uint8_t paper_type;
	uint8_t power_off_mode;
	
	uint16_t paper_size;
	uint16_t gap_size;
	uint16_t bm_size;
	uint16_t hold_size;

	
}EEPROM_STRUCT;  
extern EEPROM_STRUCT EEPROM;

extern unsigned int CalculateChineseAddr(unsigned char cByte1,unsigned char cByte2,unsigned char cByte3,unsigned char cByte4);//yxm add
extern unsigned int CalculateAsciiAddr(unsigned char cByte);
extern unsigned int CalculatePty860Addr(unsigned char cByte1);
extern unsigned char AsciiCharacterRotate(unsigned char *pAsciiPattern,unsigned char AsciiWidth);
extern unsigned char JudgeExceedByteLine(unsigned int iDotWillAdd);

extern void GetChineseZimo(unsigned int Addr);
extern void GetAsciiZimo(unsigned int Addr);
extern void FillPrtBufChinese(void);
extern void FillPrtBufAscii(void);
extern void StartupPrint(unsigned char cNeedFeedLineSpace);
extern void ExecuteData(unsigned char data);
extern void ClrCharPrtBuf(unsigned char Line);
extern void BarCodeInit(void);
extern void SelfTestPrint(void);
extern void HexPrint(void);

extern void PrintStr(unsigned char *pPrintData,unsigned char fPrint);
extern void SendStr(unsigned char *pStr);
extern void InitCharLine(unsigned char Line);
extern void AsciiHightMultiple(unsigned char *pAsciiPattern,unsigned char *pAsciiHightiPattern,unsigned char AsciiWidth);
extern void ChineseHightMultiple(unsigned char *pChinesePattern,unsigned char *pChineseHightiPattern,unsigned char ChineseWidth);
extern void CharPrtMiddle(unsigned char Line,unsigned char cHight,unsigned int iRightPos);
extern void CharPrtRight(unsigned char Line,unsigned char cHight,unsigned int iRightPos);
extern void AddUnderLine(unsigned char Line,unsigned int width,unsigned char underline);
extern void AddBlod(unsigned char Line,unsigned int width,unsigned char hight);
extern void ChineseCharacterRotate(unsigned char *pAsciiPattern,unsigned char ChineseWidth);
extern void PrtInvertOneLine(unsigned char Line);
extern void PrtBufferVToH(unsigned char Line);
void SelfTestPrint_Chiness(void);


extern u8 os_type;



#endif
/**********************************END*****************************************/





























//                          PrtConfig.h


//PrtConfig.h
#ifndef PRTCONFIG_H
#define PRTCONFIG_H

#define PrintMachineType  POS58ThermalPrint

#define POS58ThermalPrint   1
#define POS80ThermalPrint   2

#if(PrintMachineType == POS58ThermalPrint)
	#define PRT_WIDTH_80mm  0
	#define GB2312          1//需用1M  FLASH
#endif

#endif



















//                              PrtHead.c



/*******************************************************************************
* File Name    : PrtHead.c
* Date         : Dec 18 2010
* Description  : PrtHead  Operation
* Designer     : XXXXXXXXXXXXXXXX
*******************************************************************************/
#include "board_config.h"
#include "yc_timer.h"
#include "yc_bt.h"
#include "PrtBuf.h"
#include "Interface.h"
#include "CmdSet.h"
#include "RcvBuf.h"

#include "yc3121.h"
#include "PrtHead.h"
#include "yc_wdt.h"
#include "Sensor.h"
#include "LcdMenu.h"

#include "BarCode_app.h"
#include "App.h"

volatile STRUCT_MOTOR MOTOR;
volatile STRUCT_TPH TPH;
volatile STRUCT_PAPER PAPER;
volatile STRUCT_EXT_DEV EXT_DEV;

typedef struct
{
    UINT16  TargetTime;
    UINT16  TimeIndex;
    UINT16  HeatTime;
    UINT16  HeatIdx;
}ST_TPH_STATUS;
ST_TPH_STATUS TPHStatus = {0};
INT32 SuppliesDecLength = 0;
SemaphoreHandle_t SuppliesDecMutexHandle = NULL;
static BOOL feedFlag = 0;
BOOL SuppliesDecLength_Lock(void)
{
    if(SuppliesDecMutexHandle == NULL)
    {
        SuppliesDecMutexHandle = xSemaphoreCreateMutex();
    }
    if(xSemaphoreTake(SuppliesDecMutexHandle, 10000) != pdTRUE)
    {
        return 0;
    }
    return 1;
}
void SuppliesDecLength_Unlock(void)
{
    if(SuppliesDecMutexHandle == NULL)
    {
        SuppliesDecMutexHandle = xSemaphoreCreateMutex();
    }
    xSemaphoreGive(SuppliesDecMutexHandle);
}

//const unsigned int  LFMotorTime[34]={
	sRush,   LFacc1,  LFacc2,  LFacc3,
//	5000,   4500,   4000,   3500, 
  LFacc4,  LFacc5,  LFacc6,   LFacc7,
//	3000,   2500,   2100,   2000,
  LFacc8,  LFacc9,  LFacc10, LFacc11, 
//	1900,   1850,   1800,   1750,
  LFacc12,LFacc13,LFacc14, LFacc15,
//	1700,	1650,	1600,	1550, 
  LFacc16,LFacc17,LFacc18, LFacc19,
//	1500,	1450,	1400,	1350,
  LFacc20,LFacc21,LFacc22, LFacc23,
//	1300,	1250,	1200,	1150,
  LFacc24,LFacc25,LFacc26, LFacc27,
//	1100,	1100,	1100,	1100, //950,
  LFacc28,LFacc29,LFacc30, LFconst,
//    1100,   1100,   1100,   1100,
//
  LFeLash,LFeStop
//	10000 ,   5000	
//};


const unsigned int  LFMotorTime[34]={
//	sRush,   LFacc1,  LFacc2,  LFacc3,
	5000,   4500,   4000,   3500, 
//  LFacc4,  LFacc5,  LFacc6,   LFacc7,
	3000,   2500,   2100,   2000,
//  LFacc8,  LFacc9,  LFacc10, LFacc11, 
	1900,   1850,   1800,   1750,
//  LFacc12,LFacc13,LFacc14, LFacc15,
	1700,	1650,	1600,	1550, 
//  LFacc16,LFacc17,LFacc18, LFacc19,
	1500,	1450,	1400,	1350,
//  LFacc20,LFacc21,LFacc22, LFacc23,
	1300,	1250,	1200,	1150,
//  LFacc24,LFacc25,LFacc26, LFacc27,
	1100,	1050,	1000,	1000, //950,
//  LFacc28,LFacc29,LFacc30, LFconst,
    950,    950,    900,    900,
//  LFeLash,LFeStop
//	10000 ,   5000	
 	10000,   5000	
};


//const unsigned int  LFMotorTime[34]={
	sRush,   LFacc1,  LFacc2,  LFacc3,
//	      5000,   4500,   4000,   3500, 
  LFacc4,  LFacc5,  LFacc6,   LFacc7,
//	    3000,   2500,   2100,   2000,
  LFacc8,  LFacc9,  LFacc10, LFacc11, 
//	1900,   1850,   1800,   1750,
  LFacc12,LFacc13,LFacc14, LFacc15,
//	1700,	1650,	1600,	1550, 
  LFacc16,LFacc17,LFacc18, LFacc19,
//	1500,	1450,	1400,	1350,
  LFacc20,LFacc21,LFacc22, LFacc23,
//	1300,	1250,	1200,	1150,
  LFacc24,LFacc25,LFacc26, LFacc27,
//	1100,	1050,	1000,	950, //950,
  LFacc28,LFacc29,LFacc30, LFconst,
//    900,   850,   800,   750,
//
  LFeLash,LFeStop
//	10000 ,   5000	
//};



const unsigned int  Thermistor[20]={
    269,208,178,124,100,78,60,47,37,30,24,19,
	16 ,13 ,11,9,7,6,5,4
};
//打印头温度调节
const unsigned int Thermistor_ADC[20]={
	2014, //-20
	1854, //-15
	1764, //-10
	1580, //-5
	1487, //0
	1395, //5
	1314, //10
	1252, //15
	1205, //20
	1166, //25
	1136, //30
	1111, //35
	1091, //40
	1075, //45
	1062, //50
	1055, //55
	1048, //60
	1040, //65
	1035, //70
	1030, //75
};



const signed int  HeadTemp[20]={
    -20,-15,-10,-5,0,5,10,15,20,25,30,35,
	40 ,45 ,50,55,60,65,70,75
};

const unsigned int Thermistor_Heat_Time[20]={
	1000, //-20
	990, //-15
	980, //-10
	970, //-5
	960, //0
	950, //5
	940, //10
	930, //15
	920, //20
	900, //25
	870, //30
	830, //35
	780, //40
	740, //45
	680, //50
	630, //55
	580, //60
	530, //65
	480, //70
	430, //75

};


/*	
const float Thermistor_persent[15]=
{
	0.86	,//0
	0.9 	,//1
	0.94	,//2
	0.98	,//3
	1.02	,//4
	1.06	,//5
	1.1 	,//6
	1.14	,//7
	1.18	,//8
	1.22	,//9
	1.26	,//10
	1.3 	,//11
	1.34	,//12
	1.38	,//13
	1.42	,//14


};
	//*/
///*	
const float Thermistor_persent[15]=
{
	0.55,
	0.65,
	0.75,//0
	0.85	,//1
	0.95	,//2
	1.05	,//3
	1.15	,//4
	1.2875 	,//11
	1.325	,//12
	1.3625	,//13
	1.4	,//8
	1.4375	,//9
	1.475	,        //10
	1.5125	,//11
	1.55	,//12


};
	//*/

/*
const float Thermistor_persent[15]=
{
		0.98, 
		1,
		1.02,
		1.04,
		1.06,
		1.08,
		1.1,
		1.12,
		1.14,
		1.16,
		1.18,
		1.2,
		1.22,
		1.24,
		1.26,


};

*/
		

/********************************************************************************/


/*******************************************************************************
** Function name:    WaitMotorStop    
**
** Descriptions :    等待马达停止工作
**  
******************************************************************************/
void WaitMotorStop(void)
{
	while(PrtBuf[cCurrentPrtCharLine].Status != Empty)
	{

		PollingExtDev(1);    //检测USB插拔及是否有纸
		KEY_Main();
#ifdef USE_BLE
		BT_Progress();
		usb_main();

#endif
//	      print_check_1();
	}
	while(MOTOR.bLFMotorMove)
	{

	  PollingExtDev(1);
		KEY_Main();
#ifdef USE_BLE
		BT_Progress();
		usb_main();

#endif
		
	}
}

void print_check_1(void)
{


	//MyPrintf(" WaitMotorStop_1 \r\n"); 
	//MyPrintf("PrtBuf[cCurrentPrtCharLine].Status=%d\r\n",PrtBuf[cCurrentPrtCharLine].Status);
}

void print_check(void)
{
	if(EXT_DEV.print_scan_time)	return;

	EXT_DEV.print_scan_time = 50;
       //MyPrintf("bRcvBufFull= %d \n",bRcvBufFull);
	//MyPrintf(" WaitMotorStop_2 \r\n"); 
	//MyPrintf("PrtBuf[cCurrentPrtCharLine].Status=%d\r\n",PrtBuf[cCurrentPrtCharLine].Status);
}
/*******************************************************************************
** Function name:     StartLFMotor    
**
** Descriptions :     启动马达开启中断
**  
******************************************************************************/
void StartLFMotor(void)
{
	
	LFTimer_Enable;
	PrtBuf[cCurrentPrtCharLine].Status = Printing;
	if(MOTOR.bLFMotorMove == 0)
	{
		
	       //MyPrintf("StartLFMotor \n");
		set_lf_speed(LFsRush);

	}
	
	MOTOR.bLFMotorMove = 1;
}
/*******************************************************************************
** Function name:   
**
** Descriptions :    进纸一定步数
**  
******************************************************************************/
void FeedPaper(unsigned int iStepNum)  //步进的数目
{
	WaitMotorStop();
	MOTOR.iLFStepNum	= iStepNum + LashStop_Nums; // 2014.2 yxm add
	//MyPrintf("iStepNum=%04x\n",iStepNum);

	LFTimer_Enable;
	PrtBuf[cCurrentPrtCharLine].Status = FeedLine;
//	MyPrintf("  FeedPaper \n");
	set_lf_speed(LFsRush);

	// phase
	bTimer2FeedLine = 1;
	MOTOR.bLFMotorMove = 1;
}





/*******************************************************************************
** Function name:   
**
** Descriptions :     马达前进相位加1
**  
******************************************************************************/
void LFMotorPhaseAddOne(void)
{
static INT16 decLenState = 0;
	// forward +1
	if(MOTOR.bLFForward==0)
	{
//		MyPrintf("a_1\n");
		if(MOTOR.cLFMotorPhase == cLFMotorPhase_Max)
		{
			MOTOR.cLFMotorPhase = 1;
		}
		else
		{
			MOTOR.cLFMotorPhase += 1;
		}
		decLenState--;
	}
	else
	{
	//	MyPrintf("a_2\n");
		// backward -1
		if(MOTOR.cLFMotorPhase == 1)
		{
			MOTOR.cLFMotorPhase = cLFMotorPhase_Max;
		}
		else
		{
			MOTOR.cLFMotorPhase -= 1;
		}
		decLenState++;
		if(decLenState >= 4)
		{
			decLenState -= 4;
			SuppliesDecLength++;
		}
	}
}
/*******************************************************************************
** Function name:     
**
** Descriptions :     马达前进相位减1
**  
******************************************************************************/
void LFMotorPhaseSubOne(void)
{
	// forward -1
	if(MOTOR.bLFForward)
	{
		if(MOTOR.cLFMotorPhase == 1)
		{
			MOTOR.cLFMotorPhase = cLFMotorPhase_Max;
		}
		else
		{
			MOTOR.cLFMotorPhase -= 1;
		}
	}
	else
	{
		if(MOTOR.cLFMotorPhase == cLFMotorPhase_Max)
		{
			MOTOR.cLFMotorPhase = 1;
		}
		else
		{
			MOTOR.cLFMotorPhase += 1;
		}
	}
}
/*******************************************************************************
** Function name:     LFMotorInt    
**
** Descriptions :     马达中断函数
**  
******************************************************************************/

#define  pr_debug  0


void TIMER2_IRQHandler(void)									//LFMotorInt(void)
{
	unsigned char cTemp;
	unsigned int  iDotNum;
	unsigned int  BUFF;

	volatile unsigned int iLFStepNumbuf;

	if(MOTOR.bLFMotorMove)
	{
	//	MyPrintf("TIMER2_IRQHandler\n");
	    //test_1();
		if(MOTOR.cLFMotorTime == LFeStop)  //关机
		{
			//MyPrintf("moto in LFeStop MOTOR.iLFStepNum=0x%02X \n",MOTOR.iLFStepNum);

            MyPrintf("Stop MOTOR11\n");                   //右键走纸完后进入
			LFTimer_Disable;//disenble timer
			MOTOR.bLFMotorMove = 0;//motor stop
			bTimer2Prt = 0;//not Prt
			bTimer2FeedLine = 0;//end feedline
			bTimer2KeyFeed = 0;//no key
			MOTOR.bLFForward = 1;

			LAT_ON;
			ClearPrtHead();
			LAT_OFF;
			PrtBuf[cCurrentPrtCharLine].Status = Empty;
			LFMotorPhaseSet(0);//关电机
			// extern uint8_t stopFlag;
			// stopFlag = 1;
			return;
		}
		else
		{			
			if(MOTOR.cLFMotorTime == LFeLash)                        //不换相持续走上一个相位  //  这个是在停以前的一个动作???0x16指令不进来,0X17指令和0X15及0X0C指令进来
			{
		       // 		MyPrintf("2_1\n");
				Key_Feed_Line_flag = 0;
				iOffsetSum = 0;
				LFMotorPhaseSet(MOTOR.cLFMotorPhase);                 //不换相,给相位  
			}
			else       //PC无驱打印时,(安卓打印5030纸时也是)17指令中的回退一直执行这里,0x16指令也会进来(每个0X16指令进来4次) ,单击右键走纸时也循环进来                                                      
			{
		      	
				if(f_error_no_paper)
					Key_Feed_Line_flag = 0;
				LFMotorPhaseAddOne();//相位加1
				LFMotorPhaseSet(MOTOR.cLFMotorPhase);//给相位
			}

			set_lf_speed(++MOTOR.cLFMotorTime);                //速度越来越慢,当MOTOR.cLFMotorTime循环增加到31
            //			MyPrintf("cLFMotorTime = %d \n", MOTOR.cLFMotorTime ); 
			
			//每执行1次0X16指令就先执行2次2_4再接着执行2次2_3,0X0C指令先循环执行2_4、2_5然后再循环执行2_3、2_5
			if(bTimer2FeedLine)//feed line     PC打印时会进来  安卓打印时,每执行1次0X16指令进来2次,0X15指令一直进来
			{
//			    	MyPrintf("2_3\n");
#if(pr_debug)		
				MyPrintf("An:%d\n",MOTOR.iLFStepNum); 
#endif
			    //MyPrintf("指令 2_3\n");
				PrtBuf[cCurrentPrtCharLine].Status = FeedLine;
				if(MOTOR.iLFStepNum == LashStop_Nums)        //LashStop_Nums =2 惯性, 安卓打印5030每执行1次0x16指令会进来1次
				{
					bTimer2FeedLine = 0;//feed end
					PrtBuf[cCurrentPrtCharLine].Status = Empty;
					cTemp = PrtBuf[cCurrentPrtCharLine].cNextCharLine;
//					MyPrintf("cTemp=:%d\r\n", cTemp);
//			        		MyPrintf("P1\r\n"); 

#if(pr_debug)	
					MyPrintf("St:%d\r\n", PrtBuf[cTemp].Status);
#endif
					
					if(PrtBuf[cTemp].Status == WaitForPrint)                //换行重新打印    //每执行1次0x16指令会进来1次
					{
						//MyPrintf("PA:%d,%d,%d,%d\r\n", cCurrentPrtCharLine, cCurrentFillRow, PrtBuf[cCurrentPrtCharLine].iPrtStep, PrtBuf[cCurrentPrtCharLine].iFeedStep);
						
						//MyPrintf("P22 \r\n"); 
						cCurrentPrtCharLine	= cCurrentFillRow;				//cCurrentFillRow的值=1和0交替变化
//						MyPrintf("ccpcl=:%d\r\n", cCurrentPrtCharLine);
						bTimer2Prt = 1;// Countinue Prt
						PrtBuf[cCurrentPrtCharLine].Status = Printing;
						//安卓打印5030的纸张时PrtBuf[cCurrentPrtCharLine].iFeedStep=0 一直
						MOTOR.iLFStepNum = PrtBuf[cCurrentPrtCharLine].iPrtStep + PrtBuf[cCurrentPrtCharLine].iFeedStep + LashStop_Nums;//走纸的长度,还有结束位的步数目
//						MyPrintf("odin=:%d\r\n", MOTOR.iLFStepNum);
						if(MOTOR.iLFStepNum%one_dotline_lfstep_num == 0)    //安卓打印5030不进来           //这里的MOTOR.iLFStepNum=6一直, one_dotline_lfstep_num=4,
						{
							
//				             MyPrintf("P3\r\n"); 
							//new PrtLine to Printing 
							LFMotorPhaseAddOne();//相位加1
							LFMotorPhaseSet(MOTOR.cLFMotorPhase);//给相位
							PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot--;
							iDotNum = PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot;
							
							//传送到打印头一点行数据并锁存//
							LAT_ON;//Open Lat
							if(PrtBuf[cCurrentPrtCharLine].bPrtRaster)//打印光栅模式
							{
//								MyPrintf("P3_1\r\n"); 
								GetOnedotLineFromRasterBufAndSendToPrtHead(iDotNum);
							}
							else if(PrtBuf[cCurrentPrtCharLine].bPrtBarCode)//打印条码模式
							{
//								MyPrintf("P3_2\r\n");
								GetOnedotLineFromBarCodeBufAndSendToPrtHead();
							}
							else if(PrtBuf[cCurrentPrtCharLine].bPrtRleBmp)//压缩位图
							{
//								MyPrintf("P3_3\r\n");
								GetOnedotLineFromBarCodeBufAndSendToPrtHead();
							}
							else//打印数据模式
							{	
//								MyPrintf("P3_4\r\n");
								GetOnedotLineFromPrtBufAndSendToPrtHead(iDotNum);
							}
							SetTphDensitycounter++;

							LAT_OFF;//Close Lat 锁存
							
							//Print_strobetimeSet();
							if(PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot == 0)
							{     
							      
								bTimer2Prt = 0;     //prt over
								bTimer2FeedLine = 1;//start to feed and not prt
							}
							else
							{
								;//do nothing
							}
							//MyPrintf("P1\r\n"); 
						}
//						MyPrintf("P1!!\r\n"); 
						Print_strobetimeExSet();
					
					}
//					else
//					{
//						//MyPrintf("PrtBuf[cTemp].Status:%d \n",PrtBuf[cTemp].Status);
//					}

				}
//				else
//				{
//					//MyPrintf("Printing flage2\n");
//				}
			}
			else if(bTimer2Prt)//WaitMotorStop(void)    PC打印时会进来 安卓打印5030纸时每执行一次0X16就进来2次
			{
				//Printing 
				//MyPrintf("Printing\n"); 
//				MyPrintf("2_4\n");
#if(pr_debug)                    
				MyPrintf("Bn:%d\n",MOTOR.iLFStepNum); 
#endif		
				if((MOTOR.iLFStepNum%one_dotline_lfstep_num) == 0)// 在第一步开始打印
				{
					//Printing 
					
					//MyPrintf("PB:%d,%d\r\n", PrtBuf[cCurrentPrtCharLine].Status, PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot);
					PrtBuf[cCurrentPrtCharLine].Status = Printing;
					PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot--;
					iDotNum = PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot;

					LAT_ON;//Open Lat
					/***********传送到打印头一点行数据并锁存***********/
					if(feedFlag)        //安卓打印5030纸时不进来
					{
						feedFlag = 0;
//						MyPrintf("2_5\r\n"); 
						LAT_ON;
						ClearPrtHead();
						LAT_OFF;
					}
					else if(PrtBuf[cCurrentPrtCharLine].bPrtRaster)//打印光栅模式   //安卓打印5030纸时不进来
					{   
//						MyPrintf("A1\r\n"); 
						//MyPrintf("mode GUANGSHAN\n"); 
						GetOnedotLineFromRasterBufAndSendToPrtHead(iDotNum);
					}
					else if(PrtBuf[cCurrentPrtCharLine].bPrtBarCode)//打印条码模式   //安卓打印5030纸时不进来
					{
//						MyPrintf("A2\r\n"); 
						//MyPrintf("mode TIAOXINGMA\n"); 
						GetOnedotLineFromBarCodeBufAndSendToPrtHead();
					}
					else if(PrtBuf[cCurrentPrtCharLine].bPrtRleBmp)//压缩位图    //安卓打印5030纸时每执行1次0X16指令就进来1次
					{
//						MyPrintf("A3\r\n"); 
						//MyPrintf("mode YASUOTU\n"); 
						GetOnedotLineFromBarCodeBufAndSendToPrtHead();

						//MyPrintf("one_num =%d \n",one_num );

					}
					else//打印数据模式      //安卓打印5030纸时不进来
					{	
//	                     MyPrintf("2_6\r\n"); 
						//MyPrintf("mode DAYINSHUJU\n");
						GetOnedotLineFromPrtBufAndSendToPrtHead(iDotNum);
					}
					SetTphDensitycounter++;
					LAT_OFF;//Close Lat

					if(PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot == 0)//打印完成准备走行间距
					{
#if(pr_debug) 		
						MyPrintf("Pr:%d\n",PrtBuf[cCurrentPrtCharLine].iCurrentPrtDot); 
#endif	
//						MyPrintf("2_7\r\n"); 		
						bTimer2Prt = 0;//prt over
						bTimer2FeedLine = 1;//start feed not prt
						PrtBuf[cCurrentPrtCharLine].Status = FeedLine;
					}
					else
					{
						;//do nothing
					}
					     //MyPrintf("P2\r\n"); 
				}
	
				
					Print_strobetimeExSet();
				
			}
		}
	
		if(bTimer2KeyFeed)      //单击右键走纸时,循环进来   走空白或者走间隙会进来,以及0X17指令一直进来走回退
		{
			// feed paper during push down feed key	
//	        		MyPrintf("2_5\n");
			if(f_error_no_paper)
				Key_Feed_Line_flag = 0;
			if(MOTOR.cLFMotorTime == MOTOR.cLFConstPos)             // MOTOR.cLFConstPos=31  
			{
				// constant speed
				// judge if it is time to stop
				if(MOTOR.iLFStepNum > LashStop_Nums)        //LashStop_Nums=2
				{
		             //	MyPrintf("iLFStepNum = %d \n", MOTOR.iLFStepNum);
					// keep constant speed , adjust cLFTime
					MOTOR.cLFMotorTime--;
				}
				else
				{
					;//  do nothing
				}
			}
			else
			{
				// shift motion								
			}
		}
		else                                                  //每个0x18指令会进来4次
		{
			//MyPrintf("feed paper no  feed key\n"); 
		    //	MyPrintf("2_6\n");
			if(f_error_no_paper)
				Key_Feed_Line_flag = 0;
			if(MOTOR.cLFMotorTime == LFconst)
			{
				// constant speed
				// judge if it is time to stop
				if(MOTOR.iLFStepNum > LashStop_Nums) 
				{
					// keep constant speed , adjust cLFTime
					MOTOR.cLFMotorTime--;
				}
				else
				{
					;//  do nothing
				}
			}
			else
			{
				// shift motion								
			}
		}
		//MyPrintf("MOTOR.iLFStepNum!!!!!!!!!!!!=0x%02X \n",MOTOR.iLFStepNum);  
        //     MyPrintf("2_7\n");
		switch(MOTOR.iLFStepNum --)			
		{

			//case 3:
			//{
			//LFMotorPhaseSubOne();
			//}
			//break;
			case 2:
			{
				MOTOR.cLFMotorTime = LFeLash;	 
			}
			break;
			case 1:
			{
			//	MyPrintf("2_7\n");
				MOTOR.cLFMotorTime = LFeStop;     //停止马达
				break;
			}
			//case 0:
			default:
			{
	            // MyPrintf("iLFStepNum11=%d \n",MOTOR.iLFStepNum%one_dotline_lfstep_num);
				if(MOTOR.iLFStepNum%one_dotline_lfstep_num == 0)
				{				 
					ChangePaperPos();//测试纸状态	
				}

			}
			break;
		}

	}
}
//--------------------------------------------------------------------------------------
unsigned short check_1_num_nchar(unsigned char *p,unsigned char len)
{
	unsigned char buffer=0,i=0;

	unsigned short num=0,total_num;

	total_num=0;
	for(i=0;i<len;i++)
	{
		buffer=*p;
		num=check_1_num_onechar(buffer);
		total_num=total_num+num;
		p++;
	}


	return(total_num);

}

unsigned short check_1_num_onechar(unsigned char buf)
{
	unsigned char len=0,i=0,m=0;

	len=0;

	for(i=0;i<8;i++)
	{
		m=(0x01<<i);

		if((buf&m)==m)
		{
			len++;
		}


	}
	return(len);

}



/*******************************************************************************
** Function name:     GetOnedotLineFromRasterBufAndSendToPrtHead    
**
** Descriptions :     光栅模式下取一点行打印数据并发送到打印头锁存
**  
******************************************************************************/
void GetOnedotLineFromRasterBufAndSendToPrtHead(unsigned int iPrtDotLine)
{
	unsigned char *p;
	p = (unsigned char *)&PrtBuf[cCurrentPrtCharLine].ByteLine[iPrtDotLine/8].BasePrtLine[(iPrtDotLine%8)*(MaxDotPos/8)];
	SendnBytes_To_Head(p,MaxDotPos/8);
}
/*******************************************************************************
** Function name:     GetOnedotLineFromBarCodeBufAndSendToPrtHead    
**
** Descriptions :     从条码Buffer中取一点行打印数据并发送到打印头锁存
**  
******************************************************************************/

volatile unsigned short one_num=0;

void GetOnedotLineFromBarCodeBufAndSendToPrtHead(void)
{
	unsigned char *p;	
	p= (unsigned char *)&PrtBuf[cCurrentPrtCharLine].ByteLine[0].BasePrtLine[0];
	SendnBytes_To_Head(p,MaxDotPos/8);
#if 0
	p= (unsigned char *)&PrtBuf[cCurrentPrtCharLine].ByteLine[0].BasePrtLine[0];


	MyPrintf("Head data %d bytes bt data:\n",MaxDotPos/8);
	for(int i=0;i<MaxDotPos/8;i++,p++)	MyPrintf("%02x ",*p);
	MyPrintf("\n"); 
#endif
	one_num=check_1_num_nchar(p,MaxDotPos/8);
}


void GetOnedotLineFromRELCodeBufAndSendToPrtHead(unsigned int iPrtDotLine)
{
	unsigned char *p;	
	p= (unsigned char *)&PrtBuf[cCurrentPrtCharLine].ByteLine[0].BasePrtLine[8-iPrtDotLine];
	SendnBytes_To_Head(p,MaxDotPos/8);
}
/*******************************************************************************
** Function name:  GetOnedotLineAndSendToPrtHeadFromPrtBuf    
**
** Descriptions :  从打印Buffer中取一点行打印数据并发送到打印头锁存
**  
******************************************************************************/
void GetOnedotLineFromPrtBufAndSendToPrtHead(unsigned int iPrtDotLine)
{
	unsigned char *p;	
	p = (unsigned char *)&PrtBuf[cCurrentPrtCharLine].ByteLine[iPrtDotLine/8].BasePrtLine[MaxDotPos-(iPrtDotLine%8+1)*(MaxDotPos/8)];
	SendnBytes_To_Head(p,MaxDotPos/8);
	one_num=check_1_num_nchar(p,MaxDotPos/8);
}

void ClearPrtHead(void)
{
	unsigned char temp[MaxDotPos/8] = {0};
	SendnBytes_To_Head(temp,MaxDotPos/8);
}
extern u8 os_type;


#define nomal  0

//大体上根据机头的温度,得出加热的时间,机头过高,就要适当的调低打印头的温度,加热的时间就减小.
void Print_strobetimeSet(void)   
{
	unsigned int iPrtTime = 0;
	volatile unsigned char cLoop;	
	
	volatile float kk=0,kk1,kk2,kk3;

	
	//MyPrintf("TPH.TemperatrueAdc = %d\n",TPH.TemperatrueAdc);
	//MyPrintf("EXT_DEV.bat_adc = %d\n",EXT_DEV.bat_adc);

/*
	for(cLoop = 0;cLoop < 20;cLoop++)//查表
	{
		if(TPH.TemperatrueAdc >= Thermistor_ADC[cLoop])//得到对应的机头温度
		{
			iPrtTime = Thermistor_Heat_Time[cLoop];
			break;
		}
		else
		{
			//25度
			iPrtTime = Thermistor_Heat_Time[10];
		}
	}

*/



	iPrtTime= adjust_density_by_temprature(1000,20);
	//MyPrintf("iPrtTime = %d\n",iPrtTime);

	//if(PAPER.print_density >15 )
	//{
	//	PAPER.print_density = 15;
	//}

	if(PAPER.print_density >14 )
	{
		PAPER.print_density = 14;
	}
#if(nomal)    
	kk=1.3; 
	kk1=adjust_density_by_numdot_inonelin(one_num,1.5);
#else	
	kk=1; 
	kk1=adjust_density_by_numdot_inonelin(one_num,2.1);
#endif	
	kk2=adjust_density_by_volatage(EXT_DEV.bat_adc,0.4);

	kk3=adjust_density_by_speed(MOTOR.cLFMotorTime,0.02,0.35);
       //MyPrintf("kk3=%d\n",(unsigned short)(kk3*100));

	kk=kk1*kk2*kk3*kk;
	//iPrtTime = (unsigned int)(iPrtTime * Thermistor_persent[PAPER.print_density-1]*kk);
	iPrtTime = (unsigned int)(iPrtTime * Thermistor_persent[PAPER.print_density]*kk);
	MyPrintf("iPrtTime=%d\n",iPrtTime);
	if(iPrtTime <630)
	{
		iPrtTime = 630;
	}

	PrtStbAllStatus(1);
	PrtTimer_SetCounter(iPrtTime);
	
	PrtTimer_Enable;
	
    //MyPrintf("iPrtTime=%d\n",iPrtTime);

}
void Print_strobetimeExSet(void)   
{
	unsigned int iPrtTime = 0;
	volatile unsigned char cLoop;	

	volatile float kk=0,kk1,kk2,kk3;
	volatile unsigned int iPrtTimeBase1=0,iPrtTimeBase2;
	iPrtTime= adjust_density_by_temprature(1000,20);
    //iPrtTime=930
	//if(PAPER.print_density >15 )
	//{
	//	PAPER.print_density = 15;
	//}
	if(PAPER.print_density >14 )
	{
		PAPER.print_density = 14;
	}
		
#if(nomal)    
	kk=1.3; 
	kk1=adjust_density_by_numdot_inonelin(one_num,1.5);
#else	
	kk=1; 

//_	kk1=adjust_density_by_numdot_inonelin(one_num,2.1);
	kk1=adjust_density_by_numdot_inonelin(one_num,1.85);
#endif	
	kk2=adjust_density_by_volatage(EXT_DEV.bat_adc,0.4);

	kk3=adjust_density_by_speed(MOTOR.cLFMotorTime,0.02,0.35);
       //MyPrintf("kk3=%d\n",(unsigned short)(kk3*100));

	kk=kk1*kk2*kk3*kk;
	//iPrtTime = (unsigned int)(iPrtTime * Thermistor_persent[PAPER.print_density-1]*kk);
	iPrtTime = (unsigned int)(iPrtTime * Thermistor_persent[PAPER.print_density]*kk);
//		iPrtTimeBase1 = 100;
//		if(PAPER.print_density>=3)
//			iPrtTimeBase2=1400;
//		else
//			iPrtTimeBase2=1200;
//		if(one_num>=256)
//		{  
//			if(ionedotlineFlag<=6)
//				iPrtTime = 2500;
//			else
//				iPrtTime = iPrtTimeBase2+PAPER.print_density*iPrtTimeBase1;	    //浓度为6时,加热0.83ms
//			
//		}
//		else if(256>one_num>192)//主要针对表格显示       不屏蔽时打印90°边框或竖条线时会断线 (iPrtTimeBase2-200)
//		{
//			if(ionedotlineFlag<=6)
//				iPrtTime = 2500;
//			else
//				iPrtTime = (iPrtTimeBase2-100)+PAPER.print_density*iPrtTimeBase1;     
//		}
//		else if(0<one_num<= 192)
//		{
//			if(ionedotlineFlag<=6)
//				iPrtTime = 2500;
//			else
//				iPrtTime = (iPrtTimeBase2-200)+PAPER.print_density*iPrtTimeBase1;
//		}
//		else if(0<one_num<= 64)
//        {
//			if(ionedotlineFlag<=4)
//			 iPrtTime = 2500;
//			else
//			iPrtTime = 1450+PAPER.print_density*50;
//		}			
	
	if(iPrtTime <630)
	{
		iPrtTime = 630;
	}

	PrtStbAllStatus(1);
	PrtTimer_SetCounter(iPrtTime /3);
	PrtTimer_Enable;
	
    //

}



//k_tem<50


/*
unsigned int adjust_density_by_temprature(unsigned int heat_time,unsigned char k_tem)
{

	volatile unsigned char cLoop=0;
	unsigned int mm;

	for(cLoop = 0;cLoop < 20;cLoop++)//查表
	{
		if(TPH.TemperatrueAdc >= Thermistor_ADC[cLoop])//得到对应的机头温度
		{
			//mm = Thermistor_Heat_Time[0]-cLoop*k_tem;
			break;
		}

	}

	//mm = Thermistor_Heat_Time[0]+200-cLoop*k_tem;

	mm = heat_time-cLoop*k_tem;

	return(mm);

}

*/

//线性反馈是不行的
unsigned int adjust_density_by_temprature(unsigned int heat_time,unsigned char k_tem)
{

	volatile unsigned char cLoop=0;
	unsigned int mm;

	for(cLoop = 0;cLoop < 20;cLoop++)//查表
	{
		if(TPH.TemperatrueAdc >= Thermistor_ADC[cLoop])//得到对应的机头温度
		{
			mm = Thermistor_Heat_Time[cLoop];
			break;
		}

        if(cLoop==19)
        {
			mm = Thermistor_Heat_Time[cLoop];
		}
	}


       
	//mm = Thermistor_Heat_Time[0]+200-cLoop*k_tem;

	//mm = heat_time-cLoop*k_tem;

	return(mm);

}




//float k  >1
float  adjust_density_by_numdot_inonelin(unsigned short one_number,float k)
{

		volatile float MM=0,KK1;
		if(one_number>15)//主要针对表格显示       不屏蔽时打印90°边框或竖条线时会断线
		{
		 	one_num=one_number+80;     //100改为90
		}
		else if(0<one_number<= 15)
		{
			one_num=one_number+40;
		}
//		else if(0<one_number<= 6)
//        {
//			one_num=one_number+20;
//		}			
        if(one_num>LINE_DOTS)
       	{
			one_num=LINE_DOTS;

		}
        

		KK1=(float)one_num/LINE_DOTS;

		KK1=KK1*k;
		KK1=KK1+1;
		
		return(KK1);
}



//
//
//  k2 的范围 (0,0.3)

#define ziro_1volatage   10      //0.1v大约对应10个ad
#define dalta_volatage   (3*ziro_1volatage)  //这个数值的存在主要是为了协助定义最大的电池电压的ad值。



float  adjust_density_by_volatage(unsigned short volatage,float k2)
{

		volatile float MM=0,KK2,KK3;
    
	    if(volatage<=bat_level_adc[0])//电压太低的情况下,不修正这个参数
       	{
			KK2=1;

		}
       // else if(volatage>=bat_level_adc[3]+dalta_volatage)//电压太高的情况下也不修正这个参数   
      // 	{
	//		KK2=1;

	//	}
        else 
       	{
			KK2=(float)(volatage-bat_level_adc[0])/(bat_level_adc[3]+dalta_volatage-bat_level_adc[0]);
			
			KK2=KK2*k2;
            KK2=1-KK2;
			//KK3=(u8)(KK2*10);
			//MyPrintf("KK3=%d\n",(KK3));
		}   
		return(KK2);
}





//如果速度慢就要增加加热的时间。
//MOTOR.cLFMotorTime 这个变量就是参数

//k1 0.2
//k2 0.01
float  adjust_density_by_speed(unsigned char speed,float k2,float k1)
{

		volatile float MM=0,KK2,KK3;
  /*  
	    if(volatage<=bat_level_adc[0])//电压太低的情况下,不修正这个参数
       	{
			KK2=1;

		}
        else if(volatage>=bat_level_adc[3]+dalta_volatage)//电压太高的情况下也不修正这个参数   
       	{
			KK2=1;

		}
        else 
       	{
			KK2=(float)(volatage-bat_level_adc[0])/(bat_level_adc[3]+dalta_volatage-bat_level_adc[0]);

			KK2=KK2*k2;
			KK2=1-KK2;
			//KK3=(u8)(KK2*10);
			//MyPrintf("KK3=%d\n",(KK3));
		}
 */

		KK2=1;
		if(speed==LFconst)        //LFconst
		{
			KK2=KK2;
		}
		else if(speed<LFconst)
		{
			KK2=(LFconst-speed)*k2+KK2;
		}
              else if(speed>LFconst)
              {
			KK2=(speed-LFconst)*k1+KK2;
      	        }

		return(KK2);
}


/*******************************************************************************
** Function name:    PrtTimerInt
**
** Descriptions :    加热时间中断函数
**
**
******************************************************************************/


void TIMER3_IRQHandler(void)//PrtTimerInt(void)
{
	static u8 cPrtBits = 1;
	PrtTimer_Disable;

	PrtStbAllStatus(0);
	cPrtBits = 1;
//	MyPrintf("leng--");
	//PrtTimer_Disable;
//    if(TPHStatus.TimeIndex < TPHStatus.TargetTime)
//    {
//        TPHStatus.TargetTime    = maxTime / 4;
//        TPHStatus.TimeIndex     = 0;
//        TPHStatus.HeatIdx       = 0;
//    }

}



/*******************************************************************************
** Function name:    CountinueLineFeed
**
** Descriptions:     连续走纸计算
**
**
******************************************************************************/
void CountinueLineFeed(unsigned int iStep)
{
	CloseAllInt;
	MOTOR.iLFStepNum += iStep;
    feedFlag = 1;
	OpenAllInt;

}
/*******************************************************************************
** Function name:     StartSysTimer    StoptSysTimer   DelayMs
**
** Descriptions :      系统延时函数
**
**
******************************************************************************/
void StartSysTimer(unsigned char flash)
{
	MOTOR.bSysTimer = 1;//
	EXT_DEV.iNumOfMs = 0;//计数值
	Timer_SetCounter(1000);
	Timer_Enable;//启动定时器
}

void StopSysTimer(void)
{
	MOTOR.bSysTimer = 0;
	Timer_Disable;
}

void DelayMs(unsigned int iMs)//延时函数 毫秒级别
{

	StartSysTimer(0);

	//MyPrintf("lcd init  step3\n");
	//MyPrintf("EXT_DEV.iNumOfMs: %d\r\n",EXT_DEV.iNumOfMs);
	while(EXT_DEV.iNumOfMs < iMs)
	{
		//MyPrintf("-");	// wait
	}
	StopSysTimer();

}
/*******************************************************************************
** Function name:     SysTimerInt
**
** Descriptions:     闪灯定时和系统延时函数 :缺纸400ms一循环 高温800ms一循环
**
**
******************************************************************************/
void TIMER4_IRQHandler(void)
{
	if(MOTOR.bSysTimer)
	{
		EXT_DEV.iNumOfMs++;	
		Timer_SetCounter(1000);
		
		return ;
	}

}







/*******************************************************************************
** Function name:    
**
** Descriptions :    按键启动电机 准备进纸
**
**
******************************************************************************/

void StartKeyFeedPaper(unsigned int cStepNum,unsigned char cStepTime)
{
	bTimer2KeyFeed	= 1;  //按键走纸标志位
	CloseAllInt;
	//MyPrintf("MOTOR.iLFStepNum:%d \n",MOTOR.iLFStepNum);
	MOTOR.iLFStepNum	+= (cStepNum*one_dotline_lfstep_num + LashStop_Nums); // 2013.12.25      LashStop_Nums =2 
  
//	MyPrintf("cStepNum:%d \n",cStepNum);

//	MyPrintf("iLFStepNum_1:%d \n",MOTOR.iLFStepNum);

	OpenAllInt;
	MOTOR.cLFConstPos = cStepTime;           

	LFMotorPhaseSet(MOTOR.cLFMotorPhase);
	
	//LFMotorPhaseSubOne();
	LFTimer_Enable;
	//LFTimer_SetCounter(LFMotorTime[LFsRush]);
	//MOTOR.cLFMotorTime = LFsRush;
	set_lf_speed(LFsRush);         //LFsRush=0   设置速度

	MOTOR.bLFMotorMove = 1;

}

//这个函数相对于原来的函数第一形参直接是一个电机的步数,不是元素点,因为元素点有时候是3步(打印图片的时候),
//有时候是4步(打印字符的时候),
void StartKeyFeedPaper_1(unsigned int cStepNum,unsigned char cStepTime) 
{
	bTimer2KeyFeed	= 1;
	CloseAllInt;
	//MyPrintf("MOTOR.iLFStepNum:%d \n",MOTOR.iLFStepNum);
	MOTOR.iLFStepNum	+= (cStepNum + LashStop_Nums); // 2013.12.25
	
	MyPrintf("cStepNum:%d \n",cStepNum);

	//MyPrintf("MOTOR.iLFStepNum:%d \n",MOTOR.iLFStepNum);

	OpenAllInt;
	MOTOR.cLFConstPos = cStepTime;

	LFMotorPhaseSet(MOTOR.cLFMotorPhase);
	
	//LFMotorPhaseSubOne();
	LFTimer_Enable;
	//LFTimer_SetCounter(LFMotorTime[LFsRush]);
	//MOTOR.cLFMotorTime = LFsRush;
	set_lf_speed(LFsRush);    //设置定时器重载值(通过重装载来改变速度) LFsRush=0

	MOTOR.bLFMotorMove = 1;

}

void StartKeyFeedPaper_coutinue(unsigned int cStepNum,unsigned char cStepTime,unsigned char cStepTime_start)
{
	bTimer2KeyFeed	= 1;
	CloseAllInt;
	//MyPrintf("MOTOR.iLFStepNum:%d \n",MOTOR.iLFStepNum);
	MOTOR.iLFStepNum	+= (cStepNum*one_dotline_lfstep_num + LashStop_Nums); // 2013.12.25
	
	MyPrintf("cStepNum:%d \n",cStepNum);

	//MyPrintf("MOTOR.iLFStepNum:%d \n",MOTOR.iLFStepNum);

	OpenAllInt;
	MOTOR.cLFConstPos = cStepTime;

	LFMotorPhaseSet(MOTOR.cLFMotorPhase);
	
	//LFMotorPhaseSubOne();
	LFTimer_Enable;
	//LFTimer_SetCounter(LFMotorTime[LFsRush]);
	//MOTOR.cLFMotorTime = LFsRush;
	set_lf_speed(cStepTime_start);   

	MOTOR.bLFMotorMove = 1;

}



void set_lf_speed(unsigned char speed)
{
	if(speed>LFconst)                         //LFconst=31
	{
		speed=LFconst;

	}

	MOTOR.cLFMotorTime = speed;
	LFTimer_SetCounter(LFMotorTime[MOTOR.cLFMotorTime]);//设置定时器重装载值
//  MyPrintf("LFMotorTime= %d \n", LFMotorTime[MOTOR.cLFMotorTime]);

}


/**********************************END*****************************************/
























//                                      PrtHead.h


#ifndef _PRTHEAD_H_
#define _PRTHEAD_H_

#include "type.h"
// PrtHead.h
#define  LashStop_Nums     2 //hole rush  惯性
#define  DIVTIMES_FLAG     2 //·??????óèè   
#define cLFMotorPhase_Max	 8

enum enumADValue{
	pe, thermal};

#define GAP_IDE								0
#define GAP_MOVE_PAPTER_TO_TPH				1
#define GAP_MOVE_PAPTER_TO_CUT				2
#define GAP_CALIBRATE						3
#define GAP_MOVE_PAPTER_TO_HOLD				4             //移动到定位孔(新增)



//加一个修正值
#define dia_gap_to_tph_offset                   20
#define dis_tph_to_cut_offset                   30
#define DIS_GAP_TO_TPH						(74*ONEDOTSTEPNUM-dia_gap_to_tph_offset)	// 9mm*8*ONEDOTSTEPNUM      276
#define DIS_TPH_TO_CUT						(42*ONEDOTSTEPNUM-dis_tph_to_cut_offset)	// 3mm*8*ONEDOTSTEPNUM      138


#define off_seta                            (6) //  0.03125
#define off_setb                            (6) //  0.03125



//加一个修正值
//#define dia_gap_to_tph_k                    0.95// 0.90
//#define dis_tph_to_cut_k                    0.80
//#define DIS_GAP_TO_TPH						(74*ONEDOTSTEPNUM*dia_gap_to_tph_k)	// 9mm*8*ONEDOTSTEPNUM
//#define DIS_TPH_TO_CUT						(42*ONEDOTSTEPNUM*dis_tph_to_cut_k)	// 3mm*8*ONEDOTSTEPNUM


//#define DIS_GAP_TO_TPH						(74*ONEDOTSTEPNUM)	// 9mm*8*ONEDOTSTEPNUM
//#define DIS_TPH_TO_CUT						(42*ONEDOTSTEPNUM)	// 3mm*8*ONEDOTSTEPNUM



enum enumLFStatus{
	LFsRush,  LFacc1,  LFacc2,  LFacc3,
	LFacc4,   LFacc5,  LFacc6,  LFacc7,
	LFacc8,   LFacc9,  LFacc10, LFacc11,
	LFacc12,  LFacc13, LFacc14, LFacc15,
	LFacc16,  LFacc17, LFacc18, LFacc19,
	LFacc20,  LFacc21, LFacc22, LFacc23,
	LFacc24,  LFacc25, LFacc26, LFacc27,
	LFacc28,  LFacc29, LFacc30, LFconst,
	LFeLash,  LFeStop
};

typedef struct  StructMotor{
	unsigned char bSysTimer;//启用延时标志位
	unsigned char bLFMotorMove;//电机转动标志位
	unsigned char cLFMotorPhase;//电机相位
	unsigned char cLFMotorTime;//电机每步时间           准确的说是速度的挡位
	unsigned char bLFForward;//电机正转
	unsigned int  iLFStepNum;//电机运行步数
//	unsigned int  iLFStepNum2;  //预设的运行步数   
	unsigned char cLFConstPos;//匀速
}STRUCT_MOTOR;
extern volatile STRUCT_MOTOR MOTOR;

typedef struct  StructTph{

	unsigned char bErrTemperature;//过温错误
	unsigned int  iDensitySetTime;//浓度级别对应加热时间
	unsigned int  TemperatrueAdc;

}STRUCT_TPH;
extern volatile STRUCT_TPH TPH;
extern volatile unsigned short one_num;


#define PAPER_FILTER_HOLD		0        //保持
#define PAPER_FILTER_UP			1       //上升沿
#define PAPER_FILTER_DOWM		2       //下降沿

#define MAX_ADSW_CHANNEL		4
#define MAX_FILTER_COUNT		5       //过滤次数
typedef struct  StructPaper{

	uint8_t move_ctl_state;          //电机步进控制的类型
	uint8_t last_gap_state;
	uint8_t current_gap_state;       //当前缺口状态
	uint8_t type;
	uint8_t auto_cal_type;

	uint8_t print_density;   //[0,14]
	uint8_t print_speed;     //[0,4]
	uint16_t print_speed_time_multiple;
	uint8_t move_to_cut_flag;
	uint8_t calibrate_state;        //校准状态
	uint8_t auto_calibrate_flag;     //定标开始及结束标志
	uint8_t calibrate_error_flag;    //校验错误标志
	uint16_t sensor_adc[MAX_ADSW_CHANNEL];
	uint16_t adc_filter[MAX_FILTER_COUNT];         //adc过滤
	uint16_t adj_gap_size;
	uint16_t adj_bm_size;
	uint16_t adj_hold_size;
	uint16_t adj_paper_size;

	uint16_t paper_end_flag;
	uint16_t paper_start_offset_flag;
	uint16_t paper_start_offset;	

	uint16_t size_h;	              //纸张高度
	uint16_t print_size;            //打印内容长度
	uint16_t offest_fh;              //打印内容纵向偏移量
	uint8_t printing_process_flag;   //打印开始及结束标志
	uint8_t NAK_flag;                //空走纸标志
	unsigned int  PaperAdc;          //存放纸的ADC值
}STRUCT_PAPER;
extern volatile STRUCT_PAPER PAPER;

typedef struct  StructExtDev{
	
	uint8_t dlabel_save_counter;
	uint8_t print_scan_time;
	uint8_t tph_scan_time;
	uint8_t tph_scan_enable;
	uint8_t no_paper_scan_time;
	uint8_t head_open_flag;
	uint8_t bat_error_flag;
	
	uint8_t usb_pugin_flag;
	uint8_t usb_scan_time;
	
	uint8_t bat_level;
	uint8_t bat_level2;
	uint8_t ble_link_flag;
	uint8_t spp_link_flag;
	uint8_t usb_link_flag;  //
	uint8_t charging_flag;	
	uint8_t charging_flsh_time;
	uint8_t charging_flsh_time2;   //_新增 
	uint8_t charging_flsh_state;
	uint8_t charging_flsh_state2;  //_新增
	uint8_t base_100ms_time;
	
	uint16_t Lcd_flsh_time;     //打印过程显示刷新时间
	uint8_t Lce_flsh_state;       
	
	uint8_t f_eeprom_updata;
	
	uint16_t bat_adc;
	uint16_t bat_adc2;
	uint16_t bat_scan_time;

	uint16_t iNumOfMs;
	uint16_t power_off_mode;
	uint16_t power_off_time_count;
	uint16_t hight_tem_release_counter;	
	uint16_t print_err_release_delay_counter;	

}STRUCT_EXT_DEV;
extern volatile STRUCT_EXT_DEV EXT_DEV;

extern const unsigned int Thermistor_ADC[20];
#define EEROR_TPH_TEMP_INDEX	       15          //60
#define EEROR_THP_RESUME_INDEX	14          //14



void WaitMotorStop(void);
void CloseAll(void);
void LFMotorPhaseAddOne(void);
void LFMotorPhaseSubOne(void);
void StartLFMotor(void);
void StartSysTimer(unsigned char flash);
void StopSysTimer(void);
void DelayMs(unsigned int iMs);
void StartKeyFeedPaper(unsigned int cStepNum,unsigned char cStepTime);
void ChangePaperPos(void);
void GetOnedotLineFromRasterBufAndSendToPrtHead(unsigned int iPrtDotLine);
void GetOnedotLineFromPrtBufAndSendToPrtHead(unsigned int iPrtDotLine);
void GetOnedotLineFromBarCodeBufAndSendToPrtHead(void);
void GetOnedotLineFromRELCodeBufAndSendToPrtHead(unsigned int iPrtDotLine);

void Print_strobetimeSet(void);
void CountinueLineFeed(unsigned int iStep);
void FeedPaper(unsigned int iStepNum);
void GetPaperState(void);
void ContinueFeedPaper(void);
extern void set_lf_speed(unsigned char speed);
extern void StartKeyFeedPaper_1(unsigned int cStepNum,unsigned char cStepTime) ;
extern unsigned short check_1_num_onechar(unsigned char buf);
extern unsigned short check_1_num_nchar(unsigned char *p,unsigned char len);



extern float  adjust_density_by_numdot_inonelin(unsigned short one_number,float k);
extern float  adjust_density_by_volatage(unsigned short volatage,float k2);
extern unsigned int adjust_density_by_temprature(unsigned int heat_time,unsigned char k_tem);
extern   float  adjust_density_by_speed(unsigned char speed,float k2,float k1);



extern void print_check(void);
extern void print_check_1(void);
extern const uint16_t bat_level_adc[];
extern void Print_strobetimeExSet(void);
#endif
/**********************************END*****************************************/


























//                           PwmBeep.c



#include "yc3121.h"
#include "yc_gpio.h"
#include "yc_uart.h"
#include "yc_timer.h"
#include "misc.h"
#include "type.h"
#include "board_config.h"
#include "Interface.h"
#include "PrtHead.h"

void PWM_Configuration(void)
{
	PWM_InitTypeDef PWM_init_struct;

	PWM_init_struct.TIMx = TIM5;
	PWM_init_struct.LowLevelPeriod = 4800;
	PWM_init_struct.HighLevelPeriod = 4800;
	PWM_init_struct.SatrtLevel = OutputLow;
	//GPIO_Config(BEEP_PORT, BEEP_PIN, GPCFG_PWM_OUT5);
	TIM_PWMInit(&PWM_init_struct);

	/* Configure PWM for counting mode */
	TIM_ModeConfig(TIM5, TIM_Mode_PWM);

	/* The last step must be enabled */
	TIM_Cmd(TIM5, ENABLE);

 	delay_ms(55);
	TIM_Cmd(TIM5, DISABLE);
	
}


void BeepKey(void)
{

#ifdef USE_PWM_BEEP
	TIM_Cmd(TIM5, ENABLE);

	delay_ms(50);
	TIM_Cmd(TIM5, DISABLE);
#endif

}

//生日快乐歌闹钟音谱
const uint8_t SONG_TONE[]={212,212,190,212,159,169,212,212,190,212,142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,0};
const uint8_t SONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,12,12,12,12,9,3,12,12,12,24,0};

void MusicPlay(void)
{

	static uint8_t flag = 0;
	
	uint16_t i=0,j,k;

	MyPrintf("play music\n");
	while(SONG_LONG[i]!=0||SONG_TONE[i]!=0)
	{
		for(j=0;j<SONG_LONG[i]*20;j++)
		{
			flag ^= 0x01;
			if(flag){
				//BEEP_ON;
			}
			else{
				//BEEP_OFF;
			}
			for(k=0;k<SONG_TONE[i]/3;k++);
		}
		
		delay_us(200);
		i++;
	}
}



























//                                     PwmBeep.h


//空文件

















//                                   RcvBuf.c


/*******************************************************************************
* File Name    : RcvBuf.c
* Date         : Dec 18 2010
* Description  : Receive Buffer
* Designe      : XXXXXXXXXXXXXXXX
*******************************************************************************/
#include "string.h"
//#include <studio.h>
#include "yc3121.h"
#include "board_config.h"
#include "yc_uart.h"
#include "yc_wdt.h"
#include "usb.h"
#include "bsp_lcd.h"
#include "PrtBuf.h"
#include "Interface.h"
#include "LcdCommand.h"
#include "PrtHead.h"
#include "Type.h"
#include "CmdSet.h"
#include "BT_BLE.h"
#include "LcdDrv.h"
#include "RcvBuf.h"
#include "Sensor.h"
#include "LcdMenu.h"
#include "app.h"
#include "api_font_img.h"

extern void KEY_Main(void);

extern unsigned char Calibrate_enable;


#ifndef BIT0
	#define BIT0  LSB
	#define BIT1  2
	#define BIT01 3
	#define BIT2  4
	#define BIT3  8
	#define BIT23 12
	#define BIT4  16
	#define BIT5  32
	#define BIT6  64
	#define BIT56 96
	#define BIT7  128
#endif

#define DLE 0x10
#define EOT 0x04
#define ENQ 0x05

enum enumRTStatus{
	cNormalRT,cDLERT,cEOTRT,cENQRT
};

unsigned char cStatus = cNormalRT;

// hardware



volatile unsigned int  PosHead;    //接收数据缓存数组的索引
//volatile unsigned int  PosHeadIOS;    //IOS接收数据缓存数组的索引
volatile unsigned int  PosTrail;    //表示从RcvBuff[PosTrail++]缓存中取出第PosTrail个数据
volatile unsigned int  RemainSize;//剩下缓冲区大小
volatile unsigned char bRcvBufFull;
volatile unsigned char RcvBuff[RcvBufSize];//数据缓冲区
//volatile unsigned char RcvBuff_IOS[RcvBufSize_IOS];//IOS数据缓冲区
volatile unsigned char Rcv_Port;           //接收端口
volatile unsigned char Rcv_Data_Delay;
volatile unsigned char f_rcv_data;          // 接收数据标志 0:没有数据, 1:接收数据正常
volatile unsigned char f_rcv_data2;          //用于判断多张打印时有无数据接收的标志,当打印完第一张跳到第二张开始打印的间隙f_rcv_data是没有数据的,f_rcv_data2表示打印总张数接收标志

void FillRcvBuf(unsigned char cRvcData);
/*******************************************************************************
** Function name:     InitRcvBuf    
**
** Descriptions :     接收buffer初始化
**  
******************************************************************************/
void InitRcvBuf(void)
{
	f_rcv_data = 0;
	f_rcv_data2 = 0;
	RemainSize = RcvBufSize;       //36864
	PosHead = 0;
//	PosHeadIOS = 0;
	PosTrail = 0;
	bRcvBufFull = 0;
}

/*******************************************************************************
** Function name:      
**
** Descriptions :    通信接口接收的数据存放到接收RcvBuff
**  
******************************************************************************/
void FillRcvBuf(unsigned char cRvcData)
{
	
	if(BOARD_KEY.power_state == 0)
	{
		return;
	}

	
	else
	{//把数据缓存起来
	//	MyPrintf("cRvcData= %2x\n\r",cRvcData);
		RcvBuff[PosHead++] = cRvcData;  
		f_rcv_data = 1;//数据接收正常
//		

		RemainSize--;
	}
	if(PosHead == RcvBufSize)//缓冲区满
	{
		PosHead = 0;
	}

}

//-----------------------------------------------------接收缓冲检查
void receive_buf_check(void)
{
//	MyPrintf("RcvBufSize=%d",RcvBufSize);
//	MyPrintf("CanRcvSize=%d",CanRcvSize);
	if((RcvBufSize-RemainSize) >= RcvFullSize)             //RcvBufSize=36864   CanRcvSize=26624(0x6800)      RcvFullSize =  36864-256   RemainSize(剩余大小)<256时
	{
		bRcvBufFull = 1;
		Busy_ON;                  //目前没用                 
	}else if((RcvBufSize-RemainSize) < RcvFullSize/*CanRcvSize*/){          //  RemainSize>10240,RemainSize一旦小于10240就不执行

		bRcvBufFull = 0;
		Busy_OFF;        		//目前没用 
	}

}

#define get_data_debug    1

/*******************************************************************************
** Function name:        
**
** Descriptions :     在接收数据buffer读取一个字节      循环执行
**  
******************************************************************************/
unsigned char GetDataFromRcvBuf(void)
{

	static UINT16 cnt = 0;
	unsigned char ReturnData;
//	uint8_t *img_ptr;
#if(get_data_debug)	
       test_2(1);
#endif	
//	MyPrintf("GetDataFromRcvBuf_ \n");
while(!f_rcv_data)//have nothing data 
{		
	IWDG_Reload;
	PollingExtDev(1);             //检测USB连接情况及纸张的有无
//	if(f_printer_error)
	{
		PollingExtDev_1(1);     //检测电量
		PollingExtDev_2(1);      //检测打印头温度
	}
//    MyPrintf("GetDataFromRcvBuf_ \n");
	if(f_error_no_paper &&(!f_error_Voltage_low))//缺纸	
	{
//		menu_state = LCD_MENU_ERROR;
		LFMotorPhaseSet(0);
		LCD_Charge_Flash();		       
	}
		
	
#ifdef USE_BLE
		BT_Progress();
		usb_main();
//    MyPrintf("GetDataFromRcvBuf_1 \n");
#endif

#ifdef USE_LCD

//		MyPrintf("LCD_Main() \n");
#endif
	
//	if(UndetectedGapPaper_Flag==1 && f_lable_printing==0/*&&LCD.time_event6_50ms==0*/)
//	{
//		UndetectedGapPaper_Flag = 2;
//		menu_state = LCD_MENU_ERROR;
//		LCD.time_event6_50ms = 500;
//		LCD_DspUndetectedGapPaper(); 
//	}
//	if(UndetectedHoldPaper==1 && LCD_MENU_ERROR != menu_state && f_lable_printing==0)       //未检测到定位孔纸
//	{
//		menu_state = LCD_MENU_ERROR;
//		LCD_DspUndetectedHoldPaper();
//		LCD.time_event6_50ms = 300;
//		UndetectedHoldPaper=0;
//	//	MyPrintf("LCD_Main_2 \n");
//	}

  if(f_lable_printing==0)                      //打印过程屏蔽按键功能
		KEY_Main();
		vTaskDelay(1);
}
//---------------------------------------------------------------------------以下是打印状态下的循环代码
	//test_2(0);	
	IWDG_Reload;
	if(++cnt >= 50)
	{
		cnt = 0;
		vTaskDelay(1);
	}

//  MyPrintf("GetDataFromRcvBuf_2 \n");
	PollingExtDev(1);
	PollingExtDev_1(1);
	PollingExtDev_2(1);
//	f_lable_printing = 1;
#ifdef USE_BLE
	BT_Progress();
#endif

	usb_main();
	if(f_lable_printing==0)       //打印过程屏蔽按键功能     if(f_lable_printing==0&&(page_tatal == pape_current))
	  KEY_Main();

//  MyPrintf("GetDataFromRcvBuf_3 \n");
//	CloseAllInt;
	ReturnData = RcvBuff[PosTrail++];

	RemainSize++;
//	MyPrintf("RemainSize_22=%d\n\r",RemainSize);
//	OpenAllInt;

	if(PosTrail == RcvBufSize)
	{
		PosTrail = 0;
	}
	if(RemainSize == RcvBufSize)
	{
		f_rcv_data = 0;
	}
	

	receive_buf_check();
	   
#if(get_data_debug)	 
	test_2(0);	
#endif
	return ReturnData;
}


/*******************************************************************************
** Function name:     UART0_IRQHandler    
**
** Descriptions :     串口中断接收函数
**  
******************************************************************************/

void UART0_IRQHandler(void)
{
    uint8_t rbuf[10];

	int r,i;
    uint8_t tbuf[] = "UART1 TX INTERRUPT test successful!\n";


    if (UART_GetITIdentity(UART0) == UART_IT_RX)
    {
		if (UART_IsRXFIFONotEmpty(UART0))
		{

			r = UART_RecvBuf(UART0, rbuf, 9);
			//			if(bRcvBufFull)
			//			{
			//				// set busy 
			//				Busy_ON; 
			//			}
			Rcv_Port = RCV_TYPE_UART;
			for(i=0;i<r;i++)
			FillRcvBuf(rbuf[i]);
		}
		//MyPrintf("UART1 RX INTERRUPT test successful, this buf is %s!\n", rbuf);
    }
    else if (UART_GetITIdentity(UART0) == UART_IT_TX)
    {
        UART_SendBuf(UART0, tbuf, sizeof(tbuf) - 1);
        UART_ClearIT(UART0);
    }
}
























//                             RcvBuf.h               


#ifndef _RCVBUF_H_
#define _RCVBUF_H_
/***********************************************************************
* File Name  : RcvBuf.h
* Description: Receive Buffer
*
***********************************************************************/
#include "Types.h"
#define RcvBufSize  0x9000
//#define RcvBufSize_IOS  0x60
#define RcvFullSize (RcvBufSize-256)       //
//_  #define CanRcvSize  (RcvBufSize-10240)
#define CanRcvSize  (RcvBufSize-1024)


extern volatile unsigned char Rcv_Port;
extern volatile unsigned char bRcvBufFull;
extern volatile unsigned char Rcv_Data_Delay;
extern volatile unsigned char f_rcv_data;
extern volatile unsigned char f_rcv_data2;
extern volatile unsigned char RcvBuff[];
extern volatile unsigned int  RemainSize;

typedef struct 
{
	unsigned char  return_data;
	unsigned char  buf_state;

} ret_stru;

// function

extern void FillRcvBuf(unsigned char cRvcData);
extern  unsigned char GetDataFromRcvBuf(void);
extern ret_stru GetDataFromRcvBuf_main(void);

extern void InitRcvBuf(void);
extern void receive_buf_check(void);
BOOL SuppliesDecLength_Lock(void);
void SuppliesDecLength_Unlock(void);
extern INT32 SuppliesDecLength;
#endif

/**********************************END*****************************************/


























//                                   Sensor.c



#include "board_config.h"
#include "yc_timer.h"
#include "yc_bt.h"
#include "PrtBuf.h"
#include "Interface.h"
#include "yc3121.h"
#include "PrtHead.h"
#include "yc_wdt.h"
#include "LcdMenu.h"
#include "PrtHead.h"
#include "Sensor.h"
#include "CmdSet.h"
#include "bsp_lcd.h"
#include "api_font_img.h"
#include "RcvBuf.h"
KalmanInfo KFP_height={0,0,0,0,0,0};
//KalmanInfo KFP_height={0.02,0,0,0,0.001,0.543};

UCharField transfer_state;
UshortField error_state;
extern const BMP_INDEX_STRUCT BMP_DEVICE_FLAG_MAP[];
unsigned char Paper_Use_Up_Flag =0;                      //纸张打印完标志
unsigned char UndetectedGapPaper_Flag =0;
unsigned char UndetectedHoldPaper=0;
unsigned int iOffsetSum=0;
unsigned char Can_Be_Calibrated_Flag=0;          
const uint16_t bat_level_adc[]={
	1690,//6.8
	1750,//7.3
	1800,//7.8
	1840,//8.2
	0xffff,
};


/*
const uint16_t bat_level_adc[]=
{
	1660, // 1630,//6.8
	1700, // 1690,//7.3
	1740,//7.8
	1780,//8.2
	0xffff,
};

*/


void SendSor_Init(void){
	
	transfer_state.byte = 0x09;
	error_state.byte[0] = 0x01;
	
	
}
uint8_t GetBatLevel(uint16_t bat_adc){

	uint8_t i;
	for(i=0;i<5;i++){

		if(bat_adc < bat_level_adc[i])	return i;
	}
	return i;
}
/*************************************************
**************************************************/

//根据实际的测试0~3通道,2通道的间隙纸的差值最大.



uint16_t GetPaperSensorAdc(uint8_t channel_index)
{	
	if(channel_index==0){
		BM_E0_OFF;
		BM_E1_OFF;
	}
	else if(channel_index == 1)
	{
		BM_E0_OFF;
		BM_E1_ON;

	}
	else if(channel_index == 2)
	{
		BM_E0_ON;
		BM_E1_OFF;
	}
	else
	{
		BM_E0_ON;
		BM_E1_ON;
	}
	return ADC_GetResult(ADC_CH_GAP);
}

//判断检纸传感器的ADC是上升沿还是下降沿,还是paper hold

// 这个算法是定义,paper_UP  ,PAPER_DOWN,PAPER_HOLD
uint8_t PaperFilter(uint16_t *adc_buff,uint8_t filter_size)
{

	uint8_t i;
	uint8_t up_count = 0;
	uint8_t dn_count = 0;


  static unsigned char counter=0;

//这个开始的时候不测试间隙。因为这个时候容易引入干扰
//10*4     5mm

	if(counter<10)
	{
    counter++;
		return PAPER_FILTER_HOLD;     
	}
	
	//check up
	for(i=0;i<(filter_size-1);i++){

		if((adc_buff[i]+bianhualiang)<adc_buff[i+1])	up_count++;

		if((adc_buff[i]-bianhualiang)>adc_buff[i+1])	dn_count++;
	}

	if(up_count == (filter_size-1))
	{
//		MyPrintf("paper up0 -- >%d\n",adc_buff[0]);
//		MyPrintf("paper up1 -- >%d\n",adc_buff[1]);
//		MyPrintf("paper up2 -- >%d\n",adc_buff[2]);
//		MyPrintf("paper up3 -- >%d\n",adc_buff[3]);
//		MyPrintf("paper up4 -- >%d\n",adc_buff[4]);
		return PAPER_FILTER_UP;   
	}
	else if(dn_count ==  (filter_size-1))
	{
//		MyPrintf("paper do0 -- >%d\n",adc_buff[0]);
//		MyPrintf("paper do1 -- >%d\n",adc_buff[1]);
//		MyPrintf("paper do2 -- >%d\n",adc_buff[2]);
//		MyPrintf("paper do3 -- >%d\n",adc_buff[3]);
//		MyPrintf("paper do4 -- >%d\n",adc_buff[4]);
		return PAPER_FILTER_DOWM;
	}
	else
	{
		return PAPER_FILTER_HOLD;       

	}

}
//采集检纸传感器的ADC,并存入BUFF备用
void PushSensorAdc(uint8_t paper_type)
{
	uint8_t i;
	volatile uint16_t sum = 0,sum1=0;

  static unsigned char  counter_1=0;
/*
	if(counter_1<10)    //开机的时候有干扰,去掉
	{
		counter_1++;
		return;
	}

	*/

	for(i=0;i<MAX_ADSW_CHANNEL;i++)      //MAX_ADSW_CHANNEL=4
	{ 
		PAPER.sensor_adc[i] = GetPaperSensorAdc(2);
		sum += PAPER.sensor_adc[i];
	}
	for(i=0;i<(MAX_FILTER_COUNT - 1);i++)
	{
		PAPER.adc_filter[i] = PAPER.adc_filter[i+1];
	}

    sum1=KalmanFilter(&KFP_height,(double)sum);//卡尔曼滤波
//	MyPrintf("sum1=%d \n",sum1);
	PAPER.adc_filter[i] = sum1;
//  MyPrintf("i=%d \n",i);
	

	

#if 0
	for(i=0;i<MAX_ADSW_CHANNEL;i++)
	MyPrintf("%d ",PAPER.sensor_adc[i]);
	MyPrintf("%d ",sum);
	MyPrintf("%d ",sum1);
	MyPrintf("\n");	
#endif	
}

void GetPaperState(void)
{

	PushSensorAdc(PAPER.type);          //采集检纸传感器的ADC,并存入BUFF备用-

	PAPER.last_gap_state = PAPER.current_gap_state;

	PAPER.current_gap_state = PaperFilter(&PAPER.adc_filter[0],MAX_FILTER_COUNT);

	//MyPrintf("PAPER.current_gap_state=%d\n",PAPER.current_gap_state);
}

//原始代码
void PaperCalibrate(void)
{
	PAPER.calibrate_state = 0;
	PAPER.move_ctl_state = GAP_CALIBRATE;
	MOTOR.bLFForward = 1;	
	StartKeyFeedPaper(1600,LFconst);

	WaitMotorStop();

	if(PAPER.move_ctl_state == GAP_CALIBRATE)
	{

		LCD_Dsp_AutoCal_Doing(2);            //标定失败
	}
	else
	{
		LCD_Dsp_AutoCal_Doing(1);           //标定成功
	}

}


///*------------------------------------------------------------------------自动标定
void PaperCalibrate_1(void)
{
	PAPER.calibrate_state = 0;
//	if(PAPER.type==E_PAPER_TYPE_HOLD)               //如果是定位孔纸就走到定位孔
//	   PAPER.move_ctl_state = GAP_MOVE_PAPTER_TO_HOLD;
//	else
		PAPER.move_ctl_state = GAP_CALIBRATE;
	
	MOTOR.bLFForward = 1;	
	//one_dotline_lfstep_num=ONEDOTSTEPNUM;
	StartKeyFeedPaper(2500,LFconst);               //当步数设置为1600步时,2538-90的间隙纸定标会失败 ,设置到2000就不会定标失败 

	WaitMotorStop();  
//	if(PAPER.calibrate_state == 0)//说明没有顶到标,那就是连续纸.
//	{
//	
//		PAPER.type=E_PAPER_TYPE_CONTINUE;                       屏蔽的原因是:不去改变设置的纸张类型
//		MyPrintf("PAPER.type = %d\n",PAPER.type);
//	}

	if(PAPER.move_ctl_state == GAP_CALIBRATE)         //定标
	{
		if(PAPER.calibrate_error_flag==1&&LCD_MENU_ERROR != menu_state&& PAPER.type!=E_PAPER_TYPE_HOLD)          //纸张类型设置为间隙纸,装入其它类型的纸时
		{
			menu_state = LCD_MENU_ERROR;
			PAPER.auto_calibrate_flag =0; 
			LCD_DspUndetectedGapPaper(); 
			PAPER.calibrate_error_flag=0;
		//	MyPrintf("GAP_CALIBRATE_1\n");
		//	menu_state = LCD_MENU_MAIN;
		}
		else
		{
			PAPER.auto_calibrate_flag =0;      
			LCD_Dsp_AutoCal_Doing(2);         //标定失败
	//		MyPrintf("GAP_CALIBRATE_2\n");
	//		menu_state = LCD_MENU_MAIN;
		}
	}
	else       //不是标定
	{
	//	MyPrintf("123_4_5\n");
		PAPER.auto_calibrate_flag =0;
		LCD_Dsp_AutoCal_Doing(1);        //标定成功
	}

}

//*/

/*******************************************************************************
** Function name:      
**
** Descriptions :     test paper status     自动定标的时候循环执行此函数(马达定时器中调用)  改变纸张的位置
**  
******************************************************************************/
void ChangePaperPos(void)
{
	if(MOTOR.bLFForward ==0)//反转的时候就不检测纸张的状态  
	{
    		return;
	}
	GetPaperState();        //获取纸张的间隙状态 PAPER.current_gap_state
//	MyPrintf("move_ctl_state=%d \n",PAPER.move_ctl_state);
	switch(PAPER.move_ctl_state)
	{
		case GAP_IDE:

#if 1
			if(PAPER.current_gap_state == PAPER_FILTER_UP && PAPER.paper_start_offset_flag == 0)
			{
				PAPER.paper_start_offset_flag = 1;	
				PAPER.paper_start_offset = 0;
				Key_Feed_Line_flag = 0;
				f_lable_printing = 0;
//				f_lable_print_end = 1;
//				PAPER.move_to_cut_flag =0; 
//				MyPrintf("cut_1\n");
			//	if(PAPER.move_to_cut_flag)       //此标志主要用于标记打印中字样什么时候清屏_
		
			}
			else if(PAPER.current_gap_state == PAPER_FILTER_DOWM && PAPER.paper_start_offset_flag == 1)
			{
				PAPER.paper_start_offset_flag = 0;	
				PAPER.paper_start_offset = 0;
				PAPER.paper_end_flag = 1;
				Key_Feed_Line_flag = 0;
//				MyPrintf("cut_2\n");
	//			MyPrintf("GAP_IDE_PAPER_FILTER_DOWM \n" );
			}
			else      //安卓刚启动打印时进来     有驱每执行1次0X16指令就进来执行1次
			{
//				MyPrintf("cut_3\n");     //IOS每一点行都进来
				Key_Feed_Line_flag = 0;
			       //MyPrintf("PAPER.paper_start_offset(INPos)=%d \n",PAPER.paper_start_offset);
				PAPER.paper_start_offset += one_dotline_lfstep_num;
			}
#endif
			break;
		case GAP_MOVE_PAPTER_TO_TPH: //寻纸到加热线    
			iOffsetSum++;
//			MyPrintf("iLFStepNum=%d\n",MOTOR.iLFStepNum);
			if(PAPER.current_gap_state == PAPER_FILTER_UP && PAPER.last_gap_state != PAPER_FILTER_HOLD)
			{
//				MyPrintf("cut_4_1\n");
				MOTOR.iLFStepNum	= DIS_GAP_TO_TPH;
				PAPER.move_ctl_state = GAP_IDE;			
				Key_Feed_Line_flag = 0;
			}
		    else if((MOTOR.iLFStepNum<5)/*||(f_error_no_paper)*/)
			{
				f_error_no_paper=1;

				f_printer_error = 1;
				f_lable_printing = 0;
		//		f_lable_print_end = 1;
				Key_Feed_Line_flag = 0;
	//			PAPER.move_ctl_state = GAP_IDE; 
			//	MyPrintf("cut_4_2\n");
			}		
			if(f_error_no_paper)
			{
				f_printer_error = 1;
				f_lable_printing = 0;
	//			f_lable_print_end = 1;
				PAPER.move_ctl_state = GAP_IDE; 
				Key_Feed_Line_flag = 0;
		//		MyPrintf("cut_4_3\n");
			}                 
			break;		
		case GAP_MOVE_PAPTER_TO_CUT://寻纸到切纸位置           //右键走纸时第一步进来了 (current_gap_state开始=0直到检测间隙位=2 再到离开间隙位=1 ,再=0)
//		    MyPrintf("cut_5\n");
		//    MyPrintf("iLFStepNum=%d\n",MOTOR.iLFStepNum);
		   
			if(PAPER.current_gap_state == PAPER_FILTER_UP && PAPER.last_gap_state != PAPER_FILTER_HOLD)
			{
			  MOTOR.iLFStepNum	= (DIS_GAP_TO_TPH+DIS_TPH_TO_CUT);  //DIS_TPH_TO_CUT =138      DIS_GAP_TO_TPH =276
			//		MyPrintf("iLFStepNum=%d\n",MOTOR.iLFStepNum);
				PAPER.move_ctl_state = GAP_IDE; 
				f_lable_printing = 0;				
				Key_Feed_Line_flag = 0;
		//		MyPrintf("get to cut\n");			
			}
			else if(/*(Key_Feed_Line_flag == 1)||*/(MOTOR.iLFStepNum<5))      //走纸时未检测到间隙纸且步数走完(打印机装入连续纸,纸张类型设置为间隙纸时检测)
			{
				   if(Key_Feed_Line_flag)     //右键走纸
				   {
						f_printer_error = 1;
						Key_Feed_Line_flag = 0;
						f_lable_printing = 0;
						UndetectedGapPaper_Flag = 1;
				   }
				   else
				   {
						if(page_tatal != pape_current||f_lable_printing ==1||f_rcv_data==1)   //打印过程
						{
							//f_error_no_paper = 1;
							f_printer_error = 1;
						//	MyPrintf("cut_5\n");
						}
						else
						{
							//if(page_tatal == pape_current)
							{
								f_printer_error = 1;
								Key_Feed_Line_flag = 0;
								f_lable_printing = 0;
								UndetectedGapPaper_Flag = 1;
							}
						}
					}
				
			}
			if(f_error_no_paper)
			{
				PAPER.move_ctl_state = GAP_IDE; 
				Key_Feed_Line_flag = 0;
				f_lable_printing = 0;
			}
			break;	
		case GAP_MOVE_PAPTER_TO_HOLD:
//			 MyPrintf("PaperAdc=%d\n",PAPER.PaperAdc);
			
			if(PAPER.PaperAdc<1100)
			{
			//  MOTOR.iLFStepNum	= (DIS_GAP_TO_TPH+DIS_TPH_TO_CUT);  //DIS_TPH_TO_CUT =138      DIS_GAP_TO_TPH =276
				MOTOR.iLFStepNum	= (DIS_GAP_TO_TPH+230);
				PAPER.move_ctl_state = GAP_IDE;
				UndetectedHoldPaper=0;
				Key_Feed_Line_flag = 0;
				f_lable_printing = 0;
		//		MyPrintf("hold_11\n");			
			}
			else if(MOTOR.iLFStepNum<5)      //步数走完了还没检测到定位孔就报错
			{
				if(Key_Feed_Line_flag)     //右键走纸
			   {
					f_printer_error = 1;
					UndetectedHoldPaper=1;        //没检查到定位孔纸
					Key_Feed_Line_flag = 0;
					f_lable_printing = 0;
			   }
			   else
			   {
				//	MyPrintf("hold_22\n");	
					if(/*f_lable_printing ==1||*/f_rcv_data==1||page_tatal != pape_current)   //打印过程
					{
					//	MyPrintf("f_lable_printing=%d\n",f_lable_printing);
						//f_error_no_paper = 1;
						f_printer_error = 1;
					//	MyPrintf("cut_5\n");
					}
					else
					{
					//	 MyPrintf("cut_666\n");   
					//	if(page_tatal == pape_current)
						{
					//		f_error_no_paper = 1;
							f_printer_error = 1;
							UndetectedHoldPaper=1;        //没检查到定位孔纸
							Key_Feed_Line_flag = 0;
							f_lable_printing = 0;
						 
						}
					}
				}
			}
			if(f_error_no_paper)
			{
			//	PAPER.move_ctl_state = GAP_IDE; 
				f_lable_printing = 0;
				Key_Feed_Line_flag = 0;
			}
			break;
		case GAP_CALIBRATE://纸张校准校准

			if(PAPER.calibrate_state == 0)//
			{
//				MyPrintf("iLFStepNum=%d\n",MOTOR.iLFStepNum);
				if(PAPER.PaperAdc<1100)
				{
//					MyPrintf("type= %d\n",PAPER.type);
					if(PAPER.type==E_PAPER_TYPE_HOLD)
					{
//						MyPrintf("gap_11\n");
						PAPER.calibrate_state = 1;
						MOTOR.iLFStepNum	= (DIS_GAP_TO_TPH+230);
						PAPER.move_ctl_state = GAP_IDE;
					}
					else
					{
//						MyPrintf("gap_22\n");
						MOTOR.iLFStepNum	= (DIS_GAP_TO_TPH+DIS_TPH_TO_CUT);
						PAPER.calibrate_error_flag = 1;
					}
		//		  PAPER.move_ctl_state = GAP_IDE;				
				}
				else if(MOTOR.iLFStepNum<5)      //步数走完了还没检测到定位孔就报错
				{
//					MyPrintf("gap_aaa\n");
					//MOTOR.iLFStepNum	= (DIS_GAP_TO_TPH+DIS_TPH_TO_CUT);
					PAPER.calibrate_error_flag = 1;
				}
				else if(PAPER.current_gap_state == PAPER_FILTER_UP && PAPER.last_gap_state == PAPER_FILTER_HOLD && PAPER.type!=E_PAPER_TYPE_HOLD)
				{
//					MyPrintf("gap_33\n");
					PAPER.calibrate_state = 1;//间隙纸
					PAPER.adj_paper_size = 0; 
					PAPER.adj_gap_size = 0;
//					MyPrintf("find paper start\n");
				}
			
			}
			else if(PAPER.calibrate_state == 1)
			{
//				MyPrintf("gap_44\n");
				PAPER.adj_paper_size += one_dotline_lfstep_num;
				if(PAPER.current_gap_state == PAPER_FILTER_DOWM && PAPER.last_gap_state == PAPER_FILTER_HOLD)
				{
					PAPER.calibrate_state = 2;
//					MyPrintf("find paper end\n");
				}

			}
			else if(PAPER.calibrate_state == 2)
			{
//				MyPrintf("gap_55\n");
				PAPER.adj_gap_size += one_dotline_lfstep_num;
				if(PAPER.current_gap_state == PAPER_FILTER_UP && PAPER.last_gap_state == PAPER_FILTER_HOLD){
					MOTOR.iLFStepNum	= (DIS_GAP_TO_TPH+DIS_TPH_TO_CUT);
					PAPER.move_ctl_state = GAP_IDE;
									
					PAPER.auto_cal_type = E_AUTO_CAL_TYPE_CONTINUE;
					PAPER.type=E_PAPER_TYPE_GAP;             
					
           // MyPrintf("PAPER.type = %d\n",PAPER.type);
		      //		MyPrintf("paper size = %d\n",PAPER.adj_paper_size);
         //					MyPrintf("gap size = %d\n",PAPER.adj_gap_size);
				}

			}
			break;	
	}

}
//--------------------------------------------------------------------------------------------
/********************************低电压的检测模式*********************************/
//-----------------------------------------------------------------------------------------------
#define  lowpower_debug   0  

uint8_t stopBatteryFlag = 0;
void BatPolling(unsigned char flag)
{
	static uint8_t counter=0,con1=0 ,i=0,con2=0,ii=0;
	static uint16_t Bat_adc_buffer[5]={0},buf1;           //给电池显示刷新
	static uint16_t Bat_adc_buffer2[5]={0};               //给电量低检测
	static uint8_t lowpowertimes=0;       //检测低电压次数
	static uint8_t lowpowertimes2=0;       //检测低电压次数2
	uint8_t *img_ptr;
//	MyPrintf("BatPolling_1111\r\n");
	if(flag ==1)
	{
		if(EXT_DEV.bat_scan_time )	
		{
			return;
		}
		EXT_DEV.bat_scan_time = 10;	
	}

	if(con1<4)
	{
		con1++;
	}
	  
	if(con1<4)
	{
	//	con1++;
		for(i=0;i<5;i++)
		{
			Bat_adc_buffer[i]=ADC_GetResult(ADC_CH_BAT);
		//	i++;
	//		Bat_adc_buffer[i]=buf1;
//			MyPrintf("Bat_adc_buffer[i]= %d\n",Bat_adc_buffer[i]);
		}
//		EXT_DEV.bat_adc = ADC_GetResult(ADC_CH_BAT);
		EXT_DEV.bat_adc=(Bat_adc_buffer[4]+Bat_adc_buffer[3]+Bat_adc_buffer[2]+Bat_adc_buffer[1]+Bat_adc_buffer[0])/5;
	}
	else
	{
		Bat_adc_buffer[4]=Bat_adc_buffer[3];
		Bat_adc_buffer[3]=Bat_adc_buffer[2];
		Bat_adc_buffer[2]=Bat_adc_buffer[1];
		Bat_adc_buffer[1]=Bat_adc_buffer[0];
	//	Bat_adc_buffer[0]=buf1;
		Bat_adc_buffer[0]=ADC_GetResult(ADC_CH_BAT);
		EXT_DEV.bat_adc=(Bat_adc_buffer[4]+Bat_adc_buffer[3]+Bat_adc_buffer[2]+Bat_adc_buffer[1]+Bat_adc_buffer[0])/5;
  }
	
	EXT_DEV.bat_level = GetBatLevel(EXT_DEV.bat_adc);              //给电池图标刷新使用
  //---------------------------------------------------------------	
	if(con2<5)
	{
		con2++;
	  Bat_adc_buffer2[ii]=ADC_GetResult(ADC_CH_BAT);
		ii++;
		return;
  }
	 con2 = 0;
	 ii = 0;
	EXT_DEV.bat_adc2=(Bat_adc_buffer2[4]+Bat_adc_buffer2[3]+Bat_adc_buffer2[2]+Bat_adc_buffer2[1]+Bat_adc_buffer2[0])/5;
//	MyPrintf("bat_adc2=%d\r\n",EXT_DEV.bat_adc2);
	EXT_DEV.bat_level2 = GetBatLevel(EXT_DEV.bat_adc2);                 //给检测电量低使用
#if(lowpower_debug)

	if(counter<99)
	{
       	counter++;		
	}
	else
	{
		counter=0;
	}

	 if(counter>=50)
	 {
		EXT_DEV.bat_level=1;
	 }
        else
        {
		EXT_DEV.bat_level=0;
	 }

#endif


#if 0
	
#else
	if(BOARD_KEY.ProcessTime4==0)  //按键按下之后ProcessTime4赋值并开始递减计时
	{
		if(EXT_DEV.bat_level == 0)
		{		
 //   MyPrintf("BatPolling_1\r\n");
			lowpowertimes++;
	
			if((f_lable_printing)||(f_rcv_data==1)||(MOTOR.bLFMotorMove))         //打印过程中检测30次
			{
				if(lowpowertimes>=30)
				{
			//		if(EXT_DEV.usb_pugin_flag == 0)    //USB没插或者usb插的不是插适配器    ||(EXT_DEV.usb_pugin_flag == 1&&EXT_DEV.usb_link_flag==1)
					
					{
						f_error_Voltage_low=1;//电量低状态
			//			LCD.main_menu_resume_time = 0;
						lowpowertimes=0;
						f_lable_printing = 0;   					
						f_printer_error=1;
						LCD.main_menu_resume_time = 0;    //作用是递减完之后回到主界面
		//				MyPrintf("bat_adc2=%d\r\n",EXT_DEV.bat_adc2);
				//		MyPrintf("BatPolling_2\r\n");
					}	
			  }
			}
			else                         //不在打印状态时检测10次
			{
				if(lowpowertimes>=12)
				{
			//		if(EXT_DEV.usb_pugin_flag == 0)    //USB没插或者usb插的不是插适配器    ||(EXT_DEV.usb_pugin_flag == 1&&EXT_DEV.usb_link_flag==1)
					{
						f_error_Voltage_low=1;//电量低状态
		//				LCD.main_menu_resume_time = 0;  
						lowpowertimes=0;
						f_lable_printing = 0;
						f_printer_error=1;
						LCD.main_menu_resume_time = 0;    //作用是递减完之后回到主界面
				//		MyPrintf("BatPolling_2\r\n");
					}	
				}
		  }
		
//		if(EXT_DEV.usb_pugin_flag == 1&&EXT_DEV.usb_link_flag==0)       //检测到插上适配器时取消电量低提示
//		{
//			f_error_Voltage_low=0;
//			lowpowertimes=0;
//			f_printer_error=0;
//			LCD.main_menu_resume_time= 0;
//			LCD_Main();
//	//		MyPrintf("BatPolling_3\r\n");
//		}
			if(!f_printer_error)               //检测到低电量并且有插适配器的时
			{
				extern uint8_t stopFlag;
				stopBatteryFlag = 1;//
				stopFlag= 1;
	//			MyPrintf("stopFlag_4\r\n");
			}
		
	    //stopFlag = 1;    
		//MOTOR.iLFStepNum=0;
		//PrtBuf[cCurrentPrtCharLine].Status=Empty;
		//MOTOR.bLFMotorMove = 0;

//		MyPrintf("EXT_DEV.bat_level = %d\n",EXT_DEV.bat_level);
//		MyPrintf("f_printer_error=1 \r\n");
	       
	}
//	else if(EXT_DEV.bat_level > 1)//
//	else if(EXT_DEV.bat_adc2 > 1705)	                 //这个数值很重要,取低了会导致插上USB时,电量低一下子就消失,取高了又会导致打印过程容易提示电量低
		else if(EXT_DEV.bat_adc>1705)
		{
	//		MyPrintf("BatPolling_5\r\n");
			lowpowertimes=0;
			if(f_error_Voltage_low==1)
			{	
				f_error_Voltage_low=0;
				
				if((!(error_state.byte[0] & 0xFE)) && (!(error_state.byte[1] & 0x18)))
				{
					f_printer_error = 0;
					
				}
			}
		}
	}
#endif
 //   MyPrintf("error_state.byte[0] = %d\n",error_state.byte[0]);
	//MyPrintf("error_state.byte[0] = %d\n",error_state.byte[0]);
	//MyPrintf("transfer_state.byte = %d\n",transfer_state.byte);
	//MyPrintf("EXT_DEV.bat_adc = %d\n",EXT_DEV.bat_adc);	
	//MyPrintf("EXT_DEV.bat_level = %d\n",EXT_DEV.bat_level);
	//MyPrintf("EXT_DEV.bat_error_flag = %d\n",EXT_DEV.bat_error_flag);

}




//检测USB插拔------------------------------------------------------
void UsbPluginPolling(unsigned char flag)
{

	static uint8_t usb_push_in_state;          //USB插入状态
	
	if(flag==1)
	{
		if(EXT_DEV.usb_scan_time)	return;
		EXT_DEV.usb_scan_time = 30;      //300毫秒
	}

//  	MyPrintf("UsbPluginPolling\n");
	usb_push_in_state <<= 1;
//	MyPrintf("usb_push_in_state= %d\n",usb_push_in_state);
	usb_push_in_state |= CHARGE_InsertDet();  
//	MyPrintf("usb_pugin_flag= %d\n",EXT_DEV.usb_pugin_flag);
	if(EXT_DEV.usb_pugin_flag == 0 && usb_push_in_state == 0xff)    
	{
		EXT_DEV.usb_pugin_flag = 1;           //适配器和USB线插上都是1
	
//		MyPrintf("usb in\n");
		
		//if(EXT_DEV.usb_link_flag==0)
		//{
		//	charge_enable();
	//		MyPrintf("charge enable\n");
		//}

	}
	else if(EXT_DEV.usb_pugin_flag && usb_push_in_state == 0)      //USB没连接
	{
		EXT_DEV.usb_pugin_flag = 0;
	
//		MyPrintf("usb out\n");
		EXT_DEV.usb_link_flag=0;
	//	MyPrintf("charge_disable\n");
		//charge_disable();
	}

//   MyPrintf("usb_link_flag= %d\n",EXT_DEV.usb_link_flag);
//	if(EXT_DEV.usb_pugin_flag == 1&&EXT_DEV.usb_link_flag==1)         //USB已插上,且没有数据通信   插上适配器时usb_link_flag= 0  插上USB时usb_link_flag= 1
	if(EXT_DEV.usb_pugin_flag == 1)
	{
		charge_enable();                   //开启充电
		//MyPrintf("charge enable\n");
		EXT_DEV.charging_flag=ChargeState_Get();
	}
	else
	{
//		EXT_DEV.usb_pugin_flag = 0;
		charge_disable();
	//	MyPrintf("charge disable_22\n");
		 EXT_DEV.charging_flag=NOCHARGE;             //#define  NOCHARGE      3  不充电
	}
	
}


#define charge_ok    0   


uint8_t ChargeState_Get(void)
{
	uint8_t charge_state = 0;

	uint8_t k1=0;
	
	//充电状态  
	charge_state = CHARGE_InsertDet();      //检测外电插入
	
	//MyPrintf("state:%d\r\n",charge_state);
	
	//充电状态  
	if(charge_state)          //有外电插入
	{

#if(charge_ok)	
		//高电平  
		if(GET_CHARGE_STATE)
#else
		if(!GET_CHARGE_STATE)
#endif		
		{
			k1=CHARGE_FILL;
		}
		else 
		{
			
			k1=CHARGING;
		}
	}
	else 
	{
	
		k1=NOCHARGE;
	}

	return (k1);

	
}

//---------------------------------------------打印温度查询-----------
#define  three_min     (18000)
uint8_t stopTemperatureFlag = 0;
void TPH_Temp_Polling(unsigned char flag)
{

	static unsigned int adc_buf[5]={0},databufer=0;
  static unsigned char counter=0;
	static unsigned char i=0;
//  MyPrintf("TPH_Temp_Polling_\n");
	if(flag==1)                        //300ms查询1次
	{
		if(EXT_DEV.tph_scan_time)	
		{
			return;
		}
		EXT_DEV.tph_scan_time = 30;
	}
	if(counter<4)
	{
		counter++;
	}     
#if 1	
//   databufer= ADC_GetResult(ADC_CH_TM);              //ADC_CH_TM = 3
	if(counter<4)
	{
			for(i=0;i<5;i++)
			{
			//	adc_buf[i]=databufer;
				adc_buf[i]=ADC_GetResult(ADC_CH_TM);
			}
	}
 else
	{	
		adc_buf[4]=adc_buf[3];
		adc_buf[3]=adc_buf[2];
		adc_buf[2]=adc_buf[1];
		adc_buf[1]=adc_buf[0];
		adc_buf[0]=ADC_GetResult(ADC_CH_TM);
  }      
/*	if(counter<5)
	{
		counter++;
	  adc_buf[i]=ADC_GetResult(ADC_CH_TM);
		i++;
		return;
  }
	 counter = 0;
	 i = 0;          */
	TPH.TemperatrueAdc =(adc_buf[0]+adc_buf[1]+adc_buf[2]+adc_buf[3]+adc_buf[4])/5;


//	MyPrintf("TemperatrueAdc = %d\n",TPH.TemperatrueAdc);//adc检测缝隙传感器平均值

	get_tem(TPH.TemperatrueAdc);	//打印信息

	//	if(TPH.TemperatrueAdc > 2000 && f_error_printer == 0)
	//	{
	//		f_error_printer = 1;
	//	}
	//	else if(TPH.TemperatrueAdc <= 2000 && f_error_printer == 1)
	//	{
	//		f_error_printer = 0;
	//	}


#if 0

/*打印头温度控制*/


#else
//    MyPrintf("Thermistor_ADC = %d\n",Thermistor_ADC[EEROR_TPH_TEMP_INDEX]);//adc检测缝隙传感器平均值
		if(TPH.TemperatrueAdc <= Thermistor_ADC[EEROR_TPH_TEMP_INDEX])//温度值大于65    EEROR_TPH_TEMP_INDEX	       15: Thermistor_ADC[EEROR_TPH_TEMP_INDEX]=1051
		{
	//		MyPrintf("bErrTemperature_errow\n");

			if(f_error_tph_temp == 0)//错误状态
			{
	//			MyPrintf("1111111111f_error_tph_temp \n %s ",f_error_tph_temp);
				f_error_tph_temp = 1;
//				LCD.main_menu_resume_time = 0;
				EXT_DEV.hight_tem_release_counter=three_min;
			}else{//出现错误
//       MyPrintf("222222222\n");
			}
			if(!f_printer_error)//传输没有错
			{
				extern uint8_t stopFlag;
				stopTemperatureFlag = 1;
				stopFlag= 1;
	//			MyPrintf("333333333f_printer_error\n",f_printer_error);
			}
			f_printer_error = 1;
	//		MyPrintf("4444444444\n");			
		}
		else if(TPH.TemperatrueAdc > Thermistor_ADC[EEROR_THP_RESUME_INDEX])   //EEROR_THP_RESUME_INDEX =14   50°
		{
			if(f_error_tph_temp==1)
			{
				f_error_tph_temp = 0;

				if((!(error_state.byte[0] & 0xFE)) && (!(error_state.byte[1] & 0x18)))
				{
					f_printer_error = 0;
				}
			}
		}

#endif
	
#endif
	
}


//获取打印头温度

void get_tem(unsigned int tem)
{

   unsigned char i=0;

	 signed char mm=0;
	   
	for(i=0;i<20;i++)
	{

		if(tem>Thermistor_ADC[i])
		{
              	break;
		}
		
	}

       mm=-20+i*5;
//  MyPrintf("tem = %d!!!!!!!!!!!!!!!!!!!\r\n", tem);
//	MyPrintf("temp_adc = %d!!!!!!!!!!!!!!!!!!!\r\n", mm);	
}




//#define nopaper_counter  5
#define nopaper_counter  ((PAPER.type ==E_PAPER_TYPE_HOLD)?6:3)
uint8_t noPaperFlag = 0;
uint8_t noYesPaperFlag = 0;
//---------------------------------------------------------------------------------------------------
/********************************************************************************************************
********  传感器查询是否有纸,  上电一直查询  ********************************   
*********************************************************************************************************/                                         
//--------------------------------------------------------------------------------------------------
void Paper_Det_Polling(unsigned char flag)       
{

	uint16_t temp_adc;
//	static	uint8_t noPapertimes ;
  static	uint8_t noPaperFlagNO ;
	static	uint8_t noPaperFlagNOT;
	static uint8_t no_paper_count =0;
	static unsigned int Paper_adc_buf[3]={0};
	unsigned char ii = 0;
	
	if(Paper_Use_Up_Flag) return;
	if(flag==1)
	{
		if(EXT_DEV.no_paper_scan_time)	return;
		EXT_DEV.no_paper_scan_time = 5;
	}
	
//	MyPrintf("Paper_Det_Polling_\n");		
  //判断间隙纸在纸张长度内没有检测到缝隙==判定为没有纸张
//	if(PAPER.adj_paper_size){
//	
//	}
	for(ii=0;ii<3;ii++)
	{
		Paper_adc_buf[ii] = GetPaperSensorAdc(2);
	}
	//temp_adc = GetPaperSensorAdc(2);
	PAPER.PaperAdc =(Paper_adc_buf[0]+Paper_adc_buf[1]+Paper_adc_buf[2])/3;
	temp_adc =PAPER.PaperAdc; 
//	MyPrintf("temp_adc=%d \n",temp_adc);
/*  
	if(1100<temp_adc&&temp_adc<1500){//检测到间隙
	   noPaperFlagNO=1;
		// MyPrintf("1111111111111111111 \n",temp_adc);
		
		}else{//
		 noPaperFlagNO=0;
		 //MyPrintf("22222222222222222 %d \n",temp_adc);
		
		}
	noYesPaperFlag++;
  if(noYesPaperFlag%20==0){
	   if(noPaperFlagNO==1&&f_lable_printing==1){
		//	MyPrintf("···················2222222222222222222 %d \n",noYesPaperFlag);
			 noPaperFlagNOT++;
			  
	    }else{
				noPaperFlagNOT=0;
			}
		 }
 
//	MyPrintf("temp_adc %d \n",temp_adc);
	if(temp_adc<1100||noPaperFlagNOT>1)//纸的间隙1100   */  
 //if(BOARD_KEY.FCancelWrongOrders!=1 )         if(LCD.main_menu_resume_time == 0)          
 if(LCD.nopaper_resume_time==0)
 {
	  BOARD_KEY.FCancelWrongOrders=0;
		if(temp_adc<1100)
		{
			no_paper_count++;
			if((no_paper_count>=nopaper_counter)&&(!f_error_Voltage_low))          //电量低的情况下缺纸,会导致显示电量低字样不全
			{
				no_paper_count = 0;
				if(BOARD_KEY.ProcessTime4==0)  //按键按下之后ProcessTime4赋值并开始递减计时,
				{
					f_error_no_paper = 1;
					Key_Feed_Line_flag = 0;
					No_paper_flag = 1;
				//	LCD.time_event6_50ms = 5;
				//	error_state.byte[0] |= 1<<2;
					LCD.main_menu_resume_time = 0;    //作用是递减完之后回到主界面
				//	menu_state = LCD_MENU_ERROR;    //在这里给menu_state赋值LCD_MENU_ERROR不会报缺纸,也不会回主界面显示
				}
				
				Can_Be_Calibrated_Flag = 1;
				f_printer_error = 1;
				
	//      LCD_DspNoPaper();             //显示未检测到纸
				extern uint8_t stopFlag;
				stopFlag = 1;

				//下边是没有纸的动作			
		//_		InitRcvBuf();//清空内存
		//		PrtStbAllStatus(0);
				MOTOR.iLFStepNum=0;
				PrtBuf[cCurrentPrtCharLine].Status=Empty;
				MOTOR.bLFMotorMove = 0;
				f_lable_printing=0;
				f_lable_print_end = 1;	
			
			}
		}
		else
		{
	//		MyPrintf("···················44444444444444 \n");
            Can_Be_Calibrated_Flag = 0;			
			no_paper_count = 0;
			
		//	   menu_state = LCD_MENU_MAIN;         //增加这一句会导致显示屏在按键界面跳到缺纸显示时出现乱码
			if(No_paper_flag)
			{
			//	if(f_error_no_paper == 1)
				{
					noPaperFlag = 1;
				}
				f_error_no_paper = 0;
				No_paper_flag = 0;
				if((!(error_state.byte[0] & 0xFE)) && (!(error_state.byte[1] & 0x18)))
				{
					f_printer_error = 0;
					EXT_DEV.print_err_release_delay_counter=200;
				}
	#ifdef USE_LCD
//				LCD_Clear_Bmp(BMP_DEVICE_FLAG_MAP[E_BMP_NO_PAPER]);     
	#endif
			}
			
		}
  }
  if(f_lable_printing==1&&temp_adc<1100)
		BOARD_KEY.FCancelWrongOrders=0;
}

//---------------------------------------------------------------------------------------------------
/*   检测USB插拔情况 ,调用查询是否有纸张的函数                                                            */
//--------------------------------------------------------------------------------------------------

//delay_flage=1 间隔一定时间采样
//delay_flage=0  立即采样
void PollingExtDev(unsigned char delay_flage)
{
	//BatPolling(delay_flage);
	//TPH_Temp_Polling(delay_flage);
	UsbPluginPolling(delay_flage);//检测USB插拔
	Paper_Det_Polling(delay_flage);//查询是否有纸的动作     PollingExtDev     PollingExtDev_1
	
#if 0
	
	MyPrintf("transfer_state=0x%02X\n",transfer_state.byte);
	MyPrintf("error_state0=0x%02X\n",error_state.byte[0]);
	MyPrintf("error_state1=0x%02X\n",error_state.byte[1]);
	
#endif
}

//下边这个量很容易受到影响,比如打印影响,比如电机走动的影响
void PollingExtDev_1(unsigned char delay_flage)
{
	BatPolling(delay_flage);//电池电量低
	//TPH_Temp_Polling(delay_flage);

	//UsbPluginPolling(delay_flage);
	//Paper_Det_Polling(delay_flage);
	
#if 0
	
	MyPrintf("transfer_state=0x%02X\n",transfer_state.byte);
	MyPrintf("error_state0=0x%02X\n",error_state.byte[0]);
	MyPrintf("error_state1=0x%02X\n",error_state.byte[1]);
	
#endif
}


//下边这个量很容易受到影响,比如打印影响,比如电机走动的影响
void PollingExtDev_2(unsigned char delay_flage)
{
	//BatPolling(delay_flage);
	TPH_Temp_Polling(delay_flage);//打印头过热

	//UsbPluginPolling(delay_flage);
	//Paper_Det_Polling(delay_flage);
	
#if 0
	
	MyPrintf("transfer_state=0x%02X\n",transfer_state.byte);
	MyPrintf("error_state0=0x%02X\n",error_state.byte[0]);
	MyPrintf("error_state1=0x%02X\n",error_state.byte[1]);
	
#endif
}





/**
* @brief Init_KalmanInfo   初始化滤波器的初始值
* @param info  滤波器指针
* @param Q 预测噪声方差 由系统外部测定给定
* @param R 测量噪声方差 由系统外部测定给定
*/
void Init_KalmanInfo(KalmanInfo* info, double Q, double R)
{
	info->A = 1;  //标量卡尔曼
	info->H = 1;  //
	info->P = 10;  //后验状态估计值误差的方差的初始值(不要为0问题不大)
	info->Q = Q;    //预测(过程)噪声方差 影响收敛速率,可以根据实际需求给出
	info->R = R;    //测量(观测)噪声方差 可以通过实验手段获得
	info->filterValue = 0;// 测量的初始值
}
double KalmanFilter(KalmanInfo* kalmanInfo, double lastMeasurement)
{
	//预测下一时刻的值
	double predictValue = kalmanInfo->A* kalmanInfo->filterValue;   //x的先验估计由上一个时间点的后验估计值和输入信息给出,此处需要根据基站高度做一个修改
	
	//求协方差
	kalmanInfo->P = kalmanInfo->A*kalmanInfo->A*kalmanInfo->P + kalmanInfo->Q;  //计算先验均方差 p(n|n-1)=A^2*p(n-1|n-1)+q
	double preValue = kalmanInfo->filterValue;  //记录上次实际坐标的值
 
	//计算kalman增益
	kalmanInfo->kalmanGain = kalmanInfo->P*kalmanInfo->H / (kalmanInfo->P*kalmanInfo->H*kalmanInfo->H + kalmanInfo->R);  //Kg(k)= P(k|k-1) H’ / (H P(k|k-1) H’ + R)
	//修正结果,即计算滤波值
	kalmanInfo->filterValue = predictValue + (lastMeasurement - predictValue)*kalmanInfo->kalmanGain;  //利用残余的信息改善对x(t)的估计,给出后验估计,这个值也就是输出  X(k|k)= X(k|k-1)+Kg(k) (Z(k)-H X(k|k-1))
	//更新后验估计
	kalmanInfo->P = (1 - kalmanInfo->kalmanGain*kalmanInfo->H)*kalmanInfo->P;//计算后验均方差  P[n|n]=(1-K[n]*H)*P[n|n-1]
 
	return  kalmanInfo->filterValue;
}//























//                                   Sensor.h




#include "type.h"

#ifndef _SENSOR_H_

#define _SENSOR_H_



extern unsigned char UndetectedGapPaper_Flag ;
extern unsigned char UndetectedHoldPaper;
extern UCharField transfer_state;
//传输状态
#define f_transfer_state_bit0	transfer_state.field.B0
#define f_transfer_state_bit1	transfer_state.field.B1
#define f_lable_printing		transfer_state.field.B2
#define f_lable_print_end		transfer_state.field.B3
#define f_printer_error			transfer_state.field.B4               有报错的时候f_printer_error不置1时PC端不会查询错误状态,所以报错不会取消打印
#define f_printer_pause			transfer_state.field.B5
#define f_print_canncel			transfer_state.field.B6              //打印被取消
#define f_transfer_state_bit7	transfer_state.field.B7
//错误状态
extern UshortField error_state;
#define f_error_state_bit0		error_state.field.B0
#define f_error_get_gap			error_state.field.B1
#define f_error_no_paper		error_state.field.B2          //没纸
#define f_error_head_open		error_state.field.B3          //上盖打开
#define f_error_printer			error_state.field.B4          
#define f_error_tph_temp		error_state.field.B5          //打印头过热
#define f_error_ribbon			error_state.field.B6
#define f_error_riboon_empty	error_state.field.B7        

#define f_error_noUse_1  		error_state.field.B8
#define f_error_noUse_2			error_state.field.B9
#define f_error_noUse_3		    error_state.field.B10
#define f_error_Voltage_low		error_state.field.B11              //电量过低
#define f_error_tape_error   	error_state.field.B12               //没检测到耗材
#define f_error_noUse_6		    error_state.field.B13
#define f_error_noUse_7			error_state.field.B14
#define f_error_noUse_8	        error_state.field.B15

#define bianhualiang	(12)

//#define bianhualiang	(25)


void PollingExtDev(unsigned char delay_flage);
void PollingExtDev_1(unsigned char delay_flage);
void PollingExtDev_2(unsigned char delay_flage);
void GetExtAdc(void);
void PaperCalibrate(void);
void PaperCalibrate_1(void);

void TPH_Temp_Polling(unsigned char flag);
void SendSor_Init(void);
void get_tem(unsigned int tem);

typedef  struct
{
	double filterValue;  //k-1时刻的滤波值,即是k-1时刻的值
	double kalmanGain;   //   Kalamn增益
	double A;   // x(n)=A*x(n-1)+u(n),u(n)~N(0,Q)
	double H;   // z(n)=H*x(n)+w(n),w(n)~N(0,R)
	double Q;   //预测过程噪声偏差的方差
	double R;   //测量噪声偏差,(系统搭建好以后,通过测量统计实验获得)
	double P;   //估计误差协方差
}KalmanInfo;
extern unsigned char Can_Be_Calibrated_Flag;
extern unsigned int iOffsetSum;
extern unsigned char Paper_Use_Up_Flag;
extern KalmanInfo KFP_height;
extern double KalmanFilter(KalmanInfo* kalmanInfo, double lastMeasurement);
extern void Init_KalmanInfo(KalmanInfo* info, double Q, double R);

#define  CHARGE_FILL   1         //充电
#define  CHARGING      2
#define  NOCHARGE      3

#endif

























//                                 usb.c



#include "yc_sysctrl.h"
#include "usb.h"
#include "misc.h"
#include "yc_timer.h"
#include "yc_qspi.h"
#include "PrtHead.h"
#include "RcvBuf.h"

#include "Sensor.h"

void dmacopy_nowait(byte *dest, byte *src, int len);

int  usb_get_buffer(uint8_t *buf);
void usb_last_packet(void);
void enable_systick(int counter);
void TIMER_Configuration(void);

extern byte aes[];
#define VENDOR_ID       0x0483
#define PRODUCT_ID      0x5720

byte const *bufptr;
byte remain, isstr;
usb_setup usb0_setup;
byte usb1_send_flag = 1;
byte mcmd, rxlen, clear_fifo;
byte usbbuf[65], uartbuf[100];
byte usbtxbuf[128];
byte pcnt[3000] __attribute__((aligned(256)));
int uwp, urp, tptr, next_urp, timeout, totallen, pcp, tc, chksum;
int utxwp, utxrp;
uint32_t totaltxlen = 0, totaltxlen_chksum = 0;





//int  len,dataLen;
//int	 usbTotallen;
//uint32_t increse = 0;


uint8_t uartretval;
uint8_t recvlen;
uint32_t recvtotallen = 0;
uint8_t buf[65] = {0};
uint8_t big_buffer_have_space = 1;
uint8_t big_buffer[1024] = {0};

const byte devicedesc[] =
{
    18,                     //bLength
    DSC_DEVICE,         		//bDescriptorType    描述类型
    WORD(0x110),            //bcdUSB
    0x00,                   //bDeviceClass
    0x00,                   //bDeviceSubClass
    0x00,                   //bDeviceProtocol
    EP0_PACKET_SIZE,        //bMaxPacketSize0
    WORD(VENDOR_ID),        //idVendor
    WORD(PRODUCT_ID),       //idProduct
    WORD(0x0200),           //bcdDevice
    0x01,                   //iManufacturerhttps://pics1.baidu.com/feed/32fa828ba61ea8d38ce039b147a8c947271f58f5.jpeg?token=7a4105931fe689ee865e634e3a7529a7
    0x02,                   //iProduct
    0x03,                   //iSerialNumber
    0x01                    //bNumConfigurations
};


const byte confdesc[] =
{
    /* Configuration 1 */
    9,                                                      /* bLength */
    DSC_CONFIG,                                            /* bDescriptorType */
    WORD(9 * 2 + 7 * 2),                                   /* wTotalLength */
    0x01,                                                   /* bNumInterfaces */
    0x01,                                                   /* bConfigurationValue */
    0x00,                                                   /* iConfiguration */
    0xc0,                                                   /* bmAttributes  BUS Powred*/
    50,                                                     /* bMaxPower = 400 mA*/

    /* Standard interface descriptor */
    9,                                          /* bLength */
    DSC_INTERFACE,                              /* bDescriptorType */
    0x00,                                                   /* bInterfaceNumber */
    0x00,                                                   /* bAlternateSetting */
    0x02,                                                   /* bNumEndpoints */
    USB_DEVICE_CLASS_PRINTER,                   /* bInterfaceClass */
    1,                                              /* bInterfaceSubClass */
    2,                                          /* bInterfaceProtocol */
    0x04,                                                   /* iInterface */

    /* Endpoint 1 - Standard Descriptor */
    7,                                          /* bLength */
    DSC_ENDPOINT,                           /* bDescriptorType */
    1,                                              /* bEndpointAddress 1 out endpoint*/
    USB_ENDPOINT_TYPE_BUCK,             /* bmAttributes */
    WORD(64),                               /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
    0x00,                                                   /* bInterval */

    /* Endpoint 81 - Standard Descriptor */
    7,                                          /* bLength */
    DSC_ENDPOINT,                           /* bDescriptorType */
    0x81,                                           /* bEndpointAddress 1 in endpoint*/
    USB_ENDPOINT_TYPE_INT,             /* bmAttributes */
    WORD(64),                               /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
    0x02,                                                   /* bInterval */

};

//char const string0[] = "\x4\x3\x9\x4";
//char const string1[] = "YICHIP";
//char const string2[] = "YC3121 Printer demo";
//char const string3[] = "000000000004";
//char const *const string[] =   {string0, string1, string2, string3};
//char const id[] = "\x0\xaprinter;";
//
//const byte strlength[] = {sizeof(string0), sizeof(string1), sizeof(string2), sizeof(string3)};
char const id[] = "\x0\xaprinter;";

char const DEVICE_ID[]= "\x0!MFG:PUTY;CMD:EPSON;CLS:PRINTER;";

char const string0[] = "\x4\x3\x9\x4";
char const string1[] = "SudingTechnology";
//char const string2[] = "PT-51DC";
char const string2[] = "PT26";

char const string3[] = "11101800002";

char const * const string[] = 	{string0, string1, string2, string3};


const byte strlength[] = {sizeof(string0), sizeof(string1), sizeof(string2), sizeof(string3)};

static void usb0_force_stall(void)
{
    USB_STALL =  1;
}

static void usb_trig(int ep)
{
    volatile int i;
    for (i = 0; i < 90; i++);
    USB_TRG =  1 << ep;
    return;
}

static void usb0_tx()
{
    byte len, i;

    if (remain)
    {
        len = remain > EP0_PACKET_SIZE ? EP0_PACKET_SIZE : remain;
        for (i = 0; i < len; i++)
        {
            USB_EP(0) = bufptr[i];
            if (isstr) USB_EP(0) = 0;
        }
        bufptr += len;
        remain -= len;
        usb_trig(0);
        USB_INT_MASK(1) =  0xfe;
    }
    else
    {
        USB_INT_MASK(1) =  0xff;
    }
}

//usb回值
static void usb0_respond(byte const *buff, byte size)   
{
    if (isstr)
    {
        USB_EP(0) = (size + 1) * 2;
        USB_EP(0) = 3;
    }
    if (size > usb0_setup.wLength)
        size = usb0_setup.wLength;
    bufptr = buff;
    remain = size;
    usb0_tx();
}

//请求设置地址
static void usb0_request_set_address(void)
{
    if (usb0_setup.bmRequestType == IN_DEVICE && usb0_setup.wIndex == 0
            && usb0_setup.wLength == 0)
    {
        USB_TRG = 0x10;
        USB_ADDR = usb0_setup.wValue;
    }
    else
    {
        usb0_force_stall();
    }
}
/*
static byte strlength(char const *str)
{
    byte i;
    for(i = 0;str[i];i++);
    return i;
}
*/
//请求设置配置
static void usb0_request_set_configuration(void)
{
    if (usb0_setup.bmRequestType == IN_DEVICE
            && usb0_setup.wIndex == 0 && usb0_setup.wLength == 0
            && usb0_setup.wValue <= 1)
    {
        USB_TRG = 0x10;
    }
    else
    {
        usb0_force_stall();
    }
}

static void usb0_request_set_interface(void)
{
    if (usb0_setup.bmRequestType == IN_INTERFACE
            && usb0_setup.wValue == 0
            && usb0_setup.wLength == 0)
    {
        USB_TRG = 0x10;
    }
    else
    {
        usb0_force_stall();
    }
}
//请求获取描述信息
static void usb0_request_get_descriptor(void)
{
    byte index;
    isstr = 0;
//	  MyPrintf("usb0_request_get_descriptor\n");
    switch (usb0_setup.wValue >> 8)
    {
    case DSC_DEVICE:
        usb0_respond((byte const *)&devicedesc, sizeof(devicedesc));
        if (USB_ADDR > 0) USB_ADDR |= 0x80;
        break;
    case DSC_CONFIG:
        usb0_respond(confdesc, sizeof(confdesc));
        break;
    case DSC_STRING:
        index = usb0_setup.wValue  & 3;
        isstr = index > 0;
        usb0_respond((byte const *)string[index], strlength[index] - 1);
//		MyPrintf("111——\n");
		    EXT_DEV.usb_link_flag=1;
        break;
    default:
        usb0_force_stall();
        break;
    }
}

#define INCPTR(x, inc)      (x + inc >= sizeof(usbbuf) ? x + inc - sizeof(usbbuf) : x + inc)

#define INTXCPTR(x, inc)      (x + inc >= sizeof(usbtxbuf) ? x + inc - sizeof(usbtxbuf) : x + inc)
int buflen()
{
    return uwp < urp ? uwp - urp + sizeof(usbbuf) : uwp - urp;
}

int txbuflen()
{
    return utxwp < utxrp ? utxwp - utxrp + sizeof(usbtxbuf) : utxwp - utxrp;
}

void usb2buf(int len)
{
    int i;
    for (i = 0; i < len; i++, uwp = INCPTR(uwp, 1))
        usbbuf[uwp] = USB_EP(1);
}

//usb2 发送缓冲
void usb2txbuf(int txlen)
{
    byte len, i;
    if (txlen)
    {
        len = txlen > EP1_PACKET_SIZE ? EP1_PACKET_SIZE : txlen;
        for (i = 0; i < len; i++, utxrp = INTXCPTR(utxrp, 1))
        {
            USB_EP(1)  = usbtxbuf[utxrp];
            totaltxlen_chksum = totaltxlen_chksum + usbtxbuf[utxrp];
        }
        totaltxlen += len;
        usb_trig(1);
        usb1_send_flag = 0;
        USB_INT_MASK(1) =  0xfd;
    }
    else
    {
        USB_INT_MASK(1) =  0xff;
    }
}

void usb1_respond(byte const *buff,byte size)
{

	for (int i = 0; i < size; i++, utxwp = INTXCPTR(utxwp, 1))
	{
		usbtxbuf[utxwp]  = buff[i];
	}
	//usb2txbuf((txbuflen()));		  

}


//
int txbufreeelen()
{
    return sizeof(usbtxbuf) - (utxwp < utxrp ? utxwp - utxrp + sizeof(usbtxbuf) : utxwp - utxrp);
}

//----------------------------
void USB_IRQHandler(void)
{
    int i, len;
    byte status, empty, full;
    byte *buf = (byte *)&usb0_setup;
    status = USB_STATUS;
    empty = USB_FIFO_EMPTY;
    full = USB_FIFO_FULL;
    USB_FIFO_EMPTY =  empty;
    USB_STATUS =  status;
    USB_FIFO_FULL = full;
    if (status & USB_STATUS_RESET)
    {
        USB_ADDR = 0x00;
    }
    if (empty & 1)
    {
        usb0_tx();
    }
    if (empty & 2)
    {
        usb1_send_flag = 1;
        USB_INT_MASK(1) =  0xff;
    }
    if (status & USB_STATUS_FIFO0_READY)
    {
        len = USB_EP_LEN(0);
        for (i = 0; i < len; i++)
            buf[i] = USB_EP(0);
        if (status & USB_STATUS_SETUP)
        {
            usb0_setup.wLength = usb0_setup.wLength;
            usb0_setup.wValue = usb0_setup.wValue;
            if ((usb0_setup.bmRequestType & ~0x80) == HCI_CLASS_REQUEST_TYPE)
            {
                USB_TRG = 0x10;
            }
            else if ((usb0_setup.bmRequestType & ~0x80) == HID_CLASS_REQUEST_TYPE)
            {
                switch (usb0_setup.bRequest)
                {
                case SET_IDLE:
                    USB_TRG = 0x10;
                    break;
                case GET_DEVICE_ID:
                    isstr = 0;
                    usb0_respond((uint8_t *)id, sizeof(id) - 1);
                    break;
                }
            }
            else
            {
                switch (usb0_setup.bRequest)
                {
                case SET_ADDRESS:
                    usb0_request_set_address();
                    break;
                case GET_DESCRIPTOR:
                    usb0_request_get_descriptor();
                    break;
                case SET_CONFIGURATION:
                    usb0_request_set_configuration();
                    break;
                case SET_INTERFACE:
                    usb0_request_set_interface();
                    break;

                default:
                    usb0_force_stall();
                    break;
                }
            }

        }

    }
    if (status & USB_STATUS_FIFO1_READY)
    {
        USB_STATUS =  USB_STATUS_FIFO1_READY;
        len = USB_EP_LEN(1);
        timeout = 0;
				Rcv_Port = RCV_TYPE_USB;

        if (status & USB_STATUS_NAK)
        {
            if (rxlen == 0)
            {
                rxlen = len;
            }
            if (buflen() + rxlen < sizeof(usbbuf))
            {
                usb2buf(rxlen);
                for (i = 0; i < len - rxlen; i++) USB_EP(1);
                rxlen = 0;
            }
        }
        else if (len > 0)
        {
            if (buflen() + len < sizeof(usbbuf))
            {
                usb2buf(len);
                rxlen = 0;
            }
            else
            {
                rxlen = len;
            }
        }
    }
}

//---------------------------------------------------------------------------------------------------------------------------
void usb_inial(void)
{

    remain = mcmd = rxlen = clear_fifo = tptr = uwp = urp = timeout = totallen = pcp = tc = chksum = utxwp = utxrp = 0;
    enable_clock(CLKCLS_BT);
    enable_clock(CLKCLS_UART);
    enable_clock(CLKCLS_USB);
    USB_CONFIG =  0x00;
    delay_ms(1);
    USB_CONFIG =  0x30;
    USB_INT_MASK(0) =  0x30;
    USB_INT_MASK(1) =  0xff;
    USB_INT_MASK(2) =  0xff;

    enable_intr(INTR_USB);
    NVIC_EnableIRQ(TIM0_IRQn);

    NVIC_SetPriority(USB_IRQn, 0);
    NVIC_SetPriority(TIM0_IRQn, 1);

    TIMER_Configuration();

}



void usb_main()
{
	unsigned short i1=0;

	static unsigned char send_enable=0; 
   
//    usb_inial(); 

//	while (1)
	{

		recvlen = buflen();
		//if(recvlen==0)
		//{
   			//MyPrintf("recvlen = %d\r\n", recvlen);
		//}
          
		if (recvlen > 0)
		{
			//if (big_buffer_have_space)//
//			MyPrintf("usb_main_1\n");
			receive_buf_check();
	//		if((!bRcvBufFull)&&(EXT_DEV.print_err_release_delay_counter==0))//&&(!f_printer_error)
			if(!bRcvBufFull)
			{
				send_enable=1;
	//			MyPrintf("usb_main_2\n");
			
				/*receive data in to big buffer*/
				recvlen = usb_get_buffer(buf);

				//memcpy(big_buffer, buf, recvlen);
				for(i1=0;i1<recvlen;i1++)
				{
					FillRcvBuf(buf[i1]);//usb接收数据			
	//			  MyPrintf("%02x ",buf[i1]);
				}

#if 0
				MyPrintf("received %d bytes:\n",recvlen);
				for(int i=0;i<recvlen;i++)	MyPrintf("%02x ",buf[i]);
				MyPrintf("\n");	
#endif				
				//recvtotallen += recvlen;
				//MyPrintf("recvlen = %d recvtotallen = %d\r\n", recvlen, recvtotallen);
			}
			else
			{
								//if(send_enable==1)
								//{
								//	send_enable=0;
								//	MyPrintf("bRcvBufFull= %d \n",bRcvBufFull);
								//}
		//		print_check();
				       /*big_buffer_have_no_space*/
	
				       //PollingExtDev_1(1);
				       //PollingExtDev_2(1);
	//			PollingExtDev(1);
			
			}

		}

		if (txbuflen() > 0)
		{
			if (usb1_send_flag == 1)
			{
				usb2txbuf(txbuflen());
			}
		}


	/*usb_last_packet in TIMER0_IRQHandler*/

	//usb_last_packet();

	//
	//        if (UART_IsRXFIFONotEmpty(UART0))
	//        {
	//            uartretval = UART_ReceiveData(UART0);
	//            switch (uartretval)
	//            {
	//            case '1':
	//                MyPrintf("case '1' !\n\n");
	//                /*prapare usb tx send data*/
	//                for (int i = 0; i < 100; i++, utxwp = INTXCPTR(utxwp, 1))
	//                    usbtxbuf[utxwp]  = i;
	//                break;
	//            case '2':
	//                MyPrintf("big_buffer_have_space '1' !\n\n");
	//                big_buffer_have_space = 1;
	//                break;
	//            case '3':
	//                MyPrintf("big_buffer_have_space '0' !\n\n");
	//                big_buffer_have_space = 0;
	//                break;
	//            case 'c':
	//                MyPrintf("totallen = %d chksum = %d \n\n", totallen, chksum);
	//                MyPrintf("totaltxlen = %d totaltxlen_chksum = %d \n\n", totaltxlen, totaltxlen_chksum);
	//                recvtotallen  = 0;
	//                totallen = 0;
	//                chksum = 0;
	//                totaltxlen = 0;
	//                totaltxlen_chksum = 0;
	//                break;
	//            default:
	//                break;
	//            }
	//            uartretval = 0;
	//        }


	};
}


//---------------------------------------------------
int usb_get_buffer(uint8_t *buf)
{
    int len;

    len = buflen();
    if (len > 0)
    {

        for (int i = 0; i < len; i++, urp = INCPTR(urp, 1))
        {
            buf[i] = usbbuf[urp];
            chksum += buf[i];
        }
        totallen += len;

    }
    return len;
}

void usb_last_packet(void)
{
	
    /*please put usb_last_packet(); into Timer interrupt*/
    if (rxlen && buflen() + rxlen < sizeof(usbbuf))
    {
        /*The expected value of the timeout is 100ms;
          timeout = 100ms/each into Timer interrupt time*/
        if (timeout++ > 100)
        {
        
			Rcv_Port = RCV_TYPE_USB;
            usb2buf(rxlen);
            for (int i = 0; i < 64 - rxlen; i++) USB_EP(1);
            rxlen = 0;
            tc++;
            timeout = 0;
        }
    }
}

/**
  * @brief  TIM configuration function.
  * @param  None
  * @retval None
  */
void TIMER_Configuration(void)
{
    TIM_InitTypeDef TIM_InitStruct;

    TIM_InitStruct.period = 96000;

    TIM_InitStruct.TIMx = TIM0;
    TIM_Init(&TIM_InitStruct);

    /* Configure timer for counting mode */
    TIM_ModeConfig(TIM0, TIM_Mode_TIMER);


    /* The last step must be enabled */
    TIM_Cmd(TIM0, ENABLE);
}

/**
  * @brief  TIM0~TIM8 Interrupt service function.
  * @param  None
  * @retval None
  */
void TIMER0_IRQHandler(void)
{
    usb_last_packet();
}





























//                    usb.h     



#define  BT_GBG_EN *(volatile uint8_t*)(0xc8904)

#define  HCI_CLASS_REQUEST_TYPE  0x20

                                       // SetReport HID Request
#define  HID_CLASS_REQUEST_TYPE  0x21 

// Standard Request Codes
#define  GET_STATUS              0x00  // Code for Get Status
#define  CLEAR_FEATURE           0x01  // Code for Clear Feature
#define  SET_FEATURE             0x03  // Code for Set Feature
#define  SET_ADDRESS             0x05  // Code for Set Address
#define  GET_DESCRIPTOR          0x06  // Code for Get Descriptor
#define  SET_DESCRIPTOR          0x07  // Code for Set Descriptor(not used)
#define  GET_CONFIGURATION       0x08  // Code for Get Configuration
#define  SET_CONFIGURATION       0x09  // Code for Set Configuration
#define  GET_INTERFACE           0x0A  // Code for Get Interface
#define  SET_INTERFACE           0x0B  // Code for Set Interface
#define  SYNCH_FRAME             0x0C  // Code for Synch Frame(not used)

// Standard Descriptor Types
#define  DSC_DEVICE              0x01  // Device Descriptor
#define  DSC_CONFIG              0x02  // Configuration Descriptor
#define  DSC_STRING              0x03  // String Descriptor
#define  DSC_INTERFACE           0x04  // Interface Descriptor
#define  DSC_ENDPOINT            0x05  // Endpoint Descriptor

// HID Descriptor Types
#define  DSC_HID			     0x21  // HID Class Descriptor
#define  DSC_HID_REPORT			 0x22  // HID Report Descriptor

// Define bmRequestType bitmaps
#define  IN_DEVICE               0x00  // Request made to device,
                                       // direction is IN
#define  OUT_DEVICE              0x80  // Request made to device,
                                       // direction is OUT
#define  IN_INTERFACE            0x01  // Request made to interface,
                                       // direction is IN
#define  OUT_INTERFACE           0x81  // Request made to interface,
                                       // direction is OUT
#define  IN_ENDPOINT             0x02  // Request made to endpoint,
                                       // direction is IN
#define  OUT_ENDPOINT            0x82  // Request made to endpoint,

#define USB_DEVICE_CLASS_AUDIO        	0x01
#define USB_DEVICE_CLASS_CDC  			0x02
#define USB_DEVICE_CLASS_HID                  	0x03
#define USB_DEVICE_CLASS_IMAGE 		0x06
#define USB_DEVICE_CLASS_PRINTER 		0x07
#define USB_DEVICE_CLASS_MASS 		0x08
#define USB_DEVICE_CLASS_HUB 			0x09
#define USB_DEVICE_CLASS_CDC_DATA	0x0a
#define USB_DEVICE_CLASS_SMARTCARD	0x0b
#define USB_DEVICE_CLASS_SECURITY		0x0d
#define USB_DEVICE_CLASS_VIDEO		0x0e
#define USB_DEVICE_CLASS_HEALTH		0x0f
#define USB_DEVICE_CLASS_AV			0x10
#define USB_DEVICE_CLASS_WIRELESS		0xe0

#define USB_ENDPOINT_TYPE_BUCK          		0x02
#define USB_ENDPOINT_TYPE_INT          		0x03
#define USB_ENDPOINT_TYPE_ADAP_ISO          	0x09
#define USB_ENDPOINT_TYPE_SYNC_ISO        	0x0d

#define GET_DEVICE_ID			0

// HID Request Codes
#define  GET_REPORT 		     0x01   // Code for Get Report
#define  GET_IDLE				 0x02   // Code for Get Idle
#define  GET_PROTOCOL			 0x03   // Code for Get Protocol
#define  SET_REPORT				 0x09   // Code for Set Report
#define  SET_IDLE				 0x0A   // Code for Set Idle
#define  SET_PROTOCOL			 0x0B   // Code for Set Protocol

#define  HID_RPT_ID           	0xf2
#define  HID_RPT_SIZE         	0x3f

#define  EP0_PACKET_SIZE         0x40 
#define  EP1_PACKET_SIZE         0x40
#define  HID_REPORT_DESCRIPTOR_SIZE    0x001B

#define  be16(x) ((x<<8)|(x>>8))                
#define LOBYTE(x)  ((byte)((x) & 0xff))
#define HIBYTE(x)  ((byte)((x) >> 8 & 0xff))
#define TRDBYTE(x)  ((byte)((x) >> 16 & 0xff))

#define WORD(x)				LOBYTE(x),HIBYTE(x)
#define TBYTE(x)				WORD(x),TRDBYTE(x)
#define DWORD(x)			WORD(x),WORD(x >> 16)

#define USB_STATUS_FIFO0_READY		1
#define USB_STATUS_FIFO1_READY		2
#define USB_STATUS_FIFO3_READY		8
#define USB_STATUS_SETUP			  0x10
#define USB_STATUS_SUSPEND			0x20
#define USB_STATUS_NAK				  0x40
#define USB_STATUS_RESET			  0x80

typedef struct
{
	byte  bmRequestType;
	byte  bRequest;
	word wValue;
	word wIndex;
	word wLength;
} usb_setup;


void usb_main(void);
extern volatile unsigned char Rcv_Port;
extern int  usb_get_buffer(unsigned char *buf);




























//                   Usbpro.c      

//#include "usbd_ccid_core.h"
#include "usbd_usr.h"
//#include "usbd_desc.h"
#include <string.h>
#include <stdio.h>
#include "usb_dcd_int.h"
#include "Usbpro.h"
#include "RcvBuf.h"
#include "LcdDrv.h"
#include "PrtHead.h"

#define VENDOR_ID 		0x0483
#define PRODUCT_ID 		0x5720


extern volatile unsigned char Rcv_Port;

const device_descriptor devicedesc =
{
	0x12,					//bLength
	0x01,					//bDescriptorType
	0x0200,					//bcdUSB
	0x00,					//bDeviceClass
	0x00,					//bDeviceSubClass
	0x00,					//bDeviceProtocol
	EP0_PACKET_SIZE,		//bMaxPacketSize0
	VENDOR_ID,				//idVendor
	PRODUCT_ID,			//idProduct
	0x0200,					//bcdDevice
	0x01,					//iManufacturer
	0x02,					//iProduct
	0x03,					//iSerialNumber
	0x01					//bNumConfigurations
}; 


const byte hidreportdesc[] =
{
	
	0x05,0x01, // Global Generic Desktop
	0x09,0x02, // Local Mouse
	0xa1,0x01, // Main app collection
	0x09,0x01, // Local Pointer
	0xa1,0x00, // Main phy collection
	0x95,0x03, // Global ReportCount
	0x75,0x01, // Global ReportSize
	0x05,0x09, // Global Button
	0x19,0x01, // Local Usage Min
	0x29,0x03, // Local Usage Max
	0x15,0x00, // Global Logical Min
	0x25,0x01, // Global Logical Max
	0x81,0x02, // Main Input(Data,Var,Abs)
	0x95,0x01, // Global ReportCount
	0x75,0x05, // Global ReportSize
	0x81,0x03, // Main Input(Cnsr,Var,Abs)
	0x95,0x03,0x75,0x08, // Global ReportCount Global ReportSize
	0x05,0x01, // Global Generic Desktip
	0x09,0x30, // Local X
	0x09,0x31, // Local Y
	0x09,0x38, // Locak Wheel
	0x15,0x81, // Global Logical Min
	0x25,0x7f, // Global Logical Max
	0x81,0x06, // Main Input(Data,Var,Rel)
	0xc0, // Main End collection
	0xc0 // Main End collection
};

const byte confdesc[] = {

	
	 //config
    0x09,//0xLength	
    0x02,//0xType
	0x20,					// Totallength (= 9+9+9+7+7)
	0x00,
    0x01,//0xNumInterfaces
    0x01,//0xbConfigurationValue
    0x00,//0xstringindexConfiguration
    0xC0,//0xbmAttributes
    0x00,//0xMaxPower0x(in0x2mA0xunits)

    //0xinterface_descriptor0xhid_interface_descriptor--mouse
    0x09,//0xbLength
    0x04,//0xbDescriptorType
    0x00,//0xbInterfaceNumber
    0x00,//0xbAlternateSetting
    0x02,//0xbNumEndpoints
    0x07,//0xbInterfaceClass0x(30x=0xHID)
    0x01,//0xbInterfaceSubClass
    0x02,//0xbInterfaceProcotol0x0x01 kb; 0x0x2=mouse
    0x00,//0xiInterface

	/*Endpoint 1 Descriptor*/
    0x07,   /* bLength: Endpoint Descriptor size */
    0x05,   /* bDescriptorType: Endpoint */
    0x81,   /* bEndpointAddress: (OUT1) */
    0x02,   /* bmAttributes: Bulk */
    0x40,             /* wMaxPacketSize: */
    0x00,
    0x00,   /* bInterval: ignore for Bulk transfer */
    
    /*Endpoint 3 Descriptor*/
    0x07,   /* bLength: Endpoint Descriptor size */
    0x05,   /* bDescriptorType: Endpoint */
    0x02,   /* bEndpointAddress: (IN2) */
    0x02,   /* bmAttributes: Bulk */
    0x40,             /* wMaxPacketSize: */
    0x00,
    0x00    /* bInterval */
};



char const DEVICE_ID[]= "\x0!MFG:PUTY;CMD:EPSON;CLS:PRINTER;";

char const string0[] = "\x4\x3\x9\x4";
char const string1[] = "SudingTechnology";
//char const string2[] = "PT-51DC";
char const string2[] = "PT20";

char const string3[] = "11101800002";

char const * const string[] = 	{string0, string1, string2, string3};


const byte strlength[] = {sizeof(string0), sizeof(string1), sizeof(string2), sizeof(string3)};

byte const *bufptr;
byte remain, isstr;
usb_setup usb0_setup;
byte mcmd;
byte usbbuf[256];


static void usb0_force_stall(void)
{
	USB_STALL =  1;
}

static void usb_trig(int ep)
{
//	int i;
	USB_TRG =  1 << ep;
	
#if 0
	return;
	USB_STATUS = USB_STATUS_NAK;
	for(i = 0;i < 10000;i++)
		if(USB_STATUS & USB_STATUS_NAK) break;
	USB_FIFO_EMPTY = 1 << ep;
	for(i = 0;i < 10000;i++) {
		if(USB_FIFO_EMPTY & 1 << ep) break;
	}
#endif
}

static void usb0_tx() 
{
	byte len, i;

	if(remain) {
		len = remain > EP0_PACKET_SIZE ? EP0_PACKET_SIZE : remain;
		for(i = 0;i < len;i++) {
			USB_EP(0) = bufptr[i];
			if(isstr) USB_EP(0) = 0;
		}
//		savelist((byte*)bufptr);
		bufptr += len;
		remain -= len;
		usb_trig(0);
		USB_INT_MASK(1) =  0xfe;
	} else {
		USB_INT_MASK(1) =  0xff;
	}
}

void usb0_respond(byte const *buff,byte size)
{
	if(isstr) {
		USB_EP(0) = (size + 1)*2;
		USB_EP(0) = 3;
	}
	if (size>usb0_setup.wLength)
		size = usb0_setup.wLength;
	bufptr = buff;
	remain = size;
	usb0_tx();
}

void usb1_respond(byte const *buff,byte size)
{
	u8 i;
	
	for(i=0;i<size;i++){
		USB_EP(1) = buff[i];
		usb_trig(1);

	}

}


static void usb0_request_set_address(void)
{
	MyPrintf("\n usb0_request_set_address:");
	if (usb0_setup.bmRequestType == IN_DEVICE && usb0_setup.wIndex == 0
		&& usb0_setup.wLength == 0)
	{
		USB_TRG = 0x10;
		USB_ADDR = usb0_setup.wValue;
		MyPrintf("%02x",usb0_setup.wValue);
	}
	else
	{
		usb0_force_stall();
	}	
	MyPrintf("\n");
}
/*
static byte strlength(char const *str)
{
	byte i;
	for(i = 0;str[i];i++);
	return i;
}
*/
static void usb0_request_set_configuration(void)
{
	MyPrintf("\n usb0_request_set_configuration:");
	if (usb0_setup.bmRequestType == IN_DEVICE
		&& usb0_setup.wIndex == 0 && usb0_setup.wLength == 0
		&& usb0_setup.wValue <= 1)
	{
		USB_TRG = 0x10;
	}
	else
	{
		usb0_force_stall();
	}
}

static void usb0_request_set_interface(void)
{
	MyPrintf("\n usb0_request_set_interface:");
	if (usb0_setup.bmRequestType == IN_INTERFACE
		&& usb0_setup.wValue == 0
		&& usb0_setup.wLength == 0)
	{
		USB_TRG = 0x10;
	}
	else
	{
		usb0_force_stall();	
	}		
}

static void usb0_request_get_descriptor(void)
{
	//MyPrintf("\n usb0_request_get_descriptor: %d",usb0_setup.wValue);
	
	byte index;
	isstr = 0;
	switch(usb0_setup.wValue >> 8)
	{
	case DSC_DEVICE:
		MyPrintf("USB DEVICE\n");
		usb0_respond((byte const *)&devicedesc, sizeof(devicedesc));
		break;
	case DSC_CONFIG:
		MyPrintf("USB CONFIG\n");
		usb0_respond(confdesc, sizeof(confdesc));
	
		break;		
	case DSC_STRING:
		MyPrintf("STRING:\n");
		index = usb0_setup.wValue  & 3;
		isstr = index > 0;
		usb0_respond((byte const *)string[index], strlength[index] - 1);
		MyPrintf("%s\n",string[index]);
		EXT_DEV.usb_link_flag=1;
		break;		


	case DSC_HID:
		MyPrintf("DSC_HID mou\n");
		usb0_respond(confdesc + 18, confdesc[18]);
		break;
	case DSC_HID_REPORT:
		MyPrintf("DSC_HID_REPORT mou\n");
		usb0_respond(hidreportdesc,sizeof(hidreportdesc));
		break;
/*
	case DSC_INTERFACE:
		usb0_respond((byte*)&desc_interface,sizeof(desc_interface));		
		break;
	case DSC_ENDPOINT:
		if (usb0_setup.wValue&0xFF == IN_EP1)
		{
			usb0_respond((byte*)&desc_ep_in,sizeof(desc_ep_in));
		}
		else if (usb0_setup.wValue&0xFF == OUT_EP1)
		{
			usb0_respond((byte*)&desc_ep_out,sizeof(desc_ep_out));	
		}
		else
		{
			usb0_force_stall();
		}
		break;
*/
	default:
		usb0_force_stall();
		break; 
	}
}

void USB_IRQHandler()
{
	int i, len;
	byte status, empty;
	byte *buf = (byte*)&usb0_setup;
	status = USB_STATUS;
	empty = USB_FIFO_EMPTY;
	USB_FIFO_EMPTY =  empty;
	USB_STATUS =  status;

	if(empty & 1) {
		usb0_tx();
	}
	if(status & USB_STATUS_FIFO0_READY) 
	{
		len = USB_EP_LEN(0);
		for(i = 0;i < len;i++)
		{
			buf[i] = USB_EP(0);
		}

		if(status & USB_STATUS_SETUP) 
		{
			usb0_setup.wLength = usb0_setup.wLength;
			usb0_setup.wValue = usb0_setup.wValue;
			if ((usb0_setup.bmRequestType & ~0x80) == HCI_CLASS_REQUEST_TYPE)
			{
				USB_TRG = 0x10;
			}
			else if ((usb0_setup.bmRequestType & ~0x80) == HID_CLASS_REQUEST_TYPE)
			{				
				if (usb0_setup.bRequest == SET_IDLE)
				{
					USB_TRG = 0x10;
				}
				else
				{
					isstr = 0;
					usb0_respond(DEVICE_ID,sizeof(DEVICE_ID));

				}
			}
			else
			{
				switch(usb0_setup.bRequest)
				{
					case SET_ADDRESS:
						usb0_request_set_address();
						break;
					case GET_DESCRIPTOR:
						usb0_request_get_descriptor();
						break;
					case SET_CONFIGURATION:
						usb0_request_set_configuration();
						break;
					case SET_INTERFACE:
						usb0_request_set_interface();
						break;	
#if 0
					case GET_STATUS:
						usb0_request_get_status();
						break;
				    	case CLEAR_FEATURE:
						usb0_request_clear_feature();
						break;
					case SET_FEATURE:
						usb0_request_set_feature();
						break;
					case GET_CONFIGURATION:
						usb0_request_get_configuration();
						break;	
					case GET_INTERFACE:
						usb0_request_get_interface();
						break;
#endif
					default:
						usb0_force_stall();
						break;																																	
				}
			}
			
		} 
		
	}

#if 0
	if(status & USB_STATUS_FIFO1_READY) {
		USB_STATUS =  USB_STATUS_FIFO1_READY;
		len = USB_EP_LEN(1);
		for(i = 0;i < len;i++){
			usbbuf[i] = USB_EP(1);			
		}
		USB_TRG = 0x20;

		usb_rev_flag_ep1 = 1;

		//for(i = 0;i < 64;i++)	USB_EP(1) = aes[i];
		//usb_trig(1);

	}
#endif

	if(status & USB_STATUS_FIFO2_READY) {
		USB_STATUS =  USB_STATUS_FIFO2_READY;
		len = USB_EP_LEN(2);

		Rcv_Port = RCV_TYPE_USB;

		for(i = 0;i < len;i++)
		{
			FillRcvBuf(USB_EP(2));			
		}
		
	}

}



void USB_Init(void){

	enable_clock(CLKCLS_BT);	
	BT_CLKPLL_EN = 0xff;
	enable_clock(CLKCLS_USB);
	SYSCTRL_HCLK_CON |= 1 << 11;

	USB_OTG_WRITE_REG8(CORE_USB_CONFIG,0x00);
	//my_delay_ms(1);
	USB_OTG_WRITE_REG8(CORE_USB_TRIG,0xc0); 
	USB_OTG_WRITE_REG8(CORE_USB_CONFIG,0x30);
	USB_OTG_WRITE_REG8(CORE_USB_STATUS,0xFF);
	USB_OTG_WRITE_REG8(CORE_USB_FIFO_EMPTY,0xFF);
	USB_OTG_WRITE_REG8(CORE_USB_ADDR,0x00);
	USB_OTG_WRITE_REG8(CORE_USB_INT_MASK(0),0xf0);
	USB_OTG_WRITE_REG8(CORE_USB_INT_MASK(1),0xff);
	USB_OTG_WRITE_REG8(CORE_USB_INT_MASK(2),0xff);	

	enable_intr(INTR_USB); 
}



























//                                      Usbpro.h


#ifndef _USBPRO_H_
#define _USBPRO_H_
#define  HCI_CLASS_REQUEST_TYPE	0x20

                                       // SetReport HID Request
#define  HID_CLASS_REQUEST_TYPE	0x21 

// Standard Request Codes
#define  GET_STATUS              	0x00  // Code for Get Status
#define  CLEAR_FEATURE           	0x01  // Code for Clear Feature
#define  SET_FEATURE             	0x03  // Code for Set Feature
#define  SET_ADDRESS             	0x05  // Code for Set Address
#define  GET_DESCRIPTOR          	0x06  // Code for Get Descriptor
#define  SET_DESCRIPTOR          	0x07  // Code for Set Descriptor(not used)
#define  GET_CONFIGURATION       	0x08  // Code for Get Configuration
#define  SET_CONFIGURATION       	0x09  // Code for Set Configuration
#define  GET_INTERFACE           	0x0A  // Code for Get Interface
#define  SET_INTERFACE           	0x0B  // Code for Set Interface
#define  SYNCH_FRAME             	0x0C  // Code for Synch Frame(not used)

// Standard Descriptor Types
#define  DSC_DEVICE        		0x01  // Device Descriptor
#define  DSC_CONFIG              	0x02  // Configuration Descriptor
#define  DSC_STRING              	0x03  // String Descriptor
#define  DSC_INTERFACE           	0x04  // Interface Descriptor
#define  DSC_ENDPOINT            	0x05  // Endpoint Descriptor

// HID Descriptor Types
#define  DSC_HID			     	0x21  // HID Class Descriptor
#define  DSC_HID_REPORT			0x22  // HID Report Descriptor

// Define bmRequestType bitmaps
#define  IN_DEVICE               	0x00  // Request made to device,
                                       // direction is IN
#define  OUT_DEVICE              	0x80  // Request made to device,
                                       // direction is OUT
#define  IN_INTERFACE            	0x01  // Request made to interface,
                                       // direction is IN
#define  OUT_INTERFACE           	0x81  // Request made to interface,
                                       // direction is OUT
#define  IN_ENDPOINT             	0x02  // Request made to endpoint,
                                       // direction is IN
#define  OUT_ENDPOINT            	0x82  // Request made to endpoint,


// HID Request Codes
#define  GET_REPORT 		     	0x01   // Code for Get Report
#define  GET_IDLE				 	0x02   // Code for Get Idle
#define  GET_PROTOCOL			 	0x03   // Code for Get Protocol
#define  SET_REPORT				0x09   // Code for Set Report
#define  SET_IDLE					0x0A   // Code for Set Idle
#define  SET_PROTOCOL			 	0x0B   // Code for Set Protocol

#define  HID_RPT_ID           	0xf2
#define  HID_RPT_SIZE         	0x3f

#define  EP0_PACKET_SIZE         	0x40 
#define  EP1_PACKET_SIZE         	6
#define  HID_REPORT_DESCRIPTOR_SIZE    0x001B

#define  be16(x) ((x<<8)|(x>>8))                

#define USB_STATUS_FIFO0_READY		1
#define USB_STATUS_FIFO1_READY		2
#define USB_STATUS_FIFO2_READY		4
#define USB_STATUS_FIFO3_READY		8
//#define USB_STATUS_SETUP				0x10
//#define USB_STATUS_SUSPEND			0x20
//#define USB_STATUS_NAK				0x40
//#define USB_STATUS_STALL				0x80

typedef struct
{
	
	byte  bmRequestType;
	byte  bRequest;
	word wValue;
	word wIndex;
	word wLength;
	
} usb_setup;

//------------------------------------------
// Standard Device Descriptor Type Defintion
//------------------------------------------
typedef /*code*/ struct
{
   byte  bLength;              // Size of this Descriptor in Bytes
   byte  bDescriptorType;      // Descriptor Type (=1)
   word bcdUSB;               // USB Spec Release Number in BCD
   byte  bDeviceClass;         // Device Class Code
   byte  bDeviceSubClass;      // Device Subclass Code
   byte  bDeviceProtocol;      // Device Protocol Code
   byte  bMaxPacketSize0;      // Maximum Packet Size for EP0
   word idVendor;             // Vendor ID
   word idProduct;            // Product ID
   word bcdDevice;            // Device Release Number in BCD
   byte  iManufacturer;        // Index of String Desc for Manufacturer
   byte  iProduct;             // Index of String Desc for Product
   byte  iSerialNumber;        // Index of String Desc for SerNo
   byte  bNumConfigurations;   // Number of possible Configurations
	
} device_descriptor;              // End of Device Descriptor Type

//--------------------------------------------------
// Standard Configuration Descriptor Type Definition
//--------------------------------------------------
typedef /*code*/ struct
{
   byte  bLength;              // Size of this Descriptor in Bytes
   byte  bDescriptorType;      // Descriptor Type (=2)
   word wTotalLength;         // Total Length of Data for this Conf
   byte  bNumInterfaces;       // No of Interfaces supported by this
                                  // Conf
   byte  bConfigurationValue;  // Designator Value for *this*
                                  // Configuration
   byte  iConfiguration;       // Index of String Desc for this Conf
   byte  bmAttributes;         // Configuration Characteristics (see below)
   byte  bMaxPower;            // Max. Power Consumption in this
                                  // Conf (*2mA)
} configuration_descriptor;       // End of Configuration Descriptor Type

//----------------------------------------------
// Standard Interface Descriptor Type Definition
//----------------------------------------------
typedef /*code*/ struct
{
   byte  bLength;              // Size of this Descriptor in Bytes
   byte  bDescriptorType;      // Descriptor Type (=4)
   byte  bInterfaceNumber;     // Number of *this* Interface (0..)
   byte  bAlternateSetting;    // Alternative for this Interface (if any)
   byte  bNumEndpoints;        // No of EPs used by this IF (excl. EP0)
   byte  bInterfaceClass;      // Interface Class Code
   byte  bInterfaceSubClass;   // Interface Subclass Code
   byte  bInterfaceProtocol;   // Interface Protocol Code
   byte  iInterface;           // Index of String Desc for this Interface
} interface_descriptor;           // End of Interface Descriptor Type

//------------------------------------------
// Standard Class Descriptor Type Definition
//------------------------------------------
typedef /*code */struct
{
   byte  bLength;              // Size of this Descriptor in Bytes (=9)
   byte  bDescriptorType;      // Descriptor Type (HID=0x21)
   word bcdHID;    			  // HID Class Specification
                                  // release number (=1.01)
   byte  bCountryCode;         // Localized country code
   byte  bNumDescriptors;	  // Number of class descriptors to follow
   byte  bReportDescriptorType;// Report descriptor type (HID=0x22)
   unsigned int wItemLength;	  // Total length of report descriptor table
} class_descriptor;               // End of Class Descriptor Type

//---------------------------------------------
// Standard Endpoint Descriptor Type Definition
//---------------------------------------------
typedef /*code*/ struct
{
   byte  bLength;              // Size of this Descriptor in Bytes
   byte  bDescriptorType;      // Descriptor Type (=5)
   byte  bEndpointAddress;     // Endpoint Address (Number + Direction)
   byte  bmAttributes;         // Endpoint Attributes (Transfer Type)
   word wMaxPacketSize;	      // Max. Endpoint Packet Size
   byte  bInterval;            // Polling Interval (Interrupt) ms
} endpoint_descriptor;            // End of Endpoint Descriptor Type

//---------------------------------------------
// HID Configuration Descriptor Type Definition
//---------------------------------------------
// From "USB Device Class Definition for Human Interface Devices (HID)".
// Section 7.1:
// "When a Get_Descriptor(Configuration) request is issued,
// it returns the Configuration descriptor, all Interface descriptors,
// all Endpoint descriptors, and the HID descriptor for each interface."
typedef /*code*/ struct {
	configuration_descriptor 	hid_configuration_descriptor;
	interface_descriptor 		hid_interface_descriptor;
	class_descriptor 			hid_descriptor;
	endpoint_descriptor 		hid_endpoint_in_descriptor;
	endpoint_descriptor 		hid_endpoint_out_descriptor;
} hid_configuration_descriptor;

#endif
                            

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值