開發環境使用 DJGPP + FreeDOS + DPMI + DOSUSB 的驅動程式 (
http://www.dosusb.net)
請參考
http://www.dosusb.net 內的論壇內容, 不同的 USB CHIP 不保證一定成功,
但我的環境下列我寫的 SOURCE CODE 是 OK 的
檔案名稱 : W6USBCOM.h
#ifndef TW6USBCOM_H
#define TW6USBCOM_H
#ifndef BYTE
#define BYTE unsigned char
#endif
#ifndef WORD
#define WORD unsigned short int
#endif
#ifdef __cplusplus
extern "C" {
#endif
void W6USBComReset(void);
WORD W6USBComDataIn(void);
int W6USBComDataOut(char *szData, int nCount);
int W6USBComGetCoding(void);
int W6USBComSetCoding(void);
int W6USBComSetState(void);
#ifdef __cplusplus
}
#endif
#endif
檔案名稱 : W6USBCOM.C
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <signal.h>
#include "USBCom.h"
#define __PACKED__ __attribute__ ((packed))
#define C4USBInterruptVector 0x65
int gnDevAdd =1;
int gnInEndpoint =3;
int gnOutEndpoint =2;
typedef struct
{
BYTE transaction_token __PACKED__ ;
BYTE chain_end_flag __PACKED__ ;
BYTE dev_add __PACKED__ ;
BYTE end_point __PACKED__ ;
BYTE error_code __PACKED__ ;
BYTE status __PACKED__ ;
WORD transaction_flags __PACKED__ ;
WORD buffer_off __PACKED__ ;
WORD buffer_seg __PACKED__ ;
WORD buffer_length __PACKED__ ;
WORD actual_length __PACKED__ ;
WORD setup_buffer_off __PACKED__ ;
WORD setup_buffer_seg __PACKED__ ;
WORD start_frame __PACKED__ ;
WORD nr_of_packets __PACKED__ ;
BYTE int_interval __PACKED__ ;
BYTE error_count __PACKED__ ;
WORD timeout __PACKED__ ;
WORD next_urb_off __PACKED__ ;
WORD next_urb_seg __PACKED__ ;
} TURBType;
typedef struct
{
BYTE bmRequestType __PACKED__;
BYTE bRequest __PACKED__;
WORD wValue __PACKED__;
WORD wIndex __PACKED__;
WORD wLength __PACKED__;
} TDeviceRequest;
char gszUSBDataIn;
int main(int argc, char *argv)
{
#ifndef ALLEGRO_MINGW32
int i, n, k;
int nInEndpoint;
char szData;
if(!__djgpp_nearptr_enable())
{
printf("!__djgpp_nearptr_enable()");
return(0);
}
if(W6USBComSetCoding()!=0) return(0);
if(W6USBComGetCoding()!=0) return(0);
if(W6USBComSetState()!=0) return(0);
printf("Simple TTY-Terminal at 38.400 baud - press ESC to exit\n");
nInEndpoint = gnInEndpoint;
gnInEndpoint = 1;
if( (n= W6USBComDataIn())>0 )
{
printf("Line status in hex: \n");
for(i=0;i<2;i++)
{
printf("%.2X ",gszUSBDataIn);
}
}
gnInEndpoint=nInEndpoint;
for(k=0;k<30;k++)
{
if((n=W6USBComDataIn())>0)
{
printf("urb.actual_length = %d\n", n);
for(i=0;i<n;i++) printf("%c", gszUSBDataIn);
printf("\n");
}
szData = 'A';
szData = 0x00;
W6USBComDataOut(szData,1);
delay(1000);
}
#else
return(0);
#endif
}
WORD W6USBComDataIn()
{
#ifndef ALLEGRO_MINGW32
__dpmi_regs regs;
TURBType urb;
urb.transaction_token =0x69;
urb.chain_end_flag =0;
urb.dev_add =gnDevAdd;
urb.end_point =gnInEndpoint;
urb.error_code =0;
urb.status =0;
urb.transaction_flags =0;
urb.buffer_seg =(__tb+64) >> 4;
urb.buffer_off =(__tb+64) & 0x0F;
urb.buffer_length =64;
urb.actual_length =64;
urb.setup_buffer_off =0;
urb.setup_buffer_seg =0;
urb.start_frame =0;
urb.nr_of_packets =0;
urb.int_interval =0;
urb.error_count =0;
urb.timeout =0;
urb.next_urb_off =0;
urb.next_urb_seg =0;
dosmemput((char *)&urb, sizeof(urb), __tb);
regs.x.ds = __tb >> 4;
regs.x.dx = __tb & 0x0F;
__dpmi_int (C4USBInterruptVector, ®s);
dosmemget (__tb, sizeof(urb), (char *)&urb);
if (urb.error_code==1) return(0);
if(urb.status > 1) return(0);
if(urb.actual_length>0) dosmemget (__tb+64, urb.actual_length, gszUSBDataIn);
return(urb.actual_length);
#else
return(0);
#endif
}
int W6USBComDataOut(char *szData, int nCount)
{
#ifndef ALLEGRO_MINGW32
__dpmi_regs regs;
TURBType urb;
char szTmp;
if(nCount==0) nCount=strlen(szData);
if(nCount==0) return(0);
dosmemput(szData, nCount, __tb+64);
urb.transaction_token =0xE1;
urb.chain_end_flag =0;
urb.dev_add =gnDevAdd;
urb.end_point =gnOutEndpoint;
urb.error_code =0;
urb.status =0;
urb.transaction_flags =0;
urb.buffer_seg =(__tb+64) >> 4;
urb.buffer_off =(__tb+64) & 0x0F;
urb.buffer_length =nCount;
urb.actual_length =64;
urb.setup_buffer_off =0;
urb.setup_buffer_seg =0;
urb.start_frame =0;
urb.nr_of_packets =0;
urb.int_interval =0;
urb.error_count =0;
urb.timeout =0;
urb.next_urb_off =0;
urb.next_urb_seg =0;
dosmemput((char *)&urb, sizeof(urb), __tb);
regs.x.ds = __tb >> 4;
regs.x.dx = __tb & 0x0F;
__dpmi_int (C4USBInterruptVector, ®s);
dosmemget (__tb, sizeof(urb), (char *)&urb);
if (urb.error_code==1) return(urb.error_code);
if(urb.status > 1) return(urb.status);
return(0);
#else
return(0);
#endif
}
int W6USBComGetCoding()
{
#ifndef ALLEGRO_MINGW32
__dpmi_regs regs;
TDeviceRequest device_request;
TURBType urb;
device_request.bmRequestType=0xA1;
device_request.bRequest =0x21;
device_request.wValue =0x00;
device_request.wIndex =0;
device_request.wLength =0x7;
dosmemput((char *)&device_request, sizeof(device_request), __tb+128);
urb.transaction_token =0x2D;
urb.chain_end_flag =0;
urb.dev_add =gnDevAdd;
urb.end_point =0;
urb.error_code =0;
urb.status =0;
urb.transaction_flags =0;
urb.buffer_seg =(__tb+64) >> 4;
urb.buffer_off =(__tb+64) & 0x0F;
urb.buffer_length =18;
urb.actual_length =64;
urb.setup_buffer_seg =(__tb+128) >> 4;
urb.setup_buffer_off =(__tb+128) & 0x0F;
urb.start_frame =0;
urb.nr_of_packets =0;
urb.int_interval =0;
urb.error_count =0;
urb.timeout =0;
urb.next_urb_seg =0;
urb.next_urb_off =0;
dosmemput((char *)&urb, sizeof(urb), __tb);
regs.x.ds = __tb >> 4;
regs.x.dx = __tb & 0x0F;
__dpmi_int (C4USBInterruptVector, ®s);
dosmemget (__tb, sizeof(urb), (char *)&urb);
if (urb.error_code==1) return(urb.error_code);
if(urb.status > 1) return(urb.status);
return(0);
#else
return(0);
#endif
}
int W6USBComSetCoding()
{
#ifndef ALLEGRO_MINGW32
__dpmi_regs regs;
int nInEndpoint;
int nOutEndpoint;
char szData;
int nDataLen;
TDeviceRequest device_request;
TURBType urb;
device_request.bmRequestType=0x21;
device_request.bRequest =0x20;
device_request.wValue =0x00;
device_request.wIndex =0;
device_request.wLength =0x7;
dosmemput((char *)&device_request, sizeof(device_request), __tb+128);
urb.transaction_token =0x2D;
urb.chain_end_flag =0;
urb.dev_add =gnDevAdd;
urb.end_point =0;
urb.error_code =0;
urb.status =0;
urb.transaction_flags =0;
urb.buffer_seg =0;
urb.buffer_off =0;
urb.buffer_length =0;
urb.actual_length =0;
urb.setup_buffer_seg =(__tb+128) >> 4;
urb.setup_buffer_off =(__tb+128) & 0x0F;
urb.start_frame =0;
urb.nr_of_packets =0;
urb.int_interval =0;
urb.error_count =0;
urb.timeout =0;
urb.next_urb_seg =0;
urb.next_urb_off =0;
dosmemput((char *)&urb, sizeof(urb), __tb);
regs.x.ds = __tb >> 4;
regs.x.dx = __tb & 0x0F;
__dpmi_int (C4USBInterruptVector, ®s);
dosmemget (__tb, sizeof(urb), (char *)&urb);
if (urb.error_code==1) return(urb.error_code);
if(urb.status > 1) return(urb.status);
nInEndpoint = gnInEndpoint;
nOutEndpoint= gnOutEndpoint;
szData = 0x00;
szData = 0x96;
szData = 0x00;
szData = 0x00;
szData = 0x00;
szData = 0x00;
szData = 0x08;
nDataLen = 7;
gnOutEndpoint = 0;
W6USBComDataOut(szData, nDataLen);
gnInEndpoint = 0;
W6USBComDataIn();
gnInEndpoint = nInEndpoint;
gnOutEndpoint = nOutEndpoint;
return(0);
#else
return(0);
#endif
}
int W6USBComSetState()
{
#ifndef ALLEGRO_MINGW32
__dpmi_regs regs;
TDeviceRequest device_request;
TURBType urb;
device_request.bmRequestType=0x21;
device_request.bRequest =0x22;
device_request.wValue =0x03;
device_request.wIndex =0;
device_request.wLength =0x00
dosmemput((char *)&device_request, sizeof(device_request), __tb+128);
urb.transaction_token =0x2D;
urb.chain_end_flag =0;
urb.dev_add =gnDevAdd;
urb.end_point =0;
urb.error_code =0;
urb.status =0;
urb.transaction_flags =0;
urb.buffer_seg =(__tb+64) >> 4;
urb.buffer_off =(__tb+64) & 0x0F;
urb.buffer_length =0;
urb.actual_length =0;
urb.setup_buffer_seg =(__tb+128) >> 4;
urb.setup_buffer_off =(__tb+128) & 0x0F;
urb.start_frame =0;
urb.nr_of_packets =0;
urb.int_interval =0;
urb.error_count =0;
urb.timeout =0;
urb.next_urb_seg =0;
urb.next_urb_off =0;
dosmemput((char *)&urb, sizeof(urb), __tb);
regs.x.ds = __tb >> 4;
regs.x.dx = __tb & 0x0F;
__dpmi_int (C4USBInterruptVector, ®s);
dosmemget (__tb, sizeof(urb), (char *)&urb);
if (urb.error_code==1) return(urb.error_code);
if(urb.status > 1) return(urb.status);
return(0);
#else
return(0);
#endif
}
void W6USBComReset()
{
#ifndef ALLEGRO_MINGW32
__dpmi_regs regs;
TURBType urb;
urb.transaction_token =0xFF;
urb.chain_end_flag =0;
urb.dev_add =gnDevAdd;
urb.end_point =0;
urb.error_code =0;
urb.status =0;
urb.transaction_flags =0;
urb.buffer_seg =0;
urb.buffer_off =0;
urb.buffer_length =0;
urb.actual_length =0;
urb.setup_buffer_seg =0;
urb.setup_buffer_off =0;
urb.start_frame =0;
urb.nr_of_packets =0;
urb.int_interval =0;
urb.error_count =0;
urb.timeout =0;
urb.next_urb_seg =0;
urb.next_urb_off =0;
dosmemput((char *)&urb, sizeof(urb), __tb);
regs.x.ax = 1;
regs.x.ds = __tb >> 4;
regs.x.dx = __tb & 0x0F;
__dpmi_int (C4USBInterruptVector, ®s);
#endif
}
int W6USBComDeviceDescriptor()
{
#ifndef ALLEGRO_MINGW32
__dpmi_regs regs;
TDeviceRequest device_request;
TURBType urb;
device_request.bmRequestType = 0x80;
device_request.bRequest = 6;
device_request.wValue = 0x100;
device_request.wIndex = 0;
device_request.wLength = 8;
dosmemput((char *)&device_request, sizeof(device_request), __tb+128);
urb.transaction_token =0x2D;
urb.chain_end_flag =0;
urb.dev_add =gnDevAdd;
urb.end_point =0;
urb.error_code =0;
urb.status =0;
urb.transaction_flags =0;
urb.buffer_seg =(__tb+64) >> 4;
urb.buffer_off =(__tb+64) & 0x0F;
urb.buffer_length =8;
urb.actual_length =8;
urb.setup_buffer_seg =(__tb+128) >> 4;
urb.setup_buffer_off =(__tb+128) & 0x0F;
urb.start_frame =0;
urb.nr_of_packets =0;
urb.int_interval =0;
urb.error_count =0;
urb.timeout =0;
urb.next_urb_seg =0;
urb.next_urb_off =0;
dosmemput((char *)&urb, sizeof(urb), __tb);
regs.x.ds = __tb >> 4;
regs.x.dx = __tb & 0x0F;
__dpmi_int (C4USBInterruptVector, ®s);
dosmemget (__tb, sizeof(urb), (char *)&urb);
if (urb.error_code==1) return(urb.error_code);
if(urb.status > 1) return(urb.status);
if(urb.actual_length>0) dosmemget (__tb+64, urb.actual_length, gszUSBDataIn);
printf("\n\nDevice Descriptor:");
printf("\nLength: %d", gszUSBDataIn);
printf("\nDescriptor type: %d", gszUSBDataIn);
printf("\nUSB specification nr.: %02X%02X hex", gszUSBDataIn,gszUSBDataIn);
printf("\nClass code: %d", gszUSBDataIn);
printf("\nSubclass code: %d", gszUSBDataIn);
printf("\nProtocol code: %d", gszUSBDataIn);
printf("\nMax Packet size: %d\n", gszUSBDataIn);
return(0);
#else
return(0);
#endif
}