@johntalton/ftdi 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +89 -0
  3. package/lib/consts.d.ts +33 -0
  4. package/lib/consts.d.ts.map +1 -0
  5. package/lib/consts.js +42 -0
  6. package/lib/consts.js.map +1 -0
  7. package/lib/eeprom.d.ts +129 -0
  8. package/lib/eeprom.d.ts.map +1 -0
  9. package/lib/eeprom.js +495 -0
  10. package/lib/eeprom.js.map +1 -0
  11. package/lib/ft232h.d.ts +37 -0
  12. package/lib/ft232h.d.ts.map +1 -0
  13. package/lib/ft232h.js +204 -0
  14. package/lib/ft232h.js.map +1 -0
  15. package/lib/ftdi.d.ts +37 -0
  16. package/lib/ftdi.d.ts.map +1 -0
  17. package/lib/ftdi.js +204 -0
  18. package/lib/ftdi.js.map +1 -0
  19. package/lib/i2c/i2c-template.d.ts +10 -0
  20. package/lib/i2c/i2c-template.d.ts.map +1 -0
  21. package/lib/i2c/i2c-template.js +122 -0
  22. package/lib/i2c/i2c-template.js.map +1 -0
  23. package/lib/i2c/i2c.d.ts +29 -0
  24. package/lib/i2c/i2c.d.ts.map +1 -0
  25. package/lib/i2c/i2c.js +169 -0
  26. package/lib/i2c/i2c.js.map +1 -0
  27. package/lib/i2c/index.d.ts +5 -0
  28. package/lib/i2c/index.d.ts.map +1 -0
  29. package/lib/i2c/index.js +5 -0
  30. package/lib/i2c/index.js.map +1 -0
  31. package/lib/i2c/range.d.ts +2 -0
  32. package/lib/i2c/range.d.ts.map +1 -0
  33. package/lib/i2c/range.js +6 -0
  34. package/lib/i2c/range.js.map +1 -0
  35. package/lib/index.d.ts +9 -0
  36. package/lib/index.d.ts.map +1 -0
  37. package/lib/index.js +9 -0
  38. package/lib/index.js.map +1 -0
  39. package/lib/mpsse/clock.d.ts +16 -0
  40. package/lib/mpsse/clock.d.ts.map +1 -0
  41. package/lib/mpsse/clock.js +34 -0
  42. package/lib/mpsse/clock.js.map +1 -0
  43. package/lib/mpsse/command.d.ts +66 -0
  44. package/lib/mpsse/command.d.ts.map +1 -0
  45. package/lib/mpsse/command.js +89 -0
  46. package/lib/mpsse/command.js.map +1 -0
  47. package/lib/mpsse/index.d.ts +7 -0
  48. package/lib/mpsse/index.d.ts.map +1 -0
  49. package/lib/mpsse/index.js +7 -0
  50. package/lib/mpsse/index.js.map +1 -0
  51. package/lib/mpsse/mpsse-template.d.ts +19 -0
  52. package/lib/mpsse/mpsse-template.d.ts.map +1 -0
  53. package/lib/mpsse/mpsse-template.js +81 -0
  54. package/lib/mpsse/mpsse-template.js.map +1 -0
  55. package/lib/mpsse/mpsse.d.ts +18 -0
  56. package/lib/mpsse/mpsse.d.ts.map +1 -0
  57. package/lib/mpsse/mpsse.js +77 -0
  58. package/lib/mpsse/mpsse.js.map +1 -0
  59. package/lib/status.d.ts +39 -0
  60. package/lib/status.d.ts.map +1 -0
  61. package/lib/status.js +62 -0
  62. package/lib/status.js.map +1 -0
  63. package/lib/util.d.ts +26 -0
  64. package/lib/util.d.ts.map +1 -0
  65. package/lib/util.js +57 -0
  66. package/lib/util.js.map +1 -0
  67. package/package.json +38 -0
  68. package/src/consts.ts +57 -0
  69. package/src/eeprom.ts +663 -0
  70. package/src/ftdi.ts +215 -0
  71. package/src/i2c/i2c-template.ts +156 -0
  72. package/src/i2c/i2c.ts +210 -0
  73. package/src/i2c/index.ts +4 -0
  74. package/src/i2c/range.ts +6 -0
  75. package/src/index.ts +8 -0
  76. package/src/mpsse/clock.ts +36 -0
  77. package/src/mpsse/command.ts +113 -0
  78. package/src/mpsse/index.ts +6 -0
  79. package/src/mpsse/mpsse-template.ts +96 -0
  80. package/src/mpsse/mpsse.ts +95 -0
  81. package/src/status.ts +94 -0
  82. package/src/util.ts +72 -0
