Subversion Repositories Kolibri OS

Rev

Rev 5037 | Rev 5042 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4985 gtament 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
5035 gtament 6
;;  FTDI chips driver for KolibriOS                             ;;
7
;;                                                              ;;
8
;;   Written by gtament@gmail.com                               ;;
9
;;                                                              ;;
10
;;         GNU GENERAL PUBLIC LICENSE                           ;;
11
;;          Version 2, June 1991                                ;;
12
;;                                                              ;;
4985 gtament 13
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
14
 
4975 gtament 15
format MS COFF
16
 
17
DEBUG = 1
18
 
19
__DEBUG__ = 1
20
__DEBUG_LEVEL__ = 1
21
 
4997 gtament 22
node equ ftdi_context
23
node.next equ ftdi_context.next_context
24
 
5038 gtament 25
include '../../proc32.inc'
26
include '../../imports.inc'
27
include '../../fdo.inc'
28
include '../../struct.inc'
4975 gtament 29
 
30
public START
31
public version
32
 
33
; USB constants
34
DEVICE_DESCR_TYPE           = 1
35
CONFIG_DESCR_TYPE           = 2
36
STRING_DESCR_TYPE           = 3
37
INTERFACE_DESCR_TYPE        = 4
38
ENDPOINT_DESCR_TYPE         = 5
39
DEVICE_QUALIFIER_DESCR_TYPE = 6
40
 
41
CONTROL_PIPE     = 0
42
ISOCHRONOUS_PIPE = 1
43
BULK_PIPE        = 2
44
INTERRUPT_PIPE   = 3
45
 
46
; USB HID constants
47
HID_DESCR_TYPE      = 21h
48
REPORT_DESCR_TYPE   = 22h
49
PHYSICAL_DESCR_TYPE = 23h
50
 
51
 
52
; LibUSB constatnts
53
LIBUSB_REQUEST_TYPE_STANDARD = (0x00 shl 5)
54
LIBUSB_REQUEST_TYPE_CLASS = (0x01 shl 5)
55
LIBUSB_REQUEST_TYPE_VENDOR = (0x02 shl 5)
56
LIBUSB_REQUEST_TYPE_RESERVED = (0x03 shl 5)
57
 
58
LIBUSB_RECIPIENT_DEVICE = 0x00
59
LIBUSB_RECIPIENT_INTERFACE = 0x01
60
LIBUSB_RECIPIENT_ENDPOINT = 0x02
61
LIBUSB_RECIPIENT_OTHER = 0x03
62
 
63
LIBUSB_ENDPOINT_IN = 0x80
64
LIBUSB_ENDPOINT_OUT = 0x00
65
 
66
; FTDI Constants
67
FTDI_DEVICE_OUT_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_OUT)
68
FTDI_DEVICE_IN_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_IN)
69
 
70
; Requests
71
;Definitions for flow control
72
SIO_RESET         =0  ;Reset the port
73
SIO_MODEM_CTRL    =1  ;Set the modem control register
74
SIO_SET_FLOW_CTRL =2  ;Set flow control register
75
SIO_SET_BAUD_RATE =3  ;Set baud rate
76
SIO_SET_DATA      =4  ;Set the data characteristics of the port
77
 
78
SIO_RESET_REQUEST            =SIO_RESET
79
SIO_SET_BAUDRATE_REQUEST     =SIO_SET_BAUD_RATE
80
SIO_SET_DATA_REQUEST         =SIO_SET_DATA
81
SIO_SET_FLOW_CTRL_REQUEST    =SIO_SET_FLOW_CTRL
82
SIO_SET_MODEM_CTRL_REQUEST   =SIO_MODEM_CTRL
83
SIO_POLL_MODEM_STATUS_REQUEST=0x05
84
SIO_SET_EVENT_CHAR_REQUEST   =0x06
85
SIO_SET_ERROR_CHAR_REQUEST   =0x07
86
SIO_SET_LATENCY_TIMER_REQUEST=0x09
87
SIO_GET_LATENCY_TIMER_REQUEST=0x0A
88
SIO_SET_BITMODE_REQUEST      =0x0B
89
SIO_READ_PINS_REQUEST        =0x0C
90
SIO_READ_EEPROM_REQUEST      =0x90
91
SIO_WRITE_EEPROM_REQUEST     =0x91
92
SIO_ERASE_EEPROM_REQUEST     =0x92
93
 
94
 
95
SIO_RESET_SIO=0
96
SIO_RESET_PURGE_RX=1
97
SIO_RESET_PURGE_TX=2
98
 
99
SIO_DISABLE_FLOW_CTRL=0x0
100
SIO_RTS_CTS_HS =(0x1 shl 8)
101
SIO_DTR_DSR_HS =(0x2 shl 8)
102
SIO_XON_XOFF_HS=(0x4 shl 8)
103
 
104
SIO_SET_DTR_MASK=0x1
105
SIO_SET_DTR_HIGH=( 1 or ( SIO_SET_DTR_MASK  shl 8))
106
SIO_SET_DTR_LOW =( 0 or ( SIO_SET_DTR_MASK  shl 8))
107
SIO_SET_RTS_MASK=0x2
108
SIO_SET_RTS_HIGH=( 2 or ( SIO_SET_RTS_MASK shl 8 ))
109
SIO_SET_RTS_LOW =( 0 or ( SIO_SET_RTS_MASK shl 8 ))
110
 
