#include "pch.h"
#include ".\SubFunc.h"
#include ".\Gpibac.h"

///// [CheckRet] Function /////////////////////////////////////////////////////////////////////////////////////
long CheckRet(CString Func, long Ret, CString *csBuf)
{
	long	RetCode,Ret1;
	
	RetCode = 0;						// Normality
	Ret1 = Ret & 0xff;					// 0xFF Masking
	if(Ret1 >= 3){						// Unusual
		RetCode = 1;					// Return of function(Unusual)
		switch(Ret1){
		case 3:		*csBuf = Func + _T(" : Data has been left within FIFO.");					break; // 0x03
		case 80:	*csBuf = Func + _T(" : It is I/O address error.");							break; // 0x50
		case 82:	*csBuf = Func + _T(" : Resistry setup is wrong. Review resistry setup.");	break; // 0x52
		case 128:	*csBuf = Func + _T(" : Data receiving was exceeded.and polling is not.");	break; // 0x80
		case 200:	*csBuf = Func + _T(" : Thread can not be made.");							break; // 0xC8
		case 201:	*csBuf = Func + _T(" : Other event is in practice.");						break; // 0xC9
		case 210:	*csBuf = Func + _T(" : DMA could not be established.");						break; // 0xD2
		case 240:	*csBuf = Func + _T(" : [Esc] key was pushed.");								break; // 0xF0
		case 241:	*csBuf = Func + _T(" : It is an I/O error of file.");						break; // 0xF1
		case 242:	*csBuf = Func + _T(" : Address appoint is wrong.");							break; // 0xF2
		case 243:	*csBuf = Func + _T(" : Buffer Error.");										break; // 0xF3
		case 244:	*csBuf = Func + _T(" : Error of array size.");								break; // 0xF4
		case 245:	*csBuf = Func + _T(" : A buffer is too small.");							break; // 0xF5
		case 246:	*csBuf = Func + _T(" : It is an unjust object name.");						break; // 0xF6
		case 247:	*csBuf = Func + _T(" : A side check of a device name is invalid.");			break; // 0xF7
		case 248:	*csBuf = Func + _T(" : It is an unjust data model.");						break; // 0xF8
		case 249:	*csBuf = Func + _T(" : Device can not be added further.");					break; // 0xF9
		case 250:	*csBuf = Func + _T(" : A device name is not found out.");					break; // 0xFA
		case 251:	*csBuf = Func + _T(" : Delimiter is wrong between device.");				break; // 0xFB
		case 252:	*csBuf = Func + _T(" : It is an error of GP-IB.");							break; // 0xFC
		case 253:	*csBuf = Func + _T(" : Only a delimiter was receiving.");					break; // 0xFD
		case 254:	*csBuf = Func + _T(" : It was done a time out.");							break; // 0xFE
		case 255:	*csBuf = Func + _T(" : It is a parameter error.");							break; // 0xFF
		}
	}else{
		*csBuf = Func + _T(" : It was terminated normally.");
	}

// It was message when [Ifc] [Srq] received. //
    Ret1 = Ret & 0xff00;					// 0xFF Masking
	switch(Ret1){
	case 0x100:		*csBuf = Func + _T("-[SRQ] was receiving.<STATUS>");						break; // [256]decimal
	case 0x200:		*csBuf = Func + _T("-[IFC] was receiving.<STATUS>");						break; // [512]decimal
	case 0x300:		*csBuf = Func + _T("-[SRQ],[IFC] was receiving.<STATUS>");					break; // [768]decimal
	}
	return	RetCode;
}

///// [Square] Function ///////////////////////////////////////////////////////////////////////////////////////
int Square(int x, int y)
{
	int tmp = 1;

	while (y-- > 0)							// Repeating counts 
		tmp *= x;							// Multiply
	return(tmp);
}

///// [Chr -> Hex] Function ///////////////////////////////////////////////////////////////////////////////////
DWORD chr2hex(char* ch)
{
	DWORD	ret = 0, rettmp = 0;
	long	count, length;

	length	= (long)strlen(ch);							// Search length of ch 
	for(count = 0;count < length ;count++){				// Repeat
		if((ch[count] >= 0x30) && (ch[count] <=0x39))	// Get ASCII code to number
		  ret = (ch[count] - 0x30) * Square(0x10,(length - (count + 1)));	// 0 - 9 
		else if((ch[count] >= 0x41) && (ch[count] <= 0x46))
		  ret = (ch[count] - 0x37) * Square(0x10,(length - (count + 1)));	// A - F 
		else if((ch[count] >= 0x61) && (ch[count] <= 0x66))
		  ret = (ch[count] - 0x57) * Square(0x10,(length - (count + 1)));	// a - f 
		else
		  ret = 0xff;						// Return is wrong when ret = 0xFF
	
		rettmp = rettmp + ret;
	}
	return rettmp;
}

