It'll be a long way round but www.electrokit.se has one. It is imported from sparkfun.
The site is in swedish but http://www.electrokit.se/instrument-logikanalysatorer-bus-pirate-plastlada_41004258 is the url for the item. Their site isn't exactly html 4.01 strict so i don't know if it'll pass through tanslate.google.com. As for payment... better learn swedish or guess, it is quite similar to a mix between english and german.
I have implemented usb string descriptors, and there is a iSerial (byte index to string with serial number), and there is a serial string. Currently the serial string is "00000001" in utf-16le as it should be according to the usb standard. The Mass Storage Device (usb-stick) mandates a 12 character hexadecimal serial number, but I haven't found any specs for other devices yet.
Perhaps it is something with the .inf first used installing the device. Also, in my last update there is an extra interface in the device with a dfu descriptor. No software to support it only a "fake" announcement on the devices part. That extra descriptor can possibly confuse windows thinking it haven't seen the device before.
[quote author="ian"] The attached firmware is quite amazing. It instantly reboots my Windows XP machine. [/quote] Ahh, room for some usb fuzzing. I heard there were some security flaws in the windows HID-parser in sp2, but in the enumerator as well is fun.
I've ordered a usbtoy for chistmas to myself and will be able to use that for dev when it arrives, should lessen the burden of those minor changes to get it to run. I also ordered an ols, thinking theres room for a vendor (ie our own) protocol with less overhead and thereby greater bandwith. Found a libusb wrapper for java on sourceforge that could be used for client conduit instead of rxtx. At least one less layer of abstraction.
Good question. I know that in mass storage devices there is a string descriptor with serial number. I havn't considered it with a cdc-acm device, but as I'm experiencing the same symptoms I'll look into it.
[quote author="honken"] Woke up this morning and had an epiphany, I set the wrong receive buffer length on the OUT-endpoints (8 bytes as for EP0 instead of 32 bytes as advertised in the descriptor) that account for the only-echos-8-chars. [/quote] Yes, that was it... also I also declared the rx/tx buffers as 32 bytes while stating in the device descriptor that the maximum endpoint buffer size was 8 bytes. So somewhere all bytes in excess of 8 got lost. But that is fixed now.
[quote author="honken"] About the 20 chars kill I believe the problem is with my "clear to send" test that busy waits. [/quote] No, that wasn't it. Do not actually know what went wrong before. But it works now. See attached image, 33 bytes sent and received a number of times.
I added some of Ian's changes but moved the VID/PID defines to the top of the usb_config.h file. I really like them there and at the top they are more visible. I suppose I should be better at commenting the code if I would want others to be able to use and extend it. It'll be on my TODO list.
I made some refactoring, and turned the stack "the other way around". Mainly to accommodate making it into a on chip lib. Now the App or Class using it is responsible for initializing the stack and there are more access methods.
I found and corrected a handful of portability problems, but I don't expect the stack to run on pic24 yet. The storage qualifiers are still wrong and there need to be a linker script defining the section for the descriptor tables (usb_bdt[] must be mapped correctly). On the pic18 this is solved with pragmas a section definition in the added linker script.
[quote author="ian"] 123456789 only echos 12345678 though, and 20 numbers kills it. [/quote]
Woke up this morning and had an epiphany, I set the wrong receive buffer length on the OUT-endpoints (8 bytes as for EP0 instead of 32 bytes as advertised in the descriptor) that account for the only-echos-8-chars. About the 20 chars kill I believe the problem is with my "clear to send" test that busy waits. Actually it test for ownership of the transmit buffer and not EIA-232 CTS. The ownership is granted the usb subsystem after the first byte and subsequent calls gets halted. When the stack is run from interrupt context I should be able to push a few more bytes into the transmit buffer until the host asks for a IN packet.
The trick is to know for how long it is still safe to to such a thing. Perhaps I could put a "flush out stream" in the start-of-frame interrupt. I'll experiment as soon as I get a little time.
I have only tested the CDC with putty and there every char gets echoed, I'm a slow typist. I suspect that I have to try a terminal with macros to se if I can reproduce and locate the bugs. Is it "Tera Term" you are using?
It should print a lot of debug info on stderr stream, but I don't know where that gets directed by default. On the p18 i set it up to print on UART1, but on p24 there's just a empty macro DINIT() at the end of usb_p24.h
Provided that this macro could be implemented ti redirect stderr to a UART it would be much easier to debug. But I guess I'll have to wait for my copy of the BPv4 to arrive.
But it sounds like I didn't get the usb hardware correctly set up as even the first request (dev descriptor including VID/PID) doesn't get a reply.
Oh, and the VID/PID supplied in the code is just for informational purposes, everyone should supply their own (row 78/79 in usb_config.h and perhaps edit the .inf accordingly)
As for the bootloader placement, Sjaaks arguments sounds reasonable. Still need to protect reset vector though if we want something a little brick-resistant.
The reason for usb code reuse is twofold 1) The code is there and any firmware is probably going to use the USB on a USB device, so why double up. 2) DFU needs a runtime descriptor and to be able to handle a DFU_DETACH request, that switches the device over to DFU mode from runtime mode. So I imagine that the DFU class implementation is closely integrated into the stack and takes control when it receives the DFU_DETACH, kind of like a little rootkit. To make it brick-resistant, my idea is to have a small descriptor setup with a null-device with only the runtime DFU interface descriptor and offer that up to the host if the device is booted with some hardware addon, like the jumper on ICSP on the buspirate. That way any faulty firmware doesn't get touched and the device can be debricked with a "better" firmware. This could also be provisioning a little more lax rules about firmware version and VID/PID/hardware ID checks.
Ok, found the "first char missing" bug. The "Data Toggle Synchronization" bit got off on the wrong foot , first usb packet on that endpoint was sent as Data1. The host then ignored that packet as some unknown error but received the second (and following) packet with correct DTS-bit.
I added workspace/project files for both p18f4550 and p24fj256gb106. The p24 compiles but is untested.
The p18 build runs the stack in interrupt context, so it should be pretty much fire and forget. For the p18 I defined the _user_putc function so if stdout is set to _H_USER ( stdout = _H_USER; ) all stdio functions (printf and friends) should output on usb-serial. If anyone knows how to do the same for input I'd be interested to know about it, but to date I haven't found any getc/getc/scanf functions in the standard library. Also, the same for the C30-libs, if anyone already knows howto do this I don't have to find out for my self. Otherwise there are a couple of functions defined in cdc.h for io, somewhat similar to posix.
Now on to the DFU bootloader. After reading other threads on this board I come to the conclusion that a bootloader at the top of memory is prefered by the community, mainly for the reason that it is possible to implement without a linker script. But for my idea of reusing the bootloader usb code as a library, a linker script is actually needed. Well not exactly, you could send the firmware as relocatable code ( .cof or .elf ) and link it during flashing, but then you add a whole new layer of complexity. So, if there has to be a linker script anyway, is there any preference for top or bottom memory bootloader? What other details come into play?
Is it really a Real-Time (preemptive) OS you need/want for the web platform?
How about contiki (www.sics.se/contiki)? It is Adam Dunkels continuation of protothreads/uIP taken to a whole new level as a cooperative multithreading operating system. Contiki is geard towards wireless sensor networks and there is a whole lot of IPv6 PAN routing protocool development beeing conducted in it right now, but it is supposed to be somewhat "pure" C99 and I've seen multiple ports beeing developed in a short amount of time. There were even a weekend class of porting it to your favorite platform a couple of years ago.
I don't want to steer you away from RTOS, but offer an possibly easier alternative if all you want is some process abstractions.
Found it, when porting I simplified to using memcpy instead of memcpypgm2ram and that meant that the device descriptor replied upon request was all zeros. Apparently memcpy can't read from program memory, at least not when the symbols are a bit ambiguously defined. I had a lot of "suspicious pointer conversion" and "type qualifier mismatch" warnings before.
I changed to a simple loop, but during debugging I also fixed the warnings so now I must see if it will work in the pic24 environment as well.
On a side note. Should I keep posting zip files here or should I get myself a googlecode svn repo? Or pehaps git hub?
Hi all, I finally managed to log a few hours in my underground hacking lair. I have been trying to port my code to the p24fj256gb110 family and now at least the code compiles with MPLAB C30.
But I have no hardware to test it on. I'll see if I can manage someting. I have a bricked pic32 lab kit and I believe the debug prop is something like this target.
I have done no changes to the CDC ACM code, but looking at it I suspect the producer-consumer design pattern, as I've implemented it, must be used in some multithread environment, i.e. interrupt driven usb stack. Actual bugs aside. The basic parts are already in the code, I just have to freshen up on how to set up vectors and such.
As for the length of the serial number, I just read in the Mass Storage Class that those devices must supply a serial number of at least length 12 chars. Any more and only the last 12 are used. The serial must also consist of the chars 0-9 and A-F, i.e. a 48 bit hexadecimal number.
So if we would like to use this for an MSD, we'd better reject my previous suggestion about base-64.
My suggestion for reduction function from the given "random" input to a appropriate sized output digest is either CRC64 which will give us a 16 char serial hex. Because why are we talking about cryptographically strong hashes, when all we want is to distinguish between two or three prototypes of the same kind.
[quote author="rsdio"] To reiterate: I've only ever seen 16-bit Unicode in USB String Descriptors, but it would seem perfectly legal to choose an 8-bit Unicode LANGID such as UTF-8 to save space here. I'm not sure where you came up with 42 bytes unless you were thinking of 16-bit Unicode as the only option. [/quote]
As I have understood, the string is ALWAYS in UTF-16-LE. The LANGID is only to supply a translated version of the string. The device could specify one or more different language IDs in string descriptor 0 (like US English, German and Japanese) and if your on a german OS it could request the string in german.
But I've read elsewhere that the most common OSes (of the Gates flavour) brakes down if there's not 0x0409 (US English) in the string descriptor 0. So much for internationalisation.