111
SIO_RTS_CTS_HS =(0x1 shl 8)
112
 
4992 gtament 113
;FTDI chip type
114
TYPE_AM=0
115
TYPE_BM=1
116
TYPE_2232C=2
117
TYPE_R=3
118
TYPE_2232H=4
119
TYPE_4232H=5
120
TYPE_232H=6
121
TYPE_230X=7
122
 
4975 gtament 123
;strings
124
my_driver       db      'usbother',0
125
nomemory_msg    db      'K : no memory',13,10,0
126
 
127
; Structures
128
struct ftdi_context
129
chipType                db      ?
130
baudrate                dd      ?
131
bitbangEnabled          db      ?
132
readBufChunkSize        dd      ?
133
writeBufChunkSize       dd      ?
5023 gtament 134
readBufPtr              dd      ?
135
writeBufPtr             dd      ?
136
readBufSize             dd      ?
137
writeBufSize            dd      ?
5018 gtament 138
maxPacketSize           dd      ?
4975 gtament 139
interface               dd      ?
140
index                   dd      ?
141
inEP                    dd      ?
142
outEP                   dd      ?
143
nullP                   dd      ?
4997 gtament 144
lockPID                 dd      ?
4975 gtament 145
next_context            dd      ?
146
ends
147
 
148
struct IOCTL
149
handle                  dd      ?
150
io_code                 dd      ?
151
input                   dd      ?
152
inp_size                dd      ?
153
output                  dd      ?
154
out_size                dd      ?
155
ends
156
 
157
struct usb_descr
4979 gtament 158
bLength                 db      ?
159
bDescriptorType         db      ?
4975 gtament 160
bcdUSB                  dw      ?
161
bDeviceClass            db      ?
162
bDeviceSubClass         db      ?
163
bDeviceProtocol         db      ?
164
bMaxPacketSize0         db      ?
165
idVendor                dw      ?
166
idProduct               dw      ?
167
bcdDevice               dw      ?
168
iManufacturer           db      ?
169
iProduct                db      ?
170
iSerialNumber           db      ?
171
bNumConfigurations      db      ?
172
ends
173
 
4979 gtament 174
struct conf_packet
175
bmRequestType           db      ?
176
bRequest                db      ?
177
wValue                  dw      ?
178
wIndex                  dw      ?
179
wLength                 dw      ?
180
ends
181
 
4975 gtament 182
section '.flat' code readable align 16
183
; The start procedure.
184
proc START stdcall, .reason:DWORD
185
 
186
        xor     eax, eax        ; initialize return value
187
        cmp     [.reason], 1    ; compare the argument
188
        jnz     .nothing
189
        stdcall RegUSBDriver, my_driver, service_proc, usb_functions
190
 
191
.nothing:
4979 gtament 192
        ret
4975 gtament 193
endp
194
 
195
 
5018 gtament 196
proc AddDevice stdcall uses ebx esi edi, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD
4975 gtament 197
 
198
        stdcall USBGetParam, [.config_pipe], 0
4997 gtament 199
        mov     edx, eax
5018 gtament 200
        DEBUGF 1,'K : Detected device vendor: %x\n', [eax+usb_descr.idVendor]
4979 gtament 201
        cmp     word[eax+usb_descr.idVendor], 0x0403
4975 gtament 202
        jnz     .notftdi
5023 gtament 203
        mov     eax, sizeof.ftdi_context
4975 gtament 204
        call    Kmalloc
205
        test    eax, eax
206
        jnz     @f
207
        mov     esi, nomemory_msg
208
        call    SysMsgBoardStr
209
        jmp     .nothing
4997 gtament 210
  @@:
4975 gtament 211
        DEBUGF 1,'K : Adding struct to list %x\n', eax
4997 gtament 212
        call    linkedlist_add
4975 gtament 213
 
214
        mov     ebx, [.config_pipe]
215
        mov     [eax + ftdi_context.nullP], ebx
4992 gtament 216
        mov     [eax + ftdi_context.index], 0
4997 gtament 217
        mov     [eax + ftdi_context.lockPID], 0
5018 gtament 218
        mov     [eax + ftdi_context.maxPacketSize], 64
5014 gtament 219
        mov     [eax + ftdi_context.readBufChunkSize], 64
220
        mov     [eax + ftdi_context.writeBufChunkSize], 64
5023 gtament 221
 
222
        mov     [eax + ftdi_context.chipType], TYPE_R
223
        jmp     .slow
4975 gtament 224
 
5018 gtament 225
        mov     cx, [edx+usb_descr.bcdDevice]
5023 gtament 226
        DEBUGF 1, 'K : Chip type %x\n', ecx
5018 gtament 227
        cmp     cx, 0x400
4997 gtament 228
        jnz     @f
229
        mov     [eax + ftdi_context.chipType], TYPE_BM
5018 gtament 230
        jmp     .slow
4997 gtament 231
  @@:
5018 gtament 232
        cmp     cx, 0x200
4997 gtament 233
        jnz     @f
234
        mov     [eax + ftdi_context.chipType], TYPE_AM
5018 gtament 235
        jmp     .slow
4997 gtament 236
  @@:
5018 gtament 237
        cmp     cx, 0x500
4997 gtament 238
        jnz     @f