///// [Initialize] Function ///////////////////////////////////////////////////////////////////////////////////
long GpibInit(CString* TextRet)
{
	int		Delim,Eoi,Timeout,Ifctime,Ret;	
	DWORD	Master;
	CString	csBuf;

	Ret = GpExit();							// Keep off initialize repeat
	Ret = GpIni();							// GP-IB initialize
	CheckRet(_T("GpIni"), Ret, &csBuf);
	if((Ret & 0xFF) != 0){					// Check of GpIni
		*TextRet = csBuf;
		return	1;
	}

	GpBoardsts(0x0a, &Master);				// Get Master/Slave mode
	if(Master == 0){
		Ifctime = 1;						// Default
		Ret = GpIfc(Ifctime);
		CheckRet(_T("GpIfc"), Ret, &csBuf);
		if((Ret & 0xFF) != 0){				// Check of GpIfc
			*TextRet = csBuf;
			return	1;
		}
		Ret = GpRen();
		CheckRet(_T("GpRen"), Ret, &csBuf);
		if((Ret & 0xFF) != 0){				// Check of GpRen
			*TextRet = csBuf;
			return	1;
		}
	}

	Delim = 1;								// Default
	Eoi = 1;								// Default
	Ret = GpDelim(Delim, Eoi);
	CheckRet(_T("GpDelim"), Ret, &csBuf);
	if((Ret & 0xFF) != 0){					// Check of GpDelim
		*TextRet = csBuf;
		return	1;
	}
	Timeout = 10000;						// Default(ms)
	Ret = GpTimeout(Timeout);
	CheckRet(_T("GpTimeout"), Ret, &csBuf);
	if((Ret & 0xFF) != 0){					// Check of GpTimeout
		*TextRet = csBuf;
		return	1;
	}

	*TextRet = _T("Initialized.");			// Normality Ended.
	return	0;
}

///// [Exit] Function /////////////////////////////////////////////////////////////////////////////////////////
void GpibExit()
{
	DWORD	Master;							// Master/Slave mode flag
	long	Ret;
	DWORD	Cmd[32];
	
	Ret = GpBoardsts(0x0a, &Master);		// Mode check
	if(Ret == 80) return;					// If found error then not doing 
	
	if(Master == 0){						// When mode is Master
		Cmd[0] = 2;							// Command count
		Cmd[1] = 0x3f;						// Unlisten / UNL
		Cmd[2] = 0x5f;						// UnTalken / UNT
		Ret = GpComand(Cmd);				// Send command
	}
		Ret = GpResetren();					// Cancel remote
	
	Ret = GpExit();
}

///// [Str -> Num] Function ///////////////////////////////////////////////////////////////////////////////////
void Str2Num(char *str, DWORD str_len , int *num, DWORD num_len)
{
	DWORD i, cnt;
	char *start;

	start = str;
	cnt = 0;
	for (i=0; i<str_len; i++) {
		/* string to integer */
		if (str[i] == ',') {
			str[i] = '\0';
			num[cnt] = atoi(start);
			str[i] = ',';
			start = &str[i+1];
			cnt++;
			if (cnt >= num_len) break;
		}
	}
	if (cnt >= num_len) {
		num[cnt] = atoi(start);
	}
}

