
#define	_IN_DATAFILE_C
#include "datafile.h" 

#include "math.h"
#include "crc16.h"
#include "norflash.h"
#include "inout.h"

//-------------------------------------------------------------------------------





//-------------------------------------------------------------------------------


//-------------------------------------------------------------------------------


// 数据文件
#if (1)

//-------------------------------------------------------------------------------

// 用外部SRAM保存文件
// 文件内容

#define	DS16ITEMSIZE				(DATA_FILE_SIZE/sizeof(Ds16Item))
#define	DS8ITEMSIZE					(DATA_FILE_SIZE/sizeof(Ds8Item))
#define	DS4ITEMSIZE					(DATA_FILE_SIZE/sizeof(Ds4Item))

#define	DS16ITEMSIZE_AT_BUF1		(DATA_FILE_SIZE1/sizeof(Ds16Item))
#define	DS8ITEMSIZE_AT_BUF1			(DATA_FILE_SIZE1/sizeof(Ds8Item))
#define	DS4ITEMSIZE_AT_BUF1			(DATA_FILE_SIZE1/sizeof(Ds4Item))

// 边框刺绣数据文件
#define	DS16FRAMESIZE				(DATA_FILE_SIZE3/sizeof(Ds16Item))
#define	DS8FRAMESIZE				(DATA_FILE_SIZE3/sizeof(Ds8Item))
#define	DS4FRAMESIZE				(DATA_FILE_SIZE3/sizeof(Ds4Item))

//-------------------------------------------------------------------------------

// 用外部串行 NOR Flash 保存文件

// FLASH 文件存放地址
#define	NOR_FILE_BASE		SNF_DAT_FILE_BEGIN		// 存放文件区域 16M 字节

// 文件区域划分
//		|-----------------|-----------------|-------------|
//		|       name      |    begin addr   |     size	  |
//		|-----------------|-----------------|-------------|
//		| file data area  |      0x00       | 0x00FFE000       |     文件内容区域
//		|-----------------|-----------------|-------------|
//		|   file manage   |   0x00FFE000    | 0x00001000  |	  文件管理区域，占用1个扇区
//		|-----------------|-----------------|-------------|


#define	NOR_FILE_DATA		(NOR_FILE_BASE + 0x00000000)
#define	MAX_NOR_FILE_SIZE	(SNF_DAT_FILE_SIZE - SNF_BYTES_PER_SEC)

#define	NOR_DAT_MANAGE		(NOR_FILE_BASE + MAX_NOR_FILE_SIZE)


#define	DS16SIZEINNOR 		(MAX_NOR_FILE_SIZE/sizeof(Ds16Item))
#define	DS8SIZEINNOR 		(MAX_NOR_FILE_SIZE/sizeof(Ds8Item ))
#define	DS4SIZEINNOR 		(MAX_NOR_FILE_SIZE/sizeof(Ds4Item ))


// FLASH 平均损耗算法（用循环利用法来减少针对扇区的擦除）

// 共16M的文件存储区域
// 以4K（扇区）为文件分配的基本单位，共4096个扇区。
// 用一个字节代表一个扇区，用于指示扇区的利用情况，共4096个字节。
// 因为数据是循环存储在扇区列表中的。
// 所以规定，字节数组中最大的值代表了扇区分配的开始（循环队列的开始）。
// 例如擦除后，全部为0xff，那么第0个扇区就是第一个开始利用的扇区。
// 如果第一次存储文件时占用了10个扇区，那么从第0个到第9个扇区对应的字节写为0x7F。
// 接下来存储文件时要占用5个扇区，那么从第10个到第14个对应的字节设置为0x7F。
// 以此类推，如果所有字节被写为0x7F，那么接下来的字节就要被写作0x3F。
// 循环队列每循环一次，写入的字节的数移动一个位，直到写入字节变为0x00。
// 如果所有字节都变成0x00，那么这个记录扇区就需要擦除。

// 这个记录扇区的作用是保证所有扇区的擦除次数尽量均匀，延长使用寿命。

#define	NOR_DAT_SEC_BEG		0
#define	NOR_DAT_SEC_NUM		(MAX_NOR_FILE_SIZE / (SNF_BYTES_PER_SEC))

//-------------------------------------------------------------------------------

typedef struct
{
	u8 wrflag;			// 写入的记录字节
	int begSecIdx;		// 循环队列的起始索引
	int queueSecNum;	// 循环队列的长度,分配的扇区个数
	int releaseFlag;	// 释放标志
}NorSectorManager;

NorSectorManager g_norManager;

void InitNorSectorManage(void)
{
	int i, idx;
	u8 flag;
	u8 rdata[SNF_BYTES_PER_SEC];
	memset(&g_norManager, 0, sizeof(NorSectorManager));

	DatFlashRdData(NOR_DAT_MANAGE, rdata, SNF_BYTES_PER_SEC);	// 读取一个扇区

	// 扫描管理扇区，得到最大的flag值
	flag = 0;
	for (i = 0, idx = 0; i < NOR_DAT_SEC_NUM; i++)		// NOR_DAT_SEC_NUM 4095
	{
		if (flag < rdata[i])
		{
			flag = rdata[i];			// 取最大值,得到写入的最大记录字节
			idx = i;
		}
	}

	if (flag == 0)
	{
		// 擦除扇区
		printf("Erase NOR_DAT_MANAGE\r\n");
		DatFlash4kErase(NOR_DAT_MANAGE, 1);
		flag = 0xff;
		idx = 0;
	}

	flag >>= 1;		//

	g_norManager.wrflag = flag;
	g_norManager.begSecIdx = idx;
	g_norManager.queueSecNum = 0;
	g_norManager.releaseFlag = 0;

//	printf("InitNorSectorManage, wrflag=0x%x, begSecIdx=%d, queueSecNum=%d\r\n", g_norManager.wrflag, g_norManager.begSecIdx, g_norManager.queueSecNum);
}

// 通过扇区索引，得到扇区地址
u32 GetAddrFromSecIdx(int sidx)
{
	sidx += g_norManager.begSecIdx;
	while (sidx >= NOR_DAT_SEC_NUM)
	{
		sidx -= NOR_DAT_SEC_NUM;
	}
	return NOR_FILE_DATA + sidx * (SNF_BYTES_PER_SEC);
}

// 通过数据索引和数据大小，得到数据首地址
u32 GetAddrFromDatIdx(int didx, int size)
{
	u32 addr;
	u32 sidx, sofst;

	sidx = didx * size / (SNF_BYTES_PER_SEC);		// 扇区逻辑地址
	sofst = (didx * size) % (SNF_BYTES_PER_SEC);	// 扇区内偏移

	addr = GetAddrFromSecIdx(sidx) + sofst;

	return addr;
}

u32 GetAddrFromLAddr(int laddr, int size)
{
	u32 addr;
	u32 sidx, sofst;

	sidx = laddr / (SNF_BYTES_PER_SEC);		// 扇区逻辑地址
	sofst = laddr % (SNF_BYTES_PER_SEC);	// 扇区内偏移

	addr = GetAddrFromSecIdx(sidx) + sofst;

	return addr;
}

// 根据占据内存，分配占用空间，设置标志
// allocBytes:需要分配的字节数
void NorAllocAndSetUsingFlags(int allocBytes)
{
	int i, idx;
	int alcsecs;		// 占用扇区数
	u8 rdata[SNF_BYTES_PER_SEC];

	// 计算占用扇区数
	alcsecs = allocBytes + (SNF_BYTES_PER_SEC-1);
	alcsecs /= (SNF_BYTES_PER_SEC);		// 占用扇区数

	printf("NorAllocAndSetUsingFlags, allocbyte=%d, alcsecs=%d\r\n", allocBytes, alcsecs);

	g_norManager.begSecIdx += g_norManager.queueSecNum;
	while (g_norManager.begSecIdx >= NOR_DAT_SEC_NUM)
	{
		g_norManager.begSecIdx -= NOR_DAT_SEC_NUM;
	}

	printf("before alloc, begsecidx=%d, queuenum=%d, wrflag=0x%x\r\n", g_norManager.begSecIdx, g_norManager.queueSecNum, g_norManager.wrflag);

	if (alcsecs > NOR_DAT_SEC_NUM)
	{
		printf("alcsecs=%d > %d\r\n", alcsecs, NOR_DAT_SEC_NUM);
		alcsecs = NOR_DAT_SEC_NUM;
	}

	DatFlashRdData(NOR_DAT_MANAGE, rdata, SNF_BYTES_PER_SEC);		// 读取记录字节

	g_norManager.queueSecNum = 0;
	for (i = 0, idx = g_norManager.begSecIdx; i < alcsecs; i++)
	{
		g_norManager.queueSecNum++;		// 计数增加

		// 设置标志
		rdata[idx] = g_norManager.wrflag;

		// 索引增加
		idx++;
		if (idx >= NOR_DAT_SEC_NUM)
		{
			idx = 0;
			if (g_norManager.wrflag == 0)
			{
				DatFlash4kErase(NOR_DAT_MANAGE, 1);
				memset(rdata, 0xff, SNF_BYTES_PER_SEC);
				g_norManager.wrflag = 0xff;
				printf("re erase dat manage\r\n");
			}

			g_norManager.wrflag >>= 1;
			printf("nor alloc queue return to 0, wrflag=0x%x\r\n", g_norManager.wrflag);
		}
	}

	if (g_norManager.queueSecNum != alcsecs)		// 验证分配个数
	{
		printf("Error: g_norManager.queueSecNum not euq alcsecs\r\n");
	}

	printf("after alloc, begsecidx=%d, queuenum=%d, wrflag=0x%x\r\n", g_norManager.begSecIdx, g_norManager.queueSecNum, g_norManager.wrflag);

	g_norManager.releaseFlag = 0;
	DatFlashWrData(NOR_DAT_MANAGE, rdata, SNF_BYTES_PER_SEC);
}

//-------------------------------------------------------------------------------
// 擦除数据，释放空间
// sync:同步标志    0,同步擦除   1,异步擦除
int ReleaseSpace(int sync)
{
	static int eraseidx = -1;		// 擦除ID
	if (sync != 0 && eraseidx == -1)
	{
		eraseidx = 0;
		g_norManager.releaseFlag = 1;
	}

	if (g_norManager.releaseFlag == 0)
	{
		eraseidx = 0;
		g_norManager.releaseFlag++;
	}
	else if (g_norManager.releaseFlag == 1)
	{
		if (g_norManager.queueSecNum != 0)		// 分配的扇区不为0
		{
			u32 eaddr;
			int idx, erflag;
			printf("ReleaseSpace, secnum=%d, eraseidx=%d, sync=%d\r\n", g_norManager.queueSecNum, eraseidx, sync);

			for (idx = eraseidx; idx < g_norManager.queueSecNum; idx++)
			{
				eaddr = GetAddrFromSecIdx(idx);
				erflag = IsDatFlashEmpty(eaddr, SNF_BYTES_PER_SEC);
				if (erflag != 0)
				{
					printf("DatFlash4kErase eaddr=0x%x\r\n", eaddr);
					DatFlash4kErase(eaddr, 1);
				}
				if (sync == 0)
				{
					idx++;
					break;
				}
			}
			eraseidx = idx;
			if (eraseidx >= g_norManager.queueSecNum)
			{
				eraseidx = -1;
				g_norManager.releaseFlag = 2;
			}
		}
		else
		{
			g_norManager.releaseFlag = -1;	// 小数据文件,不使用norflash,无需擦除
		}
	}
	return g_norManager.releaseFlag;
}

//-------------------------------------------------------------------------------
// 数据存储在上位机（通过网络动态传输）


int GetADataItem(u8 fileBlk, u32 idx, DataItem * pDat)
{
	return GetADataItemBase(fileBlk, idx, pDat, 1);
}

int GetADataItemNoSqrt(u8 fileBlk, u32 idx, DataItem * pDat)
{
	return GetADataItemBase(fileBlk, idx, pDat, 0);
}

//-------------------------------------------------------------------------------
/* return : 0:正常
 *			-1:参数错误或文件存储方式不支持或数据格式不支持
 * 			-2:没有找到索引值idx
 * para:fileBlk,暂时无用
 *      sqrtflag,是否平方根计算len,较耗时
 */
