This repository was archived by the owner on Mar 7, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 845
Expand file tree
/
Copy pathftdi.c
More file actions
181 lines (155 loc) · 4.65 KB
/
ftdi.c
File metadata and controls
181 lines (155 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/*
* This file is part of the Black Magic Debug project.
*
* Copyright (C) 2023 1BitSquared <info@1bitsquared.com>
* Written by Sid Price <sid@sidprice.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "general.h"
#include "ftdi.h"
#include "ftd2xx.h"
#include "bmp_hosted.h"
FT_HANDLE ftdi_handle;
/*
* The following structure is mocked by this module. FTD2XX
* does not provide a similar structure.
*
* Values mocked:
* ftdi_ctx.type - The type of FTDI chip in the adapter
*/
/* Used to fake the libusb context and pass required parameters back to the caller */
static ftdi_context_s ftdi_ctx = {0};
/*
* This array is used to map FTD2XX device type identifiers
* to libftdi identifiers. The array is ordered by the FTD2XX
* values, with the array entries being the libftdi values
*/
static const int ftdi_chip_types[] = {
TYPE_AM,
TYPE_BM,
-1, // FT_DEVICE_100AX not supported
-2, // Unknown type
TYPE_2232C,
TYPE_R,
TYPE_2232H,
TYPE_4232H,
TYPE_232H,
TYPE_230X,
};
static const size_t number_of_ftdi_chip_types = ARRAY_LENGTH(ftdi_chip_types);
#define READ_TIMEOUT 500 // Expressed in milliseconds
#define WRITE_TIMEOUT 500
struct ftdi_context *ftdi_new(void)
{
return &ftdi_ctx; // Just need to fake the structure being created
}
int ftdi_set_interface(ftdi_context_s *ftdi, enum ftdi_interface interface)
{
(void)ftdi;
/*
* FTD2XX needs a qualified serial number to open the correct device. Append
* an interface letter to the serial number by adding the number to 'A'
*/
char serial_number[16] = {0};
strcpy(serial_number, bmda_probe_info.serial);
serial_number[strlen(serial_number)] = 'A' + (interface - 1);
if (FT_OpenEx(serial_number, FT_OPEN_BY_SERIAL_NUMBER, &ftdi_handle) != FT_OK ||
FT_SetTimeouts(ftdi_handle, READ_TIMEOUT, WRITE_TIMEOUT) != FT_OK)
return 0;
FT_DEVICE device;
DWORD device_id = 0;
char description[64] = {'\0'};
if (FT_GetDeviceInfo(ftdi_handle, &device, &device_id, serial_number, description, NULL) != FT_OK)
return 0;
const size_t device_type_index = device;
if (device_type_index < number_of_ftdi_chip_types)
ftdi_ctx.type = ftdi_chip_types[device_type_index];
return 0;
}
int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product, const char *description, const char *serial)
{
(void)ftdi;
(void)vendor;
(void)product;
(void)description;
(void)serial;
return 0;
}
int ftdi_usb_close(struct ftdi_context *ftdi)
{
(void)ftdi;
if (FT_Close(ftdi_handle) != FT_OK)
return -1;
return 0;
}
void ftdi_free(struct ftdi_context *ftdi)
{
(void)ftdi;
}
int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate)
{
(void)ftdi;
return FT_SetBaudRate(ftdi_handle, baudrate) != FT_OK;
}
int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency)
{
(void)ftdi;
return FT_SetLatencyTimer(ftdi_handle, latency) != FT_OK;
}
int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode)
{
(void)ftdi;
return FT_SetBitMode(ftdi_handle, bitmask, mode) != FT_OK;
}
int ftdi_usb_purge_buffers(struct ftdi_context *ftdi)
{
(void)ftdi;
return FT_Purge(ftdi_handle, FT_PURGE_RX | FT_PURGE_TX) != FT_OK;
}
int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, const int size)
{
(void)ftdi;
DWORD bytes_read = 0;
if (FT_Read(ftdi_handle, buf, (DWORD)size, &bytes_read) == FT_OK && bytes_read != (DWORD)size)
return 0; // Signal read timeout
return bytes_read;
}
int ftdi_write_data(struct ftdi_context *ftdi, const unsigned char *buf, int size)
{
(void)ftdi;
DWORD bytes_written;
unsigned char *temp_buf = (unsigned char *)malloc(size);
if (temp_buf == NULL) {
return 0;
}
memcpy(temp_buf, buf, size);
if (FT_Write(ftdi_handle, temp_buf, size, &bytes_written) != FT_OK) {
free(temp_buf);
return 0;
}
free(temp_buf);
return bytes_written;
}
int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize)
{
(void)ftdi;
(void)chunksize;
return 0;
}
const char *ftdi_get_error_string(struct ftdi_context *ftdi)
{
(void)ftdi;
return "Error in ftdi.c (Windows)";
}