Prolific PL2303 driver
Rick Murray (539) 13840 posts |
Hmm, the downside of using USB for ethernet is you can’t listen to streaming radio while unpacking a billion files to a USB stick. There’s just not enough bandwidth. So I’m going to….go do something else. 768 files copied, something like 7900 to go. At least I can just leave this thing running overnight. |
Dave Higton (1515) 3526 posts |
I’ve got some of the easy stuff going in my PL2303 module. |
Ronald May (387) 407 posts |
This is exactly what Thomas Milius’ ComCentre does. Works fine with many USB “SurfSticks”. It hasn’t worked with my alcatel the times I have tried it, Is it based on the cdc atm or perhaps more correctly acm protocol? If so, it might be a recognition issue. The Surfstick may be ethernet packet orientated rather than atm/acm perhaps? Edit: I made a bit of progress, getting the device file made correctly from the setup script comments requires some further explanation, and perhaps Steffen could you convert the remaining Concept.txt to English? I’ve got some of the easy stuff going in my PL2303 module. As in transmit or receive a byte? Does the module work with BASIC or C or perhaps both? Sounds like some progress anyway, Small data like gps would possibly work without the blockdriver style buffers. |
Colin (478) 2433 posts |
Dave Higton said
If you want to go down that route I can send you the backends I have for the CH340, CP201x and PL2303 they should be easily converted into modules. The PL2303 may only be of academic interest as you already have a module. I did find however when testing against Tanks PiSerial module on the pi that it wasn’t as good using the block drivers as it was using the swis directly.
If you have 1 block driver you can give every usb device/interface a port number. You have to cope with multiple devices per module because you may be using 2 identical devices simultaneously. Rick
I don’t look at linux sources when I’m not doing GPL’d code. Netbsd sources look like they’ve just copied blindly from snoopypro and didn’t get me any further. You can change baud rate from 1200 to 115200 with the standard word format which should be ok. I note that all the PL2303 TTL boards I’ve seen only have TX and RX pins. It makes you wonder if they do rts handshaking. |
Rick Murray (539) 13840 posts |
What a pile of poo! So I plugged the serial adaptor into my EeePC and hooked it up to the weather station. Now, it could be a crappy Prolific driver with an equally crappy clone device; or it could be the crappy HeavyWeather that needed to be added to the DEP exclusions list in order to even start. I had about six days worth of data to read. I think I reset my PC more times in the past hour than in my entire time of owning and using Windows machines (and this is counting the W95 era!). I’ll be looking for other options, but my ultimate aim is to run this device on RISC OS, hence my interest in getting the USB serial port to work. I’ve done some research and it looks like the format is 2400, 8N1. The wrinkle is that the weather station does not generate serial (would kill the batteries in no time). What it uses is DTR at negative voltage (low) and RTS at positive voltage (high). They aren’t for flow control, they provide the high and low states, and the weather station switches between them to generate serial data. If this is possible, then I’d be a very happy (easter) bunny! ;-) |
Dave Higton (1515) 3526 posts |
Ronald May said:
Transmit a byte or a block, also set the baud rate.
It’s a relocatable module with a SWI API, so it’s usable from anything that can call SWIs. Additionally I’ve made the API map directly onto the blockdriver API, so that (a) writing a blockdriver should be as easy and free from confusion as possible, and (b) I’m hoping that the blockdriver will be universal if there are more modules that implement the same API. I will of course make a blockdriver available. I’m working on the API documentation. When it’s done, I’ll put it on my web site for comment. Ultimately it probably belongs on the ROOL site, certainly so if I can get the module to work properly and fully so that it’s worth adding to the RISC OS sources. Colin said:
Yes, please! Including the PL2303 one. I’m happy to learn from anyone! |
Rick Murray (539) 13840 posts |
For the avoidance of doubt – this statement refers to the Windows situation that is subsequently described. A potentially buggy application talking to a potentially buggy serial device really shouldn’t get the computer into such a state that it aborts everything and bombs out with the blue screen of infinite tragedy… |
Colin (478) 2433 posts |
Dave Sent. I seem to have the word format settings working now they seem to work similar to the usb.org CDC settings |
Dave Higton (1515) 3526 posts |
Hmm. Serial receive sort of works, but a small proportion of the transfers don’t seem to make it into the receive buffer. I’ve got receive code running on a TickerV handler, so it gets called every 10 ms (mostly). For test, I’m streaming a file in from a Linux box at 9600 baud. Transfers request 64 bytes, and the numbers received are mostly either 9 or 10 bytes. The missing chunks are of about the length of one transfer. It doesn’t seem to make any difference whether I call OS_GBPB 4 on every tick or only when a transfer has succeeded. I am making the assumption that the Linux box transmits everything, of course :-) |
Colin (478) 2433 posts |
If you are using my module I don’t know what you are doing but I can transfer files perfectly between a cp2102 on an armx6 and PL2303 on an iyonix without handshaking at 115200 baud – 9600 is ok too as you would expect. The PL2303 was receiving using the test terminal program I included so nothing fancy. Can you receive the linux data using the included terminal program – or a modification of it if the data isn’t printable? As you are reading the expected 9-10 bytes per csec it seems odd that any would be missed as the chip would buffer more than that. |
Dave Higton (1515) 3526 posts |
I’m using my own module. What worries me most is that none of my code is handling single transactions directly. The USB system is directly hooked up to the Buffer Manager, so the moves of 9 or 10 bytes to the buffer happen automatically. In my test app I take the bytes out one at a time. I am using a build of RO from roughly a year ago. I’ll give your module a whirl later today and compare and contrast. |
Colin (478) 2433 posts |
You could try running IsocUSB. This will softload the latest USB. It’ll save you updating your rom. |
Dave Higton (1515) 3526 posts |
Thanks, Colin. Firstly, updating to your IsocUSB didn’t change the performance of my module. Yours works, and I can’t see any lost bytes, but comparison is very difficult because there is a huge amount of padding with spaces. (I’m streaming the same file in from the Linux box into your !SerialTerminal app.) Is the padding a consequence of the way you convert the data to a BASIC string in FNgetLastSerialPort? |
Colin (478) 2433 posts |
getLastSerialPort just enumerates the devices:$ directory for objects matching “SerialUSB*” and picks the last one it finds. The name it finds is only used to open the endpoint. So if my terminal program is receiving data then getLastSerialPort worked correctly. Data is written to the taskwindow with OS_WriteN. OS_GBPB reads a block of data OS_WriteN writes it. So I take it the received data contains some data then a lot of blanks then some data then a lot of blanks/zeros and so on but the data otherwise seems complete. Are the bursts of data 64 bytes apart? That would imply that the linux machine is sending whole packets and the useful data is at the beginning of the packet. Is it a standard terminal program on linux or is it some special program? If it is a terminal does typing in it cause the typed text to appear properly in my terminal program? |
Colin (478) 2433 posts |
If you are using your linux box because it has a RS232 port you could use your Iyonix to test with instead. If you look in my SerialTerminal Program at line 19 you’ll see
If you set port$ to the port on your Iyonix that you have plugged the device in to then it should work on the iyonix serial ports. |
Dave Higton (1515) 3526 posts |
All results below are in a like for like test with the same session of gtkterm on the Linux box, at 9600 baud (I changed the speed in your serial terminal app; I also added the “nopad” field).
Yes. I laboriously removed the spurious spaces (they are ASCII space, ox20, not NUL) and the results were then identical to the transmitted file.
No. I can’t discern a pattern to the length of the padding. The most odd thing is that they always follow a line feed – they push every line some (variable) distance to the right. I’ve just realised that one contributor is that the file has LF-only line endings, and your terminal doesn’t expand LF to CR+LF. More is dawning… each line starts just below and one space to the right of the previous line. Add line wrap in a fixed width window, and we have an explanation.
I haven’t used the Iyonix in a long time. I got fed up with the time it takes to start up, especially in winter. The BBxM is now my main machine. At some stage I’m going to retrieve the SSD from the Iyonix and sell the latter. I take your point about testing with another machine, but I think we’ve got to the bottom of the extra spaces problem. Now to try to understand why receive into the buffers doesn’t work reliably for me… |
Colin (478) 2433 posts |
Thats a USB device special field and doesn’t do anything in serial device special fields – it would have padded with zeros anyway. Good to hear it’s working properly. I’d try reading > 1 packet size. |
Rick Murray (539) 13840 posts |
The weather station is working more reliably with the Big PC that has a <gasp> real serial port. Seems a fair bit faster too, which is ironic given the serial speed is 2400 baud. Damn, it’s hardly surprising I had a headache yesterday… Please let me know when your serial driver is able to set the control pins. Then I can set about trying to decode this protocol with SerialMon and getting RISC OS to record data and generate the charts. :-) |
Dave Higton (1515) 3526 posts |
I haven’t explained adequately how my code works, and I think you’ve interpreted my description rather differently. When I open each of the bulk endpoints, this is what I do:
For transmission, I simply put the byte or bytes into the buffer using the buffer service routine calls (PRM 5a-216 etc). This results in all the bytes being sent. I don’t need to call OS_GBPB on the USB file handles, so I never see individual USB transactions. This works nicely. I thought the converse of that would work for reception: if the buffer had any bytes in it, collect them. That doesn’t work at all. So the next step was to install a TickerV handler that, if the buffer had a free space of at least 64 bytes, called OS_GBPB 4, with a transfer length of 64 bytes, on the USB file handle for the bulk in endpoint, then go look if bytes appeared in the buffer. Some do, but unfortunately not all of the bytes that were transmitted. When I say I take bytes out one at a time, I mean that my test app is calling my module’s GetByte SWI to attempt to get a single byte – nothing to do with the size of requested USB transactions. From your code, it appears that you don’t use the buffer manager, you just call OS_GBPB 4 and deal with the buffer’s contents yourself. Maybe that’s what I have to do. I’m still curious as to why the buffer manager method works for transmission, but not reliably for reception. Any thoughts? |
David Feugey (2125) 2709 posts |
No Prolofic interfaces can be considered as reliable. |
Ronald May (387) 407 posts |
FYI I notice that there has been driver incompatibilities on other platforms with the 2303X series. |
Colin (478) 2433 posts |
The driver does use the buffer manager it uses it to move data from the USB buffer to the Serial buffer in the upcall handler – SerialUSB is a DeviceFS driver with a DeviceFS back end so there are 2 buffers involved. If you look at device_upcall_handler in module.c you will see, for rx, you need to wake up the device with any large number – I used (1 << 30).
Also if you are using UpCall_RxDataPresent you must empty the buffer every time as you only get the upcall when the buffer transitions from empty to containing data. Emptying the buffer everytime in a UpCall_RxDataPresent upcall is identical to a transfer_complete callback and you get it just before the NetBSD transfer complete function. The call above tells the USB driver how much to read. You have to use the above function every time you empty the buffer otherwise transfers will stop on a short transfer. |
Rick Murray (539) 13840 posts |
Thanks for the update. I’ll fiddle around with my multimeter to see if it works with my adaptor. Oh, and remember that big trough in the air pressure reading I posted yesterday? It’s a minor dip in comparison to what followed. Unfortunately my wind sensor registered a maximum of 22km/h which is ridiculous when a storm had just blown through. I think on a nice day I’ll try unscrewing the anemometer part and soaking it in warm soapy water, as it seems that WD40 alone isn’t enough. Might also take the time to open up the rain gauge and make sure it is clear of spider webs, etc. |
Rick Murray (539) 13840 posts |
Brilliant stuff! RTS / DTR are -6V low, and +6V high. The test program works fine.
|
Steve Pampling (1551) 8170 posts |
Digital multimeter? Edit: Rick is probably au fait with this but handy reference in simple terms – it’s a teaching piece. |