5018 gtament 239
        mov     [eax + ftdi_context.chipType], TYPE_2232C
240
        jmp     .slow
4997 gtament 241
  @@:
5018 gtament 242
        cmp     cx, 0x600
4997 gtament 243
        jnz     @f
244
        mov     [eax + ftdi_context.chipType], TYPE_R
5018 gtament 245
        jmp     .slow
4997 gtament 246
  @@:
5018 gtament 247
        cmp     cx, 0x700
4997 gtament 248
        jnz     @f
249
        mov     [eax + ftdi_context.chipType], TYPE_2232H
5018 gtament 250
        jmp     .fast
4997 gtament 251
  @@:
5018 gtament 252
        cmp     cx, 0x900
4997 gtament 253
        jnz     @f
254
        mov     [eax + ftdi_context.chipType], TYPE_232H
5018 gtament 255
        jmp     .fast
4997 gtament 256
  @@:
5018 gtament 257
        cmp     cx, 0x1000
258
        jnz     .slow
259
        mov     [eax + ftdi_context.chipType], TYPE_230X
260
        jmp     .fast
261
 
262
  .fast:
263
        add     [eax + ftdi_context.maxPacketSize], 512-64
264
  .slow:
4975 gtament 265
        mov     ebx, eax
5018 gtament 266
        stdcall USBOpenPipe, [.config_pipe],  0x81,  [ebx + ftdi_context.maxPacketSize],  BULK_PIPE, 0
267
        test    eax, eax
268
        jz      .nothing
5020 gtament 269
        mov     [ebx + ftdi_context.outEP], eax
5018 gtament 270
        stdcall USBOpenPipe, [.config_pipe],  0x02,  [ebx + ftdi_context.maxPacketSize],  BULK_PIPE, 0
271
        test    eax, eax
272
        jz      .nothing
5020 gtament 273
        mov     [ebx + ftdi_context.inEP], eax
5014 gtament 274
        mov     eax, ebx
275
        ret
4997 gtament 276
 
4975 gtament 277
  .notftdi:
278
        DEBUGF 1,'K : Skipping not FTDI device\n'
4997 gtament 279
  .nothing:
4975 gtament 280
        xor     eax, eax
281
        ret
282
endp
283
 
284
 
285
handle     equ  IOCTL.handle
286
io_code    equ  IOCTL.io_code
287
input      equ  IOCTL.input
288
inp_size   equ  IOCTL.inp_size
289
output     equ  IOCTL.output
290
out_size   equ  IOCTL.out_size
291
 
292
align 4
293
proc service_proc stdcall uses ebx esi edi, ioctl:DWORD
294
locals
295
ConfPacket  rb  8
5014 gtament 296
EventData   rd  3
4975 gtament 297
endl
4979 gtament 298
        mov     edi, [ioctl]
4997 gtament 299
        mov     eax, [edi+io_code]
4975 gtament 300
        DEBUGF 1,'K : FTDI got the request: %d\n', eax
4979 gtament 301
        test    eax, eax           ;0
302
        jz      .version
303
        dec     eax                 ;1
304
        jz      .ftdi_get_list
4985 gtament 305
 
4997 gtament 306
        push    eax
307
        mov     esi, [edi+input]
308
        mov     eax, [esi+4]
309
        call    linkedlist_isvalid
310
        test    eax, eax
311
        pop     eax
312
        jnz     .endswitch
313
 
314
        dec     eax
315
        jz      .ftdi_lock      ;2
316
        dec     eax
317
        jz      .ftdi_unlock    ;3
318
 
319
        mov     ebx, [esi+4]
5035 gtament 320
        mov     ecx, [ebx + ftdi_context.lockPID]
321
        cmp     dword[esi], 0
322
        jz      .error
4997 gtament 323
        cmp     ecx, [esi]
324
        jz      .pid_ok
325
        mov     esi, [edi+output]
326
        mov     dword[esi], 'LCKD'
327
        jmp     .endswitch
328
 
5018 gtament 329
  .pid_ok:
330
        dec     eax
5023 gtament 331
        jz      .ftdi_get_wchunksize    ;4
5018 gtament 332
        dec     eax
5023 gtament 333
        jz      .ftdi_get_rchunksize    ;5
5018 gtament 334
 
335
        mov     edi, [edi+input]
336
 
337
        dec     eax
338
        jz      .ftdi_set_rchunksize    ;6
339
        dec     eax
5023 gtament 340
        jz      .ftdi_set_wchunksize    ;7
5018 gtament 341
 
4985 gtament 342
        push    eax edi
5014 gtament 343
        mov     ecx, 0x80000000
5023 gtament 344
        cmp     eax, 8-7
5018 gtament 345
        je      .bulkevent
5023 gtament 346
        cmp     eax, 9-7
5014 gtament 347
        je      .bulkevent
4985 gtament 348
        xor     ecx, ecx
5014 gtament 349
  .bulkevent:
4985 gtament 350
        xor     esi, esi
351
        call    CreateEvent
352
        mov     [EventData], eax
353
        mov     [EventData+4], edx
5018 gtament 354
        pop     edi eax
4985 gtament 355
 
5018 gtament 356
        dec     eax                 ;8
5023 gtament 357
        jz      .ftdi_write_data
5018 gtament 358
        dec     eax                 ;9
