Libusb 를 Delphi에서 사용하기위해 usb.h 를 Delphi 용 코드로 변환을 완료하였습니다.

ADC 의 Eagle 칩에서 uClinux 를 사용할 때 U-Boot 와 uClinux(ADC 포팅버전)에서 USB를 통해 파일을 전송하는 USB Downloader 프로그램 대체하여 생산공정에 최적화된 소프트웨어를 만들었고, 테스트 결과 정상 동작하였습니다.

USB Downloader 를 대체할 수 있는 코드는 정리하여 연휴가 끝난 뒤 포스트하도록 하겠습니다.

다운로드 링크 :





추가로 이 코드를 사용하기 위해서는 libusb0.dll 이 필요합니다.
libusb-win32 는 http://libusb-win32.sourceforge.net/ 에서 받으시면 되고, 예제는 libusb-win32 내에 예제를 참고하시면 됩니다.

소스코드 전문 :

unit usb;

interface

uses
  Windows;

{
 * PATH_MAX from limits.h can't be used on Windows if the dll and
 * import libraries are build/used by different compilers
}

const LIBUSB_PATH_MAX = 512;

{
 * USB spec information
 *
 * This is all stuff grabbed from various USB specs and is pretty much
 * not subject to change
}

{
 * Device and/or Interface Class codes
}
const USB_CLASS_PER_INTERFACE = 0; { for DeviceClass }
const USB_CLASS_AUDIO         = 1;
const USB_CLASS_COMM          = 2;
const USB_CLASS_HID           = 3;
const USB_CLASS_PRINTER       = 7;
const USB_CLASS_MASS_STORAGE  = 8;
const USB_CLASS_HUB         = 9;
const USB_CLASS_DATA       = 10;
const USB_CLASS_VENDOR_SPEC  = $ff;

{
 * Descriptor types
}
const USB_DT_DEVICE   = $01;
const USB_DT_CONFIG   = $02;
const USB_DT_STRING   = $03;
const USB_DT_INTERFACE  = $04;
const USB_DT_ENDPOINT  = $05;

const USB_DT_HID   = $21;
const USB_DT_REPORT  = $22;
const USB_DT_PHYSICAL = $23;
const USB_DT_HUB   = $29;

{
 * Descriptor sizes per descriptor type
}
const USB_DT_DEVICE_SIZE  = 18;
const USB_DT_CONFIG_SIZE  = 9;
const USB_DT_INTERFACE_SIZE  = 9;
const USB_DT_ENDPOINT_SIZE  = 7;
const USB_DT_ENDPOINT_AUDIO_SIZE = 9; { Audio extension }
const USB_DT_HUB_NONVAR_SIZE  = 7;

{ Endpoint descriptor }
const USB_MAXENDPOINTS = 32;

const USB_ENDPOINT_ADDRESS_MASK = $0f;    { in bEndpointAddress }
const USB_ENDPOINT_DIR_MASK    = $80;

const USB_ENDPOINT_TYPE_MASK  = $03;    { in bmAttributes }
const USB_ENDPOINT_TYPE_CONTROL     = 0;
const USB_ENDPOINT_TYPE_ISOCHRONOUS = 1;
const USB_ENDPOINT_TYPE_BULK      = 2;
const USB_ENDPOINT_TYPE_INTERRUPT   = 3;

{ Interface descriptor }
const USB_MAXINTERFACES = 32;
const USB_MAXALTSETTING = 128; { Hard limit }

{ Configuration descriptor information.. }
const USB_MAXCONFIG  = 8;

{
 * Standard requests
}
const USB_REQ_GET_STATUS      = $00;
const USB_REQ_CLEAR_FEATURE     = $01;
{ 0x02 is reserved }
const USB_REQ_SET_FEATURE      = $03;
{ 0x04 is reserved }
const USB_REQ_SET_ADDRESS      = $05;
const USB_REQ_GET_DESCRIPTOR  = $06;
const USB_REQ_SET_DESCRIPTOR  = $07;
const USB_REQ_GET_CONFIGURATION = $08;
const USB_REQ_SET_CONFIGURATION = $09;
const USB_REQ_GET_INTERFACE    = $0A;
const USB_REQ_SET_INTERFACE    = $0B;
const USB_REQ_SYNCH_FRAME      = $0C;