int GetADataItemBase(u8 fileBlk, u32 idx, DataItem * pDat, int sqrtflag)
{
	u32 address;

	// 20231115
	if (idx >= g_datFile.pFileHead->fileHead.itemNums)
	{
		printf("GetADataItem error, idx=%d > %d\r\n", idx, g_datFile.pFileHead->fileHead.itemNums);
		return -1;
	}

	if (pDat == NULL)
	{
		return -1;
	}

	if (g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(Ds16Item))		// Ds16数据
	{
		if (g_datFile.storage == STORAGE_EXSRAM)	// 文件存储在存储在SRAM中
		{
			if (idx >= DS16ITEMSIZE)
			{
				memset(pDat, 0, sizeof(DataItem));
				return -1;
			}

			{
				Ds16Item * pDs16Item;

				if (idx < DS16ITEMSIZE_AT_BUF1)
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff1BegAddr);
					pDs16Item += idx;
				}
				else
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff2BegAddr);
					pDs16Item += (idx - DS16ITEMSIZE_AT_BUF1);
				}
				memcpy(pDat, pDs16Item, sizeof(Ds16Item));
			}
		}
		else if (g_datFile.storage == STORAGE_SPAREARAM)	// 边框刺绣数据文件(也包括花样轮廓和开位线绣)
		{
			if (idx >= DS16FRAMESIZE)
			{
				memset(pDat, 0, sizeof(DataItem));
				return -1;
			}

			{
				Ds16Item * pDs16Item;

				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff3BegAddr);
					pDs16Item += idx;
				}
				memcpy(pDat, pDs16Item, sizeof(Ds16Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NORFLASH)		// 文件存储在NORFlash中
		{
			u32 daddr;
			if (idx >= DS16SIZEINNOR)
			{
				memset(pDat, 0, sizeof(DataItem));
				return -1;
			}
			daddr = NOR_FILE_DATA+idx*sizeof(Ds16Item);
			address = (u32)pDat;
			DatFlashRdData(daddr, (u8*)(address), sizeof(Ds16Item));
		}
		else if (g_datFile.storage == STORAGE_SRAMANDNOR)
		{
			if (idx >= (DS16ITEMSIZE+DS16SIZEINNOR))
			{
				memset(pDat, 0, sizeof(DataItem));
				return -1;
			}

			if (idx < DS16ITEMSIZE)
			{
				Ds16Item * pDs16Item;

				if (idx < DS16ITEMSIZE_AT_BUF1)
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff1BegAddr);
					pDs16Item += idx;
				}
				else
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff2BegAddr);
					pDs16Item += (idx - DS16ITEMSIZE_AT_BUF1);
				}
				memcpy(pDat, pDs16Item, sizeof(Ds16Item));
			}
			else
			{
				u32 daddr;
				daddr = GetAddrFromDatIdx(idx-DS16ITEMSIZE, sizeof(Ds16Item));
				address = (u32)pDat;
				DatFlashRdData(daddr, (u8*)(address), sizeof(Ds16Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NETWORK)
		{
			int i;
			u32 dataddr;

			for (i = 0; i < FILE_EXBUF_NUM; i++)
			{
				if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID)
				{
					dataddr = idx * sizeof(Ds16Item);		// 数据在文件中的地址

					if ((dataddr >= g_datFile.pDatExCtrl->datExBeg[i]) && 
						(dataddr < g_datFile.pDatExCtrl->datExBeg[i]+DAT_BLOCK_SIZE)	)	// 在范围内，命中
					{
						dataddr -= g_datFile.pDatExCtrl->datExBeg[i];				// 数据在块内的地址（相对地址）
						dataddr += (s32)(&(g_datFile.pDatExCtrl->datExBlock[i]));	// 数据在缓冲区的地址（实际地址）

						memcpy(pDat, (u8*)dataddr, sizeof(DataItem));
						break;
					}
				}
			}
			if (i == FILE_EXBUF_NUM)
			{
				printf("not found the data of idx=%d\r\n", idx);
				return -2;
			}
		}
		else	// 不支持的存储方式
		{
			printf("error2, not support storage\r\n");
			return -1;
		}
	}
	else if (g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(Ds8Item))	// Ds8数据
	{
		if (g_datFile.storage == STORAGE_EXSRAM)
		{
			if (idx >= DS8ITEMSIZE)
			{
				memset(pDat, 0, sizeof(Ds8Item));
				return -1;
			}

			{
				Ds8Item * pDs8Item;

				if (idx < DS8ITEMSIZE_AT_BUF1)
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff1BegAddr);
					pDs8Item += idx;
				}
				else
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff2BegAddr);
					pDs8Item += (idx - DS8ITEMSIZE_AT_BUF1);
				}
				memcpy(pDat, pDs8Item, sizeof(Ds8Item));
			}
		}
		else if (g_datFile.storage == STORAGE_SPAREARAM)
		{
			if (idx >= DS8FRAMESIZE)
			{
				memset(pDat, 0, sizeof(Ds8Item));
				return -1;
			}

			{
				Ds8Item * pDs8Item;

				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff3BegAddr);
					pDs8Item += idx;
				}
				memcpy(pDat, pDs8Item, sizeof(Ds8Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NORFLASH)
		{
			u32 daddr;
			if (idx >= DS8SIZEINNOR)
			{
				memset(pDat, 0, sizeof(Ds8Item));
				return -1;
			}
			daddr = NOR_FILE_DATA+idx*sizeof(Ds8Item);
			address = (u32)pDat;

			DatFlashRdData(daddr, (u8*)(address), sizeof(Ds8Item));
		}
		else if (g_datFile.storage == STORAGE_SRAMANDNOR)
		{
			if (idx >= (DS8ITEMSIZE+DS8SIZEINNOR))
			{
				memset(pDat, 0, sizeof(Ds8Item));
				return -1;
			}

			if (idx < DS8ITEMSIZE)
			{
				Ds8Item * pDs8Item;

				if (idx < DS8ITEMSIZE_AT_BUF1)
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff1BegAddr);
					pDs8Item += idx;
				}
				else
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff2BegAddr);
					pDs8Item += (idx - DS8ITEMSIZE_AT_BUF1);
				}
				memcpy(pDat, pDs8Item, sizeof(Ds8Item));
			}
			else
			{
				u32 daddr;
				daddr = GetAddrFromDatIdx(idx-DS8ITEMSIZE, sizeof(Ds8Item));
				address = (u32)pDat;
				DatFlashRdData(daddr, (u8*)(address), sizeof(Ds8Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NETWORK)
		{
			int i;
			u32 dataddr;

			for (i = 0; i < FILE_EXBUF_NUM; i++)
			{
				if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID)
				{
					dataddr = idx * sizeof(Ds8Item);		// 数据在文件中的地址

					if ((dataddr >= g_datFile.pDatExCtrl->datExBeg[i]) && 
						(dataddr < g_datFile.pDatExCtrl->datExBeg[i]+DAT_BLOCK_SIZE)	)	// 在范围内，命中
					{
						dataddr -= g_datFile.pDatExCtrl->datExBeg[i];				// 数据在块内的地址（相对地址）
						dataddr += (s32)(&(g_datFile.pDatExCtrl->datExBlock[i]));	// 数据在缓冲区的地址（实际地址）

						memcpy(pDat, (u8*)dataddr, sizeof(Ds8Item));
						break;
					}
				}
			}
			if (i == FILE_EXBUF_NUM)
			{
				printf("not found the data of idx=%d\r\n", idx);
				return -2;
			}
		}
		else
		{
			return -1;
		}

#if (1)
		if (sqrtflag != 0)
		{
			pDat->len = sqrt(pDat->dx*pDat->dx + pDat->dy*pDat->dy);
		}
#else
		pDat->len = 0;
#endif
	//	memset(pDat->rev, 0, 6);
	}
	else if (g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(Ds4Item))
	{
		Ds4Item dsr;
		if (g_datFile.storage == STORAGE_EXSRAM)
		{
			if (idx >= DS4ITEMSIZE)
			{
				memset(pDat, 0, sizeof(Ds4Item));
				return -1;
			}

			Ds4Item * pDs4Item = &dsr;

			if (idx < DS4ITEMSIZE_AT_BUF1)
			{
				pDs4Item = (Ds4Item*)(g_datFile.dataBuff1BegAddr);
				pDs4Item += idx;
			}
			else
			{
				pDs4Item = (Ds4Item*)(g_datFile.dataBuff2BegAddr);
				pDs4Item += (idx - DS4ITEMSIZE_AT_BUF1);
			}
			memcpy(pDat, pDs4Item, sizeof(Ds4Item));
		}
		else if (g_datFile.storage == STORAGE_SPAREARAM)
		{
			if (idx >= DS4FRAMESIZE)
			{
				memset(pDat, 0, sizeof(Ds4Item));
				return -1;
			}

			Ds4Item * pDs4Item = &dsr;

			{
				pDs4Item = (Ds4Item*)(g_datFile.dataBuff3BegAddr);
				pDs4Item += idx;
			}
			memcpy(pDat, pDs4Item, sizeof(Ds4Item));
		}
		else if (g_datFile.storage == STORAGE_NORFLASH)
		{
			u32 daddr;
			if (idx >= DS4SIZEINNOR)
			{
				memset(pDat, 0, sizeof(Ds4Item));
				return -1;
			}
			daddr = NOR_FILE_DATA+idx*sizeof(Ds4Item);
			address = (u32)(&dsr);
			DatFlashRdData(daddr, (u8*)(address), sizeof(Ds4Item));
		}
		else if (g_datFile.storage == STORAGE_SRAMANDNOR)
		{
			if (idx >= (DS4ITEMSIZE+DS4SIZEINNOR))
			{
				memset(pDat, 0, sizeof(Ds4Item));
				return -1;
			}

			if (idx < DS4ITEMSIZE)
			{
				Ds4Item * pDs4Item = &dsr;

				if (idx < DS4ITEMSIZE_AT_BUF1)
				{
					pDs4Item = (Ds4Item*)(g_datFile.dataBuff1BegAddr);
					pDs4Item += idx;
				}
				else
				{
					pDs4Item = (Ds4Item*)(g_datFile.dataBuff2BegAddr);
					pDs4Item += (idx - DS4ITEMSIZE_AT_BUF1);
				}
				memcpy(pDat, pDs4Item, sizeof(Ds4Item));
			}
			else
			{
				u32 daddr;
				daddr = GetAddrFromDatIdx(idx-DS4ITEMSIZE, sizeof(Ds4Item));
				address = (u32)(&dsr);
				DatFlashRdData(daddr, (u8*)(address), sizeof(Ds4Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NETWORK)
		{
			int i;
			u32 dataddr;

			for (i = 0; i < FILE_EXBUF_NUM; i++)
			{
				if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID)
				{
					dataddr = idx * sizeof(Ds4Item);		// 数据在文件中的地址

					if ((dataddr >= g_datFile.pDatExCtrl->datExBeg[i]) && 
						(dataddr < g_datFile.pDatExCtrl->datExBeg[i]+DAT_BLOCK_SIZE)	)	// 在范围内，命中
					{
						dataddr -= g_datFile.pDatExCtrl->datExBeg[i];				// 数据在块内的地址（相对地址）
						dataddr += (s32)(&(g_datFile.pDatExCtrl->datExBlock[i]));	// 数据在缓冲区的地址（实际地址）

						memcpy(&dsr, (u8*)dataddr, sizeof(Ds4Item));
						break;
					}
				}
			}
			if (i == FILE_EXBUF_NUM)
			{
				printf("not found the data of idx=%d\r\n", idx);
				return -2;
			}
		}
		else
		{
			return -1;
		}

		pDat->ctrl = dsr.ctrl;
		pDat->attr = 0;
		pDat->dx = dsr.dx;
		pDat->dy = dsr.dx;
		pDat->dr = 0;

		// 方向属性
		if ((dsr.attr & 0x80) != 0)
		{
			pDat->dx *= -10;
		}
		else
		{
			pDat->dx *= 10;
		}

		if ((dsr.attr & 0x40) != 0)
		{
			pDat->dy *= -10;
		}
		else
		{
			pDat->dy *= 10;
		}

		// 其他属性...

#if (1)
		if (sqrtflag != 0)
		{
			pDat->len = sqrt(pDat->dx*pDat->dx + pDat->dy*pDat->dy);
		}
#else
		pDat->len = 0;
#endif
	//	memset(pDat->rev, 0, 6);
	}
	else		// 非Ds16,Ds8,Ds4
	{
		return -1;
	}

	return 0;
}

int WriteADataItem(u8 fileBlk, u32 idx, DataItem * pDat)
{
	if (g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(Ds16Item))
	{
		if (g_datFile.storage == STORAGE_EXSRAM)
		{
			if (idx > DS16ITEMSIZE ||
				pDat == NULL || 
				0	)
			{
				return -1;
			}

			{
				Ds16Item * pDs16Item;

				if (idx < DS16ITEMSIZE_AT_BUF1)
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff1BegAddr);
					pDs16Item += idx;
				}
				else
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff2BegAddr);
					pDs16Item += (idx - DS16ITEMSIZE_AT_BUF1);
				}
				memcpy(pDs16Item, pDat, sizeof(Ds16Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NORFLASH)
		{
			return -1;
		}
		else if (g_datFile.storage == STORAGE_SRAMANDNOR)
		{
			if (idx >= (DS16ITEMSIZE+DS16SIZEINNOR) ||
				pDat == NULL ||
				0	)
			{
				return -1;
			}

			if (idx < DS16ITEMSIZE)
			{
				Ds16Item * pDs16Item;

				if (idx < DS16ITEMSIZE_AT_BUF1)
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff1BegAddr);
					pDs16Item += idx;
				}
				else
				{
					pDs16Item = (Ds16Item*)(g_datFile.dataBuff2BegAddr);
					pDs16Item += (idx - DS16ITEMSIZE_AT_BUF1);
				}
				memcpy(pDs16Item, pDat, sizeof(Ds16Item));
			}
			else
			{
/*				// 不支持写入单个针步......

				u32 daddr;
				daddr = GetAddrFromDatIdx(idx-DS16ITEMSIZE, sizeof(Ds16Item));
				address = (u32)pDat;

				NFlashWrData(daddr, (u16*)address, sizeof(Ds16Item)/2);
*/
				return -1;
			}


		}
		else if (g_datFile.storage == STORAGE_NETWORK)
		{
			return -1;			
		}
		else
		{
			return -1;
		}

	}
	else if (g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(Ds8Item))
	{
		if (g_datFile.storage == STORAGE_EXSRAM)
		{
			if (idx > DS8ITEMSIZE || 
				pDat == NULL || 
				0	)
			{
				return -1;
			}

			{
				Ds8Item * pDs8Item;

				if (idx < DS8ITEMSIZE_AT_BUF1)
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff1BegAddr);
					pDs8Item += idx;
				}
				else
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff2BegAddr);
					pDs8Item += (idx - DS8ITEMSIZE_AT_BUF1);
				}
				memcpy(pDs8Item, pDat, sizeof(Ds8Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NORFLASH)
		{
			return -1;
		}
		else if (g_datFile.storage == STORAGE_SRAMANDNOR)
		{
			if (idx >= (DS8ITEMSIZE+DS8SIZEINNOR) ||
				pDat == NULL ||
				0	)
			{
				return -1;
			}

			if (idx < DS8ITEMSIZE)
			{
				Ds8Item * pDs8Item;

				if (idx < DS8ITEMSIZE_AT_BUF1)
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff1BegAddr);
					pDs8Item += idx;
				}
				else
				{
					pDs8Item = (Ds8Item*)(g_datFile.dataBuff2BegAddr);
					pDs8Item += (idx - DS8ITEMSIZE_AT_BUF1);
				}
				memcpy(pDs8Item, pDat, sizeof(Ds8Item));
			}
			else
			{
/*		// 不支持单个针步写入
				u32 daddr;
				daddr = GetAddrFromDatIdx(idx-DS8ITEMSIZE, sizeof(Ds8Item));
				address = (u32)pDat;
				NFlashWrData(daddr, (u16*)address, sizeof(Ds8Item)/2);
*/
				return -1;
			}
		}
		else if (g_datFile.storage == STORAGE_NETWORK)
		{
			return -1;
		}
		else
		{
			return -1;
		}

	}
	else if (g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(Ds4Item))
	{
		Ds4Item dsr;

		dsr.ctrl = pDat->ctrl;
		dsr.attr = pDat->attr;
		dsr.dx = pDat->dx / 10;
		dsr.dx = pDat->dy / 10;

		if (g_datFile.storage == STORAGE_EXSRAM)
		{
			if (idx >= (DS4ITEMSIZE) ||
				pDat == NULL ||
				0	)
			{
				return -1;
			}

			{
				Ds4Item * pDs4Item = &dsr;

				if (idx < DS4ITEMSIZE_AT_BUF1)
				{
					pDs4Item = (Ds4Item*)(g_datFile.dataBuff1BegAddr);
					pDs4Item += idx;
				}
				else
				{
					pDs4Item = (Ds4Item*)(g_datFile.dataBuff2BegAddr);
					pDs4Item += (idx - DS4ITEMSIZE_AT_BUF1);
				}
				memcpy(pDs4Item, pDat, sizeof(Ds4Item));
			}
		}
		else if (g_datFile.storage == STORAGE_NORFLASH)
		{
			return -1;
		}
		else if (g_datFile.storage == STORAGE_SRAMANDNOR)
		{
			if (idx >= (DS4ITEMSIZE+DS4SIZEINNOR) ||
				pDat == NULL ||
				0	)
			{
				return -1;
			}

			if (idx < DS4ITEMSIZE)
			{
				Ds4Item * pDs4Item = &dsr;

				if (idx < DS4ITEMSIZE_AT_BUF1)
				{
					pDs4Item = (Ds4Item*)(g_datFile.dataBuff1BegAddr);
					pDs4Item += idx;
				}
				else
				{
					pDs4Item = (Ds4Item*)(g_datFile.dataBuff2BegAddr);
					pDs4Item += (idx - DS4ITEMSIZE_AT_BUF1);
				}
				memcpy(pDat, pDs4Item, sizeof(Ds4Item));
			}
			else
			{
/*		// 不支持单个针步写入
				u32 daddr;
				daddr = GetAddrFromDatIdx(idx-DS4ITEMSIZE, sizeof(Ds4Item));
				address = (u32)(&dsr);
				NFlashWrData(daddr, (u16*)(address), sizeof(Ds4Item)/2);
*/
			}

			return -1;
		}
		else if (g_datFile.storage == STORAGE_NETWORK)
		{
			return -1;
		}
		else
		{
			return -1;
		}
	}
	else
	{
		return -1;
	}

	return 0;
}