5023 gtament 359
        jz      .ftdi_read_data
5018 gtament 360
        dec     eax                 ;10
5023 gtament 361
        jz      .ftdi_set_baudrate
5018 gtament 362
        dec     eax                 ;11
5023 gtament 363
        jz      .ftdi_set_bitmode
5018 gtament 364
        dec     eax                 ;12
5023 gtament 365
        jz      .ftdi_setrtshigh
5018 gtament 366
        dec     eax                 ;13
5023 gtament 367
        jz      .ftdi_setrtslow
5018 gtament 368
        dec     eax                 ;14
5023 gtament 369
        jz      .ftdi_setdtrhigh
5018 gtament 370
        dec     eax                 ;15
5023 gtament 371
        jz      .ftdi_setdtrlow
5018 gtament 372
        dec     eax                 ;16
5023 gtament 373
        jz      .ftdi_usb_reset
5018 gtament 374
        dec     eax                 ;17
5023 gtament 375
        jz      .ftdi_setflowctrl
5018 gtament 376
        dec     eax                 ;18
5023 gtament 377
        jz      .ftdi_set_event_char
5018 gtament 378
        dec     eax                 ;19
5023 gtament 379
        jz      .ftdi_set_error_char
5018 gtament 380
        dec     eax                 ;20
5023 gtament 381
        jz      .ftdi_set_latency_timer
5018 gtament 382
        dec     eax                 ;21
5023 gtament 383
        jz      .ftdi_get_latency_timer
5018 gtament 384
        dec     eax                 ;22
5023 gtament 385
        jz      .ftdi_read_pins
5018 gtament 386
        dec     eax                 ;23
5023 gtament 387
        jz      .ftdi_poll_modem_status
5018 gtament 388
        dec     eax                 ;24
4997 gtament 389
        jz      .ftdi_set_line_property
5018 gtament 390
        dec     eax                 ;25
4997 gtament 391
        jz      .ftdi_purge_rx_buf
5018 gtament 392
        dec     eax                 ;26
4997 gtament 393
        jz      .ftdi_purge_tx_buf
5018 gtament 394
        jmp     .error
395
 
4975 gtament 396
  .version:
5018 gtament 397
        jmp     .endswitch
398
  .error:
399
        mov     esi, [edi+output]
400
        mov     [esi], dword 'ERR0'
401
        or      [esi], eax
5035 gtament 402
        ret
4975 gtament 403
  .endswitch:
4979 gtament 404
        xor     eax, eax
5018 gtament 405
	    ret
4985 gtament 406
 
5018 gtament 407
  .eventdestroy:
5023 gtament 408
        ;---Dirty hack begin
409
        test    eax, eax
410
        jz      @f
411
        mov     eax, dword[ConfPacket]
412
        call    Kfree
413
  @@:
414
        ;---Dirty hack end
5018 gtament 415
        mov     eax, [EventData]
416
        mov     ebx, [EventData+4]
417
        call    DestroyEvent
418
        jmp     .endswitch
419
 
420
  .ftdi_out_control_transfer_withinp:
5035 gtament 421
        mov     dx, word[edi+8]
5018 gtament 422
        mov     word[ConfPacket+2], dx
423
  .ftdi_out_control_transfer_noinp:
424
        mov     ebx, [edi+4]
4992 gtament 425
        mov     cx, word[ebx + ftdi_context.index]
426
        mov     word[ConfPacket+4], cx
427
        xor     cx, cx
428
        mov     word[ConfPacket+6], cx
429
  .own_index:
5018 gtament 430
        mov     ebx, [edi+4]
4992 gtament 431
        DEBUGF 1,'K : ConfPacket %x %x\n', [ConfPacket], [ConfPacket+4]
4975 gtament 432
        lea     esi, [ConfPacket]
4979 gtament 433
        lea     edi, [EventData]
4975 gtament 434
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, 0, 0, control_callback, edi, 0
5018 gtament 435
        test    eax, eax
436
        jz      .error
4979 gtament 437
        mov     eax, [EventData]
438
        mov     ebx, [EventData+4]
4975 gtament 439
        call    WaitEvent
440
        jmp     .endswitch
4985 gtament 441
 
4984 gtament 442
  .ftdi_setrtshigh:
5035 gtament 443
        ;DEBUGF 1,'K : FTDI Setting RTS pin HIGH\n'
4984 gtament 444
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_HIGH shl 16)
5018 gtament 445
        jmp     .ftdi_out_control_transfer_noinp
4984 gtament 446
 
447
  .ftdi_setrtslow:
5035 gtament 448
        ;DEBUGF 1,'K : FTDI Setting RTS pin LOW\n'
4984 gtament 449
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_LOW shl 16)
5018 gtament 450
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 451
 
452
  .ftdi_setdtrhigh:
5035 gtament 453
        ;DEBUGF 1,'K : FTDI Setting DTR pin HIGH\n'
4985 gtament 454
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_HIGH shl 16)
5018 gtament 455
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 456
 
457
  .ftdi_setdtrlow:
5035 gtament 458
        ;DEBUGF 1,'K : FTDI Setting DTR pin LOW\n'
4985 gtament 459
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_LOW shl 16)
5018 gtament 460
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 461
 
462
  .ftdi_usb_reset:
5035 gtament 463
        ;DEBUGF 1,'K : FTDI Reseting\n'