const USB_TYPE_STANDARD  = ($00 shl 5);
const USB_TYPE_CLASS   = ($01 shl 5);
const USB_TYPE_VENDOR   = ($02 shl 5);
const USB_TYPE_RESERVED  = ($03 shl 5);

const USB_RECIP_DEVICE  = $00;
const USB_RECIP_INTERFACE = $01;
const USB_RECIP_ENDPOINT = $02;
const USB_RECIP_OTHER   = $03;

{
 * Various libusb API related stuff
}

const USB_ENDPOINT_IN   = $80;
const USB_ENDPOINT_OUT  = $00;

{ Error codes }
const USB_ERROR_BEGIN   = 500000;

{ All standard descriptors have these 2 fields in common }
type
  Tusb_descriptor_header = record
    bLength         : byte;
    bDescriptorType : byte;
  end;

{ String descriptor }
  Tusb_string_descriptor = record
    bLength         : byte;
    bDescriptorType : byte;
    wData           : array[0..0] of word;
  end;

{ HID descriptor }
  Tusb_hid_descriptor = record
    bLength         : byte;
    bDescriptorType : byte;
    bcdHID          : word;
    bCountryCode    : byte;
    bNumDescriptors : byte;
  end;

{ Endpoint descriptor }
  Tusb_endpoint_descriptor = record
    bLength : byte;
    bDescriptorType : byte;
    bEndpointAddress : byte;
    bmAttributes : byte;
    wMaxPacketSize : word;
    bInterval : byte;
    bRefresh : byte;
    bSynchAddress : byte;
    extra : ^byte; { Extra descriptors }
    extralen : integer;
  end;

{ Interface descriptor }
  Tusb_interface_descriptor = record
    bLength : byte;
    bDescriptorType     : byte;
    bInterfaceNumber    : byte;
    bAlternateSetting   : byte;
    bNumEndpoints       : byte;
    bInterfaceClass     : byte;
    bInterfaceSubClass  : byte;
    bInterfaceProtocol  : byte;
    iInterface          : byte;

    endpoint : ^Tusb_endpoint_descriptor;

    extra     : ^byte; { Extra descriptors }
    extralen  : integer;
  end;

  Tusb_interface = record
    altsetting : ^Tusb_interface_descriptor;
    num_altsetting : integer;
  end;

{ Configuration descriptor information.. }
  Tusb_config_descriptor  = record
    bLength             : byte;
    bDescriptorType     : byte;
    wTotalLength        : word;
    bNumInterfaces      : byte;
    bConfigurationValue : byte;
    iConfiguration      : byte;
    bmAttributes        : byte;
    MaxPower            : byte;

    interface_ : ^Tusb_interface;

    extra     : ^byte; { Extra descriptors }
    extralen  : integer;
  end;

{ Device descriptor }
  Tusb_device_descriptor = record
    bLength         : byte;
    bDescriptorType : byte;
    bcdUSB          : word;
    bDeviceClass    : byte;
    bDeviceSubClass : byte;
    bDeviceProtocol : byte;
    bMaxPacketSize0 : byte;
    idVendor        : word;
    idProduct       : word;
    bcdDevice       : word;
    iManufacturer   : byte;
    iProduct        : byte;
    iSerialNumber   : byte;
    bNumConfigurations  : byte;
  end;

  Tusb_ctrl_setup = record
    bRequestType  : byte;
    bRequest      : byte;
    wValue        : word;
    wIndex        : word;
    wLength       : word;
  end;