///// [Draw Graphic] Function /////////////////////////////////////////////////////////////////////////////////
void DrawGraph(HWND hDlg, DWORD Picture, int *num, DWORD num_len, int min, int max)
{
	HWND	Disp_handle;
	RECT	Rect;
	HDC		hDC;
	HPEN	hPen_Black, hPen_Red, hPen_White;
	HBRUSH	hBrush1, hBrush2, hBrush3;
	POINT	Point[4];
	int		x_max, y_max;
	int		x_width, y_width;
	float	x_unit, y_unit;
	DWORD	i;

	/* Initialize */
	Disp_handle = GetDlgItem(hDlg, Picture);
	GetClientRect(Disp_handle, &Rect);
	x_max = Rect.right;
	y_max = Rect.bottom;
	hDC = GetDC(Disp_handle);

	hPen_Black = CreatePen(PS_SOLID, 1, RGB(0, 0, 0));		/* Black */
	hPen_Red   = CreatePen(PS_SOLID, 1, RGB(255, 0, 0));	/* Red   */
	hPen_White = CreatePen(PS_SOLID, 1, RGB(255, 255, 255));/* White */
	/* Draw Structure */
	hBrush3 = (HBRUSH)SelectObject(hDC, hPen_White);
	Rectangle(hDC, Rect.left, Rect.top, Rect.right, Rect.bottom);
	hBrush1 = (HBRUSH)SelectObject(hDC, hPen_Black);
	for (i=0; i<=10; i++) {
		MoveToEx(hDC, (x_max / 10) * i, 0, NULL);
		LineTo(  hDC, (x_max / 10) * i, y_max);
	}
	for (i=0; i<=10; i++) {
		MoveToEx(hDC, 0,   (y_max / 10) * i, NULL);
		LineTo(hDC, x_max, (y_max / 10) * i);
	}
	hBrush2 = (HBRUSH)SelectObject(hDC, hPen_Red);
	Point[0].x = (x_max / 10) * 5 - 1; Point[0].y = 0;
	Point[1].x = (x_max / 10) * 5 + 1; Point[1].y = 0;
	Point[2].x = (x_max / 10) * 5 + 1; Point[2].y = y_max;
	Point[3].x = (x_max / 10) * 5 - 1; Point[3].y = y_max;
	Polyline(hDC, &Point[0], 4);
	Point[0].x = 0;     Point[0].y = (y_max / 10) * 5 - 1;
	Point[1].x = 0;     Point[1].y = (y_max / 10) * 5 + 1;
	Point[2].x = x_max; Point[2].y = (y_max / 10) * 5 + 1;
	Point[3].x = x_max; Point[3].y = (y_max / 10) * 5 - 1;
	Polyline(hDC, &Point[0], 4);
	/* Draw Graph */
	hBrush1 = (HBRUSH)SelectObject(hDC, hPen_Black);
	x_width = num_len;
	y_width = max - min;
	x_unit = (float)((float)x_max / (float)x_width);
	y_unit = (float)((float)y_max / (float)y_width);
	for (i=0; i<num_len-1; i++) {
		MoveToEx(hDC, (int)(x_unit * i)      , (int)((y_width - (num[i] - min)) * y_unit) , NULL);
		LineTo(  hDC, (int)(x_unit * (i + 1)), (int)((y_width - (num[i+1] - min)) * y_unit));
	}
	/* ending */
	SelectObject(hDC, hBrush1);
	DeleteObject(hPen_Black);
	SelectObject(hDC, hBrush2);
	DeleteObject(hPen_Red);
	SelectObject(hDC, hBrush3);
	DeleteObject(hPen_White);
	ReleaseDC(Disp_handle, hDC);
}

// New function(Use Oscillo2/Tektronix TDS3000Series)

///// [ GpibPrint ] function //////////////////////////////////////////////////////////////////////////////////
long GpibPrint(long DevAddr, CString Str)
{
char	srbuf[10000];
DWORD	MyAddr, Cmd[16];
CString	ErrText;
long	Ret, RetTmp, srlen;

	Ret = GpBoardsts(0x08, &MyAddr);
	Cmd[0] = 2;
	Cmd[1] = MyAddr;
	Cmd[2] = DevAddr;

	srlen = lstrlen(Str);
	strcpy_s(srbuf, CT2CA(Str));
    Ret = GpTalk(Cmd, srlen, (UCHAR*)srbuf);

	if (Ret >= 3){
		RetTmp = CheckRet(_T("GpTalk"), Ret, &ErrText);
		ErrText += _T("Continue?");
		Ret = AfxMessageBox(ErrText, MB_YESNO);
		if (Ret == IDNO) return 1;
	}
	return 0;
}