// begaddr 逻辑存储地址
int WriteFileData(u8 fileBlk, u32 begaddr, u8 * pBuf, u32 size)
{
	if (pBuf == NULL)
	{
		return -1;
	}

	if (g_datFile.storage == STORAGE_EXSRAM)
	{
		u8 * pData;
		if (begaddr+size <= g_datFile.dataBuff1Len)
		{
			pData = (u8 *)(g_datFile.dataBuff1BegAddr + begaddr);
		}
		else if (begaddr+size <= g_datFile.dataBuff1Len+g_datFile.dataBuff2Len)
		{
			pData = (u8 *)(g_datFile.dataBuff2BegAddr + begaddr - g_datFile.dataBuff1Len);
		}
		else
		{
			return -1;
		}

//		printf("WriteFileData from 0x%x to 0x%x, size=%d\r\n", (u32)pBuf, (u32)pData, size);
		memcpy(pData, pBuf, size);
	}
	else if (g_datFile.storage == STORAGE_SPAREARAM)
	{
		u8 * pData;
		if (begaddr+size <= g_datFile.dataBuff3Len)
		{
			pData = (u8 *)(g_datFile.dataBuff3BegAddr + begaddr);
		}
		else
		{
			return -1;
		}

//		printf("WriteFileData from 0x%x to 0x%x, size=%d\r\n", (u32)pBuf, (u32)pData, size);
		memcpy(pData, pBuf, size);
	}
	else if (g_datFile.storage == STORAGE_NORFLASH)
	{
		if ((begaddr+size) > DS16SIZEINNOR*sizeof(Ds16Item) ||
			0	)
		{
			return -1;
		}

		DatFlashWrDataWithErase(NOR_FILE_DATA+begaddr, (u8*)pBuf, size);
	}
	else if (g_datFile.storage == STORAGE_SRAMANDNOR)
	{
		u8 * pData;

		if (begaddr+size <= g_datFile.dataBuff1Len)
		{
			pData = (u8 *)(g_datFile.dataBuff1BegAddr + begaddr);
			memcpy(pData, pBuf, size);
//			printf("WriteFileData from 0x%x to 0x%x, size=%d\r\n", (u32)pBuf, (u32)pData, size);
		}
		else if (begaddr+size <= g_datFile.dataBuff1Len+g_datFile.dataBuff2Len)
		{
			pData = (u8 *)(g_datFile.dataBuff2BegAddr + begaddr - g_datFile.dataBuff1Len);
			memcpy(pData, pBuf, size);
//			printf("WriteFileData from 0x%x to 0x%x, size=%d\r\n", (u32)pBuf, (u32)pData, size);
		}
		else if (begaddr+size <= g_datFile.dataBuff1Len+g_datFile.dataBuff2Len+MAX_NOR_FILE_SIZE)
		{
			u32 daddr;

		//	ReleaseSpace(1);

			daddr = GetAddrFromLAddr(begaddr-(g_datFile.dataBuff1Len+g_datFile.dataBuff2Len), size);
			DatFlashWrDataWithErase(daddr, (u8*)pBuf, size);
		}
		else
		{
			return -1;
		}
	}
	else if (g_datFile.storage == STORAGE_NETWORK)
	{
		u32 blkidx, blkaddr;
		int bufidx;
		if ((size) != DAT_BLOCK_SIZE || 					// 只能存储1个数据包的大小
			(begaddr) >= g_datFile.pFileHead->fileHead.dataSize ||
			0	)
		{
			printf("(size=%d) != DAT_BLOCK_SIZE or (begaddr=%d) > (dataSize=%d)\r\n", size, begaddr, g_datFile.pFileHead->fileHead.dataSize);
			return -1;
		}

		// 计算当前数据包在整个数据中的起始地址
		blkidx = begaddr / DAT_BLOCK_SIZE;		// 块号
		blkaddr = blkidx * DAT_BLOCK_SIZE;				// 块地址
		if (blkaddr != begaddr)
		{
			printf("(blkaddr=%d) != (begaddr=%d)\r\n", blkaddr, begaddr);
			return -1;
		}

		// 找到无效buf作为新数据存储区域
		bufidx = -1;
		for (int i = 0; i < FILE_EXBUF_NUM; i++)
		{
			if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID && g_datFile.pDatExCtrl->datExBeg[i] == blkaddr)	// 已存储区域有相同的存储地址
			{
				printf("save dat to same addr, blkidx=%d\r\n", blkidx);
				// 数据存在时不再重复存储
				break;
			}
			else if (g_datFile.pDatExCtrl->exbufFlag[i] == 0)
			{
				bufidx = i;
				break;
			}
		}

		if (bufidx >= 0 && bufidx < FILE_EXBUF_NUM)
		{
			u8 * pData;
			g_datFile.pDatExCtrl->exbufFlag[bufidx] = DATA_VALID;		// 增加标志计数
			g_datFile.pDatExCtrl->datExBeg[bufidx] = blkaddr;			// 记录起始地址
			pData = (u8*)(&(g_datFile.pDatExCtrl->datExBlock[bufidx]));	// 数据在buff中的实际地址
			memcpy(pData, pBuf, size);
			printf("save data bldidx=%d begaddr=0x%x to bufidx=%d\r\n", blkidx, begaddr, bufidx);
		}
	}
	return 0;
}

// 判断数据是否在缓冲区中
// return:0,索引不在当前存储范围内
int IsDatIdxInBuf(int idx)
{
	int i;
	u32 dataddr;
	int rslt = 0;

	if (g_datFile.storage == STORAGE_NETWORK)
	{
		if ((g_datFile.enflag == DATA_VALID) &&
				(g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(DataItem)) &&
				1	)
		{
			// 当前索引的数据需要在缓冲区中
			if (idx >= 0 || idx < (s32)g_datFile.pFileHead->fileHead.itemNums)
			{
				for (i = 0; i < FILE_EXBUF_NUM; i++)
				{
					if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID)
					{
						dataddr = idx * sizeof(DataItem);		// 数据在文件中的地址

						if ((dataddr >= g_datFile.pDatExCtrl->datExBeg[i]) &&
								(dataddr < g_datFile.pDatExCtrl->datExBeg[i]+DAT_BLOCK_SIZE)	)	// 在范围内，命中
						{
							rslt = 1;
							break;
						}
					}
				}
			}
		}
	}
	else
	{
		rslt = 1;
	}
	return rslt;
}

#define MAX_IDX_RANGE		7
#define MIN_IDX_RANGE		3		// 请求范围 向后:向前 7:3 当前索引所在数据块计入向后部分

// 根据索引来预先装载文件数据
int GetBlockIdxNeedtoLoad(int datidx)
{
	int curidx, curaddr, minaddr, maxaddr, maxblkaddr, tempaddr;
	int requestIdx = -1;
	int rslt;

	if (g_datFile.pFileHead->fileHead.bytesPerItem == sizeof(DataItem))
	{
		curidx = datidx;
		if (curidx < 0)
		{
			curidx = 0;
		}
		else if (curidx >= g_datFile.pFileHead->fileHead.itemNums)
		{
			curidx = g_datFile.pFileHead->fileHead.itemNums - 1;
		}

		curaddr = curidx * sizeof(Ds16Item);	// 当前索引在文件内的地址
		curaddr /= DAT_BLOCK_SIZE;
		curaddr *= DAT_BLOCK_SIZE;		// 计算当前索引所在数据块起始地址

		minaddr = curaddr - FILE_EXBUF_NUM * MIN_IDX_RANGE / 10 * DAT_BLOCK_SIZE;
		if (minaddr < 0)
		{
			minaddr = 0;
		}

		maxblkaddr = (g_datFile.pFileHead->fileHead.itemNums - 1) * sizeof(Ds16Item);
		maxblkaddr /= DAT_BLOCK_SIZE;
		maxblkaddr *= DAT_BLOCK_SIZE;

		maxaddr = curaddr + (FILE_EXBUF_NUM * MAX_IDX_RANGE / 10 - 1) * DAT_BLOCK_SIZE;
		if (maxaddr > maxblkaddr)
		{
			maxaddr = maxblkaddr;
		}

		for (int i = 0; i < FILE_EXBUF_NUM; i++)
		{
			if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID)
			{
				if (g_datFile.pDatExCtrl->datExBeg[i] < minaddr ||
						g_datFile.pDatExCtrl->datExBeg[i] > maxaddr ||
						0)
				{
					g_datFile.pDatExCtrl->exbufFlag[i] = 0;
				}
			}
		}

		tempaddr = curaddr;
		while(tempaddr <= maxaddr)
		{
			rslt = 0;
			for (int i = 0; i < FILE_EXBUF_NUM; i++)
			{
				if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID)
				{
					if (tempaddr == g_datFile.pDatExCtrl->datExBeg[i])
					{
						rslt = 1;
						break;
					}
				}
			}
			if (rslt == 0)
			{
				requestIdx = tempaddr;
				break;
			}
			else
			{
				tempaddr += DAT_BLOCK_SIZE;
			}
		}

		if (requestIdx < 0)
		{
			tempaddr = curaddr;
			while(tempaddr >= minaddr)
			{
				rslt = 0;
				for (int i = 0; i < FILE_EXBUF_NUM; i++)
				{
					if (g_datFile.pDatExCtrl->exbufFlag[i] == DATA_VALID)
					{
						if (tempaddr == g_datFile.pDatExCtrl->datExBeg[i])
						{
							rslt = 1;
							break;
						}
					}
				}
				if (rslt == 0)
				{
					requestIdx = tempaddr;
					break;
				}
				else
				{
					tempaddr -= DAT_BLOCK_SIZE;
				}
			}
		}
	}

	if (requestIdx >= 0)
	{
		requestIdx /= DAT_BLOCK_SIZE;
	}

	return requestIdx;
}

void OutFileInfo(void)
{
	printf("\r\ndata file info:\r\n");

	printf("\tenflag=0x%x, storage=0x%x, ", g_datFile.enflag, g_datFile.storage);
	if (g_datFile.storage == STORAGE_EXSRAM)
	{
		printf("data store at exsram\r\n");
	}
	else if (g_datFile.storage == STORAGE_NORFLASH)
	{
		printf("data store at norflash\r\n");
	}
	else if (g_datFile.storage == STORAGE_NANDFLASH)
	{
		printf("data store at nandflash\r\n");
	}
	else if (g_datFile.storage == STORAGE_SRAMANDNOR)
	{
		printf("data store at exsram and norflash\r\n");
	}
	else if (g_datFile.storage == STORAGE_NETWORK)
	{
		printf("data store at network\r\n");
	}
	else if (g_datFile.storage == STORAGE_SPAREARAM)
	{
		printf("data store at frame exram\r\n");
	}
	else
	{
		printf("not support storage type\r\n");
	}	

	printf("\r\n\tfilehead:\r\n");
	printf("\tfilename=%s\r\n", g_datFile.pFileHead->fileHead.fileName);
	printf("\tfilelen=%d,itemnums=%d,bytesperitem=%d,bytesperblk=%d\r\n", \
			g_datFile.pFileHead->fileHead.dataSize, g_datFile.pFileHead->fileHead.itemNums, g_datFile.pFileHead->fileHead.bytesPerItem, g_datFile.pFileHead->fileHead.bytesPerBlk);
	printf("\tchecksum=0x%x,checkCrc=0x%x\r\n", g_datFile.pFileHead->fileHead.dataChecksum, g_datFile.pFileHead->fileHead.checkCrc);

	printf("\tbegHead=%d\r\n", g_datFile.pFileHead->fileHead.begHead);

	printf("\tfileID=0x%x\r\n", g_datFile.pFileHead->fileHead.fileid);

	printf("\tanchorx=%d,anchory=%d,\r\n\tbeginx=%d,beginy=%d,beginr=%d\r\n\tminx=%d,maxx=%d,miny=%d,maxy=%d\r\n", \
			g_datFile.pFileHead->fileHead.anchorX, g_datFile.pFileHead->fileHead.anchorY, \
			g_datFile.pFileHead->fileHead.beginX, g_datFile.pFileHead->fileHead.beginY, g_datFile.pFileHead->fileHead.beginR,\
			g_datFile.pFileHead->fileHead.minX,g_datFile.pFileHead->fileHead.maxX,g_datFile.pFileHead->fileHead.minY,g_datFile.pFileHead->fileHead.maxY);

	printf("\tanchorx2=%d,anchory2=%d,\r\n\tbeginx2=%d,beginy2=%d,beginr2=%d\r\n", \
			g_datFile.pFileHead->fileHead.anchorX2, g_datFile.pFileHead->fileHead.anchorY2, \
			g_datFile.pFileHead->fileHead.beginX2, g_datFile.pFileHead->fileHead.beginY2, g_datFile.pFileHead->fileHead.beginR2);

	printf("\tEnFlag=0x%x,offsetX=%d,offsetY=%d\r\n", g_datFile.pFileHead->fileHead.EnFlag,
			g_datFile.pFileHead->fileHead.offsetX, g_datFile.pFileHead->fileHead.offsetY);

	printf("\txRepeatNums=%d,yRepeatNums=%d,xRepeatDistance=%d,yRepeatDistance=%d\r\n", g_datFile.pFileHead->fileHead.xRepeatNums,
			g_datFile.pFileHead->fileHead.yRepeatNums, g_datFile.pFileHead->fileHead.xRepeatDistance, g_datFile.pFileHead->fileHead.yRepeatDistance);
}

//---------------------------------------------------------------------------------------------------------
// 判断文件是否有效
int IsDatFileAvailable(void)
{
	if (g_datFile.enflag == DATA_VALID)
	{
		return TRUE;
	}
	return FALSE;
}

// 判断文件索引值是否有效
int IsDatIndexAvailable(u32 idx)
{
	if (IsDatFileAvailable() == TRUE)
	{
		if (idx < (s32)g_datFile.pFileHead->fileHead.itemNums)
		{
			return TRUE;
		}
	}

	return FALSE;
}

u32 GetFileItemNums(void)
{
	return g_datFile.pFileHead->fileHead.itemNums;
}

s32 GetFileWide(void)//文件宽度
{
	return (g_datFile.pFileHead->fileHead.maxX-g_datFile.pFileHead->fileHead.minX);
}

s32 GetFileHigh(void)//文件高度
{
	return (g_datFile.pFileHead->fileHead.maxY-g_datFile.pFileHead->fileHead.minY);
}

// 文件失效
int InvalidDatFile(u32 idx)
{
	printf("InvalidDatFile\r\n");

	g_datFile.enflag = 0;
	return TRUE;
}

int AvalidDatFile(u32 idx)
{
	printf("AvalidDatFile\r\n");

	g_datFile.enflag = DATA_VALID;
	return TRUE;
}

// 数据块失效
void InvalidDatBlock(void)
{
	printf("InvalidDatBlock\r\n");

	memset(&(g_datFile.pDatExCtrl->exbufFlag[0]), 0, sizeof(int)*FILE_EXBUF_NUM);	// 数据交换区域清空
}

void SetNewDatFlag(u32 idx, int en)
{
	g_datFile.newFile = en;
}

int IsNewDatFile(u32 idx)
{
	if (g_datFile.newFile != 0)
	{
		return TRUE;
	}
	return FALSE;
}


void ReSetFileParaOld(DataFilePara * pNewPara)
{
	s32 tbx, tby;
	tbx = pNewPara->beginX - g_datFile.pFileHead->fileHead.beginX;
	tby = pNewPara->beginY - g_datFile.pFileHead->fileHead.beginY;

	g_datFile.pFileHead->fileHead.minX += tbx;
	g_datFile.pFileHead->fileHead.maxX += tbx;
	g_datFile.pFileHead->fileHead.minY += tby;
	g_datFile.pFileHead->fileHead.maxY += tby;		// 起始点发生变化, 轮廓会跟着改变

	g_datFile.pFileHead->fileHead.anchorX = pNewPara->anchorX;
	g_datFile.pFileHead->fileHead.anchorY = pNewPara->anchorY;
	g_datFile.pFileHead->fileHead.beginX  = pNewPara->beginX;
	g_datFile.pFileHead->fileHead.beginY  = pNewPara->beginY;

	SetNewDatFlag(0, TRUE);
}


void ReSetFilePara(DataFileHead * pNewPara)
{
	printf("set new file para:\r\n\r\n");

#if (0)
	printf("before set, filepara:\r\n");
	OutFileInfo();
#endif

	// 比较前面字节
	
	// 拷贝参数部分

	// 20210902 适配边框刺绣
	//memcpy(g_datFile.pFileHead->headparts.fileparas, pNewPara->headparts.fileparas, sizeof(pNewPara->headparts.fileparas));
	memcpy(g_datFile.pFileHead, pNewPara, sizeof(DataFileHead));

	SetNewDatFlag(0, TRUE);

#if (0)
	printf("after set, filepara:\r\n");
	OutFileInfo();
#endif
}

// 文件参数校验
u16 GetFileParaCheckCrc(void)
{
	u16 crc;
	crc = 0;

	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.anchorX, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.anchorY, sizeof(u32));

	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.beginX, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.beginY, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.beginR, sizeof(u32));

	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.minX, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.maxX, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.minY, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.maxY, sizeof(u32));

	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.sizeX, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.sizeY, sizeof(u32));

	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.anchorX2, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.anchorY2, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.beginX2, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.beginY2, sizeof(u32));
	crc += CalcCrc16((u8*)&g_datFile.pFileHead->fileHead.beginR2, sizeof(u32));

	return crc;
}

//-------------------------------------------------------------------------

void InitTempData(int type)
{
	u8 * pData = NULL;

	if (type == TEMP_DATA1)
	{
		pData = (u8 *)(TEMP_DATA1_ADDR);
		memset(pData, 0, TEMP_DATA1_SIZE);
	}
	else if (type == TEMP_DATA2)
	{
		pData = (u8 *)(TEMP_DATA2_ADDR);
		memset(pData, 0, TEMP_DATA2_SIZE);
	}
	else if (type == TEMP_DATA3)
	{
		pData = (u8 *)(TEMP_DATA3_ADDR);
		memset(pData, 0, TEMP_DATA3_SIZE);
	}
	else if (type == TEMP_DATA4)
	{
		pData = (u8 *)(TEMP_DATA4_ADDR);
		memset(pData, 0, TEMP_DATA4_SIZE);
	}
}

u8 * GetTempData(int type)
{
	u8 * pData = NULL;

	if (type == TEMP_DATA1)
	{
		pData = (u8 *)(TEMP_DATA1_ADDR);
	}
	else if (type == TEMP_DATA2)
	{
		pData = (u8 *)(TEMP_DATA2_ADDR);
	}
	else if (type == TEMP_DATA3)
	{
		pData = (u8 *)(TEMP_DATA3_ADDR);
	}
	else if (type == TEMP_DATA4)
	{
		pData = (u8 *)(TEMP_DATA4_ADDR);
	}

	return pData;
}