{ Data types }

  Pusb_bus = ^Tusb_bus;
  Pusb_device = ^Tusb_device;

  Tusb_device = record
    next, prev : Pusb_device;

    filename : array [0..LIBUSB_PATH_MAX-1] of Char;

    bus : Pusb_bus;

    descriptor : Tusb_device_descriptor;
    config : ^Tusb_config_descriptor;

    dev : Pointer;  { Darwin support }

    devnum : byte;

    num_children : byte;
    children : ^Pusb_device;
  end;

  Tusb_bus = record
    next, prev : Pusb_bus;

    dirname : array[0..LIBUSB_PATH_MAX - 1] of Char;

    devices : Pusb_device;
    location : Cardinal;

    root_dev : Pusb_device;
  end;

{ Version information, Windows specific }
  Tusb_version = record
    dll : record
      major : integer;
      minor : integer;
      micro : integer;
      nano : integer;
    end;
    driver : record
      major : integer;
      minor : integer;
      micro : integer;
      nano : integer;
    end;
  end;

  Pusb_dev_handle = ^Tusb_dev_handle;
  Tusb_dev_handle = record
    fd  : integer;
    bus : Pusb_bus;
    device  : Pusb_device;
    config  : integer;
    interface_ : integer;
    altestting  : integer;
    impl_info : Pointer;
  end;


{ Function prototypes }

  { usb.c }
  function usb_open(dev : Pusb_device) : Pusb_dev_handle; cdecl; external 'libusb0.dll';
  function usb_close(dev : Pusb_dev_handle) : integer; cdecl; external 'libusb0.dll';
  function usb_get_string(dev: Pusb_dev_handle; index: integer; langid: integer; buf: PChar; buflen: Cardinal): integer; cdecl; external 'libusb0.dll';
  function usb_get_string_simple(dev : Pusb_dev_handle; index: integer; buf: PChar; buflen: Cardinal): integer; cdecl; external 'libusb0.dll';

  { descriptors.c }
  function usb_get_descriptor_by_endpoint(udev: Pusb_dev_handle; ep: integer; type_: Byte; index: Byte; buf: Pointer; size: integer): integer; cdecl; external 'libusb0.dll';
  function usb_get_descriptor(udev: Pusb_dev_handle; type_: Byte; index: Byte; buf : Pointer; size: integer): integer; cdecl; external 'libusb0.dll';

  { <arch>.c }
  function usb_bulk_write(dev: Pusb_dev_handle; ep: integer; bytes: PChar; size: integer; timeout: integer): integer; cdecl; external 'libusb0.dll';
  function usb_bulk_read(dev: Pusb_dev_handle; ep: integer; bytes: PChar; size: integer; timeout: integer): integer; cdecl; external 'libusb0.dll';
  function usb_interrupt_write(dev: Pusb_dev_handle; ep: integer; bytes: PChar; size: integer; timeout: integer): integer; cdecl; external 'libusb0.dll';
  function usb_interrupt_read(dev: Pusb_dev_handle; ep: integer; bytes: PChar; size: integer; timeout: integer): integer; cdecl; external 'libusb0.dll';
  function usb_control_msg(dev: Pusb_dev_handle; requesttype: integer; request: integer; value: integer; index: integer; bytes: PChar; size: integer; timeout: integer): integer; cdecl; external 'libusb0.dll';
  function usb_set_configuration(dev: Pusb_dev_handle; configuration: integer): integer; cdecl; external 'libusb0.dll';
  function usb_claim_interface(dev: Pusb_dev_handle; interface_: integer): integer; cdecl; external 'libusb0.dll';
  function usb_release_interface(dev: Pusb_dev_handle; interface_: integer): integer; cdecl; external 'libusb0.dll';
  function usb_set_altinterface(dev: Pusb_dev_handle; alternate: integer): integer; cdecl; external 'libusb0.dll';
  function usb_resetep(dev: Pusb_dev_handle; ep: Cardinal): integer; cdecl; external 'libusb0.dll';
  function usb_clear_halt(dev: Pusb_dev_handle; ep: Cardinal): integer; cdecl; external 'libusb0.dll';
  function usb_reset(dev: Pusb_dev_handle): integer; cdecl; external 'libusb0.dll';

  function usb_strerror: PChar; cdecl; external 'libusb0.dll';

  procedure usb_init; cdecl; external 'libusb0.dll'
  procedure usb_set_debug(level: integer); cdecl; external 'libusb0.dll';
  function usb_find_busses: integer; cdecl; external 'libusb0.dll';
  function usb_find_devices: integer; cdecl; external 'libusb0.dll';
  function usb_device(dev: Pusb_dev_handle): Pusb_device; cdecl; external 'libusb0.dll';
  function usb_get_busses: Pusb_bus; cdecl; external 'libusb0.dll';

  { Windows specific functions }

  const LIBUSB_HAS_INSTALL_SERVICE_NP = 1;
  function usb_install_service_np: integer; stdcall; external 'libusb0.dll';
  procedure usb_install_service_np_rundll(wnd: HWND; instance: HINST; cmd_line: PChar; cmd_show: integer); stdcall; external 'libusb0.dll';

  const LIBUSB_HAS_UNINSTALL_SERVICE_NP = 1;
  function usb_uninstall_service_np: integer; stdcall; external 'libusb0.dll';
  procedure usb_uninstall_service_np_rundll(wnd:HWND; instance: HINST; cmd_line: PChar; cmd_show: Integer); stdcall; external 'libusb0.dll';

  const LIBUSB_HAS_INSTALL_DRIVER_NP = 1;
  function usb_install_driver_np(const inf_file : PChar): integer; stdcall; external 'libusb0.dll';
  procedure usb_install_driver_np_rundll(wnd: HWND; instance: HINST; cmd_line: PChar; cmd_show: integer); stdcall; external 'libusb0.dll';

  const LIBUSB_HAS_TOUCH_INF_FILE_NP = 1;
  function usb_touch_inf_file_np(const inf_file: PChar): integer; stdcall; external 'libusb0.dll';
  procedure usb_touch_inf_file_np_rundll(wnd: HWND; instance: HINST; cmd_line: PChar; cmd_show: Integer); stdcall; external 'libusb0.dll';

  const LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP = 1;
  function usb_install_needs_restart_np: integer; stdcall; external 'libusb0.dll';

