Skip to content

Commit 1c04d59

Browse files
authored
Merge pull request #2494 from tommie/usbtmcnotif
Add notification support for device class USBTMC
2 parents ee00862 + bd033a2 commit 1c04d59

File tree

4 files changed

+72
-17
lines changed

4 files changed

+72
-17
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ hw/mcu/st/cmsis_device_f4
5757
hw/mcu/st/cmsis_device_f7
5858
hw/mcu/st/cmsis_device_g0
5959
hw/mcu/st/cmsis_device_g4
60+
hw/mcu/st/cmsis_device_h5
6061
hw/mcu/st/cmsis_device_h7
6162
hw/mcu/st/cmsis_device_l0
6263
hw/mcu/st/cmsis_device_l1
@@ -72,6 +73,7 @@ hw/mcu/st/stm32f4xx_hal_driver
7273
hw/mcu/st/stm32f7xx_hal_driver
7374
hw/mcu/st/stm32g0xx_hal_driver
7475
hw/mcu/st/stm32g4xx_hal_driver
76+
hw/mcu/st/stm32h5xx_hal_driver
7577
hw/mcu/st/stm32h7xx_hal_driver
7678
hw/mcu/st/stm32l0xx_hal_driver
7779
hw/mcu/st/stm32l1xx_hal_driver

src/class/usbtmc/usbtmc.h

+25
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,23 @@ typedef enum {
183183

184184
} usmtmc_request_type_enum;
185185