int SetTempData(int type, int idx, u8 * pBuf)
{
	if (pBuf == NULL)
	{
		return -1;
	}

	u8 * pData = NULL;

	if (type == TEMP_DATA1)
	{
		if ((idx+1)*1024 <= TEMP_DATA1_SIZE)
		{
			pData = (u8 *)(TEMP_DATA1_ADDR + idx*1024);
		}
	}
	else if (type == TEMP_DATA2)
	{
		if ((idx+1)*1024 <= TEMP_DATA2_SIZE)
		{
			pData = (u8 *)(TEMP_DATA2_ADDR + idx*1024);
		}
	}
	else if (type == TEMP_DATA3)
	{
		if ((idx+1)*1024 <= TEMP_DATA3_SIZE)
		{
			pData = (u8 *)(TEMP_DATA3_ADDR + idx*1024);
		}
	}
	else if (type == TEMP_DATA4)
	{
		if ((idx+1)*1024 <= TEMP_DATA4_SIZE)
		{
			pData = (u8 *)(TEMP_DATA4_ADDR + idx*1024);
		}
	}
	else
	{
		return -3;
	}

	if (pData != NULL)
	{
		memcpy(pData, pBuf, 1024);

		return 0;
	}
	else
	{
		return -2;
	}
}

//-------------------------------------------------------------------------
int GetMinMaxFromFileDatWithAnchor(s32 * pminx, s32 * pmaxx, s32 * pminy, s32 * pmaxy)
{
	return GetMinMaxFromFileDatBase(1, pminx, pmaxx, pminy, pmaxy);
}

int GetMinMaxFromFileDat(s32 * pminx, s32 * pmaxx, s32 * pminy, s32 * pmaxy)
{
	return GetMinMaxFromFileDatBase(0, pminx, pmaxx, pminy, pmaxy);
}

int GetMinMaxFromFileDatBase(int point, s32 * pminx, s32 * pmaxx, s32 * pminy, s32 * pmaxy)
{
	s32 minx, maxx, miny, maxy, actx, acty;
	u32 idx, nums;
	DataItem item;
	int rslt;

	if (IsDatFileAvailable() != TRUE)
	{
		minx = 0;
		maxx = 0;
		miny = 0;
		maxy = 0;
	}
	else
	{
		nums = g_datFile.pFileHead->fileHead.itemNums;

		if (point == 0)
		{
			actx = g_datFile.pFileHead->fileHead.beginX;
			acty = g_datFile.pFileHead->fileHead.beginY;
		}
		else
		{
			actx = g_datFile.pFileHead->fileHead.anchorX;
			acty = g_datFile.pFileHead->fileHead.anchorY;
		}

		minx = actx;
		maxx = actx;
		miny = acty;
		maxy = acty;

		if (point == 0)
		{
			printf("file info, begx=%d, begy=%d\r\n", actx, acty);
		}
		else
		{
			printf("file info, anchorX=%d, anchorY=%d\r\n", actx, acty);
		}

		for (idx = 0; idx < nums; idx++)
		{
			rslt = GetADataItemNoSqrt(0, idx, &item);
			if (rslt != 0)
			{
				printf("get item error at GetMinMaxFromFileDatBase, rslt = %d\r\n", rslt);
				break;		// 结束
			}

			if (item.ctrl == DATA_END		||	// 结束码
				item.ctrl == DATA_NULL		|| 	// 文件结束
				item.ctrl == DATA_END_OLD	||	// 结束
				0	)
			{
				idx++;
				break;
			}

			if (item.ctrl == DATA_PAUSE 	||	// 暂停功能码
				item.ctrl == DATA_PAUSE_OLD	||	// 暂停功能码
				item.ctrl == DATA_CHGND 	||	// 换针功能码（换色）
				item.ctrl == DATA_CUTTRD	||	// 剪线功能码
				item.ctrl == DATA_CUT_OLD 	||	// 剪线功能码
				item.ctrl == DATA_ANGLE		||	// 拐点
				item.ctrl == DATA_ANGLE_OLD ||	// 拐点
				0	)
			{
				continue;
			}

			actx += item.dx;
			acty += item.dy;

			if (actx < minx)
			{
				minx = actx;
			}
			if (actx > maxx)
			{
				maxx = actx;
			}

			if (acty < miny)
			{
				miny = acty;
			}
			if (acty > maxy)
			{
				maxy = acty;
			}
		}
		g_datFile.pFileHead->fileHead.itemNums = idx;
	}

	printf("GetMinMaxFromFileDatBase, num=%d minx=%d, maxx=%d, miny=%d, maxy=%d \r\n", g_datFile.pFileHead->fileHead.itemNums, minx, maxx, miny, maxy);

	*pminx = minx;
	*pmaxx = maxx;
	*pminy = miny;
	*pmaxy = maxy;

	return 0;
}

void InitDatFiles(void)
{
	memset(&g_datFile, 0, sizeof(DatFileCtrl));

	g_datFile.pFileHead = &g_fileHead1;

	g_datFile.dataBuff1BegAddr = DATA_FILE_ADDR1;	// 存放区域1
	g_datFile.dataBuff1Len = DATA_FILE_SIZE1;

	g_datFile.dataBuff2BegAddr = DATA_FILE_ADDR2;	// 存放区域2
	g_datFile.dataBuff2Len = DATA_FILE_SIZE2;

	g_datFile.dataBuff3BegAddr = DATA3_BASE_ADDR;	// 存放区域3,用于存放边框刺绣等类型的数据文件
	g_datFile.dataBuff3Len = DATA_FILE_SIZE3;

	g_datFile.pDatExCtrl = (DatExCtrl*)g_datFile.dataBuff1BegAddr;
	g_datFile.enflag = 0;

	InitNorSpi();			// 初始化 nor flash 访问 SPI
	DatFlashInit(SetNorSpiNssOn, SetNorSpiNssOff, NorSpiReadByte, NorSpiWriteByte);

}




//---------------------------------------------------------------------------------------------------------
// 生成数据文件的算法

#if (1)

// 支持ds8 和 ds16
#define	DATA_ITEM	Ds8Item		// Ds16Item
#define SAVE_LEN	8			// 16

// 分割直线
int CalcLine(double x0, double y0, double x1, double y1, int * pactx, int * pacty, int stepSize, DATA_ITEM * pData, u8 type, s16 dr)
{
	double length, tmp;
	double stepx, stepy;
	double sx, sy;
	double xlk;
	int i, count;
	int actx, acty;
	s32 sdx, sdy;
	u8 attr;

	attr = 0;

	if (x0 == x1 && y0 == y1)
	{
		return 0;
	}

	if (x0 > x1)
	{
		sx = -1.0;				// x反向
	}
	else
	{
		sx = 1.0;
	}

	if (y0 > y1)
	{
		sy = -1.0;				// y反向
	}
	else
	{
		sy = 1.0;
	}

	// 开始分割针步
	length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));
	tmp = length/stepSize;		// 实际针步数
	count = (int)(tmp);			// 最少整针步数

	if (tmp - count >= 0.5)
	{
		count += 1;
//		printf("count++=%d\r\n", count);
	}

	if (count == 0 && length > 0)	// 短直线
	{
		count = 1;
	}

	if (pData == NULL)
	{
		return count;
	}

	actx = *pactx;
	acty = *pacty;

	if (x1 != x0 && y1 == y0)				// 横直线
	{
	//	printf("H Line: \r\n");
		sdy = 0;
		for (i = 0; i < count; i++)
		{
			tmp = ((i+1)*(length)/count)*sx + x0;	// 实际坐标

			stepx = (tmp - actx);
			sdx = (s32)(stepx+0.5*sx);

			pData[i].ctrl = type;
			pData[i].attr = attr;
			pData[i].dx = sdx;
			pData[i].dy = sdy;
			pData[i].dr = 0;

#if (SAVE_LEN == 16)
			{
				double len;
				len = sqrt(1.0*sdx*sdx + 1.0*sdy*sdy);
				pData[i].len = (u16)(len+0.9);
			}
#endif
			actx += sdx;
			acty += sdy;
		}
	}
	else if (x1 == x0 && y1 != y0)			// 竖直线
	{
	//	printf("v Line: \r\n");

		sdx = 0;
		for (i = 0; i < count; i++)
		{
			tmp = ((i+1)*(length)/count)*sy + y0;	// 实际针步

			stepy = (tmp - acty);
			sdy = (s32)(stepy+0.5*sy);

			pData[i].ctrl = type;
			pData[i].attr = attr;
			pData[i].dx = sdx;
			pData[i].dy = sdy;
			pData[i].dr = 0;

#if (SAVE_LEN == 16)
			len = sqrt(1.0*sdx*sdx + 1.0*sdy*sdy);
			pData[i].len = (u16)(len+0.9);
#endif
			actx += sdx;
			acty += sdy;
		}
	}
	else if(x1 != x0 && y1 != y0)			 // 任意斜线
	{
		// 斜率
		xlk = (y1-y0)/(x1-x0);
	//	printf("any Line: k=%f\r\n", xlk);

		for (i = 0; i < count; i++)
		{
			tmp = ((i+1)*(length)/count);	// 实际针步

			stepx = fabs(tmp*cos(atan(xlk)))*sx + x0 - actx;
			stepy = fabs(tmp*sin(atan(xlk)))*sy + y0 - acty;

			sdx = (s32)(stepx+0.5*sx);
			sdy = (s32)(stepy+0.5*sy);

			pData[i].ctrl = type;
			pData[i].attr = attr;
			pData[i].dx = sdx;
			pData[i].dy = sdy;
			pData[i].dr = 0;

#if (SAVE_LEN == 16)
			len = sqrt(1.0*sdx*sdx + 1.0*sdy*sdy);
			pData[i].len = (u16)(len+0.9);
#endif
			actx += sdx;
			acty += sdy;
		}
	}
	pData[0].dr = dr;		// 第一段数据添加r变化量

	*pactx = actx;
	*pacty = acty;

	return count;
}

//---------------------------------------------------------------------------------------------------------
// 圆弧

// 旋转坐标值
void Rotatec(double xin, double yin, double * px, double * py, double angle)
{
	*px=xin*cos(angle)-yin*sin(angle);
	*py=xin*sin(angle)+yin*cos(angle);
}

// 根据坐标确定增加方向
int ArcDir(const double x[], const double y[])
{
	double k;
	if(x[1] > x[0])
	{
		k = (y[1] - y[0]) / (x[1]-x[0]);
		if (y[2] < (k*(x[2]-x[1]) + y[1]))
		{
			return -1;
		}
		else
		{
			return 1;
		}
	}
	else if (x[1] < x[0])
	{
		k = (y[1] - y[0]) / (x[1] - x[0]);
		if (y[2] < (k * (x[2]-x[1]) + y[1]))
		{
			return 1;
		}
		else
		{
			return -1;
		}
	}
	else if ( (x[2]>x[1] && y[1]<y[0]) || (x[2]<x[1] && y[0]<y[1]) )
	{
		return 1;
	}
	else if ( (x[2]>x[1] && y[1]>y[0]) || (x[2]<x[1] && y[0]>y[1]) )
	{
		return -1;
	}
	else
	{
		printf("1. what's this case?\r\n");
		return 0;
	}
}

// 三点共线
int	IsThreePointOnALine(const double threex[], const double threey[])
{
	double	k0,k1,k2;

	if ((fabs(threex[0]-threex[1]) < 1e-6) &&
		(fabs(threex[0]-threex[2]) < 1e-6) &&
		(fabs(threex[2]-threex[1]) < 1e-6) &&
		(fabs(threey[0]-threey[1]) < 1e-6) &&
		(fabs(threey[0]-threey[2]) < 1e-6) &&
		(fabs(threey[2]-threey[1]) < 1e-6) &&
		1	)
	{
//		printf("1.IsThreePointOnALine\r\n");
		return 1;
	}
	else if (	((fabs(threex[0]-threex[1]) < 1e-6) && (fabs(threey[0]-threey[1]) < 1e-6)) || 
				((fabs(threex[0]-threex[2]) < 1e-6) && (fabs(threey[0]-threey[2]) < 1e-6)) ||
				((fabs(threex[2]-threex[1]) < 1e-6) && (fabs(threey[2]-threey[1]) < 1e-6)) ||
				0	)
	{
//		printf("2.IsThreePointOnALine\r\n");
		return 1;
	}
	else if (	(fabs(threex[0]-threex[1]) < 1e-6) &&
				(fabs(threex[0]-threex[2]) < 1e-6) &&
				(fabs(threex[2]-threex[1]) < 1e-6) &&
				1	)
	{
//		printf("3.IsThreePointOnALine\r\n");
		return 1;
	}
	else if (	(fabs(threey[0]-threey[1]) < 1e-6) &&
				(fabs(threey[0]-threey[2]) < 1e-6) &&
				(fabs(threey[2]-threey[1]) < 1e-6) && 
				1	)
	{
//		printf("4.IsThreePointOnALine\r\n");
		return 1;
	}
	else if (	(fabs(threex[2]-threex[1]) >= 1e-6) &&
				(fabs(threex[2]-threex[0]) >= 1e-6) &&
				(fabs(threex[1]-threex[0]) >= 1e-6) &&
				(fabs(threey[2]-threey[1]) >= 1e-6) &&
				(fabs(threey[2]-threey[0]) >= 1e-6) &&
				(fabs(threey[1]-threey[0]) >= 1e-6) &&
				1	)
	{
		k0 = (threey[2]-threey[1])/(threex[2]-threex[1]);
		k1 = (threey[2]-threey[0])/(threex[2]-threex[0]);
		k2 = (threey[1]-threey[0])/(threex[1]-threex[0]);

		if(fabs(k0-k1) < 1e-6 && fabs(k1-k2) < 1e-6)
		{
//			printf("5.IsThreePointOnALine\r\n");
			return 1;
		}
		else
		{
//			printf("6.IsThreePointOnALine\r\n");
			return 0;
		}
	}	
	else
	{
//		printf("7.IsThreePointOnALine\r\n");
		return 0;
	}
}

// 得到圆心和半径
int GetArcCenter(const double x[], const double y[], double * pxc, double * pyc, double * pr)
{
	long double a, b, c, d, e, f;
	double xc, yc, r;

	if (IsThreePointOnALine(x, y) == 1)
	{
		return -1;
	}

	a = 2 * (x[1]-x[0]);
	b = 2 * (y[1]-y[0]);
	c = x[1]*x[1] + y[1]*y[1] - x[0]*x[0] - y[0]*y[0];
	d = 2 * (x[2]-x[1]);
	e = 2 * (y[2]-y[1]);
	f = x[2]*x[2] + y[2]*y[2] - x[1]*x[1] - y[1]*y[1];

	xc = (b*f-e*c)/(b*d-e*a);
	yc = (d*c-a*f)/(b*d-e*a);
	r = sqrt((xc-x[0])*(xc-x[0])+(yc-y[0])*(yc-y[0]));

	*pxc = xc;
	*pyc = yc;
	*pr = r;

	return 0;
}

// 得到直线角度和角度差

s16 GetAngle(const double bx, const double by, const double ex, const double ey, int * pActAng)
{
	double cosf, angle, length;
	s32 dr;

	length = sqrt((ex-bx)*(ex-bx) + (ey-by)*(ey-by));
	if (length != 0)
	{
		// 计算直线角度（和x正方向的夹角。弧度表示，范围为 0--2PI）
		cosf = (ex-bx)/length;
		angle = acos(cosf);
		if (ey < by)
		{
			angle = 2*PI - angle;
		}

		// 角度差
		if ((angle*RADIAN_ACCURACY - *pActAng) > PI*RADIAN_ACCURACY)	// 角度差大于180度，
		{
			dr = (s32)(angle*RADIAN_ACCURACY - *pActAng - 2*PI* RADIAN_ACCURACY);		// 反向到达目标角度
			*pActAng += (int)(2*PI*RADIAN_ACCURACY)+dr;									// 实际位置
		}
		else if ((angle*RADIAN_ACCURACY - *pActAng) < (-1)*PI*RADIAN_ACCURACY)	// 角度差大于180度
		{
			dr = (s32)(angle*RADIAN_ACCURACY - *pActAng + 2*PI* RADIAN_ACCURACY);
			*pActAng += (int)(-2*PI*RADIAN_ACCURACY)+dr;								// 实际位置
		}
		else
		{
			dr = (s32)(angle*RADIAN_ACCURACY - *pActAng);		// 正向
			*pActAng += dr;
		}

		while (*pActAng > 2*PI*RADIAN_ACCURACY)
		{
			*pActAng -= 2*PI*RADIAN_ACCURACY;
		}
		while (*pActAng < 0)
		{
			*pActAng += 2*PI*RADIAN_ACCURACY;
		}

		return dr;
	}
	return 0;
}