//  #define struct usb_version *usb_get_version(void);

  type PPointer = ^Pointer;
  function usb_isochronous_setup_async(dev: Pusb_dev_handle; context: PPointer; ep: Byte; pktsize: integer): integer; stdcall; external 'libusb0.dll';
  function usb_bulk_setup_async(dev: Pusb_dev_handle; context: PPointer; ep: Byte): integer; stdcall; external 'libusb0.dll';
  function usb_interrupt_setup_async(dev: Pusb_dev_handle; context: PPointer; ep: Byte): integer; stdcall; external 'libusb0.dll';

  function usb_submit_async(context: Pointer; bytes: PChar; size: Integer): integer; stdcall; external 'libusb0.dll';
  function usb_reap_async(context: Pointer; timeout: integer): integer; stdcall; external 'libusb0.dll';
  function usb_reap_async_nocancel(context: Pointer; timeout: integer): integer; stdcall; external 'libusb0.dll';
  function usb_cancel_async(context: Pointer): integer; stdcall; external 'libusb0.dll';
  function usb_free_async(context: PPointer): integer; stdcall; external 'libusb0.dll';

implementation


end.


이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/30 21:57 2009/04/30 21:57
Posted by TylorSTYLE™
Libusb 의 usb.h Header 를 Delphi 용으로 변환하다가 이런 자료는 구하기 힘들겠다 싶어 정리해 올립니다.
Libusb 를 변환한 것도 테스트가 완료되는대로 올립니다. (인터넷에 찾기 쉽지 않더군요.  그나마 있는 것도 사이트가 폐쇄되면서 날아갔습니다.)

