//////////////////////////////////////////////////////////////////////
// Pro.cpp: implementation of the CPro class.
//这个类负责管理串行编程器和下载线，提供串口编程器或并口编程器类
//与界面的通信
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "EPro.h"
#include "Pro.h"
#include "EProDlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPro::CPro()
{
	m_pReadBuf=(BYTE*)GlobalAlloc(GMEM_FIXED,0x10000);//建立缓冲2
	m_pWriteBuf=(BYTE*)GlobalAlloc(GMEM_FIXED,0x10000);//建立缓冲1
	memset(m_pReadBuf,0xff,0x10000);
	memset(m_pWriteBuf,0xff,0x10000);
	m_pSerialPro=NULL;
	m_pParlPro=NULL;
	m_nChipSel=0;
}

CPro::~CPro()
{

}

BOOL CPro::InitPro(CWnd* pWnd,int nProType,int nIspSpd)
{
	m_pDlg=(CEProDlg*)pWnd;
	m_nProType=nProType;//编程器类型
	if(m_nProType==0)
	{
		if(m_pSerialPro!=NULL)
			delete m_pSerialPro;
		m_pSerialPro=new CSerialPro;
		switch(m_nBaudSel)//初始化串口
		{
			case 0:
				return m_pSerialPro->InitPort(this,m_nSerialPort,9600);
			case 1:
				return m_pSerialPro->InitPort(this,m_nSerialPort,19200);
			case 2:
				return m_pSerialPro->InitPort(this,m_nSerialPort,28800);
			case 3:
				return m_pSerialPro->InitPort(this,m_nSerialPort,57600);
			default : FALSE;
		}
	}
	else if(m_nProType>=1 && m_nProType<=3)//使用并口的编程器
	{
		m_pParlPro=new CParallelPro;
		return m_pParlPro->InitPort(this,0x378,m_nProType,nIspSpd);//初始化并口
	}
	return FALSE;
}

void CPro::Notify(int nInfo)//向界面发送消息
{
	PostMessage(m_pDlg->m_hWnd, WM_PRO_MSG, (WPARAM)nInfo, 0);
}

void CPro::DetectPro(int nChipSel)//检测编程器
{
	if(m_nProType==0)//如果是串口的
	{
		m_pSerialPro->DetectPro(GetChipType(nChipSel)->FID);
	}
	else if(m_nProType>=1 && m_nProType<=3)//如果是并口的
	{
		m_pParlPro->DetectPro(GetChipType(nChipSel)->FID);
	}
}

void CPro::DetectChip(int nChipSel)//检测器件，就是读特征字再比较特征字
{
	if(m_nProType==0)//如果是串口的
	{
		m_pSerialPro->ReadSign(GetChipType(nChipSel)->FID);
		
	}
	else if(m_nProType>=1 && m_nProType<=3)//如果是并口的
	{
		m_pParlPro->ReadSign(GetChipType(nChipSel)->FID);
	}
}

void CPro::Erase(int nChipSel)//擦除器件
{
	if(m_nProType==0)//如果是串口的
	{
		m_pSerialPro->Erase(GetChipType(nChipSel)->FID);
	}
	else if(m_nProType>=1 && m_nProType<=3)//如果是并口的
	{
		m_pParlPro->Erase(GetChipType(nChipSel)->FID);
	}
}

void CPro::Write(int nChipSel)//写器件
{
	if(m_nProType==0)//如果是串口的
	{
		m_pSerialPro->BeginWrite(GetChipType(nChipSel)->FID);
	}
	else if(m_nProType>=1 && m_nProType<=3)//如果是并口的
	{
		m_pParlPro->BeginWrite(GetChipType(nChipSel)->FID);
	}
}

void CPro::Read(int nChipSel)//读器件
{
	memset(m_pReadBuf,0xff,0x10000);
	if(m_nProType==0)//如果是串口的
	{
		m_pSerialPro->BeginRead(GetChipType(nChipSel)->FID);
	}
	else if(m_nProType>=1 && m_nProType<=3)//如果是并口的
	{
		m_pParlPro->BeginRead(GetChipType(nChipSel)->FID);
	}

}

void CPro::LockBit(int nChipSel, int nBit)//写锁定位
{
	if(m_nProType==0)//如果是串口的
	{
		m_pSerialPro->LockBit(GetChipType(nChipSel)->FID,nBit);
	}
	else if(m_nProType>=1 && m_nProType<=3)//如果是并口的
	{
		m_pParlPro->LockBit(GetChipType(nChipSel)->FID,nBit);
	}
}

extern CString m_strAppPath;//应用程序所在的目录
void CPro::LoadChipList()//从ChipList.chip中载入器件列表
{
	CFile fileOpen;
	if(fileOpen.Open(m_strAppPath+"ChipList.chip",CFile::shareCompat|CFile::modeRead,NULL))
	{
		int	BufSize=fileOpen.GetLength();
		int	nVer;
		int	nChip;
		BYTE* fileBuf=new BYTE[BufSize];
		fileOpen.Read(fileBuf,BufSize);
		memcpy(&nVer,fileBuf,4);
		memcpy(&nChip,&fileBuf[4],4);
		ChipType* pChip=(ChipType*)&fileBuf[8];
		CString strChip;
		for(int n=0;n<=nChip-1;n++)
		{
			m_arChips.Add(&pChip[n]);
			strChip=pChip[n].Name;
			m_pDlg->m_comboChipType.InsertString(n,strChip);
		}
		fileOpen.Close();
	}
}

ChipType* CPro::GetCurChip()//得到当前的器件类型
{	
	return GetChipType(m_nChipSel);
}

ChipType* CPro::GetChipType(int nChipSel)//根据器件序号的到器件类型
{
	if(nChipSel<0)
		nChipSel=0;
	m_nChipSel=nChipSel;
	return m_arChips.GetAt(nChipSel);
}

int CPro::GetMinLength(BYTE *pBuf, int nLength)
{//计算缓冲中最小数据块的长度，跳过0xFF
	int n;
	for(n=nLength-1;n>=0;n--)
	{
		if(pBuf[n]!=0xff)
		{
			if(n==0)
			 return m_nDataLength=1;
			break;
		}
	}
	if(n==0)
		return m_nDataLength=0;
	n++;
	if(n>GetCurChip()->RomSize*1024)
		return m_nDataLength=GetCurChip()->RomSize*1024;
	return m_nDataLength=n;
}

BOOL CPro::CheckChip()//根据特征字缓冲中数据查找与之匹配的器件
{
	int n;
	for(n=0;n<m_arChips.GetSize();n++)
	{
		if(SignByte[0]==m_arChips.GetAt(n)->SignBytes[0]
		&& SignByte[1]==m_arChips.GetAt(n)->SignBytes[1]
		&& SignByte[2]==m_arChips.GetAt(n)->SignBytes[2])
		{
			Notify(PRO_DETECTCHIP_SEC);
			m_nChipSel=n;
			m_pDlg->m_comboChipType.SetCurSel(n);
			return TRUE;
		}
	}
	Notify(PRO_DETECTCHIP_ER);
	return FALSE;
}