// 分割圆弧线
int CalcCurve(double threex[], double threey[], int * pactx, int * pacty, int * pActAng, int stepSize, DATA_ITEM * pData, u8 type)
{
	u8 attr;
	s16 dx, dy, dr;

	double k, alph, increment;
	double xc, yc, r;
	double distance2;
	double curx, cury, lastx, lasty;
	double xrot, yrot;
	int actx, acty;
	int ddx, ddy;
	int count = 0;
	int i;

    dx = 0;
    dy = 0;
    dr = 0;
//	printf("Calc Curve x0=%.2f,y0=%.2f,x1=%.2f,\r\n\t y1=%.2f,x2=%.2f,y2=%.2f\r\n", threex[0],threey[0],threex[1],threey[1],threex[2],threey[2]);

	if(IsThreePointOnALine(threex, threey) == 1)	// 3点共线
	{
		// 直线和X坐标轴正方向的夹角, 公式: cosφ=∣A1A2+B1B2∣/[√(A1^2+B1^2)√(A2^2+B2^2)]
		if (pData != NULL)
		{
			dr = GetAngle(threex[0], threey[0], threex[2], threey[2], pActAng);
		}
		return CalcLine(threex[0], threey[0], threex[2], threey[2], pactx, pacty, stepSize, pData, type, dr);	// 作为直线分割
    }

	// 计算圆心和半径
	GetArcCenter(threex, threey, &xc, &yc, &r);

	printf("center=%f,%f,r=%f\r\n", xc, yc, r);

	// 计算弦长和圆心角
	distance2 = ((threex[0]-threex[2])*(threex[0]-threex[2])+(threey[0]-threey[2])*(threey[0]-threey[2]));	// 两点间距离就是弦长
	k = ((r*r+r*r)-distance2)/(2*r*r);	// cosc = (a*a + b*b - c*c)/2*a*b
	if (k < -1)
	{
		k = -1;
	}
	else if (k > 1)
	{
		k = 1;
	}

#if (0)
	distance2 = sqrt(distance2);
	printf("distance=%f, k=%f\r\n", distance2, k);
#endif

	// 圆心角
	alph = acos(k);
#if (0)
    printf("calc alph=%f\r\n", alph);
    printf("long double size=%d\r\n", sizeof(long double));
#endif
	// 区分象限和旋转方向
	k = (threex[0]-threex[1])*(threex[2]-threex[1]) + (threey[0]-threey[1])*(threey[2]-threey[1]);	// 向量 01 和 向量 21 的夹角的余弦的符号-- > 0 小于90度. < 0 大于90度 = 0, 90 度

	if (k > 0)	// 夹角小于90度, 说明弧是大于半圆
	{
		alph = 2*PI-alph;
	}
	else	// 夹角大于等于90度, 说明弧是小于等于半圆, 不需要处理
	{
	}
#if (0)
	printf("act alph=%f, arclen=%d\r\n", alph, alph*r);
#endif

	// 计算每个针步对应的弧心角大小
	if (fabsl(2*r*r-1.0*stepSize*stepSize)/(2*r*r) > 1)
	{
		increment = alph;
	}
	else
	{
		increment = (acos((2*r*r-1.0*stepSize*stepSize)/(r*r+r*r)));
	}

	// 计算分割针步数
	count = (int)(alph/increment+0.5);
	if (count == 0)
	{
		count++;
	}
//	printf("1.count=%d, increment=%f\r\n", count, increment);

	if (pData == NULL)		// 返回个数
	{
		return count;
	}

	// 重新计算每个针步弧心角
	increment = alph/count;

	// 确定针步增加的角度和方向
	increment *= ArcDir(threex, threey);
	printf("2.count=%d, increment=%f\r\n", count, increment);

	// 起点
	lastx = threex[0];
	lasty = threey[0];

	actx = *pactx;
	acty = *pacty;

	i = 0;
	do
	{
		if (i == count-1)
		{
			// 最后一个针步
//			printf("the last step\r\n");
			curx = threex[2];
			cury = threey[2];
		}
		else
		{
			// 点 (lastx, lasty) 在圆上旋转
//			printf("before Rotatec point(%f, %f)\r\n", lastx, lasty);
			Rotatec(lastx-xc, lasty-yc, &xrot, &yrot, increment);
			curx = xrot + xc;
			cury = yrot + yc;
		}

		ddx = curx-actx;
		ddy = cury-acty;

		dx = (s16)(curx-actx+(0.5*(ddx>=0?1:-1)));
		dy = (s16)(cury-acty+(0.5*(ddy>=0?1:-1)));
		dr = GetAngle(lastx, lasty, curx, cury, pActAng);		// 计算直线 (lastx, lasty) 到（curx, cury）和上条直线的角度差

		attr = 0;

		pData[i].ctrl = type;
		pData[i].attr = attr;
		pData[i].dx = dx;
		pData[i].dy = dy;
		pData[i].dr = dr;

#if (SAVE_LEN == 16)
		{
			double len;
			len = sqrt(1.0*dx*dx + 1.0*dy*dy);
			pData[i].len = (u16)(len+0.9);
		}
#endif

//		printf("after Rotatec point(%f, %f)\r\n", lastx, lasty);

		lastx = curx;
		lasty = cury;
		actx += dx;
		acty += dy;
		i++;

	} while(i < count);

	*pactx = actx;
	*pacty = acty;

	return count;
}

int CreateCommFile(SqrtInfo * pSqrt)
{
	double threex[3], threey[3];

	int begx, begy, begr, begflag;

//	int begx2, begy2, begr2, begflag2;

    int paraBLockNum, paraBLockTimes, paraBLockJumps;
    int paraELockNum, paraELockTimes, paraELockJumps;
	int blockNum, blockTimes;
	int elockNum, elockTimes;
	int blockjumps, elockjumps;
	int stepSize, sqrtNum;
	int actx, acty, actr;
	int i, j, k, idx;
	int stepNumber, curtNumber, totalNumber;
	int n, cutflag;

	u8 ctrl, oldctrl, attr;

	DATA_ITEM * pSteps, * pData, * pTemp;

	InitDatFiles();
	g_datFile.storage = STORAGE_EXSRAM;					// 存储在外部RAM中

	pSteps = (DATA_ITEM*)(g_datFile.dataBuff1BegAddr);	// 数据存放地址

	if (pSqrt == NULL)
	{
		return -1;
	}

	if (pSqrt->sqrtNum <= 0)
	{
		return -1;
	}

	
	
	
//------------------
#if (0)
	printf("SqrtInfo para:\r\n");

	printf("\t midy = %d\r\n", pSqrt->sqrtNum);
	printf("\t stepSize = %d\r\n", pSqrt->stepSize);
	printf("\t blockNum = %d\r\n", pSqrt->blockNum);
	printf("\t blockTimes = %d\r\n", pSqrt->blockTimes);
	printf("\t elockNum = %d\r\n", pSqrt->elockNum);
	printf("\t elockTimes = %d\r\n", pSqrt->elockTimes);
	printf("\t blockjumps = %d\r\n", pSqrt->blockjumps);
	printf("\t elockjumps = %d\r\n", pSqrt->elockjumps);
#endif

	sqrtNum = pSqrt->sqrtNum;			// 图形个数

	begx = pSqrt->sqrtItem[0].begx;
	begy = pSqrt->sqrtItem[0].begy;
	begr = 0;

	actx = begx;
	acty = begy;
	actr = 0;

	begflag = 0;
//	begflag2 = 0;
	totalNumber = 0;
	oldctrl = 0;
    ctrl = 0;
	cutflag = 0;

//------------------
	// 生成文件内容

	for (idx = 0; idx < sqrtNum; idx++)
	{
		stepSize = pSqrt->sqrtItem[idx].stepSize;			// 分割针步大小

		if (stepSize == 0)
		{
			stepSize = pSqrt->stepSize;			// 分割针步大小
		}

		paraBLockNum = pSqrt->sqrtItem[idx].blockNum;
		paraBLockTimes = pSqrt->sqrtItem[idx].blockTimes;
		paraBLockJumps = pSqrt->sqrtItem[idx].blockjumps;
		paraELockNum = pSqrt->sqrtItem[idx].elockNum;
		paraELockTimes = pSqrt->sqrtItem[idx].elockTimes;
		paraELockJumps = pSqrt->sqrtItem[idx].elockjumps;
#if (0)
		printf("SqrtInfo[%d] para:\r\n", idx);

		printf("\t stepSize = %d\r\n", pSqrt->sqrtItem[idx].stepSize);
		printf("\t blockNum = %d\r\n", pSqrt->sqrtItem[idx].blockNum);
		printf("\t blockTimes = %d\r\n", pSqrt->sqrtItem[idx].blockTimes);
		printf("\t blockjumps = %d\r\n", pSqrt->sqrtItem[idx].blockjumps);
		printf("\t elockNum = %d\r\n", pSqrt->sqrtItem[idx].elockNum);
		printf("\t elockTimes = %d\r\n", pSqrt->sqrtItem[idx].elockTimes);
		printf("\t elockjumps = %d\r\n", pSqrt->sqrtItem[idx].elockjumps);
#endif

		// 起始回针参数处理
		if (paraBLockTimes > 0 && paraBLockNum > 0)
		{
			if (paraBLockJumps > paraBLockTimes*paraBLockNum)
			{
				paraBLockNum = 0;
				paraBLockTimes = 0;
				paraBLockJumps = 0;
			}
		}
		else
		{
			paraBLockNum = 0;
			paraBLockTimes = 0;
			paraBLockJumps = 0;
		}
		while (paraBLockJumps >= paraBLockNum && paraBLockTimes > 1) // 保证jumps小于locknums
		{
			paraBLockJumps -= paraBLockNum;
			paraBLockTimes--;
		}

		// 结束回针参数处理
		if (paraELockTimes > 0 && paraELockNum > 0)
		{
			if (paraELockJumps > paraELockTimes*paraELockNum)
			{
				paraELockNum = 0;
				paraELockTimes = 0;
				paraELockJumps = 0;
			}
		}
		else
		{
			paraELockNum = 0;
			paraELockTimes = 0;
			paraELockJumps = 0;
		}
		while (paraELockJumps >= paraELockNum && paraELockTimes > 1) // 保证jumps小于locknums
		{
			paraELockJumps -= paraELockNum;
			paraELockTimes--;
		}
		//------------------

#if (0)
		qDebug("calc para:\r\n");

		qDebug("\t sqrtNum = %d\r\n", sqrtNum);
		qDebug("\t stepSize = %d\r\n", stepSize);
		qDebug("\t blockNum = %d\r\n", paraBLockNum);
		qDebug("\t blockTimes = %d\r\n", paraBLockTimes);
		qDebug("\t blockjumps = %d\r\n", paraBLockJumps);
		qDebug("\t elockNum = %d\r\n", paraELockNum);
		qDebug("\t elockTimes = %d\r\n", paraELockTimes);
		qDebug("\t elockjumps = %d\r\n", paraELockJumps);
#endif

#if (0)
		printf("\t begx = %f\r\n", pSqrt->sqrtItem[idx].begx);
		printf("\t begy = %f\r\n", pSqrt->sqrtItem[idx].begy);
		printf("\t endx = %f\r\n", pSqrt->sqrtItem[idx].endx);
		printf("\t endy = %f\r\n", pSqrt->sqrtItem[idx].endy);
		printf("\t midx = %f\r\n", pSqrt->sqrtItem[idx].midx);
		printf("\t midy = %f\r\n", pSqrt->sqrtItem[idx].midy);
#endif
		//------------------
		if (begflag != 0)   // 非起始，插入偏移数据
		{
			if (pSqrt->sqrtItem[idx].begx != pSqrt->sqrtItem[idx-1].endx ||
				pSqrt->sqrtItem[idx].begy != pSqrt->sqrtItem[idx-1].endy ||
				0	)
			{
				// 自动插入偏移数据
				threex[0] = pSqrt->sqrtItem[idx-1].endx;
				threey[0] = pSqrt->sqrtItem[idx-1].endy;
				threex[1] = pSqrt->sqrtItem[idx].begx;
				threey[1] = pSqrt->sqrtItem[idx].begy;
				threex[2] = pSqrt->sqrtItem[idx].begx;
				threey[2] = pSqrt->sqrtItem[idx].begy;		// 三点共线，作为直线

				stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX/2, pSteps, pSqrt->defofst);
				pSteps += stepNumber;
				totalNumber += stepNumber;
				if (stepNumber != 0)
				{
					ctrl = pSqrt->defofst;
				}
			}
		}
/*
		if (begflag2 != 0)   // 非起始，插入偏移数据
		{
			if (pSqrt->sqrtItem[idx].begx != pSqrt->sqrtItem[idx-1].endx ||
				pSqrt->sqrtItem[idx].begy != pSqrt->sqrtItem[idx-1].endy ||
				0	)
			{
				// 自动插入偏移数据
				threex[0] = pSqrt->sqrtItem[idx-1].endx;
				threey[0] = pSqrt->sqrtItem[idx-1].endy;
				threex[1] = pSqrt->sqrtItem[idx].begx;
				threey[1] = pSqrt->sqrtItem[idx].begy;
				threex[2] = pSqrt->sqrtItem[idx].begx;
				threey[2] = pSqrt->sqrtItem[idx].begy;		// 三点共线，作为直线

				stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX/2, pSteps, DATA_SECF_SEW);
				pSteps += stepNumber;
				totalNumber += stepNumber;
				if (stepNumber != 0)
				{
					ctrl = DATA_SECF_SEW;
				}
			}
		}
*/
        oldctrl = ctrl;
        ctrl = pSqrt->sqrtItem[idx].type;

        blockNum = 0;
        blockTimes = 0;
        blockjumps = 0;

        elockNum = 0;
        elockTimes = 0;
        elockjumps = 0;
        cutflag = 0;

		if (ctrl == DATA_SEWING		|| 
			ctrl == DATA_SEWING_R	||
			ctrl == DATA_SECF_SEW	||
			ctrl == DATA_SECF_SEW_R	||
			ctrl == DATA_SYNCSEW	||
			0	)
		{
			if (oldctrl != ctrl)
			{
                blockNum = paraBLockNum;						// 起始锁针针数
                blockTimes = paraBLockTimes;                    // 起始锁针次数
                blockjumps = paraBLockJumps;                    // 起针跳过针数

                if ((blockTimes%2) != 0)                        // 使回针成为偶数
                {
                    blockTimes++;
                    blockjumps += blockNum;
                }
            }

            if (    idx+1 >= sqrtNum ||
                    (pSqrt->sqrtItem[idx+1].type != ctrl &&
					   ((pSqrt->sqrtItem[idx+1].type == DATA_SEWING   && ctrl != DATA_SYNCSEW)	||
						(pSqrt->sqrtItem[idx+1].type == DATA_SECF_SEW && ctrl != DATA_SYNCSEW)	||
						(pSqrt->sqrtItem[idx+1].type == DATA_SYNCSEW  && ctrl != DATA_SEWING)	||
						(pSqrt->sqrtItem[idx+1].type == DATA_SYNCSEW  && ctrl != DATA_SECF_SEW)	||
						0	) &&

					1	) ||
                    pSqrt->sqrtItem[idx+1].begx != pSqrt->sqrtItem[idx].endx ||
                    pSqrt->sqrtItem[idx+1].begy != pSqrt->sqrtItem[idx].endy ||
                    0   )
            {
                elockNum = paraELockNum;						// 结束锁针针数
                elockTimes = paraELockTimes;                    // 结束锁针次数
                elockjumps = paraELockJumps;                    // 结束跳过针数
                if ((elockTimes%2) != 0)                        // 使回针成为偶数
                {
                    elockTimes++;
                    elockjumps += elockNum;
                }

                cutflag = 1;
            }
        }

        threex[0] = pSqrt->sqrtItem[idx].begx;
        threey[0] = pSqrt->sqrtItem[idx].begy;
        threex[1] = pSqrt->sqrtItem[idx].midx;
        threey[1] = pSqrt->sqrtItem[idx].midy;
        threex[2] = pSqrt->sqrtItem[idx].endx;
        threey[2] = pSqrt->sqrtItem[idx].endy;

        stepNumber = CalcCurve(threex, threey, NULL, NULL, NULL, stepSize, NULL, ctrl);
        curtNumber = stepNumber + blockNum*blockTimes - blockjumps + elockNum*elockTimes;		// 直接跳过起始跳过针数
	//	printf("stepNumber = %d, cur totalNumber=%d:\r\n", stepNumber, curtNumber);

		pData = pSteps + (blockNum*blockTimes) - blockjumps;		// 直接跳过起始跳过针数，不给跳过针数预留位置
		n = CalcCurve(threex, threey, &actx, &acty, &actr, stepSize, pData, ctrl);
		if (n != stepNumber)
		{
			printf("create number =%d, is not equal to stepNumber=%d:\r\n", n, stepNumber);
		}

#if (0)
		// 起始锁针信息
		printf("before add lock:\r\n");
		for (i = 0; i < curtNumber; i++)
		{
			printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
		}
#endif

        // 倒序添加起针锁针
        pTemp = pData - 1;
        k = blockTimes*blockNum;
        for (i = 0; i < blockTimes; i++)
        {
            if (i%2 == 0)	// 奇数锁针
            {
//				printf("ji shu:\r\n");
				for (j = 0; j < blockNum; j++)
				{
					// 拷贝针步
                    k--;
                    if (k < blockjumps)		// 跳过计数器
					{
					//	pTemp->ctrl = pSqrt->defofst;  // 转换为offset
					}
                    else
                    {
						memcpy(pTemp, &(pData[j]), sizeof(DATA_ITEM));
						pTemp->dx *= (-1);
						pTemp->dy *= (-1);		// 方向取反
						pTemp->dr *= (-1);		// 方向取反
                        attr = pTemp->attr;
                        attr |= ATTR_RESEW;		// 回针标志
                        pTemp->attr = attr;
						pTemp--;

						if (begflag == 0)						// 改变起点坐标
						{
							begx += pData[j].dx * 1;
							begx += pData[j].dy * 1;
							begx += pData[j].dr * 1;
						}
                    }

                }
            }
            else	// 偶数锁针
            {
//				printf("ou shu:\r\n");
                for (j = blockNum-1; j >= 0; j--)
                {
                    // 拷贝针步
                    k--;
                    if (k < blockjumps)		// 跳过计数器
                    {
					//	pTemp->ctrl = pSqrt->defofst;  // 转换为offset
                    }
                    else
                    {
						memcpy(pTemp, &(pData[j]), sizeof(DATA_ITEM));
                        attr = pTemp->attr;
                        attr |= ATTR_RESEW;		// 回针标志
                        pTemp->attr = attr;
						pTemp--;

						if (begflag == 0)						// 改变起点坐标
						{
							begx += pData[j].dx * (-1);
							begx += pData[j].dy * (-1);
							begx += pData[j].dr * (-1);
						}
					}
                }
            }
        }
        /**/
        // 正向扫描，修正起针回针中的dr
        k = blockTimes*blockNum;
        pTemp = pData - k;
        if(blockTimes != 0  )
        {
            for (i = 0; i <= blockTimes; i++)   // 跳过第一次锁针(偶数)，且
            {
                if (i%2 == 0)	// 偶数锁针
                {
                    if (i == 0)   // 第一针, 这里不做处理，后面添加单独运动dr的offset
                    {
                    }
                    else
                    {
                        pTemp->dr = 0;
                    }
                    pTemp += blockNum;
                }
                else            // 奇数锁针
                {
                    pTemp += blockNum - 1 ;
                    pTemp->dr = 0;
                    pTemp++;
                }
            }
        }

#if (0)
		// 结束锁针信息
		printf("after add begin lock:\r\n");
		for (i = 0; i < curtNumber; i++)
		{
			printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
		}
#endif

        // 顺序添加末针锁针
        pTemp = pData + stepNumber;
        k = 0;
        for (i = 0; i < elockTimes; i++)
        {
            if (i%2 == 0)	// 奇数锁针
            {
                for (j = 0; j < elockNum; j++)
                {
                    // 拷贝针步
                    memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DATA_ITEM));
                    pTemp->dx *= -1;
                    pTemp->dy *= -1;		// 方向取反
                    pTemp->dr *= -1;		// 方向取反

                    k++;
                    if (k > elockTimes*elockNum - elockjumps)		// 结束跳过计数器
                    {
                        pTemp->ctrl = pSqrt->defofst;  // 转换为offset
                    }
                    else
                    {
                        attr = pTemp->attr;
                        attr |= ATTR_RESEW;		// 回针标志
                        pTemp->attr = attr;
                    }
                    pTemp++;
                }
            }
            else
            {
                for (j = elockNum-1; j >= 0; j--)
                {
                    // 拷贝针步
                    memcpy(pTemp, &(pData[stepNumber-1-j]), sizeof(DATA_ITEM));
                    k++;
                    if (k > elockTimes*elockNum - elockjumps)		// 结束跳过计数器
                    {
                        pTemp->ctrl = pSqrt->defofst;  // 转换为offset
                    }
                    else
                    {
                        attr = pTemp->attr;
                        attr |= ATTR_RESEW;		// 回针标志
                        pTemp->attr = attr;
                    }
                    pTemp++;
                }
            }
        }