C, VC++
Delphi
INT Integer
UNSIGNED INT Cardinal
UINT Cardinal
WORD Word
UNSIGNED SHORT Word
UNSIGNED SHORT INT Word
SHORT SmallInt
SHORT INT SmallInt
DWORD LongInt
LONG LongInt
LONG INT LongInt
UNSIGNED LONG LongInt
UNSIGNED LONG INT LongInt
CHAR Char
UNSIGNED CHAR Byte
CHAR* PChar
LPSTR PChar
PSTR PChar
LPWSTR PWideChar
VOID* Pointer
BOOL Bool
FLOAT Single
DOUBLE Double
LONG DOUBLE Extended


이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/29 22:42 2009/04/29 22:42
Posted by TylorSTYLE™
 이 내용은 ADChips 의 uClinux와 함께 사용되는 u-boot 에서만 적용 될 수도 있습니다만, 혹시 다른 버전의 u-boot 에서도 적용될지 몰라 작성합니다.
 Nand Flash 의 경우 양산시 수급상황에 따라, 혹은 용량으로 인해 변경될 수 있지만 U-Boot 에서 지원하지 않는 메모리는 직접 Define 해줘야 사용이 가능합니다.
 이 문서는 메모리 타이밍과 관련된 부분을 다룹니다.
 먼저 u-boot 의 include 폴더의 config.h 파일을 보도록 합니다.  이 파일은 컴파일 시 스크립트에 의해 자동 생성되는 파일입니다.
 이 파일을 보면 u-boot 의 config 데이터가 어디에 있는디 include 되어있습니다.
ADChips 의 Eagle CPU 의 경우 u-boot 의 boot command 가 include/configs/eagle.h 로 지정되어있습니다.
/* Automatically generated - do not edit */
#include <configs/eagle.h>
eagle.h 파일을 열면 Nand Flash 들이 define 되어있습니다.
제가 가지고 있는 ADChips 의 U-Boot 의 경우
K9F1G08U0M, K9F2G08U0M, K9F4G08U0M, K9F8G08U0M, HY27UT084G2A , HY27UT088G2A
등이 define 되어있고, 필자가 사용하고자 하는 Nand Flash 는 K9F5608U0D 입니다.
K9F5608U0D 의 타이밍은 Alldatasheet 에서 찾아서 기입하도록 합니다.
/* K9F5608U0D */
#ifdef CONFIG_NAND_K9F5608U0D
#define NAND_ALECLE_SETUP       0       /* 10ns */
#define NAND_WE_WIDTH           2       /* 30ns */
#define NAND_RE_WIDTH           2       /* 30ns */
#define NAND_ALECLECE_HOLD      1       /* 10ns */
#endif
그리고 Nand Flash 디파인을 변경합니다.
#undef CONFIG_NAND_K9F1G08U0M
#undef CONFIG_NAND_K9F2G08U0M
#undef CONFIG_NAND_K9F4G08U0M
#undef CONFIG_NAND_K9F8G08U0M
#define CONFIG_NAND_K9F5608U0D
이제 하단에 플래시 관련 세팅 부분인 'FLASH and environment organization', 'NAND-FLASH stuff' 부분을환인하고 필요한 부분은 변경합니다.
그리고 U-Boot 를 재빌드 하면 K9F5608U0D Nand Flash 를 사용할 수 있게 됩니다.
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/13 17:48 2009/04/13 17:48
Posted by TylorSTYLE™
 이 내용은 ADChips 의 uClinux와 함께 사용되는 u-boot 에서만 적용 될 수도 있습니다만, 혹시 다른 버전의 u-boot 에서도 적용될지 몰라 작성합니다.

 u-boot 에서 bootcmd 를 매번 바꾼다는건 일이 될 수 있습니다.  하지만 코드 레벨에서 변경한다면 구지 u-boot 의 command 모드에 매번 들어가 수정할 필요가 없겠지요.

 먼저 u-boot 의 include 폴더의 config.h 파일을 보도록 합니다.  이 파일은 컴파일 시 스크립트에 의해 자동 생성되는 파일입니다.

 이 파일을 보면 u-boot 의 config 데이터가 어디에 있는디 include 되어있습니다.

