Problems with pcFullDuplexSerial4FC using port 0 as Debug Terminal
Steve Lindeng
Posts: 6
Tim, if you're out there, HELP!
Seriously though, this is probably a simple problem of not understanding the object and what's passed.· I have an application where I'd like to use debug terminal to confirm the instructions and data are passed properly before I 'blindly' set the data stream.
Eventually, I will have two UART peripherals attached to the propeller - one uses #RTS/#CTS (RTS and CTS low handshake) for flow control and another with no flow control.· Looking at the pcFullDuplexSerial4FC, I see that I can invert RTS or invert CTS, but it combining the code for invert RTS and Invert CTS does not appear to be supported:
······· if_nz·········· xor···· start0,doifc2ifnc···· 'if_c jmp to if_nc
····················································· 'patch tx routine depending on whether cts is used
····················································· 'and if it is inverted
······················· or····· ctsmask,#0···· wz···· 'cts pin? z not set if in use
······· if_nz·········· test··· rxtx_mode,#INVERTCTS wc 'c set if inverted
······· if_nz_and_nc··· or····· ctsi0,doif_z_or_nc··· 'if_nc jmp
······· if_nz_and_c···· or····· ctsi0,doif_z_or_c···· 'if_c jmp
······· if_z··········· mov···· txcts0,transmit······ 'copy the jmpret over the cts test
······· if_z··········· movs··· ctsi0,#txcts0········ 'patch the jmps to transmit to txcts0·
······· if_z··········· add···· txcode,#1············ 'change co-routine entry to skip first jmpret
····················································· 'patch rx routine depending on whether rts is used
····················································· 'and if it is inverted
······················· or····· rtsmask,#0···· wz···· 'rts pin, z not set if in use
······· if_nz·········· test··· rxtx_mode,#INVERTRTS wc
······· if_nz_and_nc··· or····· rts0,domuxnc········· 'patch muxc to muxnc
······· if_z··········· mov···· norts0,rec0i········· 'patch to a jmp #receive
······· if_z··········· movs··· start0,#receive······ 'skip all rts processing if not used
····················································· 'patch all of tx routine out if not used·················
······················· or····· txmask,#0······ wz
'······· if_z··········· mov···· txcode,rxcode1······· 'use variable in case it has been changed
····················································· 'patch all of rx routine out if not used·················
······················· or····· rxmask,#0······ wz
Did I miss something?
In any case, I can start the debug as port 0 and it appears to kind of work, but starting the inverted RTS/CTS UART as Port 1 'loses' Port 0.· Do I need to restart (COGINIT) the cog identified for port 0 when initializing port 1 (use init method + addport method?
Any advice would be illuminating.
·
Seriously though, this is probably a simple problem of not understanding the object and what's passed.· I have an application where I'd like to use debug terminal to confirm the instructions and data are passed properly before I 'blindly' set the data stream.
Eventually, I will have two UART peripherals attached to the propeller - one uses #RTS/#CTS (RTS and CTS low handshake) for flow control and another with no flow control.· Looking at the pcFullDuplexSerial4FC, I see that I can invert RTS or invert CTS, but it combining the code for invert RTS and Invert CTS does not appear to be supported:
······· if_nz·········· xor···· start0,doifc2ifnc···· 'if_c jmp to if_nc
····················································· 'patch tx routine depending on whether cts is used
····················································· 'and if it is inverted
······················· or····· ctsmask,#0···· wz···· 'cts pin? z not set if in use
······· if_nz·········· test··· rxtx_mode,#INVERTCTS wc 'c set if inverted
······· if_nz_and_nc··· or····· ctsi0,doif_z_or_nc··· 'if_nc jmp
······· if_nz_and_c···· or····· ctsi0,doif_z_or_c···· 'if_c jmp
······· if_z··········· mov···· txcts0,transmit······ 'copy the jmpret over the cts test
······· if_z··········· movs··· ctsi0,#txcts0········ 'patch the jmps to transmit to txcts0·
······· if_z··········· add···· txcode,#1············ 'change co-routine entry to skip first jmpret
····················································· 'patch rx routine depending on whether rts is used
····················································· 'and if it is inverted
······················· or····· rtsmask,#0···· wz···· 'rts pin, z not set if in use
······· if_nz·········· test··· rxtx_mode,#INVERTRTS wc
······· if_nz_and_nc··· or····· rts0,domuxnc········· 'patch muxc to muxnc
······· if_z··········· mov···· norts0,rec0i········· 'patch to a jmp #receive
······· if_z··········· movs··· start0,#receive······ 'skip all rts processing if not used
····················································· 'patch all of tx routine out if not used·················
······················· or····· txmask,#0······ wz
'······· if_z··········· mov···· txcode,rxcode1······· 'use variable in case it has been changed
····················································· 'patch all of rx routine out if not used·················
······················· or····· rxmask,#0······ wz
Did I miss something?
In any case, I can start the debug as port 0 and it appears to kind of work, but starting the inverted RTS/CTS UART as Port 1 'loses' Port 0.· Do I need to restart (COGINIT) the cog identified for port 0 when initializing port 1 (use init method + addport method?
Any advice would be illuminating.
·
Comments
This is self modifying code, which uses different jmp and mux instructions for the different flags set. If you want to have low RTS and CTS you simply do an OR with both flags, when you initialize the object (start? function)
INVERTCTS | INVERTRTS and it should work.
As mentioned, I don't know the object yet, but I think if you want to run 2 serial ports with it, you need two objects as well:
obj
ser1: "FullDuplexSerial4FC"
ser2: "FullDuplexSerial4FC"
pub
ser1.start(....)
ser2.start(....)
You only need one object to support up to 4 serial ports.
Steve,
I know you have to initialize the ports (Addport) that you're going to use prior to starting the cog (Start) so the proper code can be generated.
I haven't tried what you want, but it looks like each port's settings affect a different instruction, so it should work.
from a first glance I thought 4 stands for 'for FC'. Who could imagine that 4 stands for 4? ;o) Nice driver then. Are the serial IOs completely independend in FC and speed?
Then it seems to be a sophisticated piece of code. Need to have a look at it.
If I understand the asm code correctly now, the 'test rxtx_mode,#INVERTCTS (or #INVERTRTS, they work the same) wc'·will do a bitwise AND of rxtx_mode against the CON #INVERT??? and as long as the bitwise AND is an odd number, set the c flag to 1.· Now, I can see if c is set to 1, a particular patch is applied, but I still haven't figured out how that sets FC high or low - or if I need to figure that out.
The implication is that if I set rxtx_mode to $11000 (bitwise·#INVERTCTS | #INVERTRTS), then I should get both inverted RTS and CTS.· I've tried this, but it may also be a slip in the code on setting the ports properly.
BTW, from my testing, 'pcFullDuplexSerial4FC' may stand for 'propeller code Full Duplex Serial 4 Port Flow Control.'· The code is POWERFUL, though confusing (it's been nearly 30 years since I seriously programmed in assembly, so I'm rusty).
If this works, I'll attach the modified object (code added to SimpleDebug.spin) for your review.
At the start of tx look for txctsX(0-3) to ctsiX, that code is patched, to bypass the cts testing or to invert the test - if_z in ctsi0 is patched to if_z_or_c or if_z_or_nc. Similar code at the end of tx - txjmp0 is patched to skip the cts test. Also in rx look for nortsX to rtsX that code is patched for rts.
I did have the cts/rts logic inverted originally. I uploaded the fixed code - the comments should have 8/14 as the fix date for cts/rts invert.
The version of 'pcFullDuplexSerial4FC' has the last comment as 7/24/08 (I downloaded this 5/1/09), so its possible that the latest updated object is not properly in the object forum. I'd appreciate if you could upload the latest version again or attach to another reply.
Steve.
P.S. Have you thought of using COGINIT to allow restarts of the UART cog? I tried a small mod to your program, but i haven't tried to run it:
PUB restart(SameCog)
'' Restarts the cog initialized before
'' Returns false if Cog is already utilized.
Coginit(SameCog,@entry,@rx_head)
I have attached my latest version to this reply.
I'll work with the new pcFullDuplexSerial4FC and your suggested entry code.· Your entry code appears to imply we have to completely re-initialize the parameters for all ports when we change any port - this is because we do not store which cog is running UART?· Or does the stop/init methods clear all pointers?
Attached is a re-write of SimpleDebug to start a debug in a cog using pcFullDuplexSerial4FC.· I've reworked from your comments, but it worked previously (in terms of passing port info and starting the cog correctly).
Steve.
If you do the changes below, and then change DebugRedux to use ReInit and before initializing DebugRedux call uarts.init once at start of your app. I think it will do what you are trying to do.
I would make one suggestion, pass the port number for uart into DebugRedux rather than have it hardcoded as 0. It would allow easier combination of objects that use different ports.
The simplest change would be to add a routine
Then modify AddPort to (since it assumes the variables are initialized to 0 and ReInit will not)
Then my init code would change to (note the reinit call and the removed addport(0...)
I can go further and do the equalivalent that you have done to the camera and gps code and move hte port config/baud rate modification code into those objects.
You can also disable a port by calling AddPort and set tx/rx pins to PINNOTUSED
Note: It still has some effect on other ports, during the reconfiguration, you can't receive/transmit on ports that are not being changed, since they are being re-initialized, just to the same values. So you have to be sure that all the port configuration is done when the other ports are not sending/receiving.
·