FullDuplexSerial Object - Detecting when data has been sent?
DavidM
Posts: 630
HI,
Is there a way to detect when the data has been sent fully, after you use the TX command?
I would like the current method ( the tx methods) to STOP/PAUSE until the data has been sent.
I need to disable the 485 driver AFTER data has been sent, my data size varies, So far I am doing this with a time out, but this means that I am not transmitting as fast as I want to?
SO..
Q1) Is there any variable in the assembly code that I can READ and check via SPIN code?
Thanks
David M
Is there a way to detect when the data has been sent fully, after you use the TX command?
I would like the current method ( the tx methods) to STOP/PAUSE until the data has been sent.
I need to disable the 485 driver AFTER data has been sent, my data size varies, So far I am doing this with a time out, but this means that I am not transmitting as fast as I want to?
SO..
Q1) Is there any variable in the assembly code that I can READ and check via SPIN code?
Thanks
David M
Comments
If that's sufficient (transmit buffer empty) then you'd need to add a method checking for tx_tail == tx_head. OTOH, if off-chip is required you could use transmit-buffer-empty + a single character delay (bit time * 10) or modify the PASM section to tell you it's gone (although that may be overkill).
I will try out what you have suggested, I am reading a tutorial on PASM, I might even use this as an excuse to learn something about assembly!
thanks
Dave M
Ok, I managed to get this idea working ( thanks kuroneko!) . I am running the serial at 57600 baud ( works at 115200 as well)
I modified ( a copy ) of FullDuplexSerial.spin
I added a method ( a copy of TX ) called..
PUB TXWait(TxByte)
I added to this the following lines at the end of the method
I then modified ( temporarily) the STR call to use TXWait instead of TX
I experimented with differnt values, I.e 5000, 7000, and 10,000 worked out best.
BUT, I would prefer to use some indicator from the Assembly routine to tell me that the "bits" sent have finished, Just in case I trample on some of the message. I would then add a fixed delay after that, so the driver has time to switch.
Is this possible
It's certainly doable. I don't have time right now to look at it (off-line stuff) but maybe someone else chimes in. For the time being the approach you have now should work well enough.
Its close enough now, I can live with this , So I can get on with the other this I need to do regarding a RS485 Object, I want to be the first to make this!
Dave M
repeat until not lockset
A lock will do the job as well. What do you need the extra flag for? I have the odd feeling that you get a free race condition with your purchase (I could be wrong though). This needs some more thought in case you take that approach. A t1, t2
B t1, t2, t3 (now t4 instead of t1)
Let me know how the RS485 network is coming, as I have considerable experience with this code, as well.
I think you are right about not needing the flag variable. It was there to clear the lock only when the buffer makes the transition from busy to empty. But that doesn't matter in the context of blocking tx until the transmission finishes. I don't see a race condition in it. It is an example maybe to use a lock as a simple resource-busy flag.
Your solution changing the position where the tail pointer is updated is neat, so that the extra character delay is not needed when the spin code tests the difference head-tail.
I'm interested in the RS485 code too. Mike, it is ideal to have an ack/nack handshake, but that is often wishful thinking unless you control both ends of the channel. I wish!
Q1) Can I READ the "Flag" Status in SPIN code say within the FDSerial object (Modified as suggested by kuroneko? If so How?
To Mike Huselton..
Q2) You say to leave the code alone, ! Why, All that is happening is that a flag is being sent, Are you also assuming that the messages sent are of the same length? If you have done lots of work with RS485, then how about sharing some code ideas?
Please excuse my ignorance regarding Assembly.
Thanks
Dave M
Along with the code you modified?
because I can test this out now .
Dave M
My original thought had been to let the supplier set the lock and then wait until the lock is cleared. I probably over-complicated the issue by introducing the busy-flag and by putting the lockset in the pasm code.
It should really be quite simple. Supplier hands over the data, sets lock and waits for it to be cleared, either blocking or between executing other tasks. Pasm clears the lock when finished through to the last bit of the last byte.
OK!
I did the mods as suggested, ( I was also using a 128byte RX & TX buffers , when I reverted back to a 16 byte buffer, I got a mess, ( I may not have made the changes properly, so I when back to my 128 byte buffers)
Seems to work! with 128 byte buffers!
I was sending a long message AT 57600 i.e
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
Well done kuroneko!!!!!!!! and others
Also, as a test
I checked my normal SERIAL-RS232 via USB coms to an application I wrote on the MAC using REALBASIC, and I CAN communicate with that AT THE SAME TIME, So the MAC is reading continuous data from my RS485 connection, AND sending and receiving data via Serial RS232 !!!
both are using the same MODIFIED FULLDUPLEXSERIAL Objects!!!!
Sweeet!!!
regards
Dave M
Yes I know, I had to change in about 8 places including the asm code. I got the info ages ago form somewhere here! can;t remember where.
I really should test back on 16 byte buffer, to see any difference, I want to know if I send say 40 bytes in one string, and the buffer is only 16 bytes, what will happen?
thanks
Dave M