-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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 usbtmc class driver (READY FOR TESTING) #160
Conversation
case USBTMC_MSGID_VENDOR_SPECIFIC_IN: | ||
case USBTMC_MSGID_USB488_TRIGGER: | ||
default: | ||
TU_VERIFY(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To NAK (stall?), should it TU_VERIFY(false) or return false?
…rts makes sense. Probably adding too many concurance issues; need to figure out semaphores.
neat! ive never heard of this |
@ladyada: Yeah, it's a quite powerful protocol. Most "test instruments" like DMM or oscilloscopes speak it over USB. It's designed to replace GPIB (and have all of its features, where ever possible). I've been wanting to use it it in personal projects for a while, but have not found any complete open-source implementations. My feeling is that each company (Keysight, Tek, LeCroy, etc likely have their own implementations, and these days all of those would be on an embedded Linux or Windows SoC). This USBTMC spec is much more complicated to implement than I had anticipated. My code in this request (at the moment) is a bit too simplistic (and the number of lines will probably double or triple :/). I've finished up implemented the "indicator pulse" LED flash, but the transaction aborts and device clears are needing a lot of planning (due to the asynchronous nature of them). I'm still aiming to have minimal locking, and such. I don't want it to implement its own task, so some locking will be necessary as it can be called both from the USBD core and application code. I also ran into a few implementation problems with my stm32 fsdev driver which I'm also fixing (it didn't properly support endpoints != 64 bytes, and had a typo-bugs, and had 400 B of type conversions going into its flash). Those should be put together into a PR early this week. I'll update this PR in a day or once I figure out how to cope with concurrency and aborting transactions. Some progress (both USBTMC and stm fsdev driver) are my fork. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you very much for yet another great PR. It is never be too soon to submit PR, you can constantly push the new code to update the PR. Even after merged, I did constantly changing the stack all around.
There is only API naming changes to keep thing consistency for now, though I will read some docs and try to get familiar with this class later on. Meanwhile, would you mind give me a bit of instruction on how to test this class: e.g application link, or simple instructions to use those app to test with.
}; | ||
|
||
typedef enum { | ||
USBTMC_bREQUEST_INITIATE_ABORT_BULK_OUT = 1u, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
all UPPER case, you can remove the b
Yes, I'l l do that. Which operating system do you use? The drivers are different for different OS. I can add a simple python script to talk to the device once the drivers are installed. |
@hathach, With the latest changes, I think the class is ready for testing. The main functionality is working well. I'm worried a little bit about concurrency (I added locking for the state machine variable, but it isn't sufficient). I added a python test script to the examples folder, which demonstrates the core functionality and some of the error handling. I'm happy for it to be merged, or sit here in testing for a while. I'm sure that there will be issues that will come up. |
I seem to have forgotten an important feature. The app layer has to be able to signal that it's busy, and have the class driver NAK the bulk-out endpoint. This will require another function for the app layer to call when it's ready. Delay state are not mentioned in the specification, so I think that a NAK is the proper response when the micro's internal buffers are full. |
…id. Assume a single interface, for now.
Having the app control the interface flow control is implemented. Also, I removed references to My python regression testing script is still passing, though only tested with a 64 byte endpoint size on STM32F0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fantastic works on this PR. There is only minor naming convention for the API. If you don't have time, I will merge this first and then rename it later on. Not a big deal at all.
src/class/usbtmc/usbtmc_device.h
Outdated
// * (successful) tud_usbtmc_app_check_abort_bulk_in_cb | ||
// * (successful) usmtmcd_app_bulkOut_clearFeature_cb | ||
|
||
void tud_usbtmc_app_open_cb(uint8_t interface_id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we replace tud_usbtmc_app
by simply tud_usbtmc_
dropping *app in API
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure. I've found it hard to keep track of which functions are for which direction of communication, and keeping app there makes it more clear that certain functions are for implementation by the app, not the class library.
I think other libraries fix this by using structs of function pointers to create a namespace, but the TUSB code at the moment doesn't do that.
I can go either way with this question.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is rather simple, if the API is invoked by the stack and application have to implement that function, it is a callback and must end with _cb()
. Otherwise, it doesn't has _cb()
e.g
tud_cdc_write() : implemented by stack
tud_cdc_rx_cb(): implemented by application
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to change this to be as you suggested.
I usually read left-to-right, so looking for the _cb is less easy, as I need to read left to right to center.
However, there are more levels of complexity....
- app calls class (tud_class_*)
- class calls app (tud_class_*_cb)
- stack calls class (tud_class_* or tud_class_*_cb); // Sometimes with _cb, other times without _cb?
- class calls stack (usbd_*)
Number 1 and 2 and 3 have overlap. This somewhat impacts the app developer since auto-complete will suggest both.
@hathach Would you mind taking a look at the latest changes? They are mostly cosmetic, but I did have some small updates to the testing script, and also changed the get_capabilities method to use a callback function instead of an extern struct. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perfect !!! Thank you very much for putting lots of effort into this PR.
Here is an initial revision of a USBTMC class driver.
It has most of the features I need, but not all of the features that exist in USBTMC. I added some comments on what's lacking in the headers of
src/class/usbtmc/usbtmc_device.c
. It's missing many of the "required" specifications, but is implemented enough to meet most needs.The example application does not have any message/passing or multi-thread capability at the moment. I'm not planning to use a usbtmc task in the example, but I will in my more final project.
I don't intend on this being accepted right away, as I'm likely to create some breaking changes in the interface, but I want to get feedback on what I have now.
Note that it's against the "develop" branch because it requires the class-type EP-recipient patch to work.
This has been tested with NI MAX's visa control panel on Windows 10. Send, receive, query, and read STB all work (or at least with very short messages which won't overflow buffers).
(I fear I'm created this PR too soon; can delete if I'm committing to it too much, or can just start pushing once a day or something. I also understand why I see so many incomplete USBTMC implementations in commercial hardware.)
Some other implementations:
karlp/discotmc
FTDI FT51A
Linux USBTMC host class