Multiple port serial driver
Timmoore
Posts: 1,031
This may be of interest if you run multiple serial ports. I have a version of fullduplexserial that supports multiple ports. The code supports 4 but I have only tested up to 3 so far. The package also contains my demo app. It runs debug port at 115200, a gps at 38400 and cmu3 camera at 116500 using 1 cog for the serial port. The package also contains modified gps object and cmucam object that using this serial port object. Those objects have also been modified to share a cog for their reading rather than having a cog each. The orginal version of this demo need 6 cogs - main, gps reader, camera reader and 3 serial ports. This version uses 3 cogs - main, gps/camera reader and 1 cog for all the serial ports.
Edit: Update the object to support CTS/RTS flow control
Edit:Fixed bug not accepting receive chars with 1 port enabled. Fixed bug with rts on ports 0,2,3
Tim
Post Edited (Timmoore) : 7/2/2008 3:18:40 AM GMT
Edit: Update the object to support CTS/RTS flow control
Edit:Fixed bug not accepting receive chars with 1 port enabled. Fixed bug with rts on ports 0,2,3
Tim
Post Edited (Timmoore) : 7/2/2008 3:18:40 AM GMT
Comments
Edit: I need to try it out but thinking about it I believe I can add flow control without affecting the non-flow control paths too much.
With flow control disabled it will drop the max baudrate about 3% which means for 3 ports it should still support 115200 baud which is what I need.
With flow control enabled its much slower probably around 25% slower, if you want 115200 you probably can only run 2 ports. So the question is what baudrate do you need your flow controlled port to run at?
Post Edited (Timmoore) : 6/13/2008 9:09:36 PM GMT
Thanks!
Wow, this is amazing Timmoore, I love you for this, I am going to have to do some redesigning to accommodate the fact I wont have to use 5 cogs on the prop just to run serial ports! If you have good luck with the CTS/RTS let me know, I had to put some logic before every sendstring to see if the CTS was ready before I did a sendstring and I just left RTS high and it seemed to work, just have to be super careful about long string.
Edit: CTS is an input, it will stop the driver transmitting. Normal is high and will·tx, low stops tx. mode can be used to invert the pin.
RTS is an output, when the rx buffer gets to a threshold. Default threshold is 48 bytes (buffer is 64bytes). Pin is high when can receive, low when buffer > threshold. Again mode can invert. AddPort has a parameter to set threshold if needed (0 means use default threshold).
Post Edited (Timmoore) : 6/16/2008 7:13:58 AM GMT
Transmit works fine, and receive works if I use FullDuplexSerial instead so I think my hardware is OK.
But I don't ever get a character received.
I've simplified my test code as far as possible : currently I have this (cut down from gpstest):
con
_clkmode = xtal1 + pll16x '
_xinfreq = 5_000_000 '
obj
uarts : "pcFullDuplexSerial4FC" '1 COG for 4 serial ports
var
pub main | time
waitcnt(clkfreq*3 + cnt)
uarts.Init 'Restart serial ports to change baudrate
uarts.AddPort(0,31,30,UARTS#PINNOTUSED,UARTS#PINNOTUSED,UARTS#DEFAULTTHRESHOLD, {
} UARTS#NOMODE,UARTS#BAUD115200) 'Add debug port
uarts.Start 'Start the ports
uarts.str(0, string("Start "))
time := cnt + clkfreq*2
repeat
if time < cnt
time := cnt + clkfreq*2
uarts.str(0, string("in "))
uarts.dec(0, uarts.rx(0))
uarts.newline(0)
I've now wired up another port (pins 0 & 1). If I call that port 1, it still doesn't receive.
However, if I create a port 0 on pins 30 & 31, port 1 (pins 0 & 1) will then work but port 0 still won't receive.
And I can swap those over (port 0 on 0&1, port 1 on 30,31) and port 1 still works.
It seems that just the first port used doesn't receive.
Hope this helps.
-adrian
Post Edited (agodwin) : 7/1/2008 9:44:17 AM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
This is a really useful bit of code !
I'm looking at possibly porting this to C, but I'm running tight on memory. Having a version without flow control support would save some space. I'm probably going to strip it to only contain either two, possibly three of the ports (haven't decided yet) which will also cut down on code space.
I should probably have started with, has anyone ported this to Prop C yet?
Jason
There are options with fewer features. I'll add links as I find them.
Here's a related thread. I don't think it has any of the simplified drivers in it. I haven't found the thread I'm looking for yet.
ksltd posted his single port and four port serial drivers in this thread. These are the simplified versions I referred to earlier.
In this version I changed the pasm initialization code for the port rx and tx coroutine vectors and believe it is much more efficient at short-circuiting unused coroutines.
revised version, please see 6 posts down.
I can run sample programs and all work for text, but I don't seem to be able to send null $00.
Is this a bug or just me?
Thanks; GWKAUB
StrN(port,pointer,byteCount)
or
Packet(port, bytePointer, byteCount)
For longer packets, the latter can be much faster than the StrN loop that repeats the method tx(port,byte). The Packet method, adapted from kltsd's serial object, uses bytemoves to get data into the serial buffer.
J