4985 gtament 464
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_SIO shl 16)
5018 gtament 465
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 466
 
467
  .ftdi_purge_rx_buf:
468
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_RX shl 16)
5018 gtament 469
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 470
 
471
  .ftdi_purge_tx_buf:
472
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_TX shl 16)
5018 gtament 473
        jmp     .ftdi_out_control_transfer_noinp
4985 gtament 474
 
5018 gtament 475
  .ftdi_set_bitmode:
476
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_BITMODE_REQUEST shl 8)
477
        jmp     .ftdi_out_control_transfer_withinp
4992 gtament 478
 
4985 gtament 479
  .ftdi_set_line_property:
4992 gtament 480
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_DATA_REQUEST shl 8)
5018 gtament 481
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 482
 
483
  .ftdi_set_latency_timer:
5018 gtament 484
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_LATENCY_TIMER_REQUEST shl 8)
485
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 486
 
487
  .ftdi_set_event_char:
4992 gtament 488
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_EVENT_CHAR_REQUEST shl 8)
5018 gtament 489
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 490
 
491
  .ftdi_set_error_char:
4992 gtament 492
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_ERROR_CHAR_REQUEST shl 8)
5018 gtament 493
        jmp     .ftdi_out_control_transfer_withinp
4985 gtament 494
 
4992 gtament 495
  .ftdi_setflowctrl:
5018 gtament 496
        mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_FLOW_CTRL_REQUEST shl 8) + (0 shl 16)
497
        mov     ebx, [edi+4]
4997 gtament 498
        mov     cx, word[edi+8]
4992 gtament 499
        or      ecx, [ebx + ftdi_context.index]
500
        mov     word[ConfPacket+4], cx
501
        xor     cx, cx
502
        mov     word[ConfPacket+6], cx
503
        jmp     .own_index
4985 gtament 504
 
5018 gtament 505
  .ftdi_read_pins:
4984 gtament 506
        mov     ebx, [edi]
4997 gtament 507
        mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_READ_PINS_REQUEST shl 8) + (0 shl 16)
508
        mov     ecx, [ebx + ftdi_context.index]
509
        mov     word[ConfPacket+4], cx
510
        mov     word[ConfPacket+6], 1
4984 gtament 511
        lea     esi, [ConfPacket]
4985 gtament 512
        lea     edi, [EventData]
513
        mov     ecx, [ioctl]
514
        mov     ecx, [ecx+output]
515
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 1, control_callback, edi, 0
4984 gtament 516
        mov     eax, [EventData]
517
        mov     ebx, [EventData+4]
518
        call    WaitEvent
519
        jmp     .endswitch
5018 gtament 520
 
521
  .ftdi_set_wchunksize:
522
        mov     ebx, [edi+4]
5023 gtament 523
        mov     ecx, [edi+8]
5018 gtament 524
        cmp     [ebx + ftdi_context.maxPacketSize], ecx
525
        jg      .error
526
        mov     [ebx + ftdi_context.writeBufChunkSize], ecx
527
        jmp     .endswitch
528
 
529
  .ftdi_get_wchunksize:
530
        mov     esi, [edi+output]
531
        mov     edi, [edi+input]
532
        mov     ebx, [edi+4]
533
        mov     ecx, [ebx + ftdi_context.writeBufChunkSize]
534
        mov     [esi], ecx
535
        jmp     .endswitch
4997 gtament 536
 
5018 gtament 537
  .ftdi_set_rchunksize:
538
        mov     ebx, [edi+4]
539
        mov     ecx, [edi+8]
540
        cmp     [ebx + ftdi_context.maxPacketSize], ecx
541
        jg      .error
542
        mov     [ebx + ftdi_context.readBufChunkSize], ecx
543
        jmp     .endswitch
544
 
545
  .ftdi_get_rchunksize:
546
        mov     esi, [edi+output]
547
        mov     edi, [edi+input]
548
        mov     ebx, [edi+4]
549
        mov     ecx, [ebx + ftdi_context.readBufChunkSize]
550
        mov     [esi], ecx
551
        jmp     .endswitch
552
 
4997 gtament 553
  .ftdi_write_data:
5018 gtament 554
        mov     esi, edi
555
        add     esi, 12
4997 gtament 556
        mov     ebx, [edi+4]
5023 gtament 557
        ;---Dirty hack begin
558
        mov     eax, [edi+8]
559
        call    Kmalloc
560
        test    eax, eax
561
        jnz     @f
562
        mov     esi, nomemory_msg
563
        call    SysMsgBoardStr
564
        jmp     .eventdestroy
565
  @@:
566
        mov     dword[ConfPacket], eax
567
        mov     ecx, [edi+8]
568
        push    edi esi
569
        mov     edi, eax
570
        rep movsb
571
        pop     esi edi
572
        ;---Dirty hack end
5018 gtament 573
        xor     ecx, ecx        ; ecx - offset
574
  .write_loop:
575
        mov     edx, [edi+8]    ; edx - write_size
4997 gtament 576
        sub     edx, ecx
5018 gtament 577
        cmp     edx, [ebx + ftdi_context.writeBufChunkSize]
578
        jle     .lessthanchunk_write
579
        mov     edx, [ebx + ftdi_context.writeBufChunkSize]
580
  .lessthanchunk_write:
581
        add     esi, ecx
