blob: 7d7005c2e3645dcb52f4d7f6165368e403bd15c5 [file] [log] [blame]
Austin Schuh41baf202022-01-01 14:33:40 -08001
2/*
3 * The MIT License (MIT)
4 *
5 * Copyright (c) 2019 N Conrad
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 * This file is part of the TinyUSB stack.
26 */
27
28#ifndef _TUSB_USBTMC_H__
29#define _TUSB_USBTMC_H__
30
31#include "common/tusb_common.h"
32
33
34/* Implements USBTMC Revision 1.0, April 14, 2003
35
36 String descriptors must have a "LANGID=0x409"/US English string.
37 Characters must be 0x20 (' ') to 0x7E ('~') ASCII,
38 But MUST not contain: "/:?\*
39 Also must not have leading or trailing space (' ')
40 Device descriptor must state USB version 0x0200 or greater
41
42 If USB488DeviceCapabilites.D2 = 1 (SR1), then there must be a INT endpoint.
43*/
44
45#define USBTMC_VERSION 0x0100
46#define USBTMC_488_VERSION 0x0100
47
48typedef enum {
49 USBTMC_MSGID_DEV_DEP_MSG_OUT = 1u,
50 USBTMC_MSGID_DEV_DEP_MSG_IN = 2u,
51 USBTMC_MSGID_VENDOR_SPECIFIC_MSG_OUT = 126u,
52 USBTMC_MSGID_VENDOR_SPECIFIC_IN = 127u,
53 USBTMC_MSGID_USB488_TRIGGER = 128u,
54} usbtmc_msgid_enum;
55
56/// \brief Message header (For BULK OUT and BULK IN); 4 bytes
57typedef struct TU_ATTR_PACKED
58{
59 uint8_t MsgID ; ///< Message type ID (usbtmc_msgid_enum)
60 uint8_t bTag ; ///< Transfer ID 1<=bTag<=255
61 uint8_t bTagInverse ; ///< Complement of the tag
62 uint8_t _reserved ; ///< Must be 0x00
63} usbtmc_msg_header_t;
64
65typedef struct TU_ATTR_PACKED
66{
67 usbtmc_msg_header_t header;
68 uint8_t data[8];
69} usbtmc_msg_generic_t;
70
71/* Uses on the bulk-out endpoint: */
72// Next 8 bytes are message-specific
73typedef struct TU_ATTR_PACKED {
74 usbtmc_msg_header_t header ; ///< Header
75 uint32_t TransferSize ; ///< Transfer size; LSB first
76 struct TU_ATTR_PACKED
77 {
78 unsigned int EOM : 1 ; ///< EOM set on last byte
79 } bmTransferAttributes;
80 uint8_t _reserved[3];
81} usbtmc_msg_request_dev_dep_out;
82
83TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_out) == 12u, "struct wrong length");
84
85// Next 8 bytes are message-specific
86typedef struct TU_ATTR_PACKED
87{
88 usbtmc_msg_header_t header ; ///< Header
89 uint32_t TransferSize ; ///< Transfer size; LSB first
90 struct TU_ATTR_PACKED
91 {
92 unsigned int TermCharEnabled : 1 ; ///< "The Bulk-IN transfer must terminate on the specified TermChar."; CAPABILITIES must list TermChar
93 } bmTransferAttributes;
94 uint8_t TermChar;
95 uint8_t _reserved[2];
96} usbtmc_msg_request_dev_dep_in;
97
98TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_dev_dep_in) == 12u, "struct wrong length");
99
100/* Bulk-in headers */
101
102typedef struct TU_ATTR_PACKED
103{
104 usbtmc_msg_header_t header;
105 uint32_t TransferSize;
106 struct TU_ATTR_PACKED
107 {
108 uint8_t EOM: 1; ///< Last byte of transfer is the end of the message
109 uint8_t UsingTermChar: 1; ///< Support TermChar && Request.TermCharEnabled && last char in transfer is TermChar
110 } bmTransferAttributes;
111 uint8_t _reserved[3];
112} usbtmc_msg_dev_dep_msg_in_header_t;
113
114TU_VERIFY_STATIC(sizeof(usbtmc_msg_dev_dep_msg_in_header_t) == 12u, "struct wrong length");
115
116/* Unsupported vendor things.... Are these ever used?*/
117
118typedef struct TU_ATTR_PACKED
119{
120 usbtmc_msg_header_t header ; ///< Header
121 uint32_t TransferSize ; ///< Transfer size; LSB first
122 uint8_t _reserved[4];
123} usbtmc_msg_request_vendor_specific_out;
124
125
126TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_out) == 12u, "struct wrong length");
127
128typedef struct TU_ATTR_PACKED
129{
130 usbtmc_msg_header_t header ; ///< Header
131 uint32_t TransferSize ; ///< Transfer size; LSB first
132 uint8_t _reserved[4];
133} usbtmc_msg_request_vendor_specific_in;
134
135TU_VERIFY_STATIC(sizeof(usbtmc_msg_request_vendor_specific_in) == 12u, "struct wrong length");
136
137// Control request type should use tusb_control_request_t
138
139/*
140typedef struct TU_ATTR_PACKED {
141 struct {
142 unsigned int Recipient : 5 ; ///< EOM set on last byte
143 unsigned int Type : 2 ; ///< EOM set on last byte
144 unsigned int DirectionToHost : 1 ; ///< 0 is OUT, 1 is IN
145 } bmRequestType;
146 uint8_t bRequest ; ///< If bmRequestType.Type = Class, see usmtmc_request_type_enum
147 uint16_t wValue ;
148 uint16_t wIndex ;
149 uint16_t wLength ; // Number of bytes in data stage
150} usbtmc_class_specific_control_req;
151
152*/
153// bulk-in protocol errors
154enum {
155 USBTMC_BULK_IN_ERR_INCOMPLETE_HEADER = 1u,
156 USBTMC_BULK_IN_ERR_UNSUPPORTED = 2u,
157 USBTMC_BULK_IN_ERR_BAD_PARAMETER = 3u,
158 USBTMC_BULK_IN_ERR_DATA_TOO_SHORT = 4u,
159 USBTMC_BULK_IN_ERR_DATA_TOO_LONG = 5u,
160};
161// bult-in halt errors
162enum {
163 USBTMC_BULK_IN_ERR = 1u, ///< receives a USBTMC command message that expects a response while a
164 /// Bulk-IN transfer is in progress
165};
166
167typedef enum {
168 USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT = 1u,
169 USBTMC_bREQUEST_CHECK_ABORT_BULK_OUT_STATUS = 2u,
170 USBTMC_bREQUEST_INITIATE_ABORT_BULK_IN = 3u,
171 USBTMC_bREQUEST_CHECK_ABORT_BULK_IN_STATUS = 4u,
172 USBTMC_bREQUEST_INITIATE_CLEAR = 5u,
173 USBTMC_bREQUEST_CHECK_CLEAR_STATUS = 6u,
174 USBTMC_bREQUEST_GET_CAPABILITIES = 7u,
175
176 USBTMC_bREQUEST_INDICATOR_PULSE = 64u, // Optional
177
178 /****** USBTMC 488 *************/
179 USB488_bREQUEST_READ_STATUS_BYTE = 128u,
180 USB488_bREQUEST_REN_CONTROL = 160u,
181 USB488_bREQUEST_GO_TO_LOCAL = 161u,
182 USB488_bREQUEST_LOCAL_LOCKOUT = 162u,
183
184} usmtmc_request_type_enum;
185
186typedef enum {
187 USBTMC_STATUS_SUCCESS = 0x01,
188 USBTMC_STATUS_PENDING = 0x02,
189 USBTMC_STATUS_FAILED = 0x80,
190 USBTMC_STATUS_TRANSFER_NOT_IN_PROGRESS = 0x81,
191 USBTMC_STATUS_SPLIT_NOT_IN_PROGRESS = 0x82,
192 USBTMC_STATUS_SPLIT_IN_PROGRESS = 0x83
193} usbtmc_status_enum;
194
195/************************************************************
196 * Control Responses
197 */
198
199typedef struct TU_ATTR_PACKED {
200 uint8_t USBTMC_status; ///< usbtmc_status_enum
201 uint8_t _reserved;
202 uint16_t bcdUSBTMC; ///< USBTMC_VERSION
203
204 struct TU_ATTR_PACKED
205 {
206 unsigned int listenOnly :1;
207 unsigned int talkOnly :1;
208 unsigned int supportsIndicatorPulse :1;
209 } bmIntfcCapabilities;
210 struct TU_ATTR_PACKED
211 {
212 unsigned int canEndBulkInOnTermChar :1;
213 } bmDevCapabilities;
214 uint8_t _reserved2[6];
215 uint8_t _reserved3[12];
216} usbtmc_response_capabilities_t;
217
218TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_t) == 0x18, "struct wrong length");
219
220typedef struct TU_ATTR_PACKED
221{
222 uint8_t USBTMC_status;
223 struct TU_ATTR_PACKED
224 {
225 unsigned int BulkInFifoBytes :1;
226 } bmClear;
227} usbtmc_get_clear_status_rsp_t;
228
229TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length");
230
231// Used for both abort bulk IN and bulk OUT
232typedef struct TU_ATTR_PACKED
233{
234 uint8_t USBTMC_status;
235 uint8_t bTag;
236} usbtmc_initiate_abort_rsp_t;
237
238TU_VERIFY_STATIC(sizeof(usbtmc_get_clear_status_rsp_t) == 2u, "struct wrong length");
239
240// Used for both check_abort_bulk_in_status and check_abort_bulk_out_status
241typedef struct TU_ATTR_PACKED
242{
243 uint8_t USBTMC_status;
244 struct TU_ATTR_PACKED
245 {
246 unsigned int BulkInFifoBytes : 1; ///< Has queued data or a short packet that is queued
247 } bmAbortBulkIn;
248 uint8_t _reserved[2]; ///< Must be zero
249 uint32_t NBYTES_RXD_TXD;
250} usbtmc_check_abort_bulk_rsp_t;
251
252TU_VERIFY_STATIC(sizeof(usbtmc_check_abort_bulk_rsp_t) == 8u, "struct wrong length");
253
254typedef struct TU_ATTR_PACKED
255{
256 uint8_t USBTMC_status; ///< usbtmc_status_enum
257 uint8_t _reserved;
258 uint16_t bcdUSBTMC; ///< USBTMC_VERSION
259
260 struct TU_ATTR_PACKED
261 {
262 unsigned int listenOnly :1;
263 unsigned int talkOnly :1;
264 unsigned int supportsIndicatorPulse :1;
265 } bmIntfcCapabilities;
266
267 struct TU_ATTR_PACKED
268 {
269 unsigned int canEndBulkInOnTermChar :1;
270 } bmDevCapabilities;
271
272 uint8_t _reserved2[6];
273 uint16_t bcdUSB488;
274
275 struct TU_ATTR_PACKED
276 {
277 unsigned int is488_2 :1;
278 unsigned int supportsREN_GTL_LLO :1;
279 unsigned int supportsTrigger :1;
280 } bmIntfcCapabilities488;
281
282 struct TU_ATTR_PACKED
283 {
284 unsigned int SCPI :1;
285 unsigned int SR1 :1;
286 unsigned int RL1 :1;
287 unsigned int DT1 :1;
288 } bmDevCapabilities488;
289 uint8_t _reserved3[8];
290} usbtmc_response_capabilities_488_t;
291
292TU_VERIFY_STATIC(sizeof(usbtmc_response_capabilities_488_t) == 0x18, "struct wrong length");
293
294typedef struct TU_ATTR_PACKED
295{
296 uint8_t USBTMC_status;
297 uint8_t bTag;
298 uint8_t statusByte;
299} usbtmc_read_stb_rsp_488_t;
300
301TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length");
302
303typedef struct TU_ATTR_PACKED
304{
305 struct TU_ATTR_PACKED
306 {
307 unsigned int bTag : 7;
308 unsigned int one : 1;
309 } bNotify1;
310 uint8_t StatusByte;
311} usbtmc_read_stb_interrupt_488_t;
312
313TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_interrupt_488_t) == 2u, "struct wrong length");
314
315#endif
316