USB to Parallel

요즘PC는 Parallel 포트가 없다.
포트가 있다 하더라도 땜이 안되어 있을것이다.
제목처럼 굳이 이렇게 라도 하고 싶은 이유는 JTAG 디버깅시 Parallel 포트가 필수적이기 때문이다. ㅠ
그래서 일단 USB to Parallel 케이블을 하나 구입한다.

usb_to_parallel

시중에서 9천원 정도면 구입할 수 있다.
다음 PC에 꼽으면 드라이버를 자동 인식하는데, 이는 Windows에 기본으로 내장된 usbprint.sys 를 사용하기 때문.
문제없이 자동 인식 되었다면 우린 아래의 코드를 작성하고 USB를 통해서 Parallel 케이블로 데이타를 내보낸다 혹은 읽는다.

아래의 코드는 물론 테스트 되었고, 코드는 급조한거라 정리가 안되어있다.

// ----------------------------------------
// USB to Parallel example
// by inhak.min@gmail.com
// ----------------------------------------

// How to compile
// c:\> cl usbtoparallel.c setupapi.lib 
//
#include <windows.h>
#include <initguid.h>
#include <winioctl.h>
#include <setupapi.h>
#include <stdlib.h>
#include <stdio.h>

#define USBPRINT_IOCTL_INDEX  0x0000

#define IOCTL_USBPRINT_GET_LPT_STATUS \
	CTL_CODE(FILE_DEVICE_UNKNOWN,  \
	USBPRINT_IOCTL_INDEX+12,\
	METHOD_BUFFERED,  \
	FILE_ANY_ACCESS)                                                           

#define IOCTL_USBPRINT_GET_1284_ID \
	CTL_CODE(FILE_DEVICE_UNKNOWN,  \
	USBPRINT_IOCTL_INDEX+13,\
	METHOD_BUFFERED,  \
	FILE_ANY_ACCESS)                                                           

#define IOCTL_USBPRINT_VENDOR_SET_COMMAND \
	CTL_CODE(FILE_DEVICE_UNKNOWN,  \
	USBPRINT_IOCTL_INDEX+14,\
	METHOD_BUFFERED,  \
	FILE_ANY_ACCESS)                                                           

#define IOCTL_USBPRINT_VENDOR_GET_COMMAND \
	CTL_CODE(FILE_DEVICE_UNKNOWN,  \
	USBPRINT_IOCTL_INDEX+15,\
	METHOD_BUFFERED,  \
	FILE_ANY_ACCESS)                                                           

#define IOCTL_USBPRINT_SOFT_RESET \
	CTL_CODE(FILE_DEVICE_UNKNOWN,  \
	USBPRINT_IOCTL_INDEX+16,\
	METHOD_BUFFERED,  \
	FILE_ANY_ACCESS)                                                           

const GUID GUID_USBPRINT = 
		{ 0x28d78fad, 0x5a12, 0x11D1, 0xae, 0x5b, 
			0x00, 0x00, 0xf8, 0x03, 0xa8, 0xc2};

void main(void)
{	
	unsigned int dataType;
	HANDLE handle;

	HDEVINFO devs;
	DWORD devCount;
	SP_DEVINFO_DATA devInfo;
	SP_DEVICE_INTERFACE_DATA devInterface;
	DWORD size;
	PSP_DEVICE_INTERFACE_DETAIL_DATA interfaceDetail;

	devs = SetupDiGetClassDevs(&GUID_USBPRINT, 0, 0, 
			DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
	if (devs == INVALID_HANDLE_VALUE) {
		return;
	}

	devCount = 0;
	devInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	while (SetupDiEnumDeviceInterfaces(devs, 0, &GUID_USBPRINT, 
				devCount, &devInterface)) 
	{
		char driverkey[2048];
		char interfaceName[2048];
		char location[2048];
		char description[2048];

		devCount++;
		size = 0;

		SetupDiGetDeviceInterfaceDetail(devs, &devInterface, 0, 0, &size, 0);
		devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
		interfaceDetail = calloc(1, size);
		if (interfaceDetail) {
			interfaceDetail->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
			devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
			if (!SetupDiGetDeviceInterfaceDetail(devs, &devInterface, 
						interfaceDetail, size, 0, &devInfo)) 
			{
				free(interfaceDetail);
				SetupDiDestroyDeviceInfoList(devs);
				return;
			}
			strcpy(interfaceName, interfaceDetail->DevicePath);
			free(interfaceDetail);

			fprintf(stdout, "Parallel port name: %s\n", interfaceName);

			size = sizeof(driverkey);
			driverkey[0] = 0;
			if (!SetupDiGetDeviceRegistryProperty(devs, &devInfo, 
						SPDRP_DRIVER, &dataType, (LPBYTE)driverkey, size, 0)) 
			{
				SetupDiDestroyDeviceInfoList(devs);
				return;
			}
			fprintf(stdout, "Driver key: %s\n", driverkey);

			size = sizeof(location);
			location[0] = 0;
			if (!SetupDiGetDeviceRegistryProperty(devs, &devInfo, 
						SPDRP_LOCATION_INFORMATION, &dataType, 
						(LPBYTE)location, size, 0)) 
			{
				SetupDiDestroyDeviceInfoList(devs);
				return;
			}
			fprintf(stdout, "Location: %s\n", location);

			handle = CreateFile(interfaceName, 
					GENERIC_WRITE|GENERIC_READ, 
					NULL, NULL, OPEN_EXISTING, 0, NULL);
			if (handle != INVALID_HANDLE_VALUE) 
			{
				// 1000번을 쓴다.
				int i;
				for(i=0; i<1000; i++)
				{
					LPWSTR pBuffer;
					SetupDiDestroyDeviceInfoList(devs);
					pBuffer=(LPWSTR)HeapAlloc(GetProcessHeap (), HEAP_ZERO_MEMORY,50);
					pBuffer=L"\n12345678912345678912345678912345678912345/n";
					
					{
						DWORD pcbWritten=0;
						DWORD  cbBuf=49;
						long ret=0;
						ret=WriteFile(handle, pBuffer, cbBuf, &pcbWritten, 0);
						if(ret) printf("\n %d Value Printed", i);
					}

					// http://msdn.microsoft.com/en-us/library/aa506818.aspx
					{
						DWORD numread;
						int return_value;
						return_value = DeviceIoControl(
							(HANDLE)  handle, 
							IOCTL_USBPRINT_SOFT_RESET, // dwIoControlCode
							NULL, // lpInBuffer
							0,  // nInBufferSize
							NULL, // lpOutBuffer
							0, // nOutBufferSize
							&numread, 0);
						if(return_value==0){
							printf("error....\n");
						}
					}
				}

				if(CloseHandle(handle))
					printf("\nPort Closed");
			}
		}
	}

	SetupDiDestroyDeviceInfoList(devs);
}
이 글은 카테고리: Programming에 포함되어 있으며 태그: , , , (이)가 사용되었습니다. 고유주소를 북마크하세요.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다


This site uses Akismet to reduce spam. Learn how your comment data is processed.