5014 gtament 582
        lea     eax, [EventData]
5018 gtament 583
        push    ecx ebx esi edi
584
        stdcall USBNormalTransferAsync, [ebx + ftdi_context.inEP], esi, edx, bulk_callback, eax, 1
4997 gtament 585
        mov     eax, [EventData]
586
        mov     ebx, [EventData+4]
5014 gtament 587
        call    WaitEvent
5018 gtament 588
        mov     eax, [EventData]
589
        mov     ebx, [EventData+4]
590
        call    ClearEvent
591
        pop     edi esi ebx ecx
5014 gtament 592
        cmp     [EventData+8], -1
5023 gtament 593
        jz      .error
5014 gtament 594
        add     ecx, [EventData+8]
4997 gtament 595
        cmp     ecx, [edi+8]
5018 gtament 596
        jge     .eventdestroy
597
        jmp     .write_loop
4985 gtament 598
 
5014 gtament 599
  .ftdi_read_data:
5018 gtament 600
        mov     edi, [ioctl]
5014 gtament 601
        mov     esi, [edi+input]
602
        mov     edi, [edi+output]
5035 gtament 603
        mov     ebx, [esi+4]
5023 gtament 604
        ;---Dirty hack begin
605
        mov     eax, [esi+8]
606
        call    Kmalloc
607
        test    eax, eax
608
        jnz     @f
609
        mov     esi, nomemory_msg
610
        call    SysMsgBoardStr
611
        jmp     .eventdestroy
612
  @@:
613
        mov     edi, eax
5037 gtament 614
        push    edi eax
615
        mov     ecx, [esi+8]
616
        xor     eax, eax
617
        rep     stosb
618
        pop     eax edi
5035 gtament 619
        mov     dword[ConfPacket], eax ; Store in ConfPAcket ptr to allocated memory
5023 gtament 620
        ;---Dirty hack end
5014 gtament 621
        xor     ecx, ecx
5023 gtament 622
  .read_loop:
5014 gtament 623
        mov     edx, [esi+8]
5018 gtament 624
        cmp     ecx, edx
5023 gtament 625
        jge     .read_end;jge     .eventdestroy ;part of Dirty hack
5014 gtament 626
        sub     edx, ecx
627
        cmp     edx, [ebx + ftdi_context.readBufChunkSize]
628
        jl      .lessthanchunk_read
629
        mov     edx, [ebx + ftdi_context.readBufChunkSize]
630
  .lessthanchunk_read:
631
        lea     eax, [EventData]
5018 gtament 632
        add     edi, ecx
5014 gtament 633
        push    esi edi ecx ebx
5018 gtament 634
        stdcall USBNormalTransferAsync, [ebx + ftdi_context.outEP], edi, edx, bulk_callback, eax, 1
5014 gtament 635
        mov     eax, [EventData]
636
        mov     ebx, [EventData+4]
637
        call    WaitEvent
5018 gtament 638
        mov     eax, [EventData]
639
        mov     ebx, [EventData+4]
640
        call    ClearEvent
5014 gtament 641
        pop     ebx ecx edi esi
5023 gtament 642
        cmp     [EventData+8], -1
5018 gtament 643
        jz      .error
5014 gtament 644
        add     ecx, [EventData+8]
645
        jmp     .read_loop
5023 gtament 646
        ;---Dirty hack begin
647
  .read_end:
648
        mov     esi, dword[ConfPacket]
649
        mov     edi, [ioctl]
650
        mov     ecx, [edi+input]
651
        mov     ecx, [ecx+8]
652
        mov     edi, [edi+output]
653
        rep     movsb
654
        jmp     .eventdestroy
655
        ;---Dirty hack end
5014 gtament 656
 
5018 gtament 657
  .ftdi_poll_modem_status:
4997 gtament 658
        mov     ebx, [edi+4]
659
        mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_POLL_MODEM_STATUS_REQUEST shl 8) + (0 shl 16)
660
        mov     ecx, [ebx + ftdi_context.index]
661
        mov     word[ConfPacket+4], cx
662
        mov     word[ConfPacket+6], 1
663
        lea     esi, [ConfPacket]
664
        lea     edi, [EventData]
665
        mov     ecx, [ioctl]
666
        mov     ecx, [ecx+output]
667
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 2, control_callback, edi, 0
668
        mov     eax, [EventData]
669
        mov     ebx, [EventData+4]
670
        call    WaitEvent
671
        mov     ax, word[ecx]
672
        xchg    ah, al
673
        and     ah, 0xFF
674
        mov     word[ecx], ax
675
        jmp     .endswitch
676
 
5018 gtament 677
  .ftdi_get_latency_timer:
4997 gtament 678
        mov     ebx, [edi+4]
679
        mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_GET_LATENCY_TIMER_REQUEST shl 8) + (0 shl 16)
680
        mov     ecx, [ebx + ftdi_context.index]
681
        mov     word[ConfPacket+4], cx
682
        mov     word[ConfPacket+6], 1
683
        lea     esi, [ConfPacket]
684
        lea     edi, [EventData]
685
        mov     ecx, [ioctl]
686
        mov     ecx, [ecx+output]
687
        stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 2, control_callback, edi, 0
688
        mov     eax, [EventData]
689
        mov     ebx, [EventData+4]
690
        call    WaitEvent
691
        jmp     .endswitch