186+
typedef enum {
187+
// The last and first valid bNotify1 for use by the USBTMC class specification.
188+
USBTMC_bNOTIFY1_USBTMC_FIRST = 0x00,
189+
USBTMC_bNOTIFY1_USBTMC_LAST = 0x3F,
190+
191+
// The last and first valid bNotify1 for use by vendors.
192+
USBTMC_bNOTIFY1_VENDOR_SPECIFIC_FIRST = 0x40,
193+
USBTMC_bNOTIFY1_VENDOR_SPECIFIC_LAST = 0x7F,
194+
195+
// The last and first valid bNotify1 for use by USBTMC subclass specifications.
196+
USBTMC_bNOTIFY1_SUBCLASS_FIRST = 0x80,
197+
USBTMC_bNOTIFY1_SUBCLASS_LAST = 0xFF,
198+
199+
// From the USB488 Subclass Specification, Section 3.4.
200+
USB488_bNOTIFY1_SRQ = 0x81,
201+
} usbtmc_int_in_payload_format;
202+
186203
typedef enum {
187204
USBTMC_STATUS_SUCCESS = 0x01,
188205
USBTMC_STATUS_PENDING = 0x02,
@@ -303,6 +320,14 @@ typedef struct TU_ATTR_PACKED
303320

304321
TU_VERIFY_STATIC(sizeof(usbtmc_read_stb_rsp_488_t) == 3u, "struct wrong length");
305322

323+
typedef struct TU_ATTR_PACKED
324+
{
325+
uint8_t bNotify1; // Must be USB488_bNOTIFY1_SRQ
326+
uint8_t StatusByte;
327+
} usbtmc_srq_interrupt_488_t;
328+
329+
TU_VERIFY_STATIC(sizeof(usbtmc_srq_interrupt_488_t) == 2u, "struct wrong length");
330+
306331
typedef struct TU_ATTR_PACKED
307332
{
308333
struct TU_ATTR_PACKED

src/class/usbtmc/usbtmc_device.c

+28-5
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,11 @@ tu_static char logMsg[150];
8686
// imposes a minimum buffer size of 32 bytes.
8787
#define USBTMCD_BUFFER_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
8888

89+
// Interrupt endpoint buffer size, default to 2 bytes as USB488 specification.
90+
#ifndef CFG_TUD_USBTMC_INT_EP_SIZE
91+
#define CFG_TUD_USBTMC_INT_EP_SIZE 2
92+
#endif
93+
8994
/*
9095
* The state machine does not allow simultaneous reading and writing. This is
9196
* consistent with USBTMC.
@@ -124,13 +129,15 @@ typedef struct
124129
uint8_t ep_bulk_in;
125130
uint8_t ep_bulk_out;
126131
uint8_t ep_int_in;
132+
uint32_t ep_bulk_in_wMaxPacketSize;
133+
uint32_t ep_bulk_out_wMaxPacketSize;
127134
// IN buffer is only used for first packet, not the remainder
128135
// in order to deal with prepending header
129136
CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_in_buf[USBTMCD_BUFFER_SIZE];
130-
uint32_t ep_bulk_in_wMaxPacketSize;
131137
// OUT buffer receives one packet at a time
132138
CFG_TUSB_MEM_ALIGN uint8_t ep_bulk_out_buf[USBTMCD_BUFFER_SIZE];
133-
uint32_t ep_bulk_out_wMaxPacketSize;
139+
// Buffer int msg to ensure alignment and placement correctness
140+
CFG_TUSB_MEM_ALIGN uint8_t ep_int_in_buf[CFG_TUD_USBTMC_INT_EP_SIZE];
134141

135142
uint32_t transfer_size_remaining; // also used for requested length for bulk IN.
136143
uint32_t transfer_size_sent; // To keep track of data bytes that have been queued in FIFO (not header bytes)
@@ -240,6 +247,19 @@ bool tud_usbtmc_transmit_dev_msg_data(
240247
return true;
241248
}
242249

250+
bool tud_usbtmc_transmit_notification_data(const void * data, size_t len)
251+
{
252+
#ifndef NDEBUG
253+
TU_ASSERT(len > 0);
254+
TU_ASSERT(usbtmc_state.ep_int_in != 0);
255+
#endif
256+
TU_VERIFY(usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in));
257+
258+
TU_VERIFY(tu_memcpy_s(usbtmc_state.ep_int_in_buf, sizeof(usbtmc_state.ep_int_in_buf), data, len) == 0);
259+
TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, usbtmc_state.ep_int_in_buf, (uint16_t)len));
260+
return true;
261+
}
262+
243263
void usbtmcd_init_cb(void)
244264
{
245265
usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb();
@@ -547,9 +567,10 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
547567
case STATE_TX_INITIATED:
548568
if(usbtmc_state.transfer_size_remaining >= sizeof(usbtmc_state.ep_bulk_in_buf))
549569
{
550-
// FIXME! This removes const below!
570+
// Copy buffer to ensure alignment correctness
571+
memcpy(usbtmc_state.ep_bulk_in_buf, usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf));
551572
TU_VERIFY( usbd_edpt_xfer(rhport, usbtmc_state.ep_bulk_in,
552-
(void*)(uintptr_t) usbtmc_state.devInBuffer, sizeof(usbtmc_state.ep_bulk_in_buf)));
573+
usbtmc_state.ep_bulk_in_buf, sizeof(usbtmc_state.ep_bulk_in_buf)));
553574
usbtmc_state.devInBuffer += sizeof(usbtmc_state.ep_bulk_in_buf);
554575
usbtmc_state.transfer_size_remaining -= sizeof(usbtmc_state.ep_bulk_in_buf);
555576
usbtmc_state.transfer_size_sent += sizeof(usbtmc_state.ep_bulk_in_buf);
@@ -585,7 +606,9 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
585606
}
586607
}
587608
else if (ep_addr == usbtmc_state.ep_int_in) {
588-
// Good?
609+
if (tud_usbtmc_notification_complete_cb) {
610+
TU_VERIFY(tud_usbtmc_notification_complete_cb());
611+
}
589612
return true;
590613
}
591614
return false;

src/class/usbtmc/usbtmc_device.h

+17-12
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp);
7373
bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp);
7474
bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp);
7575

76+
// The interrupt-IN endpoint buffer was transmitted to the host. Use
77+
// tud_usbtmc_transmit_notification_data to send another notification.
78+
TU_ATTR_WEAK bool tud_usbtmc_notification_complete_cb(void);
79+
7680
// Indicator pulse should be 0.5 to 1.0 seconds long
7781
TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult);
7882

@@ -82,17 +86,23 @@ TU_ATTR_WEAK bool tud_usbtmc_msg_trigger_cb(usbtmc_msg_generic_t* msg);
8286
//TU_ATTR_WEAK bool tud_usbtmc_app_go_to_local_cb();
8387
#endif
8488

85-
/*******************************************
86-
* Called from app
87-
*
88-
* We keep a reference to the buffer, so it MUST not change until the app is
89-
* notified that the transfer is complete.
90-
******************************************/
91-
89+
// Called from app
90+
//
91+
// We keep a reference to the buffer, so it MUST not change until the app is
92+
// notified that the transfer is complete.
9293
bool tud_usbtmc_transmit_dev_msg_data(
9394
const void * data, size_t len,
9495
bool endOfMessage, bool usingTermChar);
9596

97+
// Buffers a notification to be sent to the host. The data starts
98+
// with the bNotify1 field, see the USBTMC Specification, Table 13.
99+
//
100+
// If the previous notification data has not yet been sent, this
101+
// returns false.
102+
//
103+
// Requires an interrupt endpoint in the interface.
104+
bool tud_usbtmc_transmit_notification_data(const void * data, size_t len);
105+
96106
bool tud_usbtmc_start_bus_read(void);
97107

98108

@@ -105,9 +115,4 @@ void usbtmcd_reset_cb(uint8_t rhport);
105115
bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
106116
bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
107117

108-
/************************************************************
109-
* USBTMC Descriptor Templates
110-
*************************************************************/
111-
112-
113118
#endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */

0 commit comments

Comments
 (0)