usb-otg? #6157
Replies: 1 comment
-
Posted at 2019-04-02 by @gfwilliams I'm afraid it would involve some pretty major software changes to Espruino to get it to work. On the hardware side, the 5th pin on Micro USB isn't brought out anywhere, and to do it properly you need some power switching arrangement as well to supply power to the client device. Basically doing it that way would be really difficult. However, this has been asked a few times before, and there's a chip that will handle USB Host for you called the MAX3420/MAX3421: http://forum.espruino.com/conversations/284427/ It's available on a board with everything you need from a few places. A quick search on eBay for There's no code for it for Espruino as far as I know, but the example code looks like it would be trivial to port over and I'd be happy to help if you have any questions about it. Posted at 2019-04-03 by CWBudde1 I have order a device. Once it arrives, I will see how far I come. Posted at 2019-04-04 by @gfwilliams Great! It'll be amazing if we can get this working in Espruino - it opens up a lot of possibilities, especially as it should work on all platforms. Posted at 2019-04-11 by CWBudde1 I have just received a small device containing a MAX3421E chip. Now let the fun begin... Posted at 2019-04-12 by @MaBecker cool, just did a quick search: Posted at 2019-04-14 by CWBudde1 There's also an original repository from the board I am using. It comes in 3 versions, but v1 library looks good enough for the start: https://github.com/felis/ArduinoUSBhost/ The authors homepage also contains a good manual: https://www.circuitsathome.com/usb-host-shield-hardware-manual/ Everything else can be read in the original chip specification: https://pdfserv.maximintegrated.com/en/an/AN3785.pdf I have already started to get into it, but it seems I can't establish the SPI connection. I'm sure that I have wired everything correctly (tried both with SPI1 and SPI2), but whatever I send, I will always get back a 255 so far. Does this maybe ring a bell for someone? If not, I'll try to connect my oscilloscope tomorow to debug it further. Posted at 2019-04-14 by CWBudde1 A long sleep did help to find out that I did not connected everything correctly. The cheap board from china had one label printed one pin too far to the left. Eventually I even bricket that board, but that needs to be tested. Posted at 2019-04-14 by CWBudde1 I guess the board is really dead as there is no change on the MISO pin regardless what I do. It's always HIGH. I'm not sure what the wrong pin did, but maybe the second board I ordered will work. Hopefully it will arrive soon as I'm now into it. Posted at 2019-04-14 by CWBudde1 Luckily, the device wasn't dead an thus I was finally able to make it work now. I have created a pull request to get the basic header translation for the MAX3421 ready. It's not much useful so far, as the USB enumeration and such still has to be done from external code, but at least it is now easier to get started. Posted at 2019-04-15 by @gfwilliams That's great - thanks! I'll leave off merging your pull request (espruino/EspruinoDocs#502) for a few days though as it seems like it's possible you or someone else might actually be able to get it communicating with a simple peripheral like a keyboard pretty soon? Posted at 2019-04-15 by CWBudde1 A wise decision. While the MAX3421E module is mostly working, it is mostly not just more than this. This means that it doesn't do much USB handling on its own so far. And for this reason it's yet untested (as there isn't much outer code available so far). The original author and developer of the breakout board has decided to split the code into some files for accessing the MAX3421E chip on the one hand and files for USB handling on the other side. To me, this makes sens as it allows to create independent USB access solutions. As far as I have seen they can range from simple to complex and think it doesn't make sense the add more overhead than necessary. So in my opinion, it would make sense to have this small MAX3421E module as base and several other libraries (separated by purpose) on top of it. For the moment, some example code would probably be satisfying. Something that could later be expanded to a module. However, I fear, that even a simple device such as a keyboard, might at least introduce quite some more basic code, as all the USB enumeration and accessing needs to be done. It's in the range of about 2-3 days of work, but personally, I can not make it this week. So you probably want to keep it open a bit longer, maybe. Posted at 2019-04-15 by @gfwilliams Thanks! The separate module makes a lot of sense. I guess maybe any common bits of USB handshaking could be put in the main module, but yeah, it seems a lot more sensible to have keyboard/mass storage/etc modules. Who knows, maybe later on they could be used with other USB host interfaces :) I'm not 100% sure on this but I believe keyboards have a 'boot mode', or at the very least most of them use a very similar packet format. You may find there's very little code needed to actually get something working if you try those first. ... I don't have time at the moment, if/when I do then I'd love to build on what you've got there and try and get it supporting some other peripheral types. Posted at 2019-04-15 by CWBudde1 I already connected an old keyboard to my test setup, but didn't found the time so far to go further than that. In fact - as you mentioned - some basic module for USB Host handling could be written easily. From there it should be fairly easy to get some keyboard demo working. There are just a few questions left from my side: Can I require another module from within a module? I have found something like that in the touchscreen example, but I'm not aware issues with this approach. The touchscreen example implicitly pre-connects the ADS7843. Rather than this, I'd like to have something like passing an interface to the usb-host module. The code should look something like:
in the end. Within the module I would need a way to determin what module has been passed. If it is of type max3421 it use this internally. This would have the advantage to write the code of USBHost as independend and reusable as possible. Alternatively, I could write a module named USBHostMax3421, which kind of inherits from Max3421. The initialization would look like this then:
This is probably easier in the beginning, but less flexible in the long run. Also I'm not sure how to handle interupts and gpio querries. The original arduino code uses a loop to check periodically for 'tasks'. With Espruino this translates to watches, doesn't it? If I use them, are there known issues in regards of the use in modules? And one last question. The original code uses delays at some point to wait that some capacitors are fully loaded. So far I have translated the code directly using some time burning hack. While the time is very little (60ms), I'd like to get rid of this. Now I wonder whether there are better alternatives? The only alternative that comes to my mind is using callbacks like:
but that bloats the caller code and requires some more handling on that part. Or should I use promises? While they look very smart, I tend not to use them in my web projects, because they used to be not fully supported by some browsers. Posted at 2019-04-15 by @gfwilliams
You can, yes - but if you require multiple modules then multiple ones will be included, which probably isn't what you want.
This is probably what you want... If it's an issue it could always be shortened to
Yes,
For 60ms I'd say setTimeout and callbacks would be preferable (I really try not to use hard delays for anything more than a few milliseconds). I tend to use However promises might be good. They're fine on Espruino and while they might be overkill for the 60ms delay, you may find they actually save you loads of time and effort when you're looking at doing the actual USB negotiation stuff - and if you use them for everything the the API it'll make it seem much cleaner. Posted at 2019-04-19 by CWBudde1 Today I have advanced the development, but I guess I'm running out of memory. At least if I want to write the library very clearly (that is with meaningful variable names and constants). In particular the constants seem to eat a lot of memory, but if I do it without, I probably loose track pretty soon as the USB specification isn't really trivial. It would help if there is a way that the minification could replace constants by its value. So that "C.USB_SETUP_RECIPIENT_INTERFACE" would become "1" (its value). In the end these names would be necessary as the user would need this as well in order to customize the code for dedicated USB devices. What I have done so far is to start initializing the device and querying some basic device properties (description). Still very basic, but some constant progress. I think I can gain some memory, by switching from the original espruino to the pico, but that would only solve it for the moment. Posted at 2019-04-19 by Robin Thu 2019.04.18 Does this article get over that obstacle? In case there isn't a Pico lying around. . . .
Posted at 2019-04-19 by CWBudde1 I think the problem is that I need it for development. Quote:
As this is work in progress, I currently need to test it often. To get around the issue for the end-users I think I need to break the developed modules down in the end. This will certainly break the modular in favor of something like a "max3421UsbHostHID" or "max3421UsbHostStorage" or whatever is needed. Then I can remove unused constants and/or us the constant values directly. The user will have less options to get their hands on the USB protocol, but at least they can use the devices (otherwise they might run out of memory just for connecting the external USB device). In my case I would also need to have some code on top which takes care of processing the data I retrieved over USB. Posted at 2019-04-19 by Robin Fri 2019.04.19 @CWBudde1, I don't have an Original lying around to check available memory, but did the Pico output #17 provide any hopeful outcome? Posted at 2019-04-19 by CWBudde1 The original espruinio only has a total of 2240 variables
whereas the pico has 5100. While I own 5 Picos, all except one are in use currently. And the one not in use does not have the right headers (pins vs. sockets) to connect it straight forward. I either have to solder new headers or get new connecting cables. And/or rework the code so that it can live with what it offers. I also have a ESP32 dev board somewhere, but I do not have much experience with ESP32. There might be other issues. Posted at 2019-04-19 by CWBudde1 After some refactoring and with the "direct to flash" option, I do now have enough ram available to keep going. And if not I can still switch to the pico... Posted at 2019-04-19 by @MaBecker Have you tried activate compilation_level = ADVANCED_OPTIMIZATIONS by and than run
Posted at 2019-04-19 by @MaBecker Or start with
for Posted at 2019-04-20 by @gfwilliams Hmm - when minifying, One thing that would stop it is if you exported
The Posted at 2019-06-04 by @gniezen I managed to get the MAX3421E chip working with the Pixl.js last year and have it talk to a device with a CP2102 chip. When I came across this thread today I was finally motivated enough to write it up and post the source code. Hope it helps! |
Beta Was this translation helpful? Give feedback.
-
Posted at 2019-04-02 by CWBudde1
What is needed to support USB-OTG with the Espruino?
Background: I have a device with an USB-OTG interface. If connected with the computer it act as slave. I can open a (serial) console and send a short command (string).
Now, I would like this to happen from an Espruino powered device (can be any board).
I figured out that the cable decides who takes the initial host role by a 5th pin. Beyond that the role can be changed from software as well.
While I don't need the latter, I just want any working combination so that I can send out a string over usb (just like as it was connected by a console).
Would it just work to prepare a cable to set the initial host/slave role to make the Espruino be slave? And what is needed to make the Espruino be the host (if possible at all)? Do I have acces to the additional 5th ID wire (actualy it's the 4th wire, labeled USB_ID in the schematics)?
Beta Was this translation helpful? Give feedback.
All reactions