692
 
5037 gtament 693
  .ftdi_get_list:
694
        mov     edi, [edi+output]
695
        xor     ecx, ecx
5018 gtament 696
        call    linkedlist_gethead
697
        test    eax, eax
5037 gtament 698
        jz      .emptylist
5014 gtament 699
        push    edi
5037 gtament 700
        add     edi, 4
4997 gtament 701
  .nextdev:
5014 gtament 702
        inc     ecx
4997 gtament 703
        cmp     [eax + ftdi_context.lockPID], 0
704
        jnz      .dev_is_locked
705
        mov     dword[edi], 'NLKD'
706
        jmp     .nextfields
707
  .dev_is_locked:
708
        mov     dword[edi], 'LCKD'
709
  .nextfields:
710
        mov     bl, [eax + ftdi_context.chipType]
711
        mov     [edi+4], ebx
712
        mov     [edi+8], eax
713
        add     edi, 12
714
        mov     eax, [eax + ftdi_context.next_context]
715
        test    eax, eax
716
        jnz     .nextdev
5014 gtament 717
        pop     edi
5037 gtament 718
  .emptylist:
5014 gtament 719
        mov     [edi], ecx
4997 gtament 720
        jmp     .endswitch
721
 
722
  .ftdi_lock:
723
        mov     esi, [edi+input]
724
        mov     ebx, [esi+4]
725
        mov     eax, [ebx + ftdi_context.lockPID]
726
        test    eax, eax
727
        jnz     .lockedby
728
        mov     eax, [esi]
729
        mov     [ebx + ftdi_context.lockPID], eax
730
  .lockedby:
731
        mov     edi, [edi+output]
4979 gtament 732
        mov     [edi], eax
4985 gtament 733
        jmp     .endswitch
4997 gtament 734
 
735
  .ftdi_unlock:
736
        mov     esi, [edi+input]
737
        mov     edi, [edi+output]
738
        mov     ebx, [esi+4]
739
        mov     eax, [ebx + ftdi_context.lockPID]
740
        cmp     eax, [esi]
741
        jnz     .unlockimp
742
        mov     [ebx + ftdi_context.lockPID], 0
743
        mov     dword[edi], 0
744
        jmp     .endswitch
745
  .unlockimp:
746
        mov     [edi], eax
5018 gtament 747
        jmp     .endswitch
748
 
749
H_CLK = 120000000
750
C_CLK = 48000000
751
  .ftdi_set_baudrate:
752
        mov     ebx, [edi+4]
753
        cmp     [ebx + ftdi_context.chipType], TYPE_2232H
754
        jl      .c_clk
755
        imul    eax, [edi+8], 10
756
        cmp     eax, H_CLK / 0x3FFF
757
        jle     .c_clk
5023 gtament 758
  .h_clk:
5018 gtament 759
        cmp     dword[edi+8], H_CLK/10
760
        jl      .h_nextbaud1
761
        xor     edx, edx
762
        mov     ecx, H_CLK/10
763
        jmp     .calcend
4997 gtament 764
 
5018 gtament 765
  .c_clk:
5023 gtament 766
        cmp     dword[edi+8], C_CLK/16
5018 gtament 767
        jl      .c_nextbaud1
768
        xor     edx, edx
5023 gtament 769
        mov     ecx, C_CLK/16
5018 gtament 770
        jmp     .calcend
771
 
772
  .h_nextbaud1:
773
        cmp     dword[edi+8], H_CLK/(10 + 10/2)
774
        jl      .h_nextbaud2
775
        mov     edx, 1
776
        mov     ecx, H_CLK/(10 + 10/2)
777
        jmp     .calcend
778
 
779
  .c_nextbaud1:
5023 gtament 780
        cmp     dword[edi+8], C_CLK/(16 + 16/2)
5018 gtament 781
        jl      .c_nextbaud2
782
        mov     edx, 1
5023 gtament 783
        mov     ecx, C_CLK/(16 + 16/2)
5018 gtament 784
        jmp     .calcend
785
 
5023 gtament 786
  .h_nextbaud2:
5018 gtament 787
        cmp     dword[edi+8], H_CLK/(2*10)
788
        jl      .h_nextbaud3
789
        mov     edx, 2
790
        mov     ecx, H_CLK/(2*10)
791
        jmp     .calcend
792
 
5023 gtament 793
  .c_nextbaud2:
794
        cmp     dword[edi+8], C_CLK/(2*16)
5018 gtament 795
        jl      .c_nextbaud3
796
        mov     edx, 2
5023 gtament 797
        mov     ecx, C_CLK/(2*16)
5018 gtament 798
        jmp     .calcend
799
 
800
  .h_nextbaud3:
801
        mov     eax, H_CLK*16/10  ; eax - best_divisor
5023 gtament 802
        xor     edx, edx
5018 gtament 803
        div     dword[edi+8]      ; [edi+8] - baudrate
804
        push    eax
805
        and     eax, 1
806
        pop     eax
807
        shr     eax, 1
808
        jz      .h_rounddowndiv     ; jump by result of and eax, 1
809
        inc     eax
810
  .h_rounddowndiv:
811
        cmp     eax, 0x20000
812
        jle     .h_best_divok
813
        mov     eax, 0x1FFFF
814
  .h_best_divok:
815
        mov     ecx, eax
