usbh_ftdi.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. /*
  2. * Copyright (c) 2024 ~ 2025, sakumisu
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #ifndef USBH_FTDI_H
  7. #define USBH_FTDI_H
  8. #include "usb_cdc.h"
  9. #define FTDI_VID 0x0403 /* Vendor Id */
  10. /* FTDI device PIDs */
  11. #define FTDI_8U232AM_PID 0x6001 /* Similar device to SIO above */
  12. #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
  13. #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
  14. #define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
  15. #define FTDI_232H_PID 0x6014 /* Single channel hi-speed device */
  16. #define FTDI_FTX_PID 0x6015 /* FT-X series (FT201X, FT230X, FT231X, etc) */
  17. #define FTDI_FT2233HP_PID 0x6040 /* Dual channel hi-speed device with PD */
  18. #define FTDI_FT4233HP_PID 0x6041 /* Quad channel hi-speed device with PD */
  19. #define FTDI_FT2232HP_PID 0x6042 /* Dual channel hi-speed device with PD */
  20. #define FTDI_FT4232HP_PID 0x6043 /* Quad channel hi-speed device with PD */
  21. #define FTDI_FT233HP_PID 0x6044 /* Dual channel hi-speed device with PD */
  22. #define FTDI_FT232HP_PID 0x6045 /* Dual channel hi-speed device with PD */
  23. #define FTDI_FT4232HA_PID 0x6048 /* Quad channel automotive grade hi-speed device */
  24. #define FTDI_SIO_PID 0x8372 /* Product Id SIO application of 8U100AX */
  25. #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
  26. /* Requests */
  27. #define FTDI_SIO_RESET 0x00 /* Reset the port */
  28. #define FTDI_SIO_SET_MODEM_CTRL 0x01 /* Set the modem control register */
  29. #define FTDI_SIO_SET_FLOW_CTRL 0x02 /* Set flow control register */
  30. #define FTDI_SIO_SET_BAUDRATE 0x03 /* Set baud rate */
  31. #define FTDI_SIO_SET_DATA 0x04 /* Set the data characteristics of the port */
  32. #define FTDI_SIO_GET_MODEM_STATUS 0x05
  33. #define FTDI_SIO_SET_EVENT_CHAR 0x06
  34. #define FTDI_SIO_SET_ERROR_CHAR 0x07
  35. #define FTDI_SIO_SET_LATENCY_TIMER 0x09
  36. #define FTDI_SIO_GET_LATENCY_TIMER 0x0A
  37. #define FTDI_SIO_SET_BITMODE 0x0B
  38. #define FTDI_SIO_READ_PINS 0x0C
  39. #define FTDI_SIO_READ_EEPROM 0x90
  40. #define FTDI_SIO_WRITE_EEPROM 0x91
  41. #define FTDI_SIO_ERASE_EEPROM 0x92
  42. /* Channel indices for FT2232, FT2232H and FT4232H devices */
  43. #define FTDI_SIO_CHANNEL_A 1
  44. #define FTDI_SIO_CHANNEL_B 2
  45. #define FTDI_SIO_CHANNEL_C 3
  46. #define FTDI_SIO_CHANNEL_D 4
  47. /*
  48. * BmRequestType: 0100 0000B
  49. * bRequest: FTDI_SIO_RESET
  50. * wValue: Control Value
  51. * 0 = Reset SIO
  52. * 1 = Purge RX buffer
  53. * 2 = Purge TX buffer
  54. * wIndex: Port
  55. * wLength: 0
  56. * Data: None
  57. *
  58. * The Reset SIO command has this effect:
  59. *
  60. * Sets flow control set to 'none'
  61. * Event char = $0D
  62. * Event trigger = disabled
  63. * Purge RX buffer
  64. * Purge TX buffer
  65. * Clear DTR
  66. * Clear RTS
  67. * baud and data format not reset
  68. *
  69. * The Purge RX and TX buffer commands affect nothing except the buffers
  70. *
  71. */
  72. #define FTDI_SIO_RESET_SIO 0
  73. #define FTDI_SIO_RESET_PURGE_RX 1
  74. #define FTDI_SIO_RESET_PURGE_TX 2
  75. /*
  76. * BmRequestType: 0100 0000B
  77. * bRequest: FTDI_SIO_SET_BAUDRATE
  78. * wValue: BaudDivisor value - see below
  79. * wIndex: Port
  80. * wLength: 0
  81. * Data: None
  82. * The BaudDivisor values are calculated as follows:
  83. * - BaseClock is either 12000000 or 48000000 depending on the device.
  84. * FIXME: I wish I knew how to detect old chips to select proper base clock!
  85. * - BaudDivisor is a fixed point number encoded in a funny way.
  86. * (--WRONG WAY OF THINKING--)
  87. * BaudDivisor is a fixed point number encoded with following bit weighs:
  88. * (-2)(-1)(13..0). It is a radical with a denominator of 4, so values
  89. * end with 0.0 (00...), 0.25 (10...), 0.5 (01...), and 0.75 (11...).
  90. * (--THE REALITY--)
  91. * The both-bits-set has quite different meaning from 0.75 - the chip
  92. * designers have decided it to mean 0.125 instead of 0.75.
  93. * This info looked up in FTDI application note "FT8U232 DEVICES \ Data Rates
  94. * and Flow Control Consideration for USB to RS232".
  95. * - BaudDivisor = (BaseClock / 16) / BaudRate, where the (=) operation should
  96. * automagically re-encode the resulting value to take fractions into
  97. * consideration.
  98. * As all values are integers, some bit twiddling is in order:
  99. * BaudDivisor = (BaseClock / 16 / BaudRate) |
  100. * (((BaseClock / 2 / BaudRate) & 4) ? 0x4000 // 0.5
  101. * : ((BaseClock / 2 / BaudRate) & 2) ? 0x8000 // 0.25
  102. * : ((BaseClock / 2 / BaudRate) & 1) ? 0xc000 // 0.125
  103. * : 0)
  104. *
  105. * For the FT232BM, a 17th divisor bit was introduced to encode the multiples
  106. * of 0.125 missing from the FT8U232AM. Bits 16 to 14 are coded as follows
  107. * (the first four codes are the same as for the FT8U232AM, where bit 16 is
  108. * always 0):
  109. * 000 - add .000 to divisor
  110. * 001 - add .500 to divisor
  111. * 010 - add .250 to divisor
  112. * 011 - add .125 to divisor
  113. * 100 - add .375 to divisor
  114. * 101 - add .625 to divisor
  115. * 110 - add .750 to divisor
  116. * 111 - add .875 to divisor
  117. * Bits 15 to 0 of the 17-bit divisor are placed in the urb value. Bit 16 is
  118. * placed in bit 0 of the urb index.
  119. *
  120. * Note that there are a couple of special cases to support the highest baud
  121. * rates. If the calculated divisor value is 1, this needs to be replaced with
  122. * 0. Additionally for the FT232BM, if the calculated divisor value is 0x4001
  123. * (1.5), this needs to be replaced with 0x0001 (1) (but this divisor value is
  124. * not supported by the FT8U232AM).
  125. */
  126. enum ftdi_sio_baudrate {
  127. ftdi_sio_b300 = 0,
  128. ftdi_sio_b600 = 1,
  129. ftdi_sio_b1200 = 2,
  130. ftdi_sio_b2400 = 3,
  131. ftdi_sio_b4800 = 4,
  132. ftdi_sio_b9600 = 5,
  133. ftdi_sio_b19200 = 6,
  134. ftdi_sio_b38400 = 7,
  135. ftdi_sio_b57600 = 8,
  136. ftdi_sio_b115200 = 9
  137. };
  138. /*
  139. * BmRequestType: 0100 0000B
  140. * bRequest: FTDI_SIO_SET_DATA
  141. * wValue: Data characteristics (see below)
  142. * wIndex: Port
  143. * wLength: 0
  144. * Data: No
  145. *
  146. * Data characteristics
  147. *
  148. * B0..7 Number of data bits
  149. * B8..10 Parity
  150. * 0 = None
  151. * 1 = Odd
  152. * 2 = Even
  153. * 3 = Mark
  154. * 4 = Space
  155. * B11..13 Stop Bits
  156. * 0 = 1
  157. * 1 = 1.5
  158. * 2 = 2
  159. * B14
  160. * 1 = TX ON (break)
  161. * 0 = TX OFF (normal state)
  162. * B15 Reserved
  163. *
  164. */
  165. #define FTDI_SIO_SET_DATA_PARITY_NONE (0x0 << 8)
  166. #define FTDI_SIO_SET_DATA_PARITY_ODD (0x1 << 8)
  167. #define FTDI_SIO_SET_DATA_PARITY_EVEN (0x2 << 8)
  168. #define FTDI_SIO_SET_DATA_PARITY_MARK (0x3 << 8)
  169. #define FTDI_SIO_SET_DATA_PARITY_SPACE (0x4 << 8)
  170. #define FTDI_SIO_SET_DATA_STOP_BITS_1 (0x0 << 11)
  171. #define FTDI_SIO_SET_DATA_STOP_BITS_15 (0x1 << 11)
  172. #define FTDI_SIO_SET_DATA_STOP_BITS_2 (0x2 << 11)
  173. #define FTDI_SIO_SET_BREAK (0x1 << 14)
  174. /*
  175. * BmRequestType: 0100 0000B
  176. * bRequest: FTDI_SIO_MODEM_CTRL
  177. * wValue: ControlValue (see below)
  178. * wIndex: Port
  179. * wLength: 0
  180. * Data: None
  181. *
  182. * NOTE: If the device is in RTS/CTS flow control, the RTS set by this
  183. * command will be IGNORED without an error being returned
  184. * Also - you can not set DTR and RTS with one control message
  185. *
  186. * ControlValue
  187. * B0 DTR state
  188. * 0 = reset
  189. * 1 = set
  190. * B1 RTS state
  191. * 0 = reset
  192. * 1 = set
  193. * B2..7 Reserved
  194. * B8 DTR state enable
  195. * 0 = ignore
  196. * 1 = use DTR state
  197. * B9 RTS state enable
  198. * 0 = ignore
  199. * 1 = use RTS state
  200. * B10..15 Reserved
  201. *
  202. */
  203. #define FTDI_SIO_SET_DTR_MASK 0x1
  204. #define FTDI_SIO_SET_DTR_HIGH ((FTDI_SIO_SET_DTR_MASK << 8) | 1)
  205. #define FTDI_SIO_SET_DTR_LOW ((FTDI_SIO_SET_DTR_MASK << 8) | 0)
  206. #define FTDI_SIO_SET_RTS_MASK 0x2
  207. #define FTDI_SIO_SET_RTS_HIGH ((FTDI_SIO_SET_RTS_MASK << 8) | 2)
  208. #define FTDI_SIO_SET_RTS_LOW ((FTDI_SIO_SET_RTS_MASK << 8) | 0)
  209. /*
  210. * BmRequestType: 0100 0000b
  211. * bRequest: FTDI_SIO_SET_FLOW_CTRL
  212. * wValue: Xoff/Xon
  213. * wIndex: Protocol/Port - hIndex is protocol / lIndex is port
  214. * wLength: 0
  215. * Data: None
  216. *
  217. * hIndex protocol is:
  218. * B0 Output handshaking using RTS/CTS
  219. * 0 = disabled
  220. * 1 = enabled
  221. * B1 Output handshaking using DTR/DSR
  222. * 0 = disabled
  223. * 1 = enabled
  224. * B2 Xon/Xoff handshaking
  225. * 0 = disabled
  226. * 1 = enabled
  227. *
  228. * A value of zero in the hIndex field disables handshaking
  229. *
  230. * If Xon/Xoff handshaking is specified, the hValue field should contain the
  231. * XOFF character and the lValue field contains the XON character.
  232. */
  233. #define FTDI_SIO_DISABLE_FLOW_CTRL 0x0
  234. #define FTDI_SIO_RTS_CTS_HS (0x1 << 8)
  235. #define FTDI_SIO_DTR_DSR_HS (0x2 << 8)
  236. #define FTDI_SIO_XON_XOFF_HS (0x4 << 8)
  237. /*
  238. * BmRequestType: 1100 0000b
  239. * bRequest: FTDI_SIO_GET_MODEM_STATUS
  240. * wValue: zero
  241. * wIndex: Port
  242. * wLength: 1
  243. * Data: Status
  244. *
  245. * One byte of data is returned
  246. * B0..3 0
  247. * B4 CTS
  248. * 0 = inactive
  249. * 1 = active
  250. * B5 DSR
  251. * 0 = inactive
  252. * 1 = active
  253. * B6 Ring Indicator (RI)
  254. * 0 = inactive
  255. * 1 = active
  256. * B7 Receive Line Signal Detect (RLSD)
  257. * 0 = inactive
  258. * 1 = active
  259. */
  260. #define FTDI_SIO_CTS_MASK 0x10
  261. #define FTDI_SIO_DSR_MASK 0x20
  262. #define FTDI_SIO_RI_MASK 0x40
  263. #define FTDI_SIO_RLSD_MASK 0x80
  264. /* Possible bitmodes for FTDI_SIO_SET_BITMODE_REQUEST */
  265. #define FTDI_SIO_BITMODE_RESET 0x00
  266. #define FTDI_SIO_BITMODE_CBUS 0x20
  267. /*
  268. * IN Endpoint
  269. *
  270. * The device reserves the first two bytes of data on this endpoint to contain
  271. * the current values of the modem and line status registers. In the absence of
  272. * data, the device generates a message consisting of these two status bytes
  273. * every 40 ms
  274. *
  275. * Byte 0: Modem Status
  276. *
  277. * Offset Description
  278. * B0 Reserved - must be 1
  279. * B1 Reserved - must be 0
  280. * B2 Reserved - must be 0
  281. * B3 Reserved - must be 0
  282. * B4 Clear to Send (CTS)
  283. * B5 Data Set Ready (DSR)
  284. * B6 Ring Indicator (RI)
  285. * B7 Receive Line Signal Detect (RLSD)
  286. *
  287. * Byte 1: Line Status
  288. *
  289. * Offset Description
  290. * B0 Data Ready (DR)
  291. * B1 Overrun Error (OE)
  292. * B2 Parity Error (PE)
  293. * B3 Framing Error (FE)
  294. * B4 Break Interrupt (BI)
  295. * B5 Transmitter Holding Register (THRE)
  296. * B6 Transmitter Empty (TEMT)
  297. * B7 Error in RCVR FIFO
  298. *
  299. */
  300. #define FTDI_RS0_CTS (1 << 4)
  301. #define FTDI_RS0_DSR (1 << 5)
  302. #define FTDI_RS0_RI (1 << 6)
  303. #define FTDI_RS0_RLSD (1 << 7)
  304. #define FTDI_RS_DR 1
  305. #define FTDI_RS_OE (1 << 1)
  306. #define FTDI_RS_PE (1 << 2)
  307. #define FTDI_RS_FE (1 << 3)
  308. #define FTDI_RS_BI (1 << 4)
  309. #define FTDI_RS_THRE (1 << 5)
  310. #define FTDI_RS_TEMT (1 << 6)
  311. #define FTDI_RS_FIFO (1 << 7)
  312. #ifdef __cplusplus
  313. extern "C" {
  314. #endif
  315. #ifdef __cplusplus
  316. }
  317. #endif
  318. #endif /* USBH_FTDI_H */