Subversion Repositories Kolibri OS

Rev

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