#if (0)
		printf("after add end lock:\r\n");
		for (i = 0; i < curtNumber; i++)
		{
			printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
		}
#endif

		stepNumber = curtNumber;

		if (cutflag != 0)	// 缝纫针步添加剪线码
		{
			// 添加剪线码
			pSteps[stepNumber].ctrl = DATA_CUTTRD;
			pSteps[stepNumber].attr = 0;
			pSteps[stepNumber].dx = 0;
			pSteps[stepNumber].dy = 0;
            pSteps[stepNumber].dr = 0;
			stepNumber++;
		}

#if (0)
		printf("after jump lock:\r\n");
		for (i = 0; i < curtNumber; i++)
		{
			printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pSteps[i].ctrl, pSteps[i].attr, pSteps[i].dx, pSteps[i].dy);
		}
#endif

		pSteps += stepNumber;
		totalNumber += stepNumber;
		begflag = 1;

	}	// end of for(idx......

	// 最后一针添加结束码
    pData = (DATA_ITEM*)(g_datFile.dataBuff1BegAddr);    // 源

    pData[totalNumber].ctrl = DATA_END;
    pData[totalNumber].attr = 0;
    pData[totalNumber].dx = 0;
    pData[totalNumber].dy = 0;
    pData[totalNumber].dr = 0;
	totalNumber++;	

#if (0)
    printf("after calc, begx=%d, begy=%d, stepNumber=%d\r\n", begx, begy, totalNumber);
#endif

#if (1)

    pData = (DATA_ITEM*)(g_datFile.dataBuff1BegAddr);    // 源
    begflag = 0;

    // 剪线数据移到缝纫之后
    for (i = 0; i < totalNumber; i++)
    {
        if ((pData->ctrl == DATA_SEWING || pData->ctrl == DATA_SYNCSEW))
        {
            begflag = 1;
        }
        else if (pData->ctrl == pSqrt->defofst)
        {
            if (begflag == 1)
            {
                pSteps = pData;
                begflag = 2;
            }
            else if (begflag != 2)
            {
                begflag = 0;
            }
        }
        else if (pData->ctrl == DATA_CUTTRD)
        {
            if (begflag == 2)
            {
                // 交换 pSteps 和 pData
            	DATA_ITEM tmpItem;
                memcpy(&tmpItem, pData, sizeof(DATA_ITEM));
                memcpy(pData, pSteps, sizeof(DATA_ITEM));
                memcpy(pSteps, &tmpItem, sizeof(DATA_ITEM));
            }
            begflag = 0;
        }
        else
        {
            begflag = 0;
        }
        pData++;
    }
#endif	// 剪线移到缝纫之后

    pData = (DATA_ITEM*)(g_datFile.dataBuff1BegAddr);    // 源
    pSteps = pData;             // 目标
    // 扫描生成数据，确定起点坐标，合并offset数据
    // 起点坐标

    begr = pData[0].dr;        // 第一个针步，dr是从0开始的变化量
    pData[0].dr = 0;           // 设置第一个针步的变化量为0

    i = 0;
#if (0)
    for (i = 0; i < totalNumber; i++)
    {
        if (pData->ctrl != pSqrt->defofst)   // 起始的offset合并到起点坐标
        {
            break;
        }

        begx += pData->dx;
        begy += pData->dy;
        begr += pData->dr;        // 改变起针位置
        pData++;                  // 源后移
    }
#endif

#if (0)
    {
		int offsetdr = 0;

		begflag = 0;
		actr = begr;
		// 继续扫描生成数据，合并offset数据
		for (i = i, j = 0; i < totalNumber; i++)
		{
			if (pData->ctrl == pSqrt->defofst)
			{
				if (begflag == 0)
				{
					// 初始化offset计数
					threex[0] = 0;
					threey[0] = 0;
					threex[1] = 0;
					threey[1] = 0;
					threex[2] = 0;
					threey[2] = 0;
					offsetdr = 0;
					begflag = 1;
				}

				threex[2] += pData->dx;
				threey[2] += pData->dy;
				offsetdr += pData->dr;

			}
			else
			{
				if (begflag != 0 && pData->ctrl != DATA_END)	// 可以删除结束前的offset
				{
					// 重新插入偏移数据
					actx = 0;
					acty = 0;
					stepNumber = CalcCurve(threex, threey, &actx, &acty, &actr, S16_MAX/2, pSteps, pSqrt->defofst);
					pSteps->dr = offsetdr ;

					pSteps += stepNumber;
					j += stepNumber;
					begflag = 0;
				}
				if (pSteps != pData)
				{
					memcpy(pSteps, pData, sizeof(DATA_ITEM));
				}
				j++;
				actr += pSteps->dr;
				pSteps++;
			}

			pData++;
		}

		totalNumber = j;
    }
#endif

#if (0)
	// 删除结束前的offset
    begflag = 0;
    pData = (DATA_ITEM*)(g_datFile.dataBuff1BegAddr);    // 源
	pData += totalNumber;

    // 继续扫描生成数据，合并offset数据
    for (i = i, j = 0; i < totalNumber; i++)
    {
        if (pData->ctrl == pSqrt->defofst || pData->ctrl == DATA_END)
        {
			pData->ctrl = DATA_END;
			totalNumber--;
        }
        else
        {
			break;
        }

        pData--;
    }
#endif


#if (1)
    printf("before write begx=%d, begy=%d, stepNumber=%d\r\n", begx, begy, totalNumber);
#endif


#if (1)
	// 写文件头
	strcpy(g_datFile.pFileHead->fileHead.fileName, "test.dsr");				// 文件名称
	g_datFile.pFileHead->fileHead.dataSize = totalNumber*sizeof(DATA_ITEM);	// 文件长度
	g_datFile.pFileHead->fileHead.itemNums = totalNumber;						// 有效针数
	g_datFile.pFileHead->fileHead.bytesPerItem = sizeof(DATA_ITEM);			// 每针占的字节数
	g_datFile.pFileHead->fileHead.bytesPerBlk = 1024;							// 文件内容划分块大小

    g_datFile.pFileHead->fileHead.dataChecksum = CalcCrc16((u8*)(g_datFile.dataBuff1BegAddr), g_datFile.pFileHead->fileHead.dataSize);						// 花样数据累加校验和
    g_datFile.pFileHead->fileHead.checkCrc = CalcCrc16((u8*)&(g_datFile.pFileHead), 48);

	// 前6个字段CRC校验，文件名称，文件长度，有效针数，每针字节数，数据累加和的CRC校验值
	g_datFile.pFileHead->fileHead.anchorX = begx;	// pSqrt->startx;
	g_datFile.pFileHead->fileHead.anchorY = begy;	// pSqrt->starty;		// 定位点

	g_datFile.pFileHead->fileHead.beginX = begx;	// pSqrt->startx;
	g_datFile.pFileHead->fileHead.beginY = begy;	// pSqrt->starty;
	g_datFile.pFileHead->fileHead.beginR = begr;	// 起始点坐标

	g_datFile.pFileHead->fileHead.anchorX2 = pSqrt->startx2;
	g_datFile.pFileHead->fileHead.anchorY2 = pSqrt->starty2;	// 定位点

	g_datFile.pFileHead->fileHead.beginX2 = pSqrt->startx2;
	g_datFile.pFileHead->fileHead.beginY2 = pSqrt->starty2;
	g_datFile.pFileHead->fileHead.beginR2 = 0;					// 起始点坐标

	g_datFile.enflag = DATA_VALID;

	{
		s32 minx, miny, maxx, maxy;

		GetMinMaxFromFileDat(&minx, &maxx, &miny, &maxy);

		g_datFile.pFileHead->fileHead.minX = minx;
		g_datFile.pFileHead->fileHead.maxX = maxx;
		g_datFile.pFileHead->fileHead.minY = miny;
		g_datFile.pFileHead->fileHead.maxY = maxy;
	}

#if (0)
	printf("finial write:\r\n");
	for (i = 0; i < stepNumber; i++)
	{
		printf("DataItem %d:ctrl=0x%x, attr=0x%x, dx=%d, dy=%d\r\n", i, pData[i].ctrl, pData[i].attr, pData[i].dx, pData[i].dy);
	}
#endif

#endif		// 写文件头

	return 0;
}


#if (1)

//#include "motos.h"

