Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add notification support for device class USBTMC #2494

Merged
merged 6 commits into from Apr 28, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/class/usbtmc/usbtmc.h
Expand Up @@ -183,6 +183,23 @@ typedef enum {

} usmtmc_request_type_enum;

typedef enum {
// The last and first valid bNotify1 for use by the USBTMC class specification.
USBTMC_bNOTIFY1_USBTMC_FIRST = 0x00,
USBTMC_bNOTIFY1_USBTMC_LAST = 0x3F,

// The last and first valid bNotify1 for use by vendors.
USBTMC_bNOTIFY1_VENDOR_SPECIFIC_FIRST = 0x40,
USBTMC_bNOTIFY1_VENDOR_SPECIFIC_LAST = 0x7F,

// The last and first valid bNotify1 for use by USBTMC subclass specifications.
USBTMC_bNOTIFY1_SUBCLASS_FIRST = 0x80,
USBTMC_bNOTIFY1_SUBCLASS_LAST = 0xFF,

// From the USB488 Subclass Specification, Section 3.4.
USB488_bNOTIFY1_SRQ = 0x81,
} usbtmc_int_in_payload_format;

typedef enum {
USBTMC_STATUS_SUCCESS = 0x01,
USBTMC_STATUS_PENDING = 0x02,
Expand Down Expand Up @@ -303,6 +320,14 @@ typedef struct TU_ATTR_PACKED

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

typedef struct TU_ATTR_PACKED
{
uint8_t bNotify1; // Must be USB488_bNOTIFY1_SRQ
uint8_t StatusByte;
} usbtmc_srq_interrupt_488_t;

TU_VERIFY_STATIC(sizeof(usbtmc_srq_interrupt_488_t) == 2u, "struct wrong length");

typedef struct TU_ATTR_PACKED
{
struct TU_ATTR_PACKED
Expand Down
16 changes: 15 additions & 1 deletion src/class/usbtmc/usbtmc_device.c
Expand Up @@ -240,6 +240,18 @@ bool tud_usbtmc_transmit_dev_msg_data(
return true;
}

bool tud_usbtmc_transmit_notification_data(const void * data, size_t len)
{
#ifndef NDEBUG
TU_ASSERT(len >= 1);
TU_ASSERT(usbtmc_state.ep_int_in != 0);
#endif
if (usbd_edpt_busy(usbtmc_state.rhport, usbtmc_state.ep_int_in)) return false;

TU_VERIFY(usbd_edpt_xfer(usbtmc_state.rhport, usbtmc_state.ep_int_in, (void *)(uintptr_t) data, len));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the failing constness check by casting to uintptr_t, as done in other places.

return true;
}

void usbtmcd_init_cb(void)
{
usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb();
Expand Down Expand Up @@ -578,7 +590,9 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint
}
}
else if (ep_addr == usbtmc_state.ep_int_in) {
// Good?
if (tud_usbtmc_notification_complete_cb) {
TU_VERIFY(tud_usbtmc_notification_complete_cb());
}
return true;
}
return false;
Expand Down
20 changes: 15 additions & 5 deletions src/class/usbtmc/usbtmc_device.h
Expand Up @@ -73,6 +73,10 @@ bool tud_usbtmc_check_abort_bulk_in_cb(usbtmc_check_abort_bulk_rsp_t *rsp);
bool tud_usbtmc_check_abort_bulk_out_cb(usbtmc_check_abort_bulk_rsp_t *rsp);
bool tud_usbtmc_check_clear_cb(usbtmc_get_clear_status_rsp_t *rsp);

// The interrupt-IN endpoint buffer was transmitted to the host. Use
// tud_usbtmc_transmit_notification_data to send another notification.
TU_ATTR_WEAK bool tud_usbtmc_notification_complete_cb(void);

// Indicator pulse should be 0.5 to 1.0 seconds long
TU_ATTR_WEAK bool tud_usbtmc_indicator_pulse_cb(tusb_control_request_t const * msg, uint8_t *tmcResult);

Expand All @@ -93,6 +97,17 @@ bool tud_usbtmc_transmit_dev_msg_data(
const void * data, size_t len,
bool endOfMessage, bool usingTermChar);

// Buffers a notification to be sent to the host. The buffer must be
// valid until the tud_usbtmc_notification_complete_cb callback. The
// data starts with the bNotify1 field, see the USBTMC Specification,
// Table 13.
//
// If the previous notification data has not yet been sent, this
// returns false.
//
// Requires an interrupt endpoint in the interface.
bool tud_usbtmc_transmit_notification_data(const void * data, size_t len);

bool tud_usbtmc_start_bus_read(void);


Expand All @@ -104,9 +119,4 @@ bool usbtmcd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result,
bool usbtmcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
void usbtmcd_init_cb(void);

/************************************************************
* USBTMC Descriptor Templates
*************************************************************/


#endif /* CLASS_USBTMC_USBTMC_DEVICE_H_ */