Subversion Repositories Kolibri OS

Rev

Rev 4984 | Rev 4992 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;                                                              ;;
  3. ;; Copyright (C) KolibriOS team 2004-2014. All rights reserved. ;;
  4. ;; Distributed under terms of the GNU General Public License    ;;
  5. ;;                                                              ;;
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7.  
  8. ; standard driver stuff
  9. format MS COFF
  10.  
  11. DEBUG = 1
  12.  
  13. ; this is for DEBUGF macro from 'fdo.inc'
  14. __DEBUG__ = 1
  15. __DEBUG_LEVEL__ = 1
  16.  
  17. include '../../proc32.inc'
  18. include '../../imports.inc'
  19. include '../../fdo.inc'
  20. include '../../struct.inc'
  21.  
  22. public START
  23. public version
  24.  
  25. ; USB constants
  26. DEVICE_DESCR_TYPE           = 1
  27. CONFIG_DESCR_TYPE           = 2
  28. STRING_DESCR_TYPE           = 3
  29. INTERFACE_DESCR_TYPE        = 4
  30. ENDPOINT_DESCR_TYPE         = 5
  31. DEVICE_QUALIFIER_DESCR_TYPE = 6
  32.  
  33. CONTROL_PIPE     = 0
  34. ISOCHRONOUS_PIPE = 1
  35. BULK_PIPE        = 2
  36. INTERRUPT_PIPE   = 3
  37.  
  38. ; USB HID constants
  39. HID_DESCR_TYPE      = 21h
  40. REPORT_DESCR_TYPE   = 22h
  41. PHYSICAL_DESCR_TYPE = 23h
  42.  
  43.  
  44. ; LibUSB constatnts
  45. LIBUSB_REQUEST_TYPE_STANDARD = (0x00 shl 5)
  46. LIBUSB_REQUEST_TYPE_CLASS = (0x01 shl 5)
  47. LIBUSB_REQUEST_TYPE_VENDOR = (0x02 shl 5)
  48. LIBUSB_REQUEST_TYPE_RESERVED = (0x03 shl 5)
  49.  
  50. LIBUSB_RECIPIENT_DEVICE = 0x00
  51. LIBUSB_RECIPIENT_INTERFACE = 0x01
  52. LIBUSB_RECIPIENT_ENDPOINT = 0x02
  53. LIBUSB_RECIPIENT_OTHER = 0x03
  54.  
  55. LIBUSB_ENDPOINT_IN = 0x80
  56. LIBUSB_ENDPOINT_OUT = 0x00
  57.  
  58. ; FTDI Constants
  59. FTDI_DEVICE_OUT_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_OUT)
  60. FTDI_DEVICE_IN_REQTYPE = (LIBUSB_REQUEST_TYPE_VENDOR or LIBUSB_RECIPIENT_DEVICE or LIBUSB_ENDPOINT_IN)
  61.  
  62. ; Requests
  63. ;Definitions for flow control
  64. SIO_RESET         =0  ;Reset the port
  65. SIO_MODEM_CTRL    =1  ;Set the modem control register
  66. SIO_SET_FLOW_CTRL =2  ;Set flow control register
  67. SIO_SET_BAUD_RATE =3  ;Set baud rate
  68. SIO_SET_DATA      =4  ;Set the data characteristics of the port
  69.  
  70. SIO_RESET_REQUEST            =SIO_RESET
  71. SIO_SET_BAUDRATE_REQUEST     =SIO_SET_BAUD_RATE
  72. SIO_SET_DATA_REQUEST         =SIO_SET_DATA
  73. SIO_SET_FLOW_CTRL_REQUEST    =SIO_SET_FLOW_CTRL
  74. SIO_SET_MODEM_CTRL_REQUEST   =SIO_MODEM_CTRL
  75. SIO_POLL_MODEM_STATUS_REQUEST=0x05
  76. SIO_SET_EVENT_CHAR_REQUEST   =0x06
  77. SIO_SET_ERROR_CHAR_REQUEST   =0x07
  78. SIO_SET_LATENCY_TIMER_REQUEST=0x09
  79. SIO_GET_LATENCY_TIMER_REQUEST=0x0A
  80. SIO_SET_BITMODE_REQUEST      =0x0B
  81. SIO_READ_PINS_REQUEST        =0x0C
  82. SIO_READ_EEPROM_REQUEST      =0x90
  83. SIO_WRITE_EEPROM_REQUEST     =0x91
  84. SIO_ERASE_EEPROM_REQUEST     =0x92
  85.  
  86.  
  87. SIO_RESET_SIO=0
  88. SIO_RESET_PURGE_RX=1
  89. SIO_RESET_PURGE_TX=2
  90.  
  91. SIO_DISABLE_FLOW_CTRL=0x0
  92. SIO_RTS_CTS_HS =(0x1 shl 8)
  93. SIO_DTR_DSR_HS =(0x2 shl 8)
  94. SIO_XON_XOFF_HS=(0x4 shl 8)
  95.  
  96. SIO_SET_DTR_MASK=0x1
  97. SIO_SET_DTR_HIGH=( 1 or ( SIO_SET_DTR_MASK  shl 8))
  98. SIO_SET_DTR_LOW =( 0 or ( SIO_SET_DTR_MASK  shl 8))
  99. SIO_SET_RTS_MASK=0x2
  100. SIO_SET_RTS_HIGH=( 2 or ( SIO_SET_RTS_MASK shl 8 ))
  101. SIO_SET_RTS_LOW =( 0 or ( SIO_SET_RTS_MASK shl 8 ))
  102.  
  103. SIO_RTS_CTS_HS =(0x1 shl 8)
  104.  
  105. ;strings
  106. my_driver       db      'usbother',0
  107. nomemory_msg    db      'K : no memory',13,10,0
  108.  
  109. ; Structures
  110. struct ftdi_context
  111. chipType                db      ?
  112. baudrate                dd      ?
  113. bitbangEnabled          db      ?
  114. readBufPtr              dd      ?
  115. readBufOffs             dd      ?
  116. readBufChunkSize        dd      ?
  117. writeBufChunkSize       dd      ?
  118. interface               dd      ?
  119. index                   dd      ?
  120. inEP                    dd      ?
  121. outEP                   dd      ?
  122. nullP                   dd      ?
  123. next_context            dd      ?
  124. ends
  125.  
  126. struct IOCTL
  127. handle                  dd      ?
  128. io_code                 dd      ?
  129. input                   dd      ?
  130. inp_size                dd      ?
  131. output                  dd      ?
  132. out_size                dd      ?
  133. ends
  134.  
  135. struct usb_descr
  136. bLength                 db      ?
  137. bDescriptorType         db      ?
  138. bcdUSB                  dw      ?
  139. bDeviceClass            db      ?
  140. bDeviceSubClass         db      ?
  141. bDeviceProtocol         db      ?
  142. bMaxPacketSize0         db      ?
  143. idVendor                dw      ?
  144. idProduct               dw      ?
  145. bcdDevice               dw      ?
  146. iManufacturer           db      ?
  147. iProduct                db      ?
  148. iSerialNumber           db      ?
  149. bNumConfigurations      db      ?
  150. ends
  151.  
  152. struct conf_packet
  153. bmRequestType           db      ?
  154. bRequest                db      ?
  155. wValue                  dw      ?
  156. wIndex                  dw      ?
  157. wLength                 dw      ?
  158. ends
  159.  
  160. section '.flat' code readable align 16
  161. ; The start procedure.
  162. proc START stdcall, .reason:DWORD
  163.  
  164.         xor     eax, eax        ; initialize return value
  165.         cmp     [.reason], 1    ; compare the argument
  166.         jnz     .nothing                
  167.         stdcall RegUSBDriver, my_driver, service_proc, usb_functions
  168.  
  169. .nothing:
  170.         ret
  171. endp
  172.  
  173.  
  174. proc AddDevice stdcall uses ebx, .config_pipe:DWORD, .config_descr:DWORD, .interface:DWORD
  175.        
  176.         stdcall USBGetParam, [.config_pipe], 0
  177.         DEBUGF 1,'K : Device detected Vendor: %x\n', [eax+usb_descr.idVendor]
  178.         cmp     word[eax+usb_descr.idVendor], 0x0403
  179.         jnz     .notftdi
  180.         DEBUGF 1,'K : FTDI USB device detected\n'
  181.         movi    eax, sizeof.ftdi_context
  182.         call    Kmalloc
  183.         test    eax, eax
  184.         jnz     @f
  185.         mov     esi, nomemory_msg
  186.         call    SysMsgBoardStr
  187.         xor     eax, eax
  188.         jmp     .nothing
  189. @@:
  190.         DEBUGF 1,'K : Adding struct to list %x\n', eax
  191.         call    linkedlist.add
  192.        
  193.         mov     ebx, [.config_pipe]
  194.         mov     [eax + ftdi_context.nullP], ebx
  195.        
  196.         DEBUGF 1,'K : Open first pipe\n'
  197.         mov     ebx, eax
  198.         stdcall USBOpenPipe, [.config_pipe],  0x81,  0x40,  BULK_PIPE, 0
  199.         mov     [ebx + ftdi_context.inEP], eax
  200.         DEBUGF 1,'K : Open second pipe\n'
  201.         stdcall USBOpenPipe, [.config_pipe],  0x02,  0x40,  BULK_PIPE, 0
  202.         mov     [ebx + ftdi_context.outEP], eax        
  203.  
  204.   .nothing:
  205.         ret            
  206.   .notftdi:
  207.         DEBUGF 1,'K : Skipping not FTDI device\n'
  208.         xor     eax, eax
  209.         ret
  210. endp
  211.  
  212.  
  213. handle     equ  IOCTL.handle
  214. io_code    equ  IOCTL.io_code
  215. input      equ  IOCTL.input
  216. inp_size   equ  IOCTL.inp_size
  217. output     equ  IOCTL.output
  218. out_size   equ  IOCTL.out_size
  219.  
  220. align 4
  221. proc service_proc stdcall uses ebx esi edi, ioctl:DWORD
  222. locals
  223. ConfPacket  rb  8
  224. EventData   rd  2
  225. endl
  226.         mov     edi, [ioctl]
  227.         mov     eax, [edi + io_code]
  228.         DEBUGF 1,'K : FTDI got the request: %d\n', eax
  229.         test    eax, eax           ;0
  230.         jz      .version
  231.         dec     eax                 ;1
  232.         jz      .ftdi_get_list
  233.        
  234.         push    eax edi
  235.         xor     ecx, ecx
  236.         xor     esi, esi
  237.         call    CreateEvent        
  238.         mov     [EventData], eax
  239.         mov     [EventData+4], edx
  240.         pop     edi eax
  241.        
  242.         dec     eax                 ;2
  243.         jz      .ftdi_set_bitmode
  244.         dec     eax                 ;3
  245.         jz      .ftdi_setrtshigh  
  246.         dec     eax                 ;4
  247.         jz      .ftdi_setrtslow    
  248.        
  249.   .version:    
  250.   .endswitch:
  251.         xor     eax, eax
  252.             ret
  253.        
  254.   .ftdi_out_control_transfer:
  255.         DEBUGF 1,'K : ConfPacket %x %x\n', [ConfPacket], [ConfPacket+4]  
  256.         mov     ecx, [edi+input]
  257.         mov     ebx, [ecx]
  258.         lea     esi, [ConfPacket]
  259.         lea     edi, [EventData]        
  260.         stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, 0, 0, control_callback, edi, 0
  261.         DEBUGF 1, 'K : Returned value is %d\n', eax
  262.         mov     eax, [EventData]
  263.         mov     ebx, [EventData+4]
  264.         call    WaitEvent    
  265.         jmp     .endswitch
  266.        
  267.   .ftdi_set_bitmode:
  268.         DEBUGF 1,'K : FTDI Seting bitmode\n'                  
  269.         mov     word[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_BITMODE_REQUEST shl 8)
  270.         mov     edi, [edi+input]        
  271.         mov     dx, word[edi+4]                
  272.         mov     word[ConfPacket+2], dx
  273.         mov     dword[ConfPacket+4], 0                                        
  274.         jmp     .ftdi_out_control_transfer    
  275.         jmp     .endswitch
  276.  
  277.   .ftdi_setrtshigh:
  278.         DEBUGF 1,'K : FTDI Setting RTS pin HIGH\n'                    
  279.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_HIGH shl 16)
  280.         mov     dword[ConfPacket+4], 0
  281.         jmp     .ftdi_out_control_transfer        
  282.         jmp     .endswitch
  283.  
  284.   .ftdi_setrtslow:
  285.         DEBUGF 1,'K : FTDI Setting RTS pin LOW\n'            
  286.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_RTS_LOW shl 16)
  287.         mov     dword[ConfPacket+4], 0
  288.         jmp     .ftdi_out_control_transfer        
  289.         jmp     .endswitch
  290.        
  291.   .ftdi_setdtrhigh:
  292.         DEBUGF 1,'K : FTDI Setting DTR pin HIGH\n'                    
  293.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_HIGH shl 16)
  294.         mov     dword[ConfPacket+4], 0
  295.         jmp     .ftdi_out_control_transfer        
  296.         jmp     .endswitch
  297.  
  298.   .ftdi_setdtrlow:
  299.         DEBUGF 1,'K : FTDI Setting DTR pin LOW\n'            
  300.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_MODEM_CTRL_REQUEST shl 8) + (SIO_SET_DTR_LOW shl 16)
  301.         mov     dword[ConfPacket+4], 0
  302.         jmp     .ftdi_out_control_transfer        
  303.         jmp     .endswitch
  304.        
  305.   .ftdi_usb_reset:
  306.         DEBUGF 1,'K : FTDI Reseting\n'
  307.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_SIO shl 16)
  308.         mov     dword[ConfPacket+4], 0
  309.         jmp     .ftdi_out_control_transfer        
  310.         jmp     .endswitch
  311.        
  312.   .ftdi_purge_rx_buf:
  313.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_RX shl 16)
  314.         mov     dword[ConfPacket+4], 0
  315.         jmp     .ftdi_out_control_transfer        
  316.         jmp     .endswitch
  317.        
  318.   .ftdi_purge_tx_buf:
  319.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_RESET_REQUEST shl 8) + (SIO_RESET_PURGE_TX shl 16)
  320.         mov     dword[ConfPacket+4], 0
  321.         jmp     .ftdi_out_control_transfer        
  322.         jmp     .endswitch
  323.        
  324.   .ftdi_set_baudrate:
  325.         ;!!!!!!!!!!!!!!!!!!!!
  326.         ;jmp     .ftdi_out_control_transfer        
  327.         jmp     .endswitch
  328.        
  329.   .ftdi_set_line_property:
  330.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_DATA_REQUEST shl 8)
  331.         mov     edi, [edi+input]        
  332.         mov     dx, word[edi+4]                
  333.         mov     word[ConfPacket+2], dx
  334.         mov     dword[ConfPacket+4], 0
  335.         jmp     .ftdi_out_control_transfer        
  336.         jmp     .endswitch  
  337.        
  338.   .ftdi_set_latency_timer:
  339.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_LATENCY_TIMER_REQUEST shl 8)
  340.         mov     edi, [edi+input]        
  341.         mov     dx, word[edi+4]                
  342.         mov     word[ConfPacket+2], dx
  343.         mov     dword[ConfPacket+4], 0
  344.         jmp     .ftdi_out_control_transfer        
  345.         jmp     .endswitch
  346.        
  347.   .ftdi_set_event_char:
  348.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_EVENT_CHAR_REQUEST shl 8)
  349.         mov     edi, [edi+input]        
  350.         mov     dx, word[edi+4]                
  351.         mov     word[ConfPacket+2], dx
  352.         mov     dword[ConfPacket+4], 0
  353.         jmp     .ftdi_out_control_transfer        
  354.         jmp     .endswitch
  355.  
  356.   .ftdi_set_error_char:
  357.         mov     dword[ConfPacket], (FTDI_DEVICE_OUT_REQTYPE) + (SIO_SET_ERROR_CHAR_REQUEST shl 8)
  358.         mov     edi, [edi+input]        
  359.         mov     dx, word[edi+4]                
  360.         mov     word[ConfPacket+2], dx
  361.         mov     dword[ConfPacket+4], 0
  362.         jmp     .ftdi_out_control_transfer        
  363.         jmp     .endswitch          
  364.        
  365.  
  366.   .ftdi_read_pins:
  367.         DEBUGF 1,'K : FTDI Reading pins\n'
  368.         mov     dword[ConfPacket], FTDI_DEVICE_IN_REQTYPE + (SIO_READ_PINS_REQUEST shl 8) + (0 shl 16)
  369.         mov     dword[ConfPacket+4], 0x00000001
  370.         mov     edi, [edi+input]                                  
  371.         mov     ebx, [edi]
  372.         lea     esi, [ConfPacket]
  373.         lea     edi, [EventData]
  374.         mov     ecx, [ioctl]
  375.         mov     ecx, [ecx+output]
  376.         stdcall USBControlTransferAsync, [ebx + ftdi_context.nullP],  esi, ecx, 1, control_callback, edi, 0
  377.         DEBUGF 1, 'K : Returned value is %d\n', eax
  378.         mov     eax, [EventData]
  379.         mov     ebx, [EventData+4]
  380.         call    WaitEvent    
  381.         jmp     .endswitch
  382.        
  383.    .ftdi_read_data:
  384.         ;stdcall USBNormalTransferAsync, [ebx + ftdi_context.inEP], [ebx + ftdi_context.readBufPtr], [ebx + 1]
  385.  
  386.    .ftdi_get_list:
  387.         call    linkedlist.gethead                        
  388.         mov     edi, [edi+output]
  389.         mov     [edi], eax
  390.         DEBUGF 1, 'K : FTDI Device pointer %x\n', [edi]
  391.         mov     eax, 4        
  392.         mov     [edi+out_size], eax
  393.         jmp     .endswitch
  394.                    
  395. endp
  396. restore   handle
  397. restore   io_code
  398. restore   input
  399. restore   inp_size
  400. restore   output
  401. restore   out_size
  402.  
  403.  
  404. align 4
  405. proc control_callback stdcall uses ebx edi esi, .pipe:DWORD, .status:DWORD, .buffer:DWORD, .length:DWORD, .calldata:DWORD  
  406.    
  407.         DEBUGF 1, 'K : status is %d\n', [.status]
  408.         mov     ecx, [.calldata]
  409.         mov     eax, [ecx]
  410.         mov     ebx, [ecx+4]
  411.         xor     edx, edx
  412.         call    RaiseEvent
  413.              
  414.         ret
  415. endp
  416.  
  417.  
  418. proc DeviceDisconnected stdcall uses  ebx esi edi, .device_data:DWORD
  419.  
  420.         DEBUGF 1, 'K : FTDI deleting device data\n'
  421.         mov     eax, [.device_data]
  422.         call    linkedlist.delete
  423.         ret          
  424. endp
  425.  
  426. include 'linkedlist.inc'
  427.        
  428. ; Exported variable: kernel API version.
  429. align 4
  430. version dd      50005h
  431. ; Structure with callback functions.
  432. usb_functions:
  433.         dd      12
  434.         dd      AddDevice
  435.         dd      DeviceDisconnected
  436.  
  437. ;for DEBUGF macro
  438. include_debug_strings
  439.  
  440.  
  441.  
  442.  
  443. ; for uninitialized data
  444. ;section '.data' data readable writable align 16
  445.