int WriteTestFile(int sel, int cx, int cy, int sx, int sy, int dex, int dey, u16 type, int stepSize)
{
	SqrtInfo info;

	memset(&info, 0, sizeof(SqrtInfo));

	printf("sizeof(SqrtItem)=%d, sizeof(SqrtInfo)=%d\r\n", sizeof(SqrtItem), sizeof(SqrtInfo));
	info.defofst = DATA_OFFSET;

	if (sel == 0)
	{
		// 方框
		info.sqrtItem[0].begx = cx-sx/2;
		info.sqrtItem[0].begy = cy-sy/2;
		info.sqrtItem[0].midx = cx-sx/2;
		info.sqrtItem[0].midy = cy+sy/2;
		info.sqrtItem[0].endx = cx-sx/2;
		info.sqrtItem[0].endy = cy+sy/2;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx-sx/2;
		info.sqrtItem[1].begy = cy+sy/2;
		info.sqrtItem[1].midx = cx+sx/2;
		info.sqrtItem[1].midy = cy+sy/2;
		info.sqrtItem[1].endx = cx+sx/2;
		info.sqrtItem[1].endy = cy+sy/2;
		info.sqrtItem[1].type = type;

		info.sqrtItem[2].begx = cx+sx/2;
		info.sqrtItem[2].begy = cy+sy/2;
		info.sqrtItem[2].midx = cx+sx/2;
		info.sqrtItem[2].midy = cy-sy/2;
		info.sqrtItem[2].endx = cx+sx/2;
		info.sqrtItem[2].endy = cy-sy/2;
		info.sqrtItem[2].type = type;

		info.sqrtItem[3].begx = cx+sx/2;
		info.sqrtItem[3].begy = cy-sy/2;
		info.sqrtItem[3].midx = cx-sx/2;
		info.sqrtItem[3].midy = cy-sy/2;
		info.sqrtItem[3].endx = cx-sx/2;
		info.sqrtItem[3].endy = cy-sy/2;
		info.sqrtItem[3].type = type;

	/*	info.sqrtItem[4].begx = cx-sx;
		info.sqrtItem[4].begy = cy-sy;
		info.sqrtItem[4].midx = cx;
		info.sqrtItem[4].midy = cy;
		info.sqrtItem[4].endx = cx;
		info.sqrtItem[4].endy = cy;
		info.sqrtItem[4].type = DATA_OFFSET;*/

		info.sqrtNum = 4;
	}
	else if (sel == 1)
	{
		// 圆
		info.sqrtItem[0].begx = cx;
		info.sqrtItem[0].begy = cy-sy/2;
		info.sqrtItem[0].midx = cx-sx/2;
		info.sqrtItem[0].midy = cy;
		info.sqrtItem[0].endx = cx;
		info.sqrtItem[0].endy = cy+sy/2;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx;
		info.sqrtItem[1].begy = cy+sy/2;
		info.sqrtItem[1].midx = cx+sx/2;
		info.sqrtItem[1].midy = cy;
		info.sqrtItem[1].endx = cx;
		info.sqrtItem[1].endy = cy-sy/2;
		info.sqrtItem[1].type = type;

		info.sqrtNum = 2;
	}
	else if (sel == 2)
	{
		int idx;
		idx = 0;
		while(idx < MAX_SQRT-1)
		{
			sx -= dex;
			sy -= dey;
			idx += 2;
		}

		idx = 0;
		while(idx < MAX_SQRT-1)
		{
			// 同心圆
			info.sqrtItem[idx+0].begx = cx;
			info.sqrtItem[idx+0].begy = cy-sy/2;
			info.sqrtItem[idx+0].midx = cx-sx/2;
			info.sqrtItem[idx+0].midy = cy;
			info.sqrtItem[idx+0].endx = cx;
			info.sqrtItem[idx+0].endy = cy+sy/2;
			info.sqrtItem[idx+0].type = type;

			info.sqrtItem[idx+1].begx = cx;
			info.sqrtItem[idx+1].begy = cy+sy/2;
			info.sqrtItem[idx+1].midx = cx+sx/2;
			info.sqrtItem[idx+1].midy = cy;
			info.sqrtItem[idx+1].endx = cx;
			info.sqrtItem[idx+1].endy = cy-sy/2;
			info.sqrtItem[idx+1].type = type;

			sx += dex;
			sy += dey;
			idx += 2;
		}
		info.sqrtNum = idx;
	}
	else if (sel == 3)
	{
		int idx;
		idx = 0;
		while(idx < MAX_SQRT-1)
		{
			// 同心圆
			info.sqrtItem[idx+0].begx = cx-sx/2;
			info.sqrtItem[idx+0].begy = cy;
			info.sqrtItem[idx+0].midx = cx;
			info.sqrtItem[idx+0].midy = cy+sy/2;
			info.sqrtItem[idx+0].endx = cx+sx/2;
			info.sqrtItem[idx+0].endy = cy;
			info.sqrtItem[idx+0].type = type;

			info.sqrtItem[idx+1].begx = cx+sx/2;
			info.sqrtItem[idx+1].begy = cy;
			info.sqrtItem[idx+1].midx = cx;
			info.sqrtItem[idx+1].midy = cy-sy/2;
			info.sqrtItem[idx+1].endx = cx-sx/2;
			info.sqrtItem[idx+1].endy = cy;
			info.sqrtItem[idx+1].type = type;

			sx -= dex;
			sy -= dey;
			idx += 2;
		}
		info.sqrtNum = idx;
	}
	else if (sel == 4)
	{
		// 遮阳帘裁片
		info.sqrtItem[0].begx = cx-sx/2;
		info.sqrtItem[0].begy = cy-sy/2;
		info.sqrtItem[0].midx = cx-sx/2;
		info.sqrtItem[0].midy = cy+sy/2;
		info.sqrtItem[0].endx = cx-sx/2;
		info.sqrtItem[0].endy = cy+sy/2;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx-sx/2;
		info.sqrtItem[1].begy = cy+sy/2;
		info.sqrtItem[1].midx = cx-sx/32;
		info.sqrtItem[1].midy = cy+sy/2;
		info.sqrtItem[1].endx = cx-sx/32;
		info.sqrtItem[1].endy = cy+sy/2;
		info.sqrtItem[1].type = type;

		info.sqrtItem[2].begx = cx-sx/32;
		info.sqrtItem[2].begy = cy+sy/2;
		info.sqrtItem[2].midx = cx;
		info.sqrtItem[2].midy = cy+sy/2-sy/24;
		info.sqrtItem[2].endx = cx;
		info.sqrtItem[2].endy = cy+sy/2-sy/24;
		info.sqrtItem[2].type = type;

		info.sqrtItem[3].begx = cx;
		info.sqrtItem[3].begy = cy+sy/2-sy/24;
		info.sqrtItem[3].midx = cx+sx/32;
		info.sqrtItem[3].midy = cy+sy/2;
		info.sqrtItem[3].endx = cx+sx/32;
		info.sqrtItem[3].endy = cy+sy/2;
		info.sqrtItem[3].type = type;

		info.sqrtItem[4].begx = cx+sx/32;
		info.sqrtItem[4].begy = cy+sy/2;
		info.sqrtItem[4].midx = cx+sx/2;
		info.sqrtItem[4].midy = cy+sy/2;
		info.sqrtItem[4].endx = cx+sx/2;
		info.sqrtItem[4].endy = cy+sy/2;
		info.sqrtItem[4].type = type;

		info.sqrtItem[5].begx = cx+sx/2;
		info.sqrtItem[5].begy = cy+sy/2;
		info.sqrtItem[5].midx = cx+sx/2;
		info.sqrtItem[5].midy = cy-sy/2;
		info.sqrtItem[5].endx = cx+sx/2;
		info.sqrtItem[5].endy = cy-sy/2;
		info.sqrtItem[5].type = type;

		info.sqrtItem[6].begx = cx+sx/2;
		info.sqrtItem[6].begy = cy-sy/2;
		info.sqrtItem[6].midx = cx+sx/2-sx*1/8+sx/24;
		info.sqrtItem[6].midy = cy-sy/2-sy*1/8+sy/12;
		info.sqrtItem[6].endx = cx+sx/2-sx*1/8;
		info.sqrtItem[6].endy = cy-sy/2-sy*1/8;
		info.sqrtItem[6].type = type;

		info.sqrtItem[7].begx = cx+sx/2-sx*1/8;
		info.sqrtItem[7].begy = cy-sy/2-sy*1/8;
		info.sqrtItem[7].midx = cx-sx/2+sx*1/8;
		info.sqrtItem[7].midy = cy-sy/2-sy*1/8;
		info.sqrtItem[7].endx = cx-sx/2+sx*1/8;
		info.sqrtItem[7].endy = cy-sy/2-sy*1/8;
		info.sqrtItem[7].type = type;

		info.sqrtItem[8].begx = cx-sx/2+sx*1/8;
		info.sqrtItem[8].begy = cy-sy/2-sy*1/8;
		info.sqrtItem[8].midx = cx-sx/2+sx*1/8-sx/24;
		info.sqrtItem[8].midy = cy-sy/2-sy*1/8+sy/12;
		info.sqrtItem[8].endx = cx-sx/2;
		info.sqrtItem[8].endy = cy-sy/2;
		info.sqrtItem[8].type = type;

		info.sqrtItem[9].begx = cx-sx/2;
		info.sqrtItem[9].begy = cy-sy/2;
		info.sqrtItem[9].midx = cx;
		info.sqrtItem[9].midy = cy;
		info.sqrtItem[9].endx = cx;
		info.sqrtItem[9].endy = cy;
		info.sqrtItem[9].type = DATA_OFFSET;

		info.sqrtNum = 10;
	}
	else if (sel == 5)
	{
		// Y向曲线
		info.sqrtItem[0].begx = cx;
		info.sqrtItem[0].begy = cy;
		info.sqrtItem[0].midx = cx+sx/2;
		info.sqrtItem[0].midy = cy+sy/4;
		info.sqrtItem[0].endx = cx;
		info.sqrtItem[0].endy = cy+sy/2;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx;
		info.sqrtItem[1].begy = cy+sy/2;
		info.sqrtItem[1].midx = cx-sx/2;
		info.sqrtItem[1].midy = cy+sy*3/4;
		info.sqrtItem[1].endx = cx;
		info.sqrtItem[1].endy = cy+sy;
		info.sqrtItem[1].type = type;

		info.sqrtNum = 2;
	}
	else if (sel == 6)
	{
		// Y向曲线
		info.sqrtItem[0].begx = cx;
		info.sqrtItem[0].begy = cy;
		info.sqrtItem[0].midx = cx-sx/2;
		info.sqrtItem[0].midy = cy+sy/4;
		info.sqrtItem[0].endx = cx;
		info.sqrtItem[0].endy = cy+sy/2;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx;
		info.sqrtItem[1].begy = cy+sy/2;
		info.sqrtItem[1].midx = cx+sx/2;
		info.sqrtItem[1].midy = cy+sy*3/4;
		info.sqrtItem[1].endx = cx;
		info.sqrtItem[1].endy = cy+sy;
		info.sqrtItem[1].type = type;

		info.sqrtNum = 2;
	}
	else if (sel == 7)
	{
		// Y向直线
		info.sqrtItem[0].begx = cx;
		info.sqrtItem[0].begy = cy;
		info.sqrtItem[0].midx = cx;
		info.sqrtItem[0].midy = cy;
		info.sqrtItem[0].endx = cx;
		info.sqrtItem[0].endy = cy+sy;
		info.sqrtItem[0].type = type;

		info.sqrtNum = 1;
	}
	else if (sel == 8)
	{// 格子图, dex 个x向格子 dey 个y向格子，格子大小是sx, sy
		int i,j;

		info.startx = cx;
		info.starty = cy;

		for (i = 0; i <= dey; i++)		// x线条
		{
			if ((i%2) == 0)
			{
				info.sqrtItem[i].begx = cx;
				info.sqrtItem[i].begy = cy+i*sy;
				info.sqrtItem[i].midx = cx;
				info.sqrtItem[i].midy = cy+i*sy;
				info.sqrtItem[i].endx = cx+dex*sx;
				info.sqrtItem[i].endy = cy+i*sy;
				info.sqrtItem[i].type = type;
			}
			else
			{
				info.sqrtItem[i].begx = cx+dex*sx;
				info.sqrtItem[i].begy = cy+i*sy;
				info.sqrtItem[i].midx = cx;
				info.sqrtItem[i].midy = cy+i*sy;
				info.sqrtItem[i].endx = cx;
				info.sqrtItem[i].endy = cy+i*sy;
				info.sqrtItem[i].type = type;
			}
		}
		for (j = 0; j <= dex; j++,i++)		// y线条
		{
			if ((i%2) == 0)
			{
				info.sqrtItem[i].begx = cx+(j)*sx;
				info.sqrtItem[i].begy = cy;
				info.sqrtItem[i].midx = cx+(j)*sx;
				info.sqrtItem[i].midy = cy;
				info.sqrtItem[i].endx = cx+(j)*sx;
				info.sqrtItem[i].endy = cy+dey*sy;
				info.sqrtItem[i].type = type;
			}
			else
			{
				info.sqrtItem[i].begx = cx+(j)*sx;
				info.sqrtItem[i].begy = cy+dey*sy;
				info.sqrtItem[i].midx = cx+(j)*sx;
				info.sqrtItem[i].midy = cy;
				info.sqrtItem[i].endx = cx+(j)*sx;
				info.sqrtItem[i].endy = cy;
				info.sqrtItem[i].type = type;
			}
		}
		info.sqrtNum = i;
	}
	else if (sel == 10)
	{
		// 螺旋线
		info.sqrtItem[0].begx = cx;
		info.sqrtItem[0].begy = cy-sy*12/24;
		info.sqrtItem[0].endx = cx;
		info.sqrtItem[0].endy = cy+sy*10/24;
		info.sqrtItem[0].midx = cx+sy*11/24;
		info.sqrtItem[0].midy = cy-sy*1/24;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx;
		info.sqrtItem[1].begy = cy+sy*10/24;
		info.sqrtItem[1].endx = cx;
		info.sqrtItem[1].endy = cy-sy*8/24;
		info.sqrtItem[1].midx = cx-sy*9/24;
		info.sqrtItem[1].midy = cy+sy*1/24;
		info.sqrtItem[1].type = type;

		info.sqrtItem[2].begx = cx;
		info.sqrtItem[2].begy = cy-sy*8/24;
		info.sqrtItem[2].endx = cx;
		info.sqrtItem[2].endy = cy+sy*6/24;
		info.sqrtItem[2].midx = cx+sy*7/24;
		info.sqrtItem[2].midy = cy-sy*1/24;
		info.sqrtItem[2].type = type;

		info.sqrtItem[3].begx = cx;
		info.sqrtItem[3].begy = cy+sy*6/24;
		info.sqrtItem[3].endx = cx;
		info.sqrtItem[3].endy = cy-sy*4/24;
		info.sqrtItem[3].midx = cx-sy*5/24;
		info.sqrtItem[3].midy = cy+sy*1/24;
		info.sqrtItem[3].type = type;

		info.sqrtItem[4].begx = cx;
		info.sqrtItem[4].begy = cy-sy*4/24;
		info.sqrtItem[4].endx = cx;
		info.sqrtItem[4].endy = cy;
		info.sqrtItem[4].midx = cx+sy*2/24;
		info.sqrtItem[4].midy = cy-sy*2/24;
		info.sqrtItem[4].type = type;

		info.sqrtItem[5].begx = cx;
		info.sqrtItem[5].begy = cy;
		info.sqrtItem[5].endx = cx;
		info.sqrtItem[5].endy = cy+sy*4/24;
		info.sqrtItem[5].midx = cx-sy*2/24;
		info.sqrtItem[5].midy = cy+sy*2/24;
		info.sqrtItem[5].type = type;

		info.sqrtItem[6].begx = cx;
		info.sqrtItem[6].begy = cy+sy*4/24;
		info.sqrtItem[6].endx = cx;
		info.sqrtItem[6].endy = cy-sy*6/24;
		info.sqrtItem[6].midx = cx+sy*5/24;
		info.sqrtItem[6].midy = cy-sy*1/24;
		info.sqrtItem[6].type = type;

		info.sqrtItem[7].begx = cx;
		info.sqrtItem[7].begy = cy-sy*6/24;
		info.sqrtItem[7].endx = cx;
		info.sqrtItem[7].endy = cy+sy*8/24;
		info.sqrtItem[7].midx = cx-sy*7/24;
		info.sqrtItem[7].midy = cy+sy*1/24;
		info.sqrtItem[7].type = type;

		info.sqrtItem[8].begx = cx;
		info.sqrtItem[8].begy = cy+sy*8/24;
		info.sqrtItem[8].endx = cx;
		info.sqrtItem[8].endy = cy-sy*10/24;
		info.sqrtItem[8].midx = cx+sy*9/24;
		info.sqrtItem[8].midy = cy-sy*1/24;
		info.sqrtItem[8].type = type;

		info.sqrtItem[9].begx = cx;
		info.sqrtItem[9].begy = cy-sy*10/24;
		info.sqrtItem[9].endx = cx;
		info.sqrtItem[9].endy = cy+sy*12/24;
		info.sqrtItem[9].midx = cx-sy*11/24;
		info.sqrtItem[9].midy = cy+sy*1/24;
		info.sqrtItem[9].type = type;

		info.sqrtNum = 10;
	}
	else if (sel == 11)
	{
		// 逆时针圆
		info.sqrtItem[0].begx = cx;
		info.sqrtItem[0].begy = cy-sy/2;
		info.sqrtItem[0].midx = cx+sx/2;
		info.sqrtItem[0].midy = cy;
		info.sqrtItem[0].endx = cx;
		info.sqrtItem[0].endy = cy+sy/2;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx;
		info.sqrtItem[1].begy = cy+sy/2;
		info.sqrtItem[1].midx = cx-sx/2;
		info.sqrtItem[1].midy = cy;
		info.sqrtItem[1].endx = cx;
		info.sqrtItem[1].endy = cy-sy/2;
		info.sqrtItem[1].type = type;

		info.sqrtNum = 2;
	}
	else if (sel == 12)
	{
		// 方套圆
		info.sqrtItem[0].begx = cx-sx/2;
		info.sqrtItem[0].begy = cy-sy/2;
		info.sqrtItem[0].midx = cx-sx/2;
		info.sqrtItem[0].midy = cy+sy/2;
		info.sqrtItem[0].endx = cx-sx/2;
		info.sqrtItem[0].endy = cy+sy/2;
		info.sqrtItem[0].type = type;

		info.sqrtItem[1].begx = cx-sx/2;
		info.sqrtItem[1].begy = cy+sy/2;
		info.sqrtItem[1].midx = cx+sx/2;
		info.sqrtItem[1].midy = cy+sy/2;
		info.sqrtItem[1].endx = cx+sx/2;
		info.sqrtItem[1].endy = cy+sy/2;
		info.sqrtItem[1].type = type;

		info.sqrtItem[2].begx = cx+sx/2;
		info.sqrtItem[2].begy = cy+sy/2;
		info.sqrtItem[2].midx = cx+sx/2;
		info.sqrtItem[2].midy = cy-sy/2;
		info.sqrtItem[2].endx = cx+sx/2;
		info.sqrtItem[2].endy = cy-sy/2;
		info.sqrtItem[2].type = type;

		info.sqrtItem[3].begx = cx+sx/2;
		info.sqrtItem[3].begy = cy-sy/2;
		info.sqrtItem[3].midx = cx-sx/2;
		info.sqrtItem[3].midy = cy-sy/2;
		info.sqrtItem[3].endx = cx-sx/2;
		info.sqrtItem[3].endy = cy-sy/2;
		info.sqrtItem[3].type = type;

		info.sqrtItem[4].begx = cx;
		info.sqrtItem[4].begy = cy-sy/2;
		info.sqrtItem[4].midx = cx+sx/2;
		info.sqrtItem[4].midy = cy;
		info.sqrtItem[4].endx = cx;
		info.sqrtItem[4].endy = cy+sy/2;
		info.sqrtItem[4].type = type;

		info.sqrtItem[5].begx = cx;
		info.sqrtItem[5].begy = cy+sy/2;
		info.sqrtItem[5].midx = cx-sx/2;
		info.sqrtItem[5].midy = cy;
		info.sqrtItem[5].endx = cx;
		info.sqrtItem[5].endy = cy-sy/2;
		info.sqrtItem[5].type = type;

		info.sqrtNum = 6;
	}
	else if (sel == 100)		// 冲缝绣360测试
	{
		int idx, n, bx;
		double temp;
		idx = 0;

		// 方套圆缝纫
		info.sqrtItem[idx].begx = cx-sx/2;
		info.sqrtItem[idx].begy = cy-sy/2;
		info.sqrtItem[idx].midx = cx-sx/2;
		info.sqrtItem[idx].midy = cy+sy/2;
		info.sqrtItem[idx].endx = cx-sx/2;
		info.sqrtItem[idx].endy = cy+sy/2;
		info.sqrtItem[idx].type = DATA_SEWING;
		idx++;
		info.sqrtItem[idx].begx = cx-sx/2;
		info.sqrtItem[idx].begy = cy+sy/2;
		info.sqrtItem[idx].midx = cx+sx/2;
		info.sqrtItem[idx].midy = cy+sy/2;
		info.sqrtItem[idx].endx = cx+sx/2;
		info.sqrtItem[idx].endy = cy+sy/2;
		info.sqrtItem[idx].type = DATA_SEWING;
		idx++;
		info.sqrtItem[idx].begx = cx+sx/2;
		info.sqrtItem[idx].begy = cy+sy/2;
		info.sqrtItem[idx].midx = cx+sx/2;
		info.sqrtItem[idx].midy = cy-sy/2;
		info.sqrtItem[idx].endx = cx+sx/2;
		info.sqrtItem[idx].endy = cy-sy/2;
		info.sqrtItem[idx].type = DATA_SEWING;
		idx++;
		info.sqrtItem[idx].begx = cx+sx/2;
		info.sqrtItem[idx].begy = cy-sy/2;
		info.sqrtItem[idx].midx = cx-sx/2;
		info.sqrtItem[idx].midy = cy-sy/2;
		info.sqrtItem[idx].endx = cx-sx/2;
		info.sqrtItem[idx].endy = cy-sy/2;
		info.sqrtItem[idx].type = DATA_SEWING;
		idx++;
		info.sqrtItem[idx].begx = cx;
		info.sqrtItem[idx].begy = cy-sy/2;
		info.sqrtItem[idx].midx = cx+sx/2;
		info.sqrtItem[idx].midy = cy;
		info.sqrtItem[idx].endx = cx;
		info.sqrtItem[idx].endy = cy+sy/2;
		info.sqrtItem[idx].type = DATA_SEWING;
		idx++;
		info.sqrtItem[idx].begx = cx;
		info.sqrtItem[idx].begy = cy+sy/2;
		info.sqrtItem[idx].midx = cx-sx/2;
		info.sqrtItem[idx].midy = cy;
		info.sqrtItem[idx].endx = cx;
		info.sqrtItem[idx].endy = cy-sy/2;
		info.sqrtItem[idx].type = DATA_SEWING;
		idx++;

		temp = sx;
		temp /= sqrt(2);
		sx = (int)(temp + 0.5);

		temp = sy;
		temp /= sqrt(2);
		sy = (int)(temp + 0.5);

		// 方套圆绣花
		info.sqrtItem[idx].begx = cx-sx/2;
		info.sqrtItem[idx].begy = cy-sy/2;
		info.sqrtItem[idx].midx = cx-sx/2;
		info.sqrtItem[idx].midy = cy+sy/2;
		info.sqrtItem[idx].endx = cx-sx/2;
		info.sqrtItem[idx].endy = cy+sy/2;
		info.sqrtItem[idx].type = DATA_EMB;
		idx++;
		info.sqrtItem[idx].begx = cx-sx/2;
		info.sqrtItem[idx].begy = cy+sy/2;
		info.sqrtItem[idx].midx = cx+sx/2;
		info.sqrtItem[idx].midy = cy+sy/2;
		info.sqrtItem[idx].endx = cx+sx/2;
		info.sqrtItem[idx].endy = cy+sy/2;
		info.sqrtItem[idx].type = DATA_EMB;
		idx++;
		info.sqrtItem[idx].begx = cx+sx/2;
		info.sqrtItem[idx].begy = cy+sy/2;
		info.sqrtItem[idx].midx = cx+sx/2;
		info.sqrtItem[idx].midy = cy-sy/2;
		info.sqrtItem[idx].endx = cx+sx/2;
		info.sqrtItem[idx].endy = cy-sy/2;
		info.sqrtItem[idx].type = DATA_EMB;
		idx++;
		info.sqrtItem[idx].begx = cx+sx/2;
		info.sqrtItem[idx].begy = cy-sy/2;
		info.sqrtItem[idx].midx = cx-sx/2;
		info.sqrtItem[idx].midy = cy-sy/2;
		info.sqrtItem[idx].endx = cx-sx/2;
		info.sqrtItem[idx].endy = cy-sy/2;
		info.sqrtItem[idx].type = DATA_EMB;
		idx++;
		info.sqrtItem[idx].begx = cx;
		info.sqrtItem[idx].begy = cy-sy/2;
		info.sqrtItem[idx].midx = cx+sx/2;
		info.sqrtItem[idx].midy = cy;
		info.sqrtItem[idx].endx = cx;
		info.sqrtItem[idx].endy = cy+sy/2;
		info.sqrtItem[idx].type = DATA_EMB;
		idx++;
		info.sqrtItem[idx].begx = cx;
		info.sqrtItem[idx].begy = cy+sy/2;
		info.sqrtItem[idx].midx = cx-sx/2;
		info.sqrtItem[idx].midy = cy;
		info.sqrtItem[idx].endx = cx;
		info.sqrtItem[idx].endy = cy-sy/2;
		info.sqrtItem[idx].type = DATA_EMB;
		idx++;

		// 冲孔填充方框
		temp = sx;
		temp /= sqrt(2);
		sx = (int)(temp + 0.5);

		temp = sy;
		temp /= sqrt(2);
		sy = (int)(temp + 0.5);

		n = sx / stepSize;
		bx = cx - sx/2;
		if (n > 0)
		{
			temp = sx;
			temp /= n;
		}
		while (n > 0)
		{
			info.sqrtItem[idx].begx = bx;
			info.sqrtItem[idx].begy = cy-sy/2;
			info.sqrtItem[idx].midx = bx;
			info.sqrtItem[idx].midy = cy+sy/2;
			info.sqrtItem[idx].endx = bx;
			info.sqrtItem[idx].endy = cy+sy/2;
			info.sqrtItem[idx].type = DATA_PUNCH;

			idx++;
			n--;
			bx += temp;
		}
		info.sqrtNum = idx;
	}
	else if (sel == 201 || sel == 202 || sel == 203)		// 双头直线绗缝机测试花版
	{
		int i;
		int curtype, curofst;

		int mistep, normalstep;

		s32 begx, begy, endy;
	//	s32 endx;
		s32 temp1, temp2;

		begx = cx;
		begy = cy;

	//	endx = cx;
		endy = sy;

		if (sel == 201)
		{
			curtype = DATA_SEWING;
			curofst = DATA_OFFSET;

			info.startx = begx;
			info.starty = begy;
			info.startx2 = 0;
			info.starty2 = begy;
		}
		else if (sel == 202)
		{
			curtype = DATA_SECF_SEW;
			curofst = DATA_SECF_OFST;

			info.startx = 266600;
			info.starty = begy;
			info.startx2 = begx;
			info.starty2 = begy;
		}
		else if (sel == 203)
		{
			curtype = DATA_SECF_SEW;
			curofst = DATA_SECF_OFST;

			info.startx = begx;
			info.starty = begy;
			info.startx2 = begx + 20000;
			info.starty2 = begy;
		}

		info.defofst = curofst;

		mistep = 400;
		normalstep = 1200;

		temp1 = begy + 5000;
		temp2 = endy - 5000;

		i = 0;
		// A机头或B机头缝纫数据    密针
		info.sqrtItem[i].begx = begx;
		info.sqrtItem[i].begy = begy;
		info.sqrtItem[i].midx = begx;
		info.sqrtItem[i].midy = begy;
		info.sqrtItem[i].endx = begx;
		info.sqrtItem[i].endy = temp1;
		info.sqrtItem[i].stepSize = mistep;
		info.sqrtItem[i].type = curtype;
		i++;

		// A机头或B机头缝纫数据    普通针步
		info.sqrtItem[i].begx = begx;
		info.sqrtItem[i].begy = temp1;
		info.sqrtItem[i].midx = begx;
		info.sqrtItem[i].midy = temp1;
		info.sqrtItem[i].endx = begx;
		info.sqrtItem[i].endy = temp2;
		info.sqrtItem[i].stepSize = normalstep;
		info.sqrtItem[i].type = curtype;
		i++;

		// A机头或B机头缝纫数据    密针
		info.sqrtItem[i].begx = begx;
		info.sqrtItem[i].begy = temp2;
		info.sqrtItem[i].midx = begx;
		info.sqrtItem[i].midy = temp2;
		info.sqrtItem[i].endx = begx;
		info.sqrtItem[i].endy = endy;
		info.sqrtItem[i].stepSize = mistep;
		info.sqrtItem[i].type = curtype;
		i++;

		// 越框
		info.sqrtItem[i].begx = begx;
		info.sqrtItem[i].begy = endy;
		info.sqrtItem[i].midx = begx;
		info.sqrtItem[i].midy = endy;
		info.sqrtItem[i].endx = begx+10000;
		info.sqrtItem[i].endy = endy;
		info.sqrtItem[i].stepSize = S16_MAX/2;
		info.sqrtItem[i].type = curofst;

		begx += 10000;

		// A机头或B机头缝纫数据    密针
		info.sqrtItem[i].begx = begx;
		info.sqrtItem[i].begy = endy;
		info.sqrtItem[i].midx = begx;
		info.sqrtItem[i].midy = endy;
		info.sqrtItem[i].endx = begx;
		info.sqrtItem[i].endy = temp2;
		info.sqrtItem[i].stepSize = mistep;
		info.sqrtItem[i].type = curtype;
		i++;

		// A机头或B机头缝纫数据    普通针步
		info.sqrtItem[i].begx = begx;
		info.sqrtItem[i].begy = temp2;
		info.sqrtItem[i].midx = begx;
		info.sqrtItem[i].midy = temp2;
		info.sqrtItem[i].endx = begx;
		info.sqrtItem[i].endy = temp1;
		info.sqrtItem[i].stepSize = normalstep;
		info.sqrtItem[i].type = curtype;
		i++;

		// A机头或B机头缝纫数据    密针
		info.sqrtItem[i].begx = begx;
		info.sqrtItem[i].begy = temp1;
		info.sqrtItem[i].midx = begx;
		info.sqrtItem[i].midy = temp1;
		info.sqrtItem[i].endx = begx;
		info.sqrtItem[i].endy = begy;
		info.sqrtItem[i].stepSize = mistep;
		info.sqrtItem[i].type = curtype;
		i++;

		info.sqrtNum = i;
	}
	else if (sel == 204)
	{
		int i;

#define	MIZHEN_LEN		5000
#define	NMZHEN1_LEN		10000
#define	NMZHEN2_LEN		100000

		i = 0;

		// AB 机头移动数据
		// A机头移动数据
		// B机头移动数据

		// A机头缝纫数据    密针	50mm
		info.sqrtItem[i].begx = cx;
		info.sqrtItem[i].begy = cy;
		info.sqrtItem[i].midx = cx;
		info.sqrtItem[i].midy = cy;
		info.sqrtItem[i].endx = cx;
		info.sqrtItem[i].endy = cy+MIZHEN_LEN;
		info.sqrtItem[i].stepSize = 400;
		info.sqrtItem[i].type = DATA_SEWING;
		i++;

		cy += MIZHEN_LEN;
		// A机头缝纫数据    普通针步100mm
		info.sqrtItem[i].begx = cx;
		info.sqrtItem[i].begy = cy;
		info.sqrtItem[i].midx = cx;
		info.sqrtItem[i].midy = cy;
		info.sqrtItem[i].endx = cx;
		info.sqrtItem[i].endy = cy+NMZHEN1_LEN;
		info.sqrtItem[i].stepSize = 1000;
		info.sqrtItem[i].type = DATA_SEWING;
		i++;

		cy += NMZHEN1_LEN;
		// AB机头缝纫数据   密针 50mm
		info.sqrtItem[i].begx = cx;
		info.sqrtItem[i].begy = cy;
		info.sqrtItem[i].midx = cx;
		info.sqrtItem[i].midy = cy;
		info.sqrtItem[i].endx = cx;
		info.sqrtItem[i].endy = cy+5000;
		info.sqrtItem[i].stepSize = 400;
		info.sqrtItem[i].type = DATA_SYNCSEW;
		i++;

		// AB机头缝纫数据   普通针步	100000
		info.sqrtItem[i].begx = cx;
		info.sqrtItem[i].begy = cy;
		info.sqrtItem[i].midx = cx;
		info.sqrtItem[i].midy = cy;
		info.sqrtItem[i].endx = cx;
		info.sqrtItem[i].endy = cy+NMZHEN2_LEN;
		info.sqrtItem[i].stepSize = 1000;
		info.sqrtItem[i].type = DATA_SYNCSEW;
		i++;

		cy += NMZHEN2_LEN;

		// AB机头缝纫数据   密针
		info.sqrtItem[i].begx = cx;
		info.sqrtItem[i].begy = cy;
		info.sqrtItem[i].midx = cx;
		info.sqrtItem[i].midy = cy;
		info.sqrtItem[i].endx = cx;
		info.sqrtItem[i].endy = cy+5000;
		info.sqrtItem[i].stepSize = 400;
		info.sqrtItem[i].type = DATA_SYNCSEW;
		i++;

		// A机头缝纫数据    普通针步	100mm
		info.sqrtItem[i].begx = cx;
		info.sqrtItem[i].begy = cy;
		info.sqrtItem[i].midx = cx;
		info.sqrtItem[i].midy = cy;
		info.sqrtItem[i].endx = cx;
		info.sqrtItem[i].endy = cy+NMZHEN1_LEN;
		info.sqrtItem[i].stepSize = 1000;
		info.sqrtItem[i].type = DATA_SEWING;
		i++;

		// A机头缝纫数据    密针	50mm
		info.sqrtItem[i].begx = cx;
		info.sqrtItem[i].begy = cy;
		info.sqrtItem[i].midx = cx;
		info.sqrtItem[i].midy = cy;
		info.sqrtItem[i].endx = cx;
		info.sqrtItem[i].endy = cy+MIZHEN_LEN;
		info.sqrtItem[i].stepSize = 400;
		info.sqrtItem[i].type = DATA_SEWING;
		i++;

		// AB 机头移动数据
		// A机头移动数据
		// B机头移动数据

		// B机头缝纫数据    密针
		// B机头缝纫数据    普通针步

		// AB机头缝纫数据   密针
		// AB机头缝纫数据   普通针步

		// AB机头缝纫数据   密针
		// B机头缝纫数据    普通针步
		// B机头缝纫数据    密针

		// A机头移动数据
		// B机头移动数据
		
		
	}
	else
	{
		return 0;
	}

	if (stepSize <= 0 ||  stepSize >= 65536)
	{
		stepSize = 100;
		printf("stepsize is not support, use default\r\n");
	}

	info.stepSize = stepSize;
	info.blockNum = 0;
	info.blockTimes = 0;
	info.elockNum = 0;
	info.elockTimes = 0;

	info.blockjumps = 0;
	info.elockjumps = 0;

	return CreateCommFile(&info);
}

#endif



#endif	// 生成数据文件的算法


//---------------------------------------------------------------------------------------------------------



#endif