816
        mov     eax, H_CLK*16/10
5023 gtament 817
        xor     edx, edx
5018 gtament 818
        div     ecx
819
        xchg    ecx, eax            ; ecx - best_baud
820
        push    ecx
821
        and     ecx, 1
822
        pop     ecx
823
        shr     ecx, 1
824
        jz      .rounddownbaud
825
        inc     ecx
826
        jmp     .rounddownbaud
827
 
828
  .c_nextbaud3:
5023 gtament 829
        mov     eax, C_CLK        ; eax - best_divisor
830
        xor     edx, edx
5018 gtament 831
        div     dword[edi+8]      ; [edi+8] - baudrate
832
        push    eax
833
        and     eax, 1
834
        pop     eax
835
        shr     eax, 1
5023 gtament 836
        jnz     .c_rounddowndiv     ; jump by result of and eax, 1
5018 gtament 837
        inc     eax
838
  .c_rounddowndiv:
839
        cmp     eax, 0x20000
840
        jle     .c_best_divok
841
        mov     eax, 0x1FFFF
842
  .c_best_divok:
843
        mov     ecx, eax
5023 gtament 844
        mov     eax, C_CLK
845
        xor     edx, edx
5018 gtament 846
        div     ecx
847
        xchg    ecx, eax            ; ecx - best_baud
848
        push    ecx
849
        and     ecx, 1
850
        pop     ecx
851
        shr     ecx, 1
5023 gtament 852
        jnz     .rounddownbaud
5018 gtament 853
        inc     ecx
854
 
855
  .rounddownbaud:
856
        mov     edx, eax            ; edx - encoded_divisor
857
        shr     edx, 3
5035 gtament 858
        and     eax, 0x7
859
        push    7 6 5 1 4 2 3 0
5018 gtament 860
        mov     eax, [esp+eax*4]
861
        shl     eax, 14
5035 gtament 862
        or      edx, eax
863
        add     esp, 32
5018 gtament 864
 
865
  .calcend:
866
        mov     eax, edx        ; eax - *value
867
        mov     ecx, edx        ; ecx - *index
868
        and     eax, 0xFFFF
869
        cmp     [ebx + ftdi_context.chipType], TYPE_2232H
870
        jge     .foxyindex
871
        shr     ecx, 16
872
        jmp     .preparepacket
873
  .foxyindex:
874
        shr     ecx, 8
875
        and     ecx, 0xFF00
876
        or      ecx, [ebx + ftdi_context.index]
877
 
878
  .preparepacket:
879
        mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_BAUDRATE_REQUEST shl 8)
880
        mov     word[ConfPacket+2], ax
881
        mov     word[ConfPacket+4], cx
882
        mov     word[ConfPacket+6], 0
883
        jmp     .own_index
884
 
4975 gtament 885
endp
886
restore   handle
887
restore   io_code
888
restore   input
889
restore   inp_size
890
restore   output
891
restore   out_size
892
 
893
 
894
align 4
4984 gtament 895
proc control_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD
4975 gtament 896
 
4985 gtament 897
        DEBUGF 1, 'K : status is %d\n', [.status]
4980 gtament 898
        mov     ecx, [.calldata]
899
        mov     eax, [ecx]
900
        mov     ebx, [ecx+4]
5014 gtament 901
        mov     edx, [.status]
902
        mov     [ecx+8], edx
4997 gtament 903
        xor     esi, esi
4979 gtament 904
        xor     edx, edx
5014 gtament 905
        call    RaiseEvent
4975 gtament 906
        ret
907
endp
908
 
4997 gtament 909
proc bulk_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD
4975 gtament 910
 
5014 gtament 911
        DEBUGF 1, 'K : status is %d\n', [.status]
4997 gtament 912
        mov     ecx, [.calldata]
913
        mov     eax, [ecx]
914
        mov     ebx, [ecx+4]
5014 gtament 915
        cmp     [.status], 0
5018 gtament 916
        jz      .normal
5014 gtament 917
        cmp     [.status], 9
918
        jne     .error
5018 gtament 919
  .normal:
4997 gtament 920
        mov     edx, [.length]
5014 gtament 921
        mov     [ecx+8], edx
922
        jmp     .ok
923
  .error:
924
        mov     [ecx+8], dword -1
5018 gtament 925
  .ok:
4997 gtament 926
        xor     esi, esi
5014 gtament 927
        xor     edx, edx
928
        call    RaiseEvent
4997 gtament 929
        ret
930
endp
931
 
4975 gtament 932
proc DeviceDisconnected stdcall uses  ebx esi edi, .device_data:DWORD
933
 
5014 gtament 934
        DEBUGF 1, 'K : FTDI deleting device data %x\n', [.device_data]
4975 gtament 935
        mov     eax, [.device_data]
4997 gtament 936
        call    linkedlist_delete
4979 gtament 937
        ret
4975 gtament 938
endp
939
 
940
include 'linkedlist.inc'
941
 
942
; Exported variable: kernel API version.
943
align 4
944
version dd      50005h
945
; Structure with callback functions.
946
usb_functions:
947
        dd      12
948
        dd      AddDevice
949
        dd      DeviceDisconnected
950
 
951
;for DEBUGF macro
952
include_debug_strings
953
 
954
 
955
 
956
 
957
; for uninitialized data
958
;section '.data' data readable writable align 16