ADChips 의 Eagle CPU 의 경우 u-boot 의 boot command 가 include/configs/eagle.h 로 지정되어있습니다.

/* Automatically generated - do not edit */
#include <configs/eagle.h>

eagle.h 파일을 열어 'CONFIG_BOOTCOMMAND' 를 찾습니다.

찾아보면 익숙한 내용이 보입니다.  바로 setenv 명령으로 쓰던 내용이 define 되어있는데 이 부분을 수정하고, 재빌드를 하면 Boot Command 수정은 완료됩니다.

네트워크 부팅, BootDelay 등의 내용도 수정하면 그대로 적용됩니다. ^^
이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/13 17:47 2009/04/13 17:47
Posted by TylorSTYLE™

오늘도 다이나믹 코리아에서는 신기한 일이 일어났습니다.

바로 등록금 인하 요구 기자회견을 하던 대학생들이 경찰에 의해 잡혀갔답니다.


>> 관련기사 검색링크 <<


경찰이 밝힌 이유는 매우 간단했습니다.  기자회견이라 말하고, 구호를 외쳤기에 기자회견이 아니라 시위였다는 겁니다.  집회신고를 하지 않았기 때문에 위법이라는군요.

이제는 기자회견에서 스포츠스타들이나 연애인들이 기자들 앞에서 '화이팅!!' 을 외쳐도 안될 것이고, 나훈아 씨처럼 기자회견장에서 테이블 위에 올라가 '내가 바지를 벗겠다면 믿으시겠습니까?' 라고 액션을 취할려면 집회신고도 같이 해야할 것 같습니다.


'반값 등록금' 이란 말은 한나라당에서 먼저 내건 공약으로, 대학생과 대학생을 둔 학부모들에게는 매우 솔깃한 이야기였습니다.

하지만 현재 대학 등록금은 '글로벌 경제위기로 인해 동결' 이라는 학교측의 배려같지도 않은 배려로 올해 동결된 상황입니다.

대학이란 원래 자신이 공부하고자 하는 학문을 더 깊이 이해하고 공부하고자 가는 것이지만, 한국에서만큼은 대학이란 돈이 되면 대부분의 사람이 가야하는 교육기관이 되어있기에 의무교육화 시켜도 무방하다고 보여질 정도입니다.  만약 한나라당이 저 공약을 지키고자 대학교육은 한국에서 의무교육으로, 교육비용에 대해서는 국가가 학교에 제공하는 형태로 나아가겠다고 했다면 많은 사람들이 동의하고, 그에 따르는 사회적 비용을 감수했을지도 모릅니다.

물론 이렇게되면 대학들도 감사를 철저하게 받아야 할테니 대학 재정의 사용이 투명해지겠지요.

결국 '오해다' 로 끝내버림으로서 더 큰 반발을 일으켰고, 지금과 같은 힘든 시기에 등록금 부담으로 인해 슬픈 이야기들이 많이 들려오고 있습니다.

 >> 구글 뉴스 '등록금 자살' 로 검색한 뉴스들 <<

자신들의 공약조차 실행할 생각을 하지 않는 정치인들을 우리가 믿고 가야 할까요?

'교육이 미래다' 라는 말의 뜻을 이해하지 못하고 있을지도 모르겠네요.  아마도 자신들이 가지고 있는, 연루된 교육 재단들의 뱃속을 채워야 할테니까요.


교육을 버린 한국의 미래가 어두워지고 있는 것 같아 안타깝습니다.

이올린에 북마크하기(0) 이올린에 추천하기(0)
2009/04/10 20:24 2009/04/10 20:24
Posted by TylorSTYLE™

BLOG main image

카테고리

전체 (144)
Freeware (3)
Embedded (27)
신변잡기 (51)
디지털 회로 (2)
Programming (20)
무선 네트워크 (15)
Computer (18)
사용기 (7)

글 보관함

262

181

-35 days

today : 180

Daum 블로거뉴스
믹시