@@ -0,0 +1,113 @@
1
+ export const BAD_COMMAND = 0xAF // suggested bad command
2
+ export const BAD_COMMAND_RESPONSE = 0xFA // first response byte when any bad command sent
3
+
4
+ // Shifting commands IN MPSSE Mode
5
+ export const SHIFT_COMMANDS_DEFINITION = {
6
+ WRITE_NEGATIVE_EDGE: 0b0000_0001, // -ve CLK on write
7
+ BIT_MODE: 0b0000_0010, // bit mode = 1 else byte mode
8
+ READ_NEGATIVE_EDGE: 0b0000_0100, // -ve CLK on read
9
+ LSB_FIRST: 0b0000_1000, // LSB first = 1 else MSB first
10
+ WRITE_TDI: 0b0001_0000, // Do write TDI
11
+ READ_TDO: 0b0010_0000, // Do read TDO
12
+ WRITE_TMS: 0b0100_0000 // Do writeTMS
13
+ }
14
+
15
+ export type ShiftCommand = number
16
+
17
+ export const SHIFT_COMMAND = {
18
+ OUT_MSB_BYTES_POSITIVE_VE: 0x10, // WRITE_TDI
19
+ OUT_MSB_BYTES_NEGATIVE_VE: 0x11, // WRITE_TDI | WRITE_NEGATIVE_EDGE
20
+ OUT_MSB_BITS_POSITIVE_VE: 0x12, // WRITE_TDI | BIT_MODE
21
+ OUT_MSB_BITS_NEGATIVE_VE: 0x13, // WRITE_TDI | BIT_MODE | WRITE_NEGATIVE_EDGE
22
+
23
+ IN_MSB_BYTES_POSITIVE_VE: 0x20, // READ_TDO
24
+ IN_MSB_BYTES_NEGATIVE_VE: 0x24, // READ_TDO | READ_NEGATIVE_EDGE
25
+ IN_MSB_BITS_POSITIVE_VE: 0x22, // READ_TDO | BIT_MODE
26
+ IN_MSB_BITS_NEGATIVE_VE: 0x26, // READ_TDO | BIT_MODE | READ_NEGATIVE_EDGE
27
+
28
+ IN_OUT_MSB_BYTES_OUT_NEGATIVE_IN_POSITIVE_VE: 0x31,
29
+ IN_OUT_MSB_BYTES_OUT_POSITIVE_IN_NEGATIVE_VE: 0x34,
30
+ IN_OUT_MSB_BITS_OUT_NEGATIVE_IN_POSITIVE_VE: 0x33,
31
+ IN_OUT_MSB_BITS_OUT_POSITIVE_IN_NEGATIVE_VE: 0x36,
32
+
33
+ //
34
+ OUT_LSB_BYTES_POSITIVE_VE: 0x18, // LSB_FIRST | WRITE_TDI
35
+ OUT_LSB_BYTES_NEGATIVE_VE: 0x19, // LSB_FIRST | WRITE_TDI | WRITE_NEGATIVE_EDGE
36
+ OUT_LSB_BITS_POSITIVE_VE: 0x1A, // LSB_FIRST | WRITE_TDI | BIT_MODE
37
+ OUT_LSB_BITS_NEGATIVE_VE: 0x1B, // LSB_FIRST | WRITE_TDI | BIT_MODE | WRITE_NEGATIVE_EDGE
38
+
39
+ IN_LSB_BYTES_POSITIVE_VE: 0x28, // LSB_FIRST | READ_TDI
40
+ IN_LSB_BYTES_NEGATIVE_VE: 0x2C, // LSB_FIRST | READ_TDI | READ_NEGATIVE_EDGE
41
+ IN_LSB_BITS_POSITIVE_VE: 0x2A, // LSB_FIRST | READ_TDI | BIT_MODE
42
+ IN_LSB_BITS_NEGATIVE_VE: 0x2E, // LSB_FIRST | READ_TDI | BIT_MODE | READ_NEGATIVE_EDGE
43
+
44
+ IN_OUT_LSB_BYTES_OUT_NEGATIVE_IN_POSITIVE_VE: 0x39,
45
+ IN_OUT_LSB_BYTES_OUT_POSITIVE_IN_NEGATIVE_VE: 0x3C,
46
+ IN_OUT_LSB_BITS_OUT_NEGATIVE_IN_POSITIVE_VE: 0x3B,
47
+ IN_OUT_LSB_BITS_OUT_POSITIVE_IN_NEGATIVE_VE: 0x3E,
48
+
49
+ }
50
+
51
+ // export const LSB_FIRST_TMS_COMMANDS = {
52
+ // CLOCK_DATA_NO_READ_POSITIVE_VE: 0x4A,
53
+ // CLOCK_DATA_NO_READ_NEGATIVE_VE: 0x4B,
54
+
55
+ // CLOCK_DATA_WITH_READ_ON_POSITIVE_VE_READ_POSITIVE_VE: 0x6A,
56
+ // CLOCK_DATA_WITH_READ_ON_NEGATIVE_VE_READ_POSITIVE_VE: 0x6B,
57
+ // CLOCK_DATA_WITH_READ_ON_POSITIVE_VE_READ_NEGATIVE_VE: 0x6E,
58
+ // CLOCK_DATA_WITH_READ_ON_NEGATIVE_VE_READ_NEGATIVE_VE: 0x6F
59
+ // }
60
+
61
+ export const PIN_STATE_COMMANDS = {
62
+ SET_DATA_BITS_LOW_BYTE: 0x80,
63
+ SET_DATA_BITS_HIGH_BYTE: 0x82,
64
+
65
+ READ_DATA_BITS_LOW_BYTE: 0x81,
66
+ READ_DATA_BITS_HIGH_BYTE: 0x83
67
+ }
68
+
69
+ export const LOOPBACK_COMMANDS = {
70
+ ENABLED: 0x84,
71
+ DISABLE: 0x85
72
+ }
73
+
74
+ export const CLOCK_DIVISOR_COMMANDS = {
75
+ SET_CLK_DIVISOR: 0x86
76
+ }
77
+
78
+ export const HOST_AND_MPSSE_MODE_COMMANDS = {
79
+ SEND_IMMEDIATE: 0x87,
80
+ // WAIT_IO_HIGH: 0x88,
81
+ // WAIT_IO_LOW: 0x89
82
+ }
83
+
84
+ // export const HOST_EMULATION_MODE_COMMANDS = {
85
+ // READ_SHORT_ADDRESS: 0x90,
86
+ // READ_EXTENDED_ADDRESS: 0x91,
87
+ // WRITE_SHORT_ADDRESS: 0x92,
88
+ // WRITE_EXTENDED_ADDRESS: 0x93
89
+ // }
90
+
91
+ export const H_COMMANDS = {
92
+ DISABLE_CLOCK_DIVIDE_BY_FIVE: 0x8A,
93
+ ENABLE_CLOCK_DIVIDE_BY_FIVE: 0x8B,
94
+
95
+ ENABLE_THREE_PHASE_CLOCKING: 0x8C,
96
+ DISABLE_THREE_PHASE_CLOCKING: 0x8D,
97
+
98
+ // CLOCK_N_BITS_NO_TRANSFER: 0x8E,
99
+ // CLOCK_N_EIGHT_BITS_NO_TRANSFER: 0x8F,
100
+
101
+ // CLOCK_WAIT_IO_HIGH: 0x94,
102
+ // CLOCK_WAIT_IO_LOW: 0x95,
103
+
104
+ ENABLE_ADAPTIVE_CLOCKING: 0x96,
105
+ DISABLE_ADAPTIVE_CLOCKING: 0x97,
106
+
107
+ // CLOCK_N_BITS_NO_TRANSFER_OR_UNTIL_HIGH: 0x9C,
108
+ // CLOCK_N_EIGHT_BITS_NO_TRANSFER_OR_UNTIL_LOW: 0x9D
109
+ }
110
+
111
+ export const FT232H_ONLY_COMMANDS = {
112
+ SET_IO_ONLY_DRIVE_LOW: 0x9E
113
+ }
@@ -0,0 +1,6 @@
1
+ /** biome-ignore-all lint/performance/noBarrelFile: barrel */
2
+ /** biome-ignore-all lint/performance/noReExportAll: barrel */
3
+ export * from './clock.ts'
4
+ export * from './command.ts'
5
+ export * from './mpsse.ts'
6
+ export * from './mpsse-template.ts'
@@ -0,0 +1,96 @@
1
+ /** biome-ignore-all lint/style/useConsistentArrayType: <explanation> */
2
+ import {
3
+ CLOCK_DIVISOR_COMMANDS,
4
+ FT232H_ONLY_COMMANDS,
5
+ H_COMMANDS,
6
+ LOOPBACK_COMMANDS,
7
+ PIN_STATE_COMMANDS,
8
+ type ShiftCommand
9
+ } from './command.ts'
10
+
11
+
12
+ export class MPSSETemplate {
13
+ static shiftOutByte(command: ShiftCommand, length: number, data: number): Array<number> {
14
+ const lengthL = (length - 1) & 0x0F
15
+ const lengthH = ((length - 1) & 0xF0) >> 8
16
+ return [ command, lengthL, lengthH, data ]
17
+ }
18
+
19
+ static shiftInByte(command: ShiftCommand, length: number): Array<number> {
20
+ const lengthL = (length - 1) & 0x0F
21
+ const lengthH = ((length - 1) & 0xF0) >> 8
22
+ return [ command, lengthL, lengthH ]
23
+ }
24
+
25
+ static shiftOutBits(command: ShiftCommand, length: number, data: number): Array<number> {
26
+ return [ command, length - 1, data ]
27
+ }
28
+
29
+ static shiftInBits(command: ShiftCommand, length: number): Array<number> {
30
+ return [ command, length - 1 ]
31
+ }
32
+
33
+ static gpioSetHigh(pins: number, directions: number): Array<number> {
34
+ return [
35
+ PIN_STATE_COMMANDS.SET_DATA_BITS_HIGH_BYTE,
36
+ pins,
37
+ directions
38
+ ]
39
+ }
40
+
41
+ static gpioSetLow(pins: number, directions: number): Array<number> {
42
+ return [
43
+ PIN_STATE_COMMANDS.SET_DATA_BITS_LOW_BYTE,
44
+ pins,
45
+ directions
46
+ ]
47
+ }
48
+
49
+ static gpioGetHigh(): Array<number> {
50
+ return [ PIN_STATE_COMMANDS.READ_DATA_BITS_HIGH_BYTE ]
51
+ }
52
+
53
+ static gpioGetLow(): Array<number> {
54
+ return [ PIN_STATE_COMMANDS.READ_DATA_BITS_LOW_BYTE ]
55
+ }
56
+
57
+ static setClockDivisor(divider: number): Array<number> {
58
+ const divisorL = divider & 0xFF
59
+ const divisorH = (divider >> 8) & 0xFF
60
+
61
+ return [
62
+ CLOCK_DIVISOR_COMMANDS.SET_CLK_DIVISOR,
63
+ divisorL,
64
+ divisorH
65
+ ]
66
+ }
67
+
68
+ static enableLoopback(enable = true): Array<number> {
69
+ if(enable) { return [ LOOPBACK_COMMANDS.ENABLED ] }
70
+ return [ LOOPBACK_COMMANDS.DISABLE ]
71
+ }
72
+
73
+ static enableClockDivideBy5(enable = true): Array<number> {
74
+ if(enable) { return [ H_COMMANDS.ENABLE_CLOCK_DIVIDE_BY_FIVE ] }
75
+ return [ H_COMMANDS.DISABLE_CLOCK_DIVIDE_BY_FIVE]
76
+ }
77
+
78
+ static enableThreePhaseClocking(enable = true): Array<number> {
79
+ if(enable) { return [ H_COMMANDS.ENABLE_THREE_PHASE_CLOCKING ] }
80
+ return [ H_COMMANDS.DISABLE_THREE_PHASE_CLOCKING ]
81
+ }
82
+
83
+ static enableAdaptiveClocking(enable = true): Array<number> {
84
+ if(enable) { return [ H_COMMANDS.ENABLE_ADAPTIVE_CLOCKING ] }
85
+ return [ H_COMMANDS.DISABLE_ADAPTIVE_CLOCKING ]
86
+ }
87
+
88
+ static setDriveOnlyZero(pinsLow: number, pinsHigh: number): Array<number> {
89
+ return [
90
+ FT232H_ONLY_COMMANDS.SET_IO_ONLY_DRIVE_LOW,
91
+ pinsLow,
92
+ pinsHigh
93
+ ]
94
+ }
95
+ }
96
+
@@ -0,0 +1,95 @@
1
+ /** biome-ignore-all lint/style/useConsistentArrayType: <explanation> */
2
+ import type { FTDIDevice } from '../ftdi.ts'
3
+ import { Util } from '../util.ts'
4
+ import { BAD_COMMAND, BAD_COMMAND_RESPONSE } from './command.ts'
5
+ import { MPSSETemplate } from './mpsse-template.ts'
6
+
7
+ export class MPSSE {
8
+ readonly #device: FTDIDevice
9
+
10
+ constructor(device: FTDIDevice) {
11
+ this.#device = device
12
+ }
13
+
14
+ async executeCommands(commands: Array<number>|number): Promise<void> {
15
+ const cmdList = Array.isArray(commands) ? commands : [ commands ]
16
+ const flatCmdList = cmdList.flat()
17
+ await this.#device.sendData(Uint8Array.from(flatCmdList))
18
+ }
19
+
20
+ async validateMPSSE(command = BAD_COMMAND): Promise<boolean> {
21
+ await this.executeCommands(command)
22
+ const response = await Util.pollData(this.#device).catch(() => undefined)
23
+
24
+ if(response === undefined) { return false }
25
+ const [ first, second ] = response
26
+ if(first !== BAD_COMMAND_RESPONSE) { return false }
27
+ if(second !== command) { return false }
28
+ return true
29
+ }
30
+
31
+ async setGpioHigh(pins: number, directions: number): Promise<void> {
32
+ const command = MPSSETemplate.gpioSetHigh(pins, directions)
33
+ return this.executeCommands(command)
34
+ }
35
+
36
+ async setGpioLow(pins: number, directions: number): Promise<void> {
37
+ const command = MPSSETemplate.gpioSetLow(pins, directions)
38
+ return this.executeCommands(command)
39
+ }
40
+
41
+ async getGpioHigh(): Promise<void> {
42
+ const command = MPSSETemplate.gpioGetHigh()
43
+ return this.executeCommands(command)
44
+ }
45
+
46
+ async getGpioLow(): Promise<void> {
47
+ const command = MPSSETemplate.gpioGetLow()
48
+ return this.executeCommands(command)
49
+ }
50
+
51
+
52
+ async setClockDivisor(divider: number): Promise<void> {
53
+ const command = MPSSETemplate.setClockDivisor(divider)
54
+ return this.executeCommands(command)
55
+ }
56
+
57
+ // async waitIOHigh(): Promise<void> {s
58
+
59
+ // async waitIOLow(): Promise<void> {
60
+ // }
61
+
62
+ async enableClockDivideBy5(enable = true): Promise<void> {
63
+ const command = MPSSETemplate.enableClockDivideBy5(enable)
64
+ return this.executeCommands(command)
65
+ }
66
+
67
+ async enableThreePhaseClocking(enable = true): Promise<void> {
68
+ const command = MPSSETemplate.enableThreePhaseClocking(enable)
69
+ return this.executeCommands(command)
70
+ }
71
+
72
+ // async clcokWaitIOHigh(): Promise<void> {
73
+ // }
74
+
75
+ // async clockWaitIOLow(): Promise<void> {
76
+ // }
77
+
78
+ async enableAdaptiveClocking(enable = true): Promise<void> {
79
+ const command = MPSSETemplate.enableAdaptiveClocking(enable)
80
+ return this.executeCommands(command)
81
+ }
82
+
83
+ // async clockBitsNoTransferOrUntilHigh(): Promise<void> {
84
+ // }
85
+
86
+ // async clockByteNoTransferOrUntilLow(): Promise<void> {
87
+ // }
88
+
89
+ async setDriveOnlyZero(pinsLow: number, pinsHigh: number): Promise<void> {
90
+ const command = MPSSETemplate.setDriveOnlyZero(pinsLow, pinsHigh)
91
+ return this.executeCommands(command)
92
+ }
93
+ }
94
+
95
+
package/src/status.ts ADDED
@@ -0,0 +1,94 @@
1
+
2
+ export const STATUS_PREFIX_LENGTH = 2
3
+
4
+ export const MODEM_STATUS_CLEAR_TO_SEND = 0x10
5
+ export const MODEM_STATUS_DATA_SET_READY = 0x20
6
+ export const MODEM_STATUS_RING_INDICATOR = 0x40
7
+ export const MODEM_STATUS_DATA_CARRIER_DETECT = 0x80
8
+
9
+
10
+ export const LINE_STATUS_DATA_READY = 0x01
11
+ export const LINE_STATUS_OVERRUN_ERROR = 0x02
12
+ export const LINE_STATUS_PARITY_ERROR = 0x04
13
+ export const LINE_STATUS_FRAMING_ERROR = 0x08
14
+ export const LINE_STATUS_BREAK_INTERRUPT = 0x10
15
+ export const LINE_STATUS_TX_HOLDING_EMPTY = 0x20
16
+ export const LINE_STATUS_TX_EMPTY = 0x40
17
+ export const LINE_STATUS_RECEIVER_ERROR = 0x80
18
+
19
+
20
+ export interface DeviceModemStatus {
21
+ data: number
22
+ isClearToSend: boolean
23
+ isDataSetReady: boolean
24
+ isRing: boolean
25
+ isCarrierDetect: boolean
26
+ }
27
+
28
+ export interface DeviceLineStatus {
29
+ data: number
30
+ isDataReady: boolean
31
+ isOverrunError: boolean
32
+ isParityError: boolean
33
+ isFramingError: boolean
34
+ isInterrupt: boolean
35
+ isTXHoldingEmpty: boolean
36
+ isTXEmpty: boolean
37
+ isReceiverError: boolean
38
+ }
39
+
40
+ export interface DeviceStatusInfo {
41
+ modem: DeviceModemStatus,
42
+ line: DeviceLineStatus
43
+ }
44
+
45
+
46
+ export class DeviceStatus {
47
+ static parse(data: BufferSource): DeviceStatusInfo|undefined {
48
+ const u8 = ArrayBuffer.isView(data) ?
49
+ new Uint8Array(data.buffer, data.byteOffset, STATUS_PREFIX_LENGTH) :
50
+ new Uint16Array(data, 0, STATUS_PREFIX_LENGTH)
51
+
52
+ const [ modemStatus, lineStatus ] = u8
53
+
54
+ if(modemStatus === undefined) { return undefined }
55
+ if(lineStatus === undefined) { return undefined }
56
+
57
+ //
58
+ const isClearToSend = (modemStatus & MODEM_STATUS_CLEAR_TO_SEND) !== 0
59
+ const isDataSetReady = (modemStatus & MODEM_STATUS_DATA_SET_READY) !== 0
60
+ const isRing = (modemStatus & MODEM_STATUS_RING_INDICATOR) !== 0
61
+ const isCarrierDetect = (modemStatus & MODEM_STATUS_DATA_CARRIER_DETECT) !== 0
62
+
63
+ //
64
+ const isDataReady = (lineStatus & LINE_STATUS_DATA_READY) !== 0
65
+ const isOverrunError = (lineStatus & LINE_STATUS_OVERRUN_ERROR) !== 0
66
+ const isParityError = (lineStatus & LINE_STATUS_PARITY_ERROR) !== 0
67
+ const isFramingError = (lineStatus & LINE_STATUS_FRAMING_ERROR) !== 0
68
+ const isInterrupt = (lineStatus & LINE_STATUS_BREAK_INTERRUPT) !== 0
69
+ const isTXHoldingEmpty = (lineStatus & LINE_STATUS_TX_HOLDING_EMPTY) !== 0
70
+ const isTXEmpty = (lineStatus & LINE_STATUS_TX_EMPTY) !== 0
71
+ const isReceiverError = (lineStatus & LINE_STATUS_RECEIVER_ERROR) !== 0
72
+
73
+ return {
74
+ modem: {
75
+ data: modemStatus,
76
+ isClearToSend,
77
+ isDataSetReady,
78
+ isRing,
79
+ isCarrierDetect,
80
+ },
81
+ line: {
82
+ data: lineStatus,
83
+ isDataReady,
84
+ isOverrunError,
85
+ isParityError,
86
+ isFramingError,
87
+ isInterrupt,
88
+ isTXHoldingEmpty,
89
+ isTXEmpty,
90
+ isReceiverError
91
+ }
92
+ }
93
+ }
94
+ }
package/src/util.ts ADDED
@@ -0,0 +1,72 @@
1
+ /** biome-ignore-all lint/performance/noAwaitInLoops: <explanation> */
2
+ /** biome-ignore-all lint/style/useConsistentArrayType: <explanation> */
3
+ import type { FTDIDevice } from "./ftdi.ts"
4
+ import { STATUS_PREFIX_LENGTH } from "./status.ts"
5
+
6
+ export interface ChipInfo {
7
+ major: number
8
+ minor: number
9
+ name: string
10
+
11
+ mpsse?: boolean
12
+ cbus?: boolean
13
+ driveZero?: boolean
14
+
15
+ eepromSize?: number
16
+ }
17
+
18
+ export const USB_MAJOR_TYPE_BM = 4
19
+ export const USB_MAJOR_TYPE_2232C = 5
20
+ export const USB_MAJOR_TYPE_R = 6
21
+ export const USB_MAJOR_TYPE_2232H = 7
22
+ export const USB_MAJOR_TYPE_4232H = 8
23
+ export const USB_MAJOR_TYPE_232H = 9
24
+
25
+ export const CHIP_INFO: Array<ChipInfo> = [
26
+ // FT8U232AM FT8U245AM // AM Series 1st gen
27
+ // FT245BM FT232BL FT232BQ FT245BL // BM Series 2nd gen
28
+ // FT2232C FT2232D
29
+ // FT4222H // Hi-Speed Quad SPI/I2C Bridge
30
+ // FT600Q / FT601Q / FT602Q
31
+ { major: 0x02, minor: 0, name: 'FT232AM' }, // 1st gen
32
+ { major: 0x04, minor: 0, name: 'FT232BM', eepromSize: 64 }, // 2nd gen
33
+ { major: 0x05, minor: 0, name: 'FT2232C', mpsse: true },
34
+ { major: 0x06, minor: 0, name: 'FT232R', eepromSize: 64, cbus: true },
35
+ { major: 0x07, minor: 0, name: 'FT2232H', mpsse: true }, // Dual Channel UART/FIFO/MPSSE
36
+ { major: 0x08, minor: 0, name: 'FT4232H', mpsse: true }, // Quad Channel UART/FIFO/MPSSE
37
+ { major: 0x09, minor: 0, name: 'FT232H', eepromSize: 128, mpsse: true, driveZero: true, cbus: true }, // Single Channel UART/FIFO/MPSSE
38
+ { major: 0x10, minor: 0, name: 'FT-X', cbus: true },
39
+ { major: 0x20, minor: 0, name: 'FT2233HP' }, // Dual Channel Type-C + Power Delivery
40
+ { major: 0x28, minor: 0, name: 'FT2233HP' },
41
+ { major: 0x29, minor: 0, name: 'FT4233HP' }, // Quad Channel Type-C + Power Delivery
42
+ { major: 0x30, minor: 0, name: 'FT2232HP' }, // Dual Channel Type-C + Power Delivery
43
+ { major: 0x31, minor: 0, name: 'FT4232HP', mpsse: true }, // Quad Channel Type-C + Power Delivery
44
+ { major: 0x32, minor: 0, name: 'FT233HP' }, // Single Channel Type-C + Power Delivery
45
+ { major: 0x33, minor: 0, name: 'FT232HP' }, // Single Channel Type-C + Power Delivery
46
+ { major: 0x36, minor: 0, name: 'FT4232HA', mpsse: true }, // Automotive Grade Quad UART
47
+ ]
48
+
49
+
50
+ export const DEFAULT_DATA_READ_SIZE = 64
51
+ export const DEFAULT_MAX_POLL_ATTEMPTS = 5
52
+
53
+ export class Util {
54
+ static chip(major: number, minor: number): ChipInfo | undefined {
55
+ const info = CHIP_INFO.find(ci => ci.major === major && ci.minor === minor)
56
+ if(info === undefined) { return undefined }
57
+ return info
58
+ }
59
+
60
+ static async pollData(device: FTDIDevice, attempts = DEFAULT_MAX_POLL_ATTEMPTS): Promise<Uint8Array<ArrayBuffer>> {
61
+ for(let i = 0; i < attempts; i += 1) {
62
+ const response = await device.readData(DEFAULT_DATA_READ_SIZE)
63
+ if(response.byteLength === STATUS_PREFIX_LENGTH) { continue }
64
+ if(response === undefined) { throw new Error('no response') }
65
+ // const status = DeviceStatus.parse(response)
66
+ // console.log('attempts', i)
67
+ return new Uint8Array(response.buffer, STATUS_PREFIX_LENGTH)
68
+ }
69
+
70
+ throw new Error('no valid data acquired')
71
+ }
72
+ }