forked from KolibriOS/kolibrios
The very first version of FTDI driver. The only request is 'set_pins'. Not tested yet
git-svn-id: svn://kolibrios.org@4975 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
0651536c07
commit
53b63538c0
55
drivers/usb/usbftdi/linkedlist.inc
Normal file
55
drivers/usb/usbftdi/linkedlist.inc
Normal file
@ -0,0 +1,55 @@
|
||||
head dd 1
|
||||
node equ ftdi_context
|
||||
node.next equ ftdi_context.next_context
|
||||
linkedlist:
|
||||
.init:
|
||||
push eax
|
||||
xor eax, eax
|
||||
mov [head], eax
|
||||
pop eax
|
||||
ret
|
||||
|
||||
.add:
|
||||
push ebx
|
||||
mov ebx, [head]
|
||||
mov [head], eax
|
||||
mov [eax + node.next], ebx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
.delete:
|
||||
push ebx ecx
|
||||
mov ebx, eax ; eax - pointer to node for delete
|
||||
cmp eax, [head]
|
||||
jz .unlink_head
|
||||
|
||||
.getnext:
|
||||
cmp [ebx+node.next], eax
|
||||
jz .unlink
|
||||
cmp [ebx+node.next], 0
|
||||
jz .invalid_pointer
|
||||
mov ebx, [ebx+node.next]
|
||||
jmp .getnext
|
||||
|
||||
.unlink:
|
||||
mov ecx, [eax+node.next]
|
||||
mov [ebx+node.next], ecx
|
||||
jmp @f
|
||||
|
||||
|
||||
.unlink_head:
|
||||
mov ebx, [eax+node.next]
|
||||
mov [head], ebx
|
||||
@@:
|
||||
mov ecx, eax
|
||||
call Kfree
|
||||
.invalid_pointer:
|
||||
pop ecx ebx
|
||||
ret
|
||||
|
||||
.gethead:
|
||||
mov eax, [head]
|
||||
ret
|
||||
|
||||
restore node
|
||||
restore next
|
305
drivers/usb/usbftdi/usbftdi.asm
Normal file
305
drivers/usb/usbftdi/usbftdi.asm
Normal file
@ -0,0 +1,305 @@
|
||||
; standard driver stuff
|
||||
format MS COFF
|
||||
|
||||
DEBUG = 1
|
||||
|
||||
; this is for DEBUGF macro from 'fdo.inc'
|
||||
__DEBUG__ = 1
|
||||
__DEBUG_LEVEL__ = 1
|
||||
|
||||
include '../proc32.inc'
|
||||
include '../imports.inc'
|
||||
include '../fdo.inc'
|
||||
include '../../struct.inc'
|
||||
|
||||
public START
|
||||
public version
|
||||
|
||||
; USB constants
|
||||
DEVICE_DESCR_TYPE = 1
|
||||
CONFIG_DESCR_TYPE = 2
|
||||
STRING_DESCR_TYPE = 3
|
||||
INTERFACE_DESCR_TYPE = 4
|
||||
ENDPOINT_DESCR_TYPE = 5
|
||||
DEVICE_QUALIFIER_DESCR_TYPE = 6
|
||||
|
||||
CONTROL_PIPE = 0
|
||||
ISOCHRONOUS_PIPE = 1
|
||||
BULK_PIPE = 2
|
||||
INTERRUPT_PIPE = 3
|
||||
|
||||
; USB HID constants
|
||||
HID_DESCR_TYPE = 21h
|
||||
REPORT_DESCR_TYPE = 22h
|
||||
PHYSICAL_DESCR_TYPE = 23h
|
||||
|
||||
|
||||
; LibUSB constatnts
|
||||
LIBUSB_REQUEST_TYPE_STANDARD = (0x00 shl 5)
|
||||
LIBUSB_REQUEST_TYPE_CLASS = (0x01 shl 5)
|
||||
LIBUSB_REQUEST_TYPE_VENDOR = (0x02 shl 5)
|
||||
LIBUSB_REQUEST_TYPE_RESERVED = (0x03 shl 5)
|
||||
|
||||
LIBUSB_RECIPIENT_DEVICE = 0x00
|
||||
LIBUSB_RECIPIENT_INTERFACE = 0x01
|
||||
LIBUSB_RECIPIENT_ENDPOINT = 0x02
|
||||
LIBUSB_RECIPIENT_OTHER = 0x03
|
||||
|
||||
LIBUSB_ENDPOINT_IN = 0x80
|
||||
LIBUSB_ENDPOINT_OUT = 0x00
|
||||
|
||||
; FTDI Constants
|
||||
FTDI_DEVICE_OUT_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_OUT)
|
||||
FTDI_DEVICE_IN_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_IN)
|
||||
|
||||
; Requests
|
||||
;Definitions for flow control
|
||||
SIO_RESET =0 ;Reset the port
|
||||
SIO_MODEM_CTRL =1 ;Set the modem control register
|
||||
SIO_SET_FLOW_CTRL =2 ;Set flow control register
|
||||
SIO_SET_BAUD_RATE =3 ;Set baud rate
|
||||
SIO_SET_DATA =4 ;Set the data characteristics of the port
|
||||
|
||||
SIO_RESET_REQUEST =SIO_RESET
|
||||
SIO_SET_BAUDRATE_REQUEST =SIO_SET_BAUD_RATE
|
||||
SIO_SET_DATA_REQUEST =SIO_SET_DATA
|
||||
SIO_SET_FLOW_CTRL_REQUEST =SIO_SET_FLOW_CTRL
|
||||
SIO_SET_MODEM_CTRL_REQUEST =SIO_MODEM_CTRL
|
||||
SIO_POLL_MODEM_STATUS_REQUEST=0x05
|
||||
SIO_SET_EVENT_CHAR_REQUEST =0x06
|
||||
SIO_SET_ERROR_CHAR_REQUEST =0x07
|
||||
SIO_SET_LATENCY_TIMER_REQUEST=0x09
|
||||
SIO_GET_LATENCY_TIMER_REQUEST=0x0A
|
||||
SIO_SET_BITMODE_REQUEST =0x0B
|
||||
SIO_READ_PINS_REQUEST =0x0C
|
||||
SIO_READ_EEPROM_REQUEST =0x90
|
||||
SIO_WRITE_EEPROM_REQUEST =0x91
|
||||
SIO_ERASE_EEPROM_REQUEST =0x92
|
||||
|
||||
|
||||
SIO_RESET_SIO=0
|
||||
SIO_RESET_PURGE_RX=1
|
||||
SIO_RESET_PURGE_TX=2
|
||||
|
||||
SIO_DISABLE_FLOW_CTRL=0x0
|
||||
SIO_RTS_CTS_HS =(0x1 shl 8)
|
||||
SIO_DTR_DSR_HS =(0x2 shl 8)
|
||||
SIO_XON_XOFF_HS=(0x4 shl 8)
|
||||
|
||||
SIO_SET_DTR_MASK=0x1
|
||||
SIO_SET_DTR_HIGH=( 1 or ( SIO_SET_DTR_MASK shl 8))
|
||||
SIO_SET_DTR_LOW =( 0 or ( SIO_SET_DTR_MASK shl 8))
|
||||
SIO_SET_RTS_MASK=0x2
|
||||
SIO_SET_RTS_HIGH=( 2 or ( SIO_SET_RTS_MASK shl 8 ))
|
||||
SIO_SET_RTS_LOW =( 0 or ( SIO_SET_RTS_MASK shl 8 ))
|
||||
|
||||
SIO_RTS_CTS_HS =(0x1 shl 8)
|
||||
|
||||
;strings
|
||||
my_driver db 'usbother',0
|
||||
nomemory_msg db 'K : no memory',13,10,0
|
||||
|
||||
; Structures
|
||||
struct ftdi_context
|
||||
chipType db ?
|
||||
baudrate dd ?
|
||||
bitbangEnabled db ?
|
||||
readBufPtr dd ?
|
||||
readBufOffs dd ?
|
||||
readBufChunkSize dd ?
|
||||
writeBufChunkSize dd ?
|
||||
interface dd ?
|
||||
index dd ?
|
||||
inEP dd ?
|
||||
outEP dd ?
|
||||
nullP dd ?
|
||||
next_context dd ?
|
||||
ends
|
||||
|
||||
struct IOCTL
|
||||
handle dd ?
|
||||
io_code dd ?
|
||||
input dd ?
|
||||
inp_size dd ?
|
||||
output dd ?
|
||||
out_size dd ?
|
||||
ends
|
||||
|
||||
struct usb_descr
|
||||
bcdUSB dw ?
|
||||
bDeviceClass db ?
|
||||
bDeviceSubClass db ?
|
||||
bDeviceProtocol db ?
|
||||
bMaxPacketSize0 db ?
|
||||
idVendor dw ?
|
||||
idProduct dw ?
|
||||
bcdDevice dw ?
|
||||
iManufacturer db ?
|
||||
iProduct db ?
|
||||
iSerialNumber db ?
|
||||
bNumConfigurations db ?
|
||||
ends
|
||||
|
||||
section '.flat' code readable align 16
|
||||
; The start procedure.
|
||||
proc START stdcall, .reason:DWORD
|
||||
|
||||
xor eax, eax ; initialize return value
|
||||
cmp [.reason], 1 ; compare the argument
|
||||
jnz .nothing
|
||||
call linkedlist.init
|
||||
stdcall RegUSBDriver, my_driver, service_proc, usb_functions
|
||||
|
||||
.nothing:
|
||||
ret 4
|
||||
endp
|
||||
|
||||
|
||||
proc AddDevice stdcall uses ebx, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD
|
||||
|
||||
stdcall USBGetParam, [.config_pipe], 0
|
||||
cmp [eax+usb_descr.idVendor], 0x0403
|
||||
jnz .notftdi
|
||||
DEBUGF 1,'K : FTDI USB device detected\n'
|
||||
movi eax, sizeof.ftdi_context
|
||||
call Kmalloc
|
||||
test eax, eax
|
||||
jnz @f
|
||||
mov esi, nomemory_msg
|
||||
call SysMsgBoardStr
|
||||
xor eax, eax
|
||||
jmp .nothing
|
||||
@@:
|
||||
DEBUGF 1,'K : Adding struct to list %x\n', eax
|
||||
call linkedlist.add
|
||||
|
||||
mov ebx, [.config_pipe]
|
||||
mov [eax + ftdi_context.nullP], ebx
|
||||
|
||||
DEBUGF 1,'K : Open first pipe\n'
|
||||
mov ebx, eax
|
||||
stdcall USBOpenPipe, [.config_pipe], 0x81, 0x40, BULK_PIPE, 0
|
||||
mov [ebx + ftdi_context.inEP], eax
|
||||
DEBUGF 1,'K : Open second pipe\n'
|
||||
stdcall USBOpenPipe, [.config_pipe], 0x02, 0x40, BULK_PIPE, 0
|
||||
mov [ebx + ftdi_context.outEP], eax
|
||||
|
||||
.nothing:
|
||||
ret
|
||||
.notftdi:
|
||||
DEBUGF 1,'K : Skipping not FTDI device\n'
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
handle equ IOCTL.handle
|
||||
io_code equ IOCTL.io_code
|
||||
input equ IOCTL.input
|
||||
inp_size equ IOCTL.inp_size
|
||||
output equ IOCTL.output
|
||||
out_size equ IOCTL.out_size
|
||||
|
||||
align 4
|
||||
proc service_proc stdcall uses ebx esi edi, ioctl:DWORD
|
||||
locals
|
||||
ConfPacket rb 8
|
||||
EventData rd 2
|
||||
endl
|
||||
mov edi, [ioctl]
|
||||
mov eax, [edi + io_code]
|
||||
DEBUGF 1,'K : FTDI got the request: %d\n', eax
|
||||
test eax, eax ;0
|
||||
jz .version
|
||||
dec eax ;1
|
||||
jz .ftdi_get_list
|
||||
dec eax ;2
|
||||
jz .ftdi_set_bitmode
|
||||
|
||||
.version:
|
||||
.endswitch:
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.ftdi_set_bitmode:
|
||||
DEBUGF 1,'K : FTDI Seting bitmode\n'
|
||||
call CreateEvent
|
||||
DEBUGF 1,'K : Event created %x %x\n' , eax, edx
|
||||
mov [EventData], eax
|
||||
mov [EventData+1], edx
|
||||
mov si, (FTDI_DEVICE_IN_REQTYPE) + (SIO_SET_BITMODE_REQUEST shl 8)
|
||||
mov word[ConfPacket], si
|
||||
mov edi, [edi+input]
|
||||
mov si, word[edi+1]
|
||||
DEBUGF 1,'K : Pin value is %x\n', si
|
||||
mov word[ConfPacket+4], si
|
||||
mov ebx, [edi]
|
||||
lea esi, [ConfPacket]
|
||||
lea edi, [EventData]
|
||||
stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP], esi, 0, 0, control_callback, edi, 0
|
||||
DEBUGF 1, 'K : Returned value is %d\n', eax
|
||||
call WaitEvent
|
||||
jmp .endswitch
|
||||
.ftdi_read_pins:
|
||||
DEBUGF 1,'K : FTDI Reading pins\n'
|
||||
call CreateEvent
|
||||
mov [EventData], eax
|
||||
mov [EventData+1], edx
|
||||
mov eax, FTDI_DEVICE_IN_REQTYPE + (SIO_READ_PINS_REQUEST shl 8)
|
||||
mov dword[ConfPacket], eax
|
||||
jmp .endswitch
|
||||
.ftdi_get_list:
|
||||
call linkedlist.gethead
|
||||
DEBUGF 1, 'K : FTDI Device pointer %x\n' , eax
|
||||
mov edi, [edi+output]
|
||||
mov edi, eax
|
||||
mov eax, 4
|
||||
mov edi, [ioctl]
|
||||
mov [edi+out_size], eax
|
||||
jmp .endswitch
|
||||
endp
|
||||
restore handle
|
||||
restore io_code
|
||||
restore input
|
||||
restore inp_size
|
||||
restore output
|
||||
restore out_size
|
||||
|
||||
|
||||
align 4
|
||||
proc control_callback stdcall uses ebx, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD
|
||||
|
||||
mov eax, [.calldata]
|
||||
mov ebx, [.calldata+1]
|
||||
call RaiseEvent
|
||||
DEBUGF 1, 'K : status is %d\n', [.status+24h]
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
proc DeviceDisconnected stdcall uses ebx esi edi, .device_data:DWORD
|
||||
|
||||
DEBUGF 1, 'K : FTDI deleting device data\n'
|
||||
mov eax, [.device_data]
|
||||
;call linkedlist.delete
|
||||
endp
|
||||
|
||||
include 'linkedlist.inc'
|
||||
|
||||
; Exported variable: kernel API version.
|
||||
align 4
|
||||
version dd 50005h
|
||||
; Structure with callback functions.
|
||||
usb_functions:
|
||||
dd 12
|
||||
dd AddDevice
|
||||
dd DeviceDisconnected
|
||||
|
||||
;for DEBUGF macro
|
||||
include_debug_strings
|
||||
|
||||
|
||||
|
||||
|
||||
; for uninitialized data
|
||||
;section '.data' data readable writable align 16
|
Loading…
Reference in New Issue
Block a user