drivers/serial: implement serial ports enumeration (#629)
This PR adds a new enum_ports call to the serial driver's control API that lets user-mode programs list the serial ports currently registered in the system. It also updates debug output strings, changes the USB FTDI driver's service procedure name, and removes duplicated code from the baud rate calculation. Reviewed-on: #629 Reviewed-by: Mikhail Frolov <mixa.frolov2003@gmail.com> Reviewed-by: Burer <burer@kolibrios.org> Co-authored-by: Alexey Ryabov <alex@b00bl1k.ru>
This commit was merged in pull request #629.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
SERIAL_COMPATIBLE_API_VER = 0 ; increments in case of breaking changes
|
||||
SERIAL_COMPATIBLE_API_VER = 1 ; increments in case of breaking changes
|
||||
|
||||
SERIAL_API_GET_VERSION = 0
|
||||
SERIAL_API_SRV_ADD_PORT = 1
|
||||
@@ -9,6 +9,7 @@ SERIAL_API_CLOSE_PORT = 5
|
||||
SERIAL_API_SETUP_PORT = 6
|
||||
SERIAL_API_READ = 7
|
||||
SERIAL_API_WRITE = 8
|
||||
SERIAL_API_ENUM_PORTS = 9
|
||||
|
||||
SERIAL_API_ERR_PORT_INVALID = 1
|
||||
SERIAL_API_ERR_PORT_BUSY = 2
|
||||
@@ -29,6 +30,9 @@ SERIAL_CONF_STOP_BITS_2 = 2
|
||||
|
||||
SERIAL_CONF_FLOW_CTRL_NONE = 0
|
||||
|
||||
SERIAL_INFO_DRIVER_LEN = 16
|
||||
SERIAL_INFO_DESCR_LEN = 64
|
||||
|
||||
struct SP_DRIVER
|
||||
size dd ? ; size of this struct
|
||||
startup dd ? ; int __stdcall (*startup)(void *drv_data, const struct serial_conf *conf);
|
||||
@@ -46,7 +50,20 @@ struct SP_CONF
|
||||
flow_ctrl db ?
|
||||
ends
|
||||
|
||||
proc serial_add_port stdcall, drv:dword, drv_data:dword
|
||||
struct SP_PORT_INFO
|
||||
size dd ? ; size of this struct
|
||||
driver dd ? ; ASCIIZ driver name, e.g. "uart16550", "usb-cdc"
|
||||
descr dd ? ; ASCIIZ description, may be NULL
|
||||
ends
|
||||
|
||||
struct SP_PORT_ENUM_ENTRY
|
||||
id dd ? ; unique port number (SERIAL_PORT.id)
|
||||
busy dd ? ; 0 = free, non-zero = port is opened
|
||||
driver rb SERIAL_INFO_DRIVER_LEN
|
||||
descr rb SERIAL_INFO_DESCR_LEN
|
||||
ends
|
||||
|
||||
proc serial_add_port stdcall, drv:dword, drv_data:dword, info:dword
|
||||
locals
|
||||
handler dd ?
|
||||
io_code dd ?
|
||||
@@ -60,7 +77,7 @@ endl
|
||||
mov [io_code], SERIAL_API_SRV_ADD_PORT
|
||||
lea eax, [drv]
|
||||
mov [input], eax
|
||||
mov [inp_size], 8
|
||||
mov [inp_size], 12
|
||||
xor eax, eax
|
||||
mov [output], eax
|
||||
mov [out_size], eax
|
||||
@@ -129,7 +146,7 @@ proc serial_port_init
|
||||
ret
|
||||
endp
|
||||
|
||||
proc serial_port_get_version stdcall, version:dword
|
||||
proc serial_port_get_version stdcall uses ebx, version:dword
|
||||
locals
|
||||
.handler dd ?
|
||||
.io_code dd ?
|
||||
@@ -149,7 +166,7 @@ endl
|
||||
|
||||
lea ecx, [.handler]
|
||||
mcall SF_SYS_MISC, SSF_CONTROL_DRIVER
|
||||
|
||||
|
||||
ret
|
||||
endp
|
||||
|
||||
@@ -297,6 +314,43 @@ endl
|
||||
ret
|
||||
endp
|
||||
|
||||
proc serial_port_enum stdcall uses ebx, buf:dword, buf_size:dword, \
|
||||
total:dword, filled:dword
|
||||
locals
|
||||
.handler dd ?
|
||||
.io_code dd ?
|
||||
.input dd ?
|
||||
.inp_size dd ?
|
||||
.output dd ?
|
||||
.out_size dd ?
|
||||
endl
|
||||
push [buf_size]
|
||||
push [buf]
|
||||
mov eax, [serial_drv_handle]
|
||||
mov [.handler], eax
|
||||
mov dword [.io_code], SERIAL_API_ENUM_PORTS
|
||||
mov [.input], esp
|
||||
mov dword [.inp_size], 8
|
||||
sub esp, 8
|
||||
mov [.output], esp
|
||||
mov dword [.out_size], 8
|
||||
|
||||
lea ecx, [.handler]
|
||||
mcall SF_SYS_MISC, SSF_CONTROL_DRIVER
|
||||
|
||||
pop ebx edx
|
||||
cmp eax, -1
|
||||
je .err
|
||||
mov ecx, [total]
|
||||
mov [ecx], ebx
|
||||
mov ecx, [filled]
|
||||
mov [ecx], edx
|
||||
.err:
|
||||
|
||||
add esp, 8
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
serial_drv_name db "SERIAL", 0
|
||||
serial_drv_handle dd ?
|
||||
|
||||
+148
-7
@@ -44,6 +44,8 @@ struct SERIAL_PORT
|
||||
rx_buf RING_BUF
|
||||
tx_buf RING_BUF
|
||||
conf SP_CONF
|
||||
driver rb SERIAL_INFO_DRIVER_LEN ; ASCIIZ, copied from SP_PORT_INFO.driver in add_port
|
||||
descr rb SERIAL_INFO_DESCR_LEN ; ASCIIZ, copied from SP_PORT_INFO.descr in add_port (may be empty)
|
||||
ends
|
||||
|
||||
proc START c, reason:dword, cmdline:dword
|
||||
@@ -57,7 +59,7 @@ proc START c, reason:dword, cmdline:dword
|
||||
stdcall uart_probe, 0x2f8, 3
|
||||
stdcall uart_probe, 0x3e8, 4
|
||||
stdcall uart_probe, 0x2e8, 3
|
||||
invoke RegService, drv_name, service_proc
|
||||
invoke RegService, serial_drv_name, service_proc
|
||||
ret
|
||||
|
||||
.fail:
|
||||
@@ -75,7 +77,7 @@ srv_calls:
|
||||
dd service_proc.setup
|
||||
dd service_proc.read
|
||||
dd service_proc.write
|
||||
; TODO enumeration
|
||||
dd service_proc.enum_ports
|
||||
srv_calls_end:
|
||||
|
||||
proc service_proc stdcall uses ebx esi edi, ioctl:dword
|
||||
@@ -97,11 +99,13 @@ proc service_proc stdcall uses ebx esi edi, ioctl:dword
|
||||
; in:
|
||||
; +0: driver
|
||||
; +4: driver data
|
||||
cmp [edx + IOCTL.inp_size], 8
|
||||
; +8: port info (SP_PORT_INFO*)
|
||||
cmp [edx + IOCTL.inp_size], 12
|
||||
jb .err
|
||||
mov ebx, [edx + IOCTL.input]
|
||||
mov ecx, [ebx]
|
||||
mov edx, [ebx + 4]
|
||||
mov ebx, [ebx + 8]
|
||||
call add_port
|
||||
ret
|
||||
|
||||
@@ -137,6 +141,7 @@ proc service_proc stdcall uses ebx esi edi, ioctl:dword
|
||||
; +4 addr to SERIAL_CONF
|
||||
; out:
|
||||
; +0 port handle if success
|
||||
; eax = 0 if success, otherwise an error code SERIAL_API_ERR_*
|
||||
cmp [edx + IOCTL.inp_size], 8
|
||||
jb .err
|
||||
cmp [edx + IOCTL.out_size], 4
|
||||
@@ -220,25 +225,60 @@ proc service_proc stdcall uses ebx esi edi, ioctl:dword
|
||||
mov [ebx], ecx
|
||||
ret
|
||||
|
||||
.enum_ports:
|
||||
; in:
|
||||
; +0 output buffer (array of SP_PORT_ENUM_ENTRY), may be NULL
|
||||
; +4 output buffer size in bytes
|
||||
; out:
|
||||
; +0 total number of ports in the system
|
||||
; +4 number of entries actually filled into the buffer
|
||||
; eax = 0 if success, -1 otherwise
|
||||
cmp [edx + IOCTL.inp_size], 8
|
||||
jb .err
|
||||
cmp [edx + IOCTL.out_size], 8
|
||||
jb .err
|
||||
mov ebx, [edx + IOCTL.input]
|
||||
push edx
|
||||
mov eax, [ebx]
|
||||
mov edx, [ebx + 4]
|
||||
call sp_enum
|
||||
pop edx
|
||||
mov ebx, [edx + IOCTL.output]
|
||||
mov [ebx], eax
|
||||
mov [ebx + 4], ecx
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.err:
|
||||
or eax, -1
|
||||
ret
|
||||
endp
|
||||
|
||||
; struct SERIAL_PORT __fastcall *add_port(const struct SP_DRIVER *drv, const void *drv_data);
|
||||
align 4
|
||||
; @param ecx pointer to SP_DRIVER
|
||||
; @param edx driver-specific argument
|
||||
; @param ebx pointer to SP_PORT_INFO
|
||||
; @return SERIAL_PORT descriptor
|
||||
proc add_port uses edi
|
||||
DEBUGF L_DBG, "serial.sys: add port drv=%x drv_data=%x\n", ecx, edx
|
||||
DEBUGF L_DBG, "serial.sys: add port drv=%x drv_data=%x info=%x\n", ecx, edx, ebx
|
||||
|
||||
mov eax, [ecx + SP_DRIVER.size]
|
||||
cmp eax, sizeof.SP_DRIVER
|
||||
jne .fail
|
||||
|
||||
test ebx, ebx
|
||||
jz .fail
|
||||
mov eax, [ebx + SP_PORT_INFO.size]
|
||||
cmp eax, sizeof.SP_PORT_INFO
|
||||
jne .fail
|
||||
|
||||
; alloc memory for serial port descriptor
|
||||
push ecx
|
||||
push edx
|
||||
push ebx
|
||||
movi eax, sizeof.SERIAL_PORT
|
||||
invoke Kmalloc
|
||||
pop ebx
|
||||
pop edx
|
||||
pop ecx
|
||||
test eax, eax
|
||||
@@ -252,6 +292,17 @@ proc add_port uses edi
|
||||
invoke MutexInit
|
||||
and [edi + SERIAL_PORT.con], 0
|
||||
|
||||
; copy port info strings
|
||||
mov eax, [ebx + SP_PORT_INFO.driver]
|
||||
lea edx, [edi + SERIAL_PORT.driver]
|
||||
mov ecx, SERIAL_INFO_DRIVER_LEN
|
||||
call copy_bounded_str
|
||||
|
||||
mov eax, [ebx + SP_PORT_INFO.descr]
|
||||
lea edx, [edi + SERIAL_PORT.descr]
|
||||
mov ecx, SERIAL_INFO_DESCR_LEN
|
||||
call copy_bounded_str
|
||||
|
||||
mov ecx, port_list_mutex
|
||||
invoke MutexLock
|
||||
|
||||
@@ -282,7 +333,35 @@ proc add_port uses edi
|
||||
endp
|
||||
|
||||
align 4
|
||||
; u32 __fastcall *remove_port(struct SERIAL_PORT *port);
|
||||
; copies an ASCIIZ string into a fixed-size buffer: copies up to (size - 1)
|
||||
; bytes or until the NUL, then zero-pads the rest of the buffer
|
||||
; @param eax source ASCIIZ ptr, may be NULL
|
||||
; @param edx dest buffer ptr
|
||||
; @param ecx dest buffer size in bytes, must be >= 1
|
||||
proc copy_bounded_str uses esi edi
|
||||
mov esi, eax
|
||||
mov edi, edx
|
||||
dec ecx ; reserve the last byte for the NUL terminator
|
||||
.copy:
|
||||
test ecx, ecx
|
||||
jz .pad
|
||||
test esi, esi
|
||||
jz .pad
|
||||
lodsb
|
||||
test al, al
|
||||
jz .pad
|
||||
stosb
|
||||
dec ecx
|
||||
jmp .copy
|
||||
.pad:
|
||||
inc ecx ; account for the reserved NUL byte
|
||||
xor al, al
|
||||
rep stosb
|
||||
ret
|
||||
endp
|
||||
|
||||
align 4
|
||||
; @param ecx serial port descriptor
|
||||
proc remove_port uses esi
|
||||
mov esi, ecx
|
||||
mov ecx, port_list_mutex
|
||||
@@ -657,7 +736,69 @@ proc sp_write
|
||||
ret
|
||||
endp
|
||||
|
||||
drv_name db 'SERIAL', 0
|
||||
align 4
|
||||
; @param eax buf
|
||||
; @param edx buf_size (bytes)
|
||||
; @return eax total port count in the system
|
||||
; ecx entries filled into buf
|
||||
proc sp_enum uses ebx esi edi
|
||||
mov ecx, eax
|
||||
mov eax, edx
|
||||
xor edx, edx
|
||||
mov ebx, sizeof.SP_PORT_ENUM_ENTRY
|
||||
div ebx
|
||||
; eax max entries count
|
||||
|
||||
mov edi, ecx
|
||||
imul eax, sizeof.SP_PORT_ENUM_ENTRY
|
||||
add eax, ecx
|
||||
mov edx, eax ; end-of-buffer boundary
|
||||
|
||||
xor ebx, ebx ; total port count
|
||||
xor ecx, ecx ; filled count
|
||||
|
||||
push ecx edx
|
||||
mov ecx, port_list_mutex
|
||||
invoke MutexLock
|
||||
pop edx ecx
|
||||
|
||||
mov esi, port_list
|
||||
.next:
|
||||
mov esi, [esi + SERIAL_PORT.fd]
|
||||
cmp esi, port_list
|
||||
jz .done
|
||||
inc ebx
|
||||
cmp edi, edx
|
||||
jae .next
|
||||
|
||||
mov eax, [esi + SERIAL_PORT.id]
|
||||
mov [edi + SP_PORT_ENUM_ENTRY.id], eax
|
||||
xor eax, eax
|
||||
cmp dword [esi + SERIAL_PORT.con], 0
|
||||
setnz al
|
||||
mov [edi + SP_PORT_ENUM_ENTRY.busy], eax
|
||||
|
||||
push ecx esi edi
|
||||
lea esi, [esi + SERIAL_PORT.driver]
|
||||
lea edi, [edi + SP_PORT_ENUM_ENTRY.driver]
|
||||
mov ecx, (SERIAL_INFO_DRIVER_LEN + SERIAL_INFO_DESCR_LEN) / 4
|
||||
rep movsd
|
||||
pop edi esi ecx
|
||||
|
||||
add edi, sizeof.SP_PORT_ENUM_ENTRY
|
||||
inc ecx
|
||||
jmp .next
|
||||
|
||||
.done:
|
||||
push ecx
|
||||
mov ecx, port_list_mutex
|
||||
invoke MutexUnlock
|
||||
pop ecx
|
||||
|
||||
mov eax, ebx
|
||||
ret
|
||||
endp
|
||||
|
||||
include_debug_strings
|
||||
|
||||
align 4
|
||||
|
||||
@@ -169,6 +169,7 @@ proc uart_probe stdcall uses ebx esi edi, io_addr:dword, irqn:dword
|
||||
; register port
|
||||
lea ecx, [uart_drv]
|
||||
mov edx, edi
|
||||
lea ebx, [uart_port_info]
|
||||
call add_port
|
||||
test eax, eax
|
||||
jz .free_desc ; TODO detach_int_handler?
|
||||
@@ -406,3 +407,11 @@ uart_drv:
|
||||
dd uart_reconf
|
||||
dd uart_tx
|
||||
uart_drv_end:
|
||||
|
||||
align 4
|
||||
uart_port_info:
|
||||
dd uart_port_end - uart_port_info
|
||||
dd uart_port_name
|
||||
dd 0
|
||||
uart_port_end:
|
||||
uart_port_name db 'uart16550', 0
|
||||
|
||||
+203
-310
@@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2026. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; FTDI chips driver for KolibriOS ;;
|
||||
@@ -15,10 +15,11 @@
|
||||
format PE DLL native 0.05
|
||||
entry START
|
||||
|
||||
DEBUG = 1
|
||||
L_DBG = 1
|
||||
L_ERR = 2
|
||||
|
||||
__DEBUG__ = 1
|
||||
__DEBUG_LEVEL__ = 1
|
||||
__DEBUG_LEVEL__ = L_ERR
|
||||
|
||||
node equ ftdi_context
|
||||
node.next equ ftdi_context.next_context
|
||||
@@ -122,9 +123,10 @@ TYPE_232H=6
|
||||
TYPE_230X=7
|
||||
|
||||
;strings
|
||||
my_driver db 'usbother',0
|
||||
my_driver db 'usbftdi',0
|
||||
serial_driver db 'SERIAL',0
|
||||
nomemory_msg db 'K : no memory',13,10,0
|
||||
nomemory_msg db 'ftdi: no memory',13,10,0
|
||||
ftdi_port_name db 'ftdi',0
|
||||
|
||||
; Structures
|
||||
struct ftdi_context
|
||||
@@ -200,10 +202,13 @@ endp
|
||||
|
||||
|
||||
proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD
|
||||
|
||||
locals
|
||||
.pinfo rb sizeof.SP_PORT_INFO
|
||||
endl
|
||||
|
||||
invoke USBGetParam, [.config_pipe], 0
|
||||
mov edx, eax
|
||||
DEBUGF 2,'K : Detected device vendor: 0x%x\n', [eax+usb_descr.idVendor]
|
||||
DEBUGF L_DBG, 'ftdi: Detected device vendor: 0x%x\n', [eax+usb_descr.idVendor]
|
||||
cmp word[eax+usb_descr.idVendor], 0x0403
|
||||
jnz .notftdi
|
||||
mov eax, sizeof.ftdi_context
|
||||
@@ -214,7 +219,7 @@ proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD
|
||||
invoke SysMsgBoardStr
|
||||
jmp .nothing
|
||||
@@:
|
||||
DEBUGF 2,'K : Adding struct to list 0x%x\n', eax
|
||||
DEBUGF L_DBG, 'ftdi: Adding struct to list 0x%x\n', eax
|
||||
call linkedlist_add
|
||||
|
||||
mov ebx, [.config_pipe]
|
||||
@@ -233,7 +238,7 @@ proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD
|
||||
jmp .slow
|
||||
|
||||
mov cx, [edx+usb_descr.bcdDevice]
|
||||
DEBUGF 2, 'K : Chip type 0x%x\n', ecx
|
||||
DEBUGF L_DBG, 'ftdi: Chip type 0x%x\n', ecx
|
||||
cmp cx, 0x400
|
||||
jnz @f
|
||||
mov [eax + ftdi_context.chipType], TYPE_BM
|
||||
@@ -287,8 +292,13 @@ proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD
|
||||
mov eax, [serial_drv_entry]
|
||||
test eax, eax
|
||||
jz @f
|
||||
stdcall serial_add_port, uart_drv, ebx
|
||||
DEBUGF 1, "usbftdi: add serial port with result %x\n", eax
|
||||
mov dword [.pinfo + SP_PORT_INFO.size], sizeof.SP_PORT_INFO
|
||||
mov dword [.pinfo + SP_PORT_INFO.driver], ftdi_port_name
|
||||
; TODO obtain iManufacturer, iProduct and iSerial strings
|
||||
mov dword [.pinfo + SP_PORT_INFO.descr], 0
|
||||
lea ecx, [.pinfo]
|
||||
stdcall serial_add_port, uart_drv, ebx, ecx
|
||||
DEBUGF L_DBG, 'ftdi: add serial port with result %x\n', eax
|
||||
@@:
|
||||
mov [ebx + ftdi_context.port_handle], eax
|
||||
|
||||
@@ -296,7 +306,7 @@ proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD
|
||||
ret
|
||||
|
||||
.notftdi:
|
||||
DEBUGF 1,'K : Skipping not FTDI device\n'
|
||||
DEBUGF L_DBG, 'ftdi: Skipping not FTDI device\n'
|
||||
.nothing:
|
||||
xor eax, eax
|
||||
ret
|
||||
@@ -317,7 +327,7 @@ EventData rd 3
|
||||
endl
|
||||
mov edi, [ioctl]
|
||||
mov eax, [edi+io_code]
|
||||
DEBUGF 1,'K : FTDI got the request: %d\n', eax
|
||||
DEBUGF L_DBG, 'ftdi: FTDI got the request: %d\n', eax
|
||||
test eax, eax ;0
|
||||
jz .version
|
||||
dec eax ;1
|
||||
@@ -416,7 +426,7 @@ endl
|
||||
.version:
|
||||
jmp .endswitch
|
||||
.error:
|
||||
DEBUGF 1, 'K : FTDI error occured! %d\n', eax
|
||||
DEBUGF L_ERR, 'ftdi: error occured! %d\n', eax
|
||||
;mov esi, [edi+output]
|
||||
;mov [esi], dword 'ERR0'
|
||||
;or [esi], eax
|
||||
@@ -449,7 +459,7 @@ endl
|
||||
mov word[ConfPacket+6], cx
|
||||
.own_index:
|
||||
mov ebx, [edi+4]
|
||||
DEBUGF 2,'K : ConfPacket 0x%x 0x%x\n', [ConfPacket], [ConfPacket+4]
|
||||
DEBUGF L_DBG, 'ftdi: ConfPacket 0x%x 0x%x\n', [ConfPacket], [ConfPacket+4]
|
||||
lea esi, [ConfPacket]
|
||||
lea edi, [EventData]
|
||||
invoke USBControlTransferAsync, [ebx + ftdi_context.nullP], esi, 0,\
|
||||
@@ -465,7 +475,7 @@ endl
|
||||
jmp .error
|
||||
|
||||
.ftdi_setrtshigh:
|
||||
DEBUGF 2,'K : FTDI Setting RTS pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Setting RTS pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
|
||||
@@ -473,7 +483,7 @@ endl
|
||||
jmp .ftdi_out_control_transfer_noinp
|
||||
|
||||
.ftdi_setrtslow:
|
||||
DEBUGF 2,'K : FTDI Setting RTS pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Setting RTS pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
|
||||
@@ -481,7 +491,7 @@ endl
|
||||
jmp .ftdi_out_control_transfer_noinp
|
||||
|
||||
.ftdi_setdtrhigh:
|
||||
DEBUGF 2,'K : FTDI Setting DTR pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Setting DTR pin HIGH PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
|
||||
@@ -489,7 +499,7 @@ endl
|
||||
jmp .ftdi_out_control_transfer_noinp
|
||||
|
||||
.ftdi_setdtrlow:
|
||||
DEBUGF 2,'K : FTDI Setting DTR pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Setting DTR pin LOW PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_MODEM_CTRL_REQUEST shl 8) \
|
||||
@@ -497,7 +507,7 @@ endl
|
||||
jmp .ftdi_out_control_transfer_noinp
|
||||
|
||||
.ftdi_usb_reset:
|
||||
DEBUGF 2,'K : FTDI Reseting PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Reseting PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_RESET_REQUEST shl 8) \
|
||||
@@ -505,7 +515,7 @@ endl
|
||||
jmp .ftdi_out_control_transfer_noinp
|
||||
|
||||
.ftdi_purge_rx_buf:
|
||||
DEBUGF 2, 'K : FTDI Purge TX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Purge TX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_RESET_REQUEST shl 8) \
|
||||
@@ -513,7 +523,7 @@ endl
|
||||
jmp .ftdi_out_control_transfer_noinp
|
||||
|
||||
.ftdi_purge_tx_buf:
|
||||
DEBUGF 2, 'K : FTDI Purge RX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Purge RX buffer PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_RESET_REQUEST shl 8) \
|
||||
@@ -521,42 +531,42 @@ endl
|
||||
jmp .ftdi_out_control_transfer_noinp
|
||||
|
||||
.ftdi_set_bitmode:
|
||||
DEBUGF 2, 'K : FTDI Set bitmode 0x%x, bitmask 0x%x %d PID: %d Dev handler 0x0x%x\n', \
|
||||
DEBUGF L_DBG, 'ftdi: Set bitmode 0x%x, bitmask 0x%x %d PID: %d Dev handler 0x0x%x\n', \
|
||||
[edi+8]:2,[edi+10]:2,[edi],[edi+4]
|
||||
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_BITMODE_REQUEST shl 8)
|
||||
jmp .ftdi_out_control_transfer_withinp
|
||||
|
||||
.ftdi_set_line_property:
|
||||
DEBUGF 2, 'K : FTDI Set line property 0x%x PID: %d Dev handler 0x0x%x\n', \
|
||||
DEBUGF L_DBG, 'ftdi: Set line property 0x%x PID: %d Dev handler 0x0x%x\n', \
|
||||
[edi+8]:4,[edi],[edi+4]
|
||||
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_DATA_REQUEST shl 8)
|
||||
jmp .ftdi_out_control_transfer_withinp
|
||||
|
||||
.ftdi_set_latency_timer:
|
||||
DEBUGF 2, 'K : FTDI Set latency %d PID: %d Dev handler 0x0x%x\n', \
|
||||
DEBUGF L_DBG, 'ftdi: Set latency %d PID: %d Dev handler 0x0x%x\n', \
|
||||
[edi+8],[edi],[edi+4]
|
||||
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_LATENCY_TIMER_REQUEST shl 8)
|
||||
jmp .ftdi_out_control_transfer_withinp
|
||||
|
||||
.ftdi_set_event_char:
|
||||
DEBUGF 2, 'K : FTDI Set event char %c PID: %d Dev handler 0x0x%x\n', \
|
||||
DEBUGF L_DBG, 'ftdi: Set event char %c PID: %d Dev handler 0x0x%x\n', \
|
||||
[edi+8],[edi],[edi+4]
|
||||
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_EVENT_CHAR_REQUEST shl 8)
|
||||
jmp .ftdi_out_control_transfer_withinp
|
||||
|
||||
.ftdi_set_error_char:
|
||||
DEBUGF 2, 'K : FTDI Set error char %c PID: %d Dev handler 0x0x%x\n', \
|
||||
DEBUGF L_DBG, 'ftdi: Set error char %c PID: %d Dev handler 0x0x%x\n', \
|
||||
[edi+8],[edi],[edi+4]
|
||||
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_ERROR_CHAR_REQUEST shl 8)
|
||||
jmp .ftdi_out_control_transfer_withinp
|
||||
|
||||
.ftdi_setflowctrl:
|
||||
DEBUGF 2, 'K : FTDI Set flow control PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Set flow control PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_FLOW_CTRL_REQUEST shl 8) + (0 shl 16)
|
||||
@@ -569,7 +579,7 @@ endl
|
||||
jmp .own_index
|
||||
|
||||
.ftdi_read_pins:
|
||||
DEBUGF 2, 'K : FTDI Read pins PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Read pins PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov ebx, [edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_IN_REQTYPE) \
|
||||
@@ -598,7 +608,7 @@ endl
|
||||
jmp .error
|
||||
|
||||
.ftdi_set_wchunksize:
|
||||
DEBUGF 2, 'K : FTDI Set write chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
|
||||
DEBUGF L_DBG, 'ftdi: Set write chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
|
||||
[edi+8], [edi], [edi+4]
|
||||
mov ebx, [edi+4]
|
||||
mov ecx, [edi+8]
|
||||
@@ -608,7 +618,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_get_wchunksize:
|
||||
DEBUGF 2, 'K : FTDI Get write chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Get write chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov esi, [edi+output]
|
||||
mov edi, [edi+input]
|
||||
@@ -618,7 +628,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_set_rchunksize:
|
||||
DEBUGF 2, 'K : FTDI Set read chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
|
||||
DEBUGF L_DBG, 'ftdi: Set read chunksize %d bytes PID: %d Dev handler 0x0x%x\n', \
|
||||
[edi+8], [edi], [edi+4]
|
||||
mov ebx, [edi+4]
|
||||
mov ecx, [edi+8]
|
||||
@@ -628,7 +638,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_get_rchunksize:
|
||||
DEBUGF 2, 'K : FTDI Get read chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Get read chunksize PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov esi, [edi+output]
|
||||
mov edi, [edi+input]
|
||||
@@ -638,7 +648,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_write_data:
|
||||
DEBUGF 2, 'K : FTDI Write %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
|
||||
DEBUGF L_DBG, 'ftdi: Write %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
|
||||
[edi], [edi+4]
|
||||
mov esi, edi
|
||||
add esi, 12
|
||||
@@ -685,7 +695,7 @@ endl
|
||||
jmp .write_loop
|
||||
|
||||
.ftdi_read_data:
|
||||
DEBUGF 2, 'K : FTDI Read %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
|
||||
DEBUGF L_DBG, 'ftdi: Read %d bytes PID: %d Dev handler 0x%x\n', [edi+8],\
|
||||
[edi], [edi+4]
|
||||
mov edi, [ioctl]
|
||||
mov esi, [edi+input]
|
||||
@@ -743,7 +753,7 @@ endl
|
||||
;---Dirty hack end
|
||||
|
||||
.ftdi_poll_modem_status:
|
||||
DEBUGF 2, 'K : FTDI Poll modem status PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Poll modem status PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov ebx, [edi+4]
|
||||
mov dword[ConfPacket], (FTDI_DEVICE_IN_REQTYPE) \
|
||||
@@ -767,7 +777,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_get_latency_timer:
|
||||
DEBUGF 2, 'K : FTDI Get latency timer PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
DEBUGF L_DBG, 'ftdi: Get latency timer PID: %d Dev handler 0x0x%x\n', [edi],\
|
||||
[edi+4]
|
||||
mov ebx, [edi+4]
|
||||
mov dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE \
|
||||
@@ -787,7 +797,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_get_list:
|
||||
DEBUGF 2, 'K : FTDI devices list request\n'
|
||||
DEBUGF L_DBG, 'ftdi: devices list request\n'
|
||||
mov edi, [edi+output]
|
||||
xor ecx, ecx
|
||||
call linkedlist_gethead
|
||||
@@ -817,7 +827,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_lock:
|
||||
DEBUGF 2, 'K : FTDI Lock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
|
||||
DEBUGF L_DBG, 'ftdi: Lock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
|
||||
mov esi, [edi+input]
|
||||
mov ebx, [esi+4]
|
||||
mov eax, [ebx + ftdi_context.lockPID]
|
||||
@@ -831,7 +841,7 @@ endl
|
||||
jmp .endswitch
|
||||
|
||||
.ftdi_unlock:
|
||||
DEBUGF 2, 'K : FTDI Unlock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
|
||||
DEBUGF L_DBG, 'ftdi: Unlock PID: %d Dev handler 0x0x%x\n', [edi], [edi+4]
|
||||
mov esi, [edi+input]
|
||||
mov edi, [edi+output]
|
||||
mov ebx, [esi+4]
|
||||
@@ -845,145 +855,19 @@ endl
|
||||
mov [edi], eax
|
||||
jmp .endswitch
|
||||
|
||||
H_CLK = 120000000
|
||||
C_CLK = 48000000
|
||||
.ftdi_set_baudrate:
|
||||
DEBUGF 2, 'K : FTDI Set baudrate to %d PID: %d Dev handle: 0x%x\n',\
|
||||
DEBUGF L_DBG, 'ftdi: Set baudrate to %d PID: %d Dev handle: 0x%x\n',\
|
||||
[edi+8], [edi], [edi+4]
|
||||
mov ebx, [edi+4]
|
||||
cmp [ebx + ftdi_context.chipType], TYPE_2232H
|
||||
jl .c_clk
|
||||
imul eax, [edi+8], 10
|
||||
cmp eax, H_CLK / 0x3FFF
|
||||
jle .c_clk
|
||||
.h_clk:
|
||||
cmp dword[edi+8], H_CLK/10
|
||||
jl .h_nextbaud1
|
||||
xor edx, edx
|
||||
mov ecx, H_CLK/10
|
||||
jmp .calcend
|
||||
|
||||
.c_clk:
|
||||
cmp dword[edi+8], C_CLK/16
|
||||
jl .c_nextbaud1
|
||||
xor edx, edx
|
||||
mov ecx, C_CLK/16
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud1:
|
||||
cmp dword[edi+8], H_CLK/(10 + 10/2)
|
||||
jl .h_nextbaud2
|
||||
mov edx, 1
|
||||
mov ecx, H_CLK/(10 + 10/2)
|
||||
jmp .calcend
|
||||
|
||||
.c_nextbaud1:
|
||||
cmp dword[edi+8], C_CLK/(16 + 16/2)
|
||||
jl .c_nextbaud2
|
||||
mov edx, 1
|
||||
mov ecx, C_CLK/(16 + 16/2)
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud2:
|
||||
cmp dword[edi+8], H_CLK/(2*10)
|
||||
jl .h_nextbaud3
|
||||
mov edx, 2
|
||||
mov ecx, H_CLK/(2*10)
|
||||
jmp .calcend
|
||||
|
||||
.c_nextbaud2:
|
||||
cmp dword[edi+8], C_CLK/(2*16)
|
||||
jl .c_nextbaud3
|
||||
mov edx, 2
|
||||
mov ecx, C_CLK/(2*16)
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud3:
|
||||
mov eax, H_CLK*16/10 ; eax - best_divisor
|
||||
xor edx, edx
|
||||
div dword[edi+8] ; [edi+8] - baudrate
|
||||
push eax
|
||||
and eax, 1
|
||||
pop eax
|
||||
shr eax, 1
|
||||
jz .h_rounddowndiv ; jump by result of and eax, 1
|
||||
inc eax
|
||||
.h_rounddowndiv:
|
||||
cmp eax, 0x20000
|
||||
jle .h_best_divok
|
||||
mov eax, 0x1FFFF
|
||||
.h_best_divok:
|
||||
mov ecx, eax
|
||||
mov eax, H_CLK*16/10
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg ecx, eax ; ecx - best_baud
|
||||
push ecx
|
||||
and ecx, 1
|
||||
pop ecx
|
||||
shr ecx, 1
|
||||
jz .rounddownbaud
|
||||
inc ecx
|
||||
jmp .rounddownbaud
|
||||
|
||||
.c_nextbaud3:
|
||||
mov eax, C_CLK ; eax - best_divisor
|
||||
xor edx, edx
|
||||
div dword[edi+8] ; [edi+8] - baudrate
|
||||
push eax
|
||||
and eax, 1
|
||||
pop eax
|
||||
shr eax, 1
|
||||
jnz .c_rounddowndiv ; jump by result of and eax, 1
|
||||
inc eax
|
||||
.c_rounddowndiv:
|
||||
cmp eax, 0x20000
|
||||
jle .c_best_divok
|
||||
mov eax, 0x1FFFF
|
||||
.c_best_divok:
|
||||
mov ecx, eax
|
||||
mov eax, C_CLK
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg ecx, eax ; ecx - best_baud
|
||||
push ecx
|
||||
and ecx, 1
|
||||
pop ecx
|
||||
shr ecx, 1
|
||||
jnz .rounddownbaud
|
||||
inc ecx
|
||||
|
||||
.rounddownbaud:
|
||||
mov edx, eax ; edx - encoded_divisor
|
||||
shr edx, 3
|
||||
and eax, 0x7
|
||||
push 7 6 5 1 4 2 3 0
|
||||
mov eax, [esp+eax*4]
|
||||
shl eax, 14
|
||||
or edx, eax
|
||||
add esp, 32
|
||||
|
||||
.calcend:
|
||||
mov eax, edx ; eax - *value
|
||||
mov ecx, edx ; ecx - *index
|
||||
and eax, 0xFFFF
|
||||
cmp [ebx + ftdi_context.chipType], TYPE_2232H
|
||||
jge .foxyindex
|
||||
shr ecx, 16
|
||||
jmp .preparepacket
|
||||
.foxyindex:
|
||||
shr ecx, 8
|
||||
and ecx, 0xFF00
|
||||
or ecx, [ebx + ftdi_context.index]
|
||||
|
||||
.preparepacket:
|
||||
mov esi, [edi+8]
|
||||
call ftdi_calc_baud_divisor
|
||||
mov word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_BAUDRATE_REQUEST shl 8)
|
||||
mov word[ConfPacket+2], ax
|
||||
mov word[ConfPacket+4], cx
|
||||
mov word[ConfPacket+6], 0
|
||||
jmp .own_index
|
||||
|
||||
jmp .own_index
|
||||
|
||||
endp
|
||||
restore handle
|
||||
restore io_code
|
||||
@@ -993,10 +877,143 @@ restore output
|
||||
restore out_size
|
||||
|
||||
|
||||
proc ftdi_calc_baud_divisor
|
||||
; in: ebx = ftdi_context pointer
|
||||
; esi = baud rate
|
||||
; out: ax = encoded value
|
||||
; cx = encoded index
|
||||
; destroys: eax, ecx, edx, esi
|
||||
cmp [ebx + ftdi_context.chipType], TYPE_2232H
|
||||
jl .c_clk
|
||||
imul eax, esi, 10
|
||||
cmp eax, H_CLK / 0x3FFF
|
||||
jle .c_clk
|
||||
.h_clk:
|
||||
cmp esi, H_CLK / 10
|
||||
jl .h_nextbaud1
|
||||
xor edx, edx
|
||||
mov ecx, H_CLK / 10
|
||||
jmp .calcend
|
||||
|
||||
.c_clk:
|
||||
cmp esi, C_CLK / 16
|
||||
jl .c_nextbaud1
|
||||
xor edx, edx
|
||||
mov ecx, C_CLK / 16
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud1:
|
||||
cmp esi, H_CLK / (10 + 10 / 2)
|
||||
jl .h_nextbaud2
|
||||
mov edx, 1
|
||||
mov ecx, H_CLK / (10 + 10 / 2)
|
||||
jmp .calcend
|
||||
|
||||
.c_nextbaud1:
|
||||
cmp esi, C_CLK / (16 + 16 / 2)
|
||||
jl .c_nextbaud2
|
||||
mov edx, 1
|
||||
mov ecx, C_CLK/(16 + 16 / 2)
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud2:
|
||||
cmp esi, H_CLK / (2 * 10)
|
||||
jl .h_nextbaud3
|
||||
mov edx, 2
|
||||
mov ecx, H_CLK / (2 * 10)
|
||||
jmp .calcend
|
||||
|
||||
.c_nextbaud2:
|
||||
cmp esi, C_CLK / (2 * 16)
|
||||
jl .c_nextbaud3
|
||||
mov edx, 2
|
||||
mov ecx, C_CLK / (2 * 16)
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud3:
|
||||
mov eax, H_CLK * 16 / 10 ; eax - best_divisor
|
||||
xor edx, edx
|
||||
div esi
|
||||
push eax
|
||||
and eax, 1
|
||||
pop eax
|
||||
shr eax, 1
|
||||
jz .h_rounddowndiv ; jump by result of and eax, 1
|
||||
inc eax
|
||||
.h_rounddowndiv:
|
||||
cmp eax, 0x20000
|
||||
jle .h_best_divok
|
||||
mov eax, 0x1FFFF
|
||||
.h_best_divok:
|
||||
mov ecx, eax
|
||||
mov eax, H_CLK * 16 / 10
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg ecx, eax ; ecx - best_baud
|
||||
push ecx
|
||||
and ecx, 1
|
||||
pop ecx
|
||||
shr ecx, 1
|
||||
jz .rounddownbaud
|
||||
inc ecx
|
||||
jmp .rounddownbaud
|
||||
|
||||
.c_nextbaud3:
|
||||
mov eax, C_CLK ; eax - best_divisor
|
||||
xor edx, edx
|
||||
div esi
|
||||
push eax
|
||||
and eax, 1
|
||||
pop eax
|
||||
shr eax, 1
|
||||
jnz .c_rounddowndiv ; jump by result of and eax, 1
|
||||
inc eax
|
||||
.c_rounddowndiv:
|
||||
cmp eax, 0x20000
|
||||
jle .c_best_divok
|
||||
mov eax, 0x1FFFF
|
||||
.c_best_divok:
|
||||
mov ecx, eax
|
||||
mov eax, C_CLK
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg ecx, eax ; ecx - best_baud
|
||||
push ecx
|
||||
and ecx, 1
|
||||
pop ecx
|
||||
shr ecx, 1
|
||||
jnz .rounddownbaud
|
||||
inc ecx
|
||||
|
||||
.rounddownbaud:
|
||||
mov edx, eax ; edx - encoded_divisor
|
||||
shr edx, 3
|
||||
and eax, 0x7
|
||||
push 7 6 5 1 4 2 3 0
|
||||
mov eax, [esp + eax * 4]
|
||||
shl eax, 14
|
||||
or edx, eax
|
||||
add esp, 32
|
||||
|
||||
.calcend:
|
||||
mov eax, edx ; eax - *value
|
||||
mov ecx, edx ; ecx - *index
|
||||
and eax, 0xFFFF
|
||||
cmp [ebx + ftdi_context.chipType], TYPE_2232H
|
||||
jge .foxyindex
|
||||
shr ecx, 16
|
||||
ret
|
||||
.foxyindex:
|
||||
shr ecx, 8
|
||||
and ecx, 0xFF00
|
||||
or ecx, [ebx + ftdi_context.index]
|
||||
ret
|
||||
endp
|
||||
|
||||
proc control_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
|
||||
.buffer:DWORD, .length:DWORD, .calldata:DWORD
|
||||
|
||||
DEBUGF 1, 'K : status is %d\n', [.status]
|
||||
DEBUGF L_DBG, 'ftdi: status is %d\n', [.status]
|
||||
mov ecx, [.calldata]
|
||||
mov eax, [ecx]
|
||||
mov ebx, [ecx+4]
|
||||
@@ -1011,7 +1028,7 @@ endp
|
||||
proc bulk_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
|
||||
.buffer:DWORD, .length:DWORD, .calldata:DWORD
|
||||
|
||||
DEBUGF 1, 'K : status is %d\n', [.status]
|
||||
DEBUGF L_DBG, 'ftdi: status is %d\n', [.status]
|
||||
mov ecx, [.calldata]
|
||||
mov eax, [ecx]
|
||||
mov ebx, [ecx+4]
|
||||
@@ -1034,7 +1051,7 @@ endp
|
||||
|
||||
proc DeviceDisconnected stdcall uses ebx esi edi, .device_data:DWORD
|
||||
|
||||
DEBUGF 1, 'K : FTDI deleting device data 0x%x\n', [.device_data]
|
||||
DEBUGF L_DBG, 'ftdi: deleting device data 0x%x\n', [.device_data]
|
||||
mov esi, [.device_data]
|
||||
mov eax, [esi + ftdi_context.readBufPtr]
|
||||
test eax, eax
|
||||
@@ -1062,7 +1079,7 @@ proc bulk_in_complete stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
|
||||
mov eax, [.status]
|
||||
test eax, eax
|
||||
jz @f
|
||||
DEBUGF 2, 'ftdi: bulk in error %x\n', eax
|
||||
DEBUGF L_ERR, 'ftdi: bulk in error %x\n', eax
|
||||
@@:
|
||||
mov ebx, [.calldata]
|
||||
btr dword [ebx + ftdi_context.writeBufLock], 0
|
||||
@@ -1075,7 +1092,7 @@ proc bulk_out_complete stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
|
||||
mov eax, [.status]
|
||||
test eax, eax
|
||||
jz @f
|
||||
DEBUGF 2, 'ftdi: bulk out error %x\n', eax
|
||||
DEBUGF L_ERR, 'ftdi: bulk out error %x\n', eax
|
||||
@@:
|
||||
mov ebx, [.calldata]
|
||||
mov ecx, [.length]
|
||||
@@ -1092,18 +1109,18 @@ proc bulk_out_complete stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, \
|
||||
endp
|
||||
|
||||
proc uart_startup stdcall uses ebx, data:dword, conf:dword
|
||||
DEBUGF 1, "ftdi: startup %x %x\n", [data], [conf]
|
||||
DEBUGF L_DBG, "ftdi: startup %x %x\n", [data], [conf]
|
||||
stdcall uart_reconf, [data], [conf]
|
||||
test eax, eax
|
||||
jz @f
|
||||
DEBUGF 2, "ftdi: uart reconf error %x\n", eax
|
||||
DEBUGF L_ERR, "ftdi: uart reconf error %x\n", eax
|
||||
jmp .exit
|
||||
@@:
|
||||
mov ebx, [data]
|
||||
invoke TimerHS, 2, 2, uart_rx, ebx
|
||||
test eax, eax
|
||||
jnz @f
|
||||
DEBUGF 2, "ftdi: timer creation error\n"
|
||||
DEBUGF L_ERR, "ftdi: timer creation error\n"
|
||||
or eax, -1
|
||||
jmp .exit
|
||||
@@:
|
||||
@@ -1114,7 +1131,7 @@ proc uart_startup stdcall uses ebx, data:dword, conf:dword
|
||||
endp
|
||||
|
||||
proc uart_shutdown stdcall uses ebx, data:dword
|
||||
DEBUGF 1, "ftdi: shutdown %x\n", [data]
|
||||
DEBUGF L_DBG, "ftdi: shutdown %x\n", [data]
|
||||
mov ebx, [data]
|
||||
cmp [ebx + ftdi_context.rx_timer], 0
|
||||
jz @f
|
||||
@@ -1246,137 +1263,14 @@ proc uart_rx stdcall uses ebx esi, data:dword
|
||||
ret
|
||||
endp
|
||||
|
||||
proc ftdi_set_baudrate stdcall uses ebx, dev:dword, baud:dword
|
||||
proc ftdi_set_baudrate stdcall uses ebx esi, dev:dword, baud:dword
|
||||
locals
|
||||
ConfPacket rb 8
|
||||
endl
|
||||
mov ebx, [dev]
|
||||
cmp [ebx + ftdi_context.chipType], TYPE_2232H
|
||||
jl .c_clk
|
||||
imul eax, [baud], 10
|
||||
cmp eax, H_CLK / 0x3FFF
|
||||
jle .c_clk
|
||||
.h_clk:
|
||||
cmp dword [baud], H_CLK / 10
|
||||
jl .h_nextbaud1
|
||||
xor edx, edx
|
||||
mov ecx, H_CLK / 10
|
||||
jmp .calcend
|
||||
mov esi, [baud]
|
||||
call ftdi_calc_baud_divisor
|
||||
|
||||
.c_clk:
|
||||
cmp dword [baud], C_CLK / 16
|
||||
jl .c_nextbaud1
|
||||
xor edx, edx
|
||||
mov ecx, C_CLK / 16
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud1:
|
||||
cmp dword [baud], H_CLK / (10 + 10 / 2)
|
||||
jl .h_nextbaud2
|
||||
mov edx, 1
|
||||
mov ecx, H_CLK / (10 + 10 / 2)
|
||||
jmp .calcend
|
||||
|
||||
.c_nextbaud1:
|
||||
cmp dword [baud], C_CLK / (16 + 16 / 2)
|
||||
jl .c_nextbaud2
|
||||
mov edx, 1
|
||||
mov ecx, C_CLK/(16 + 16 / 2)
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud2:
|
||||
cmp dword [baud], H_CLK / (2 * 10)
|
||||
jl .h_nextbaud3
|
||||
mov edx, 2
|
||||
mov ecx, H_CLK / (2 * 10)
|
||||
jmp .calcend
|
||||
|
||||
.c_nextbaud2:
|
||||
cmp dword [baud], C_CLK / (2 * 16)
|
||||
jl .c_nextbaud3
|
||||
mov edx, 2
|
||||
mov ecx, C_CLK / (2 * 16)
|
||||
jmp .calcend
|
||||
|
||||
.h_nextbaud3:
|
||||
mov eax, H_CLK * 16 / 10 ; eax - best_divisor
|
||||
xor edx, edx
|
||||
div dword [baud]
|
||||
push eax
|
||||
and eax, 1
|
||||
pop eax
|
||||
shr eax, 1
|
||||
jz .h_rounddowndiv ; jump by result of and eax, 1
|
||||
inc eax
|
||||
.h_rounddowndiv:
|
||||
cmp eax, 0x20000
|
||||
jle .h_best_divok
|
||||
mov eax, 0x1FFFF
|
||||
.h_best_divok:
|
||||
mov ecx, eax
|
||||
mov eax, H_CLK * 16 / 10
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg ecx, eax ; ecx - best_baud
|
||||
push ecx
|
||||
and ecx, 1
|
||||
pop ecx
|
||||
shr ecx, 1
|
||||
jz .rounddownbaud
|
||||
inc ecx
|
||||
jmp .rounddownbaud
|
||||
|
||||
.c_nextbaud3:
|
||||
mov eax, C_CLK ; eax - best_divisor
|
||||
xor edx, edx
|
||||
div dword [baud]
|
||||
push eax
|
||||
and eax, 1
|
||||
pop eax
|
||||
shr eax, 1
|
||||
jnz .c_rounddowndiv ; jump by result of and eax, 1
|
||||
inc eax
|
||||
.c_rounddowndiv:
|
||||
cmp eax, 0x20000
|
||||
jle .c_best_divok
|
||||
mov eax, 0x1FFFF
|
||||
.c_best_divok:
|
||||
mov ecx, eax
|
||||
mov eax, C_CLK
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg ecx, eax ; ecx - best_baud
|
||||
push ecx
|
||||
and ecx, 1
|
||||
pop ecx
|
||||
shr ecx, 1
|
||||
jnz .rounddownbaud
|
||||
inc ecx
|
||||
|
||||
.rounddownbaud:
|
||||
mov edx, eax ; edx - encoded_divisor
|
||||
shr edx, 3
|
||||
and eax, 0x7
|
||||
push 7 6 5 1 4 2 3 0
|
||||
mov eax, [esp + eax * 4]
|
||||
shl eax, 14
|
||||
or edx, eax
|
||||
add esp, 32
|
||||
|
||||
.calcend:
|
||||
mov eax, edx ; eax - *value
|
||||
mov ecx, edx ; ecx - *index
|
||||
and eax, 0xFFFF
|
||||
cmp [ebx + ftdi_context.chipType], TYPE_2232H
|
||||
jge .foxyindex
|
||||
shr ecx, 16
|
||||
jmp .preparepacket
|
||||
.foxyindex:
|
||||
shr ecx, 8
|
||||
and ecx, 0xFF00
|
||||
or ecx, [ebx + ftdi_context.index]
|
||||
|
||||
.preparepacket:
|
||||
mov word [ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) \
|
||||
+ (SIO_SET_BAUDRATE_REQUEST shl 8)
|
||||
mov word [ConfPacket + 2], ax
|
||||
@@ -1451,10 +1345,9 @@ uart_drv:
|
||||
dd uart_tx
|
||||
uart_drv_end:
|
||||
|
||||
serial_drv_entry dd 0
|
||||
include_debug_strings
|
||||
|
||||
data fixups
|
||||
end data
|
||||
|
||||
;for DEBUGF macro
|
||||
include_debug_strings
|
||||
|
||||
serial_drv_entry dd ?
|
||||
|
||||
@@ -2204,6 +2204,9 @@ proc acm_arm_rx
|
||||
endp
|
||||
|
||||
proc acm_add_device stdcall uses ebx esi edi, .pipe0:dword, .config:dword, .interface:dword
|
||||
locals
|
||||
.pinfo rb sizeof.SP_PORT_INFO
|
||||
endl
|
||||
|
||||
; 1. Parse the descriptors (the ACM data interface is alt setting 0).
|
||||
xor eax, eax
|
||||
@@ -2264,7 +2267,12 @@ proc acm_add_device stdcall uses ebx esi edi, .pipe0:dword, .config:dword, .inte
|
||||
|
||||
cmp [serial_drv_entry], 0
|
||||
je .no_serial
|
||||
stdcall serial_add_port, acm_sp_driver, ebx
|
||||
mov dword [.pinfo+SP_PORT_INFO.size], sizeof.SP_PORT_INFO
|
||||
mov dword [.pinfo+SP_PORT_INFO.driver], acm_port_name
|
||||
; TODO obtain iManufacturer, iProduct and iSerial strings
|
||||
mov dword [.pinfo+SP_PORT_INFO.descr], 0
|
||||
lea ecx, [.pinfo]
|
||||
stdcall serial_add_port, acm_sp_driver, ebx, ecx
|
||||
mov [ebx+acm_dev.PortHandle], eax
|
||||
test eax, eax
|
||||
jz .no_serial
|
||||
@@ -2652,6 +2660,7 @@ endp
|
||||
|
||||
; strings and static data
|
||||
my_service db 'usbcdc', 0
|
||||
acm_port_name db 'cdc-acm', 0
|
||||
netdev_name db 'USB CDC-NCM', 0
|
||||
ecm_netdev_name db 'USB CDC-ECM', 0
|
||||
ecm_zlp_dummy db 0 ; address for zero-length transfers
|
||||
|
||||
@@ -436,7 +436,7 @@ btn_io db ?
|
||||
dev dd ?
|
||||
pid dd ?
|
||||
flags dd ?
|
||||
drv_name db 'usbother', 0
|
||||
drv_name db 'usbftdi', 0
|
||||
noftdi_msg db 'No FTDI connected', 0
|
||||
devrdy_msg db 'First FTDI is ready', 0
|
||||
devlkd_msg db 'First FTDI is locked', 0
|
||||
|
||||
Reference in New Issue
Block a user