///// [ GpibInput ] function //////////////////////////////////////////////////////////////////////////////////
long GpibInput(long DevAddr, CString *Str)
{
BYTE	srbuf[10000];
DWORD	MyAddr,srlen, Cmd[16];
CString	TmpStr, ErrText;
long	Ret, RetTmp;

   	memset( srbuf, '\0', 10000 );

    Ret = GpBoardsts(0x08, &MyAddr);
	Cmd[0] = 2;
	Cmd[1] = DevAddr;
	Cmd[2] = MyAddr;
	srlen = sizeof(srbuf);
    Ret = GpListen(Cmd, &srlen, srbuf);
	if (Ret >= 3){
		RetTmp = CheckRet(_T("GpListen"), Ret, &ErrText);
		ErrText += _T("Continue?");
		Ret = AfxMessageBox(ErrText, MB_YESNO);
		if (Ret == IDNO) return 1;
	}
	*Str = srbuf;
	return 0;
}

// Add HIOKI
///// [ GpibInput ] function //////////////////////////////////////////////////////////////////////////////////
long GpibInputHioki(long DevAddr, CString *Str)
{
	BYTE	Srbuf[10000];								// String buffer
	DWORD	Srlen;										// String length
	DWORD	MyAddr;										// My address
	DWORD	Cmd[16];									// Message(command)
	CString	ErrText;									// Error string
	long	Ret;										// Return value

	Ret = GpBoardsts(0x08, &MyAddr);					// Get my address
	Cmd[0] = 2;											// Number of command
	Cmd[1] = DevAddr;									// Slave device
	Cmd[2] = MyAddr;									// My address(PC)

	*Str = "";											// Initialize
	while (true){
		Srlen = sizeof(Srbuf) - 1;						// Max receive size
		Ret = GpListen(Cmd, &Srlen, Srbuf);
		if (Ret <= 2){									// Normal completion
			Srbuf[Srlen] = '\0';
			CString Srtmp(Srbuf);
			*Str += Srtmp;
			break;
		}
		else if (Ret == 128){							// Receive data overflow
			Srbuf[Srlen] = '\0';
			CString Srtmp(Srbuf);
			*Str += Srtmp;
			Cmd[0] = 0;									// GpListen without sending commands
		}
		else{
			CheckRet(_T("GpListen"), Ret, &ErrText);
			Ret = AfxMessageBox(ErrText, MB_OK);
			return 1;									// Invalid
		}
	}
	return 0;											// Valid
}

///// [ GpibInputB ] function /////////////////////////////////////////////////////////////////////////////////
long GpibInputB(long DevAddr, BYTE *IntData)
{
BYTE	szData[10000];
DWORD	Ret, RetTmp, MyAddr, Cmd[8], srlen;
CString	ErrText = _T("");

	memset(szData, '\0', 10000);

	Ret = GpDelim(0, 1);
    Ret = GpBoardsts(0x08, &MyAddr);
	Cmd[0] = 2;
	Cmd[1] = DevAddr;
	Cmd[2] = MyAddr;
	srlen = 2;
	Ret = GpListen(Cmd, &srlen, szData);
	if (Ret >= 3){
		RetTmp = CheckRet(_T("GpListen"), Ret, &ErrText);
		ErrText += _T("Continue?");
		Ret = AfxMessageBox(ErrText, MB_YESNO);
		if (Ret == IDNO) return 1;
	}
	Cmd[0] = 0;
	srlen = atoi((char *)&szData[1]);
	Ret = GpListen(Cmd, &srlen, szData);
	srlen = (atoi((char *)&szData)) + 1;
	Ret = GpListen(Cmd, &srlen, IntData);

	Ret = GpDelim(3, 1);
	return 0;
}

///// [ GpibCommand ] /////////////////////////////////////////////////////////////////////////////////////////
long GpibCommand(long DevAddr)
{
DWORD	Cmd[16];
CString	ErrText;
long	Ret, RetTmp;

	Cmd[0] = 2;
	Cmd[1] = 0x3F;
	Cmd[2] = 0x5F;

	Ret = GpComand(Cmd);

	if (Ret != 0){
		RetTmp = CheckRet(_T("GpComand"), Ret, &ErrText);
		AfxMessageBox(ErrText, MB_OK);
		return 1;
	}
	return 0;
}

///// [ WaitOPC ] function ////////////////////////////////////////////////////////////////////////////////////
void WaitOPC(long Dev)
{
	long	Ret;
	CString RdData;

	Ret = GpibPrint(Dev, _T("*OPC?"));
	Ret = GpibInput(Dev, &RdData);
}

