The methods in dataIO4port.spin are a mashup borrowed from ParallaxSerialTerminal and from debugPC. As you have found, you can set the MAXSTR_LENGTH constant to whatever you want. It always pays to read the program notes! Sorry for the confusion.
Reception of NULLs is quite different from detection of a BREAK condition. The former are well framed zero values that have a valid start bit and a valid stop bit. A BREAK is a continuous zero (spacing) value that persists without any stop bits. Some serial programs will put a stream of nulls into the serial buffer when the rx line is held low (or floating low for that matter). fds4port expects to see the stop bit, and if it does not, it won't put anything into the buffer. Let me know if you really do want it to stream out nulls when rx is held low,and I'll point out the place in the code where you can make that happen. But rest assured that fds4port can receive binary zeros (nulls) reliably.
What you propose, to move the buffers and housekeeping to VARs does make sense if you want multiple instances. The housekeeping VARiables would be declared in the object, and pointers to the buffers and their lengths could be passed in as parameters.
You asked how to disable ports that are not going to be used. Simply don't do an fds.AddPort. You can also selectively disable the rx or tx by setting them to -1 as you say, instead of to a pin number 0 to 31. The initialization patches the pasm code to jump over unused segments.
About speed when receiving data with no space between the bytes other than the minimum one single stop bit; it is an issue, per SRLM's comments. I'm not quite sure where the baud rate cutoff is. For sure the 4-port object will have a harder time when multiple ports are active. Say, it happens in an burst when all 8 rx+tx ports hit their stop bits at the same time, that would entail a longer than average time to cycle thru all of the co-routines. Flow control can help, if you can implement it on both ends.
On the nulls, we are seeing nulls creep into the data (using an earlier 4port serial, I think it branched off of Duane's version). I just got back from confirming it isn't the signal into the propeller via a logic analyzer. I'm hoping that using your version will solve most of our troubles, and it sounds like it will from what you said. Yeay!
I really appreciate you taking the time to get back to me; I have very little time to get this working and the entire team is relying on me.
Unfortunately, we're not going to have flow control. But I'll keep that in mind. It would require some architecture changes and not all of the devices we're using could support it.
On the nulls, we are seeing nulls creep into the data (using an earlier 4port serial, I think it branched off of Duane's version).
I think Tim Moore's original object had problems with adding nulls. I didn't do anything to fix this. My only contribution was to change the buffer sizes.
I used to have lots of extra null character popping up in my received data until I switched to Tracy's version. Tracy's version completely fixed the issue.
I've been using Tracy's version since he released it and wasn't aware of any bugs until this thread resurfaced. But I am updating my old copies with the current version and have pretty much used this object exclusively for all serial needs, regardless of the need for flow control or multiple ports. :thumb:
Thanks Chris; I think you're the person I talked to who pointed me in this direction; very much appreciated!
I had posted a message about a problem I was having but upon further investigation it appears as if my test code went awry, so if you saw that post, please disregard.
Thanks Chris; I think you're the person I talked to who pointed me in this direction; very much appreciated!
I had posted a message about a problem I was having but upon further investigation it appears as if my test code went awry, so if you saw that post, please disregard.
Fritz
Oh, you mean referred you to this code (object)? Yes, I remember telling someone on the phone about the 4-port object as I use it myself. Good stuff. Tracy is a great programmer. :thumb:
Oh, you mean referred you to this code (object)? Yes, I remember telling someone on the phone about the 4-port object as I use it myself. Good stuff. Tracy is a great programmer. :thumb:
yes, that was me.
Tracy, thanks again. I've been testing this and it's been working amazingly well. Only issue I'm having is when I send data too fast and overflow the Rx buffers. So far I've been testing at a kinda slow baud rate (19.2K) but I will step up to a faster one (38.4K) soon.
Some questions:
1) The ports seem to output NULL from the propeller on initial startup (when propeller is reset/powered up). We'll be shutting down and restarting to save power at times, so I'm wondering if there's a quick workaround to that issue. (Apologies for not having spent any time looking to see if I can answer that one myself yet...)
2) How do I go about trying to figure out how much HUB ram is remaining? When I increase the Rx buffer sizes, the simpleIDE is not showing an increase in code size. Is there a good way to tell how much memory is remaining? (OK, tech support just recommended...I was on the phone while writing this... propeller tool & F8; is that what you use, Tracy, Duane?) I guess that'll give me a general idea even though it's not for C code.
Hi Fritz, I'm happy that is working for you. Have you increased the size of the receive buffers? That is effective if the data arrives in packets. If it is streaming in continuously, it will have to be removed from the buffer at least as fast as it comes in. What are you doing with the received data?
With regard to the null at startup, what mode are you using? (true? inverted? driven? open?). I don't see any reason it should generate a null at startup. You have to watch out for garbage in the tx buffer, especially when changing clock speeds, and especially to RCslow. Be sure the transmitter buffer is empty (fds4.txflush(port)), plus one character width (clkfreq/baudrate * 10) before changing the clock speed.
I program in spin and use the F8, well, I mostly use BST and the memory usage message comes up every time I compiler, and there is a window for the compiler listing. For SimpleIDE, You'd best pose that question to the SimpleIDE folks, link.
Thanks for the kind words and vote of confidence Chris. Actually I consider myself far far from great as a programmer. I have to be dragged kicking and screaming. I like it to be structured and easy to get results. Why do you think I stuck to the BASIC Stamp for so long?! It was hard for me to get started with Spin--What are all those objects and parameters and local vs global variables, intermediate operators, and threads etc etc. Despite all that, once in, it is 100% Parallax structured and I think it is great and helps me do the best that I can.
Yes, but when you approach something, you do it as many of us old-schoolers do, and that makes the code well thought-out and functional. I see too many people go into a big project either learning as they go and/or making it up/changing it as they go. Spaghetti code doesn't give me confidence to use it. :thumb:
Hi Fritz, I'm happy that is working for you. Have you increased the size of the receive buffers? That is effective if the data arrives in packets. If it is streaming in continuously, it will have to be removed from the buffer at least as fast as it comes in. What are you doing with the received data?
With regard to the null at startup, what mode are you using? (true? inverted? driven? open?). I don't see any reason it should generate a null at startup. You have to watch out for garbage in the tx buffer, especially when changing clock speeds, and especially to RCslow. Be sure the transmitter buffer is empty (fds4.txflush(port)), plus one character width (clkfreq/baudrate * 10) before changing the clock speed.
I program in spin and use the F8, well, I mostly use BST and the memory usage message comes up every time I compiler, and there is a window for the compiler listing. For SimpleIDE, You'd best pose that question to the SimpleIDE folks, link.
Hi Tracy,
Thanks for your reply and sorry for the long-time-no-response from me.
Yes I've increased the buffer sizes, it's not your object that's at fault when I overflow the receive buffers, just my code not keeping up taking the data out. The code I was testing was just looping back the data on the spin side, basically transmitting once it received a byte. I was just blasting too much data at it; eventually the buffer has to fill up, as expected.
The null at startup--so what I've seen is some data come out of the ports when the propeller is reset. It's a low priority for me at this point. But I appreciate your comments. Eventually I'd like to make it not transmit anything at startup. Though I imagine there's got to be a transition from a zero to a one when the port is first setup, and that may be interpreted by the connected devices as a character, so there may not be much I can do about it, except perhaps to make sure that the low remains low long enough to be interpreted as a framing error on the receiver's side. As to your questions, all the ports are being used without inversion, driven, and no RTS/CTS handshaking (mode being passed to AddPort() is all zeros). I'm not changing clock speeds.
I found out that simpleIDE actually does tell you if you exceed the memory limits you can use. I was very happy about that!
What is the link to the official version of this object in the new OBEX?
And does it support multiple 4-port objects? Because I do not see any "version" variable in the file to make unique as described by the original comment by Tim Moore:
''* If you want multiple objects using this driver, you must *
''* copy the driver to a new file and make sure version long is *
''* unique in each version
I doesn't look like Tracy left the version variable but you could change some other variable that will be reset when starting up such as "rxbuff_ptr" to a different initial value or you can add you own variable. The code from the two objects just needs to be different some way. The Prop Tool will see if two objects are the same even if you rename it (which is still bazaar to me).
Duane is right, any change will do, but it has to be substantive, not comments or just the program name. You can change the size of one of the serial port buffers, for example, the following constants lead to a substantive program change...
RX_SIZE0 = 60 ' receive buffer allocations
becomes
RX_SIZE0 = 61 ' receive buffer allocations
Rename that version and declare as an additional OBJ...
fds : "FullDuplexSerial4port"
fds2 : "FullDuplexSerial4port2"
That does duplicate all the spin code, and of course it starts another pasm cog to handle the 4 additional ports.
Excellent, this information solved the issue I was having with the LockQueue object by Chad George. The documentation stated
'' [...]If different
'' queues are needed then the filenames should be different otherwise
'' all instances will share the same data space. Each unqique instance
'' only needs to be initialized once.[...]
But simply adding:
DAT
[...]
Version byte 1
and so forth to the other object instances solved a lot of problems for me.
Comments
Reception of NULLs is quite different from detection of a BREAK condition. The former are well framed zero values that have a valid start bit and a valid stop bit. A BREAK is a continuous zero (spacing) value that persists without any stop bits. Some serial programs will put a stream of nulls into the serial buffer when the rx line is held low (or floating low for that matter). fds4port expects to see the stop bit, and if it does not, it won't put anything into the buffer. Let me know if you really do want it to stream out nulls when rx is held low,and I'll point out the place in the code where you can make that happen. But rest assured that fds4port can receive binary zeros (nulls) reliably.
What you propose, to move the buffers and housekeeping to VARs does make sense if you want multiple instances. The housekeeping VARiables would be declared in the object, and pointers to the buffers and their lengths could be passed in as parameters.
You asked how to disable ports that are not going to be used. Simply don't do an fds.AddPort. You can also selectively disable the rx or tx by setting them to -1 as you say, instead of to a pin number 0 to 31. The initialization patches the pasm code to jump over unused segments.
About speed when receiving data with no space between the bytes other than the minimum one single stop bit; it is an issue, per SRLM's comments. I'm not quite sure where the baud rate cutoff is. For sure the 4-port object will have a harder time when multiple ports are active. Say, it happens in an burst when all 8 rx+tx ports hit their stop bits at the same time, that would entail a longer than average time to cycle thru all of the co-routines. Flow control can help, if you can implement it on both ends.
awesome information, thanks!
On the nulls, we are seeing nulls creep into the data (using an earlier 4port serial, I think it branched off of Duane's version). I just got back from confirming it isn't the signal into the propeller via a logic analyzer. I'm hoping that using your version will solve most of our troubles, and it sounds like it will from what you said. Yeay!
I really appreciate you taking the time to get back to me; I have very little time to get this working and the entire team is relying on me.
Unfortunately, we're not going to have flow control. But I'll keep that in mind. It would require some architecture changes and not all of the devices we're using could support it.
I think Tim Moore's original object had problems with adding nulls. I didn't do anything to fix this. My only contribution was to change the buffer sizes.
I used to have lots of extra null character popping up in my received data until I switched to Tracy's version. Tracy's version completely fixed the issue.
Fritz
I had posted a message about a problem I was having but upon further investigation it appears as if my test code went awry, so if you saw that post, please disregard.
Fritz
Oh, you mean referred you to this code (object)? Yes, I remember telling someone on the phone about the 4-port object as I use it myself. Good stuff. Tracy is a great programmer. :thumb:
yes, that was me.
Tracy, thanks again. I've been testing this and it's been working amazingly well. Only issue I'm having is when I send data too fast and overflow the Rx buffers. So far I've been testing at a kinda slow baud rate (19.2K) but I will step up to a faster one (38.4K) soon.
Some questions:
1) The ports seem to output NULL from the propeller on initial startup (when propeller is reset/powered up). We'll be shutting down and restarting to save power at times, so I'm wondering if there's a quick workaround to that issue. (Apologies for not having spent any time looking to see if I can answer that one myself yet...)
2) How do I go about trying to figure out how much HUB ram is remaining? When I increase the Rx buffer sizes, the simpleIDE is not showing an increase in code size. Is there a good way to tell how much memory is remaining? (OK, tech support just recommended...I was on the phone while writing this... propeller tool & F8; is that what you use, Tracy, Duane?) I guess that'll give me a general idea even though it's not for C code.
regards,
Fritz
With regard to the null at startup, what mode are you using? (true? inverted? driven? open?). I don't see any reason it should generate a null at startup. You have to watch out for garbage in the tx buffer, especially when changing clock speeds, and especially to RCslow. Be sure the transmitter buffer is empty (fds4.txflush(port)), plus one character width (clkfreq/baudrate * 10) before changing the clock speed.
I program in spin and use the F8, well, I mostly use BST and the memory usage message comes up every time I compiler, and there is a window for the compiler listing. For SimpleIDE, You'd best pose that question to the SimpleIDE folks, link.
Hi Tracy,
Thanks for your reply and sorry for the long-time-no-response from me.
Yes I've increased the buffer sizes, it's not your object that's at fault when I overflow the receive buffers, just my code not keeping up taking the data out. The code I was testing was just looping back the data on the spin side, basically transmitting once it received a byte. I was just blasting too much data at it; eventually the buffer has to fill up, as expected.
The null at startup--so what I've seen is some data come out of the ports when the propeller is reset. It's a low priority for me at this point. But I appreciate your comments. Eventually I'd like to make it not transmit anything at startup. Though I imagine there's got to be a transition from a zero to a one when the port is first setup, and that may be interpreted by the connected devices as a character, so there may not be much I can do about it, except perhaps to make sure that the low remains low long enough to be interpreted as a framing error on the receiver's side. As to your questions, all the ports are being used without inversion, driven, and no RTS/CTS handshaking (mode being passed to AddPort() is all zeros). I'm not changing clock speeds.
I found out that simpleIDE actually does tell you if you exceed the memory limits you can use. I was very happy about that!
What is the link to the official version of this object in the new OBEX?
And does it support multiple 4-port objects? Because I do not see any "version" variable in the file to make unique as described by the original comment by Tim Moore:
Thanks,
Here's the OBEX link.
-Marcus
RX_SIZE0 = 60 ' receive buffer allocations
becomes
RX_SIZE0 = 61 ' receive buffer allocations
Rename that version and declare as an additional OBJ...
fds : "FullDuplexSerial4port"
fds2 : "FullDuplexSerial4port2"
That does duplicate all the spin code, and of course it starts another pasm cog to handle the 4 additional ports.
But simply adding:
and so forth to the other object instances solved a lot of problems for me.
Thanks again for the help.
-Marcus