Smart Pin asyncron serial transmit how to config to open-drain/source
msrobots
Posts: 3,709
in Propeller 2
Still working on FullDuplexSerial2.spin2. The original FullDuplexSerial.spin supports a MODE parameter.
bit 0 - invert rx
bit 1 - invert tx
bit 3 - open-drain/source tx
bit 4 - ignore tx echo on rx
The last two are giving me grieve.
I can configure inverted input/output for rx and tx, but I can not figure out how to config tx to be open-drain/source.
Another thing I am stuck with is how to suppress tx echo on rx with a buffered driver.
The current version of FullDuplexSerial in Fastspin tries something alike
But that can just work with a not buffered driver, so how to solve that?
Enjoy!
Mike
bit 0 - invert rx
bit 1 - invert tx
bit 3 - open-drain/source tx
bit 4 - ignore tx echo on rx
The last two are giving me grieve.
I can configure inverted input/output for rx and tx, but I can not figure out how to config tx to be open-drain/source.
Another thing I am stuck with is how to suppress tx echo on rx with a buffered driver.
The current version of FullDuplexSerial in Fastspin tries something alike
PUB tx(txbyte) … if rxtxmode & %1000 rx
But that can just work with a not buffered driver, so how to solve that?
Enjoy!
Mike
Comments
I think that is buried in the PAD_IO modes table, in a cryptic manner.
The table shows HHH and LLL tags which I think means HHH choice applies when driven HI and LLL choice applies when driven LOW. FAST is CMOS drive
000000 default is CMOS drive both ways.
So that means any combinations are legal, so you could configure 1.5k Drive HI, and 10uA pull low, for example.
Open Drain N-FET I think becomes HHHLLL field of 111000 ?, or you might want to have some pullup rather than fully float ?
eg
010000 is 15k pullup/N-FET low
101000 is 100uA pullup/N-FET low
Driver/ISR would normally flush the rx data for anything received between start of tx until about 50% of specified turn-around window time.
I have rarely (never?) used open drain serial, but my goal is to support the same as the original FullDuplexSerial from Chip, both driver currently used by fastspin do ignore the MODE parameter.
As far as I can follow the original bit-banging Chip code, when in open-drain/source mode it uses dira to bit-bang, not outa, thus is floating while not transmitting and pulling the line low when transmitting, that means it needs a pullup, am I somehow reading this correct?
Or is it the other way around and I have to float tx low while not transmitting and dira gates a high output (on the P1 example)?
I wish I had a scope to look at it.
And what is with inverted modes for rx/tx, do I need then to switch pullup with pulldowns and vice versa?
This P2 SmartPin stuff is still very confusing to me, but I have a hard time understanding the documentation and resort to writing code to test my assumptions. And good grief I am wrong a lot. Just that INCMOD thing caused me to rewrite my code completely 4 or 5 times still not getting why the LUT buffers for rx1/2 and tx1/2 where crashing once in a while.
Where do I find that the PAD_IO modes table you mentioned?
Ah. I am currently using int 1 to receive rx1, int 2 to receive rx2 and int 3 on a timed manner (currently 100 sysclocks) to check my tx pins if they are ready to send and if something in their buffers move a byte to the pin, for tx1 and tx2 respectively.
But basically the SmartPin serial output is buffered, so when I 'send' my byte to the SmartPin it does not get send right away it is latched(?) into a register and send out as soon as the last one is finished to allow gapless transmissions, as far as the docs explain.
The RX interrupts get raised when a complete byte is received.
And that is my dilemma, even if I disable the RX1 interrupt while sending my byte to the tx1 smartpin and enable it again after sending,
the sending SmartPin might not even have started the transmission.
As I said, I am somehow stuck there,
Enjoy!
Mike
More common is N-FET open drain, so you float hi and enable-dir to drive low.
P2 has more port options, including true open drain, and pullups, so a high speed HW OD serial link is possible.
There is an ASCII version posted by evanh here
https://forums.parallax.com/discussion/comment/1450406/#Comment_1450406
and there is a image in the DOCs
https://docs.google.com/document/d/1UnelI6fpVPHFISQ9vpLzOVa8oUghxpI6UpkXVsYgBEQ/edit
search for 'The table below shows the %P..P bits as M[12:0]:'
sure, now I understand what you meant by cryptic manner. I need to digest that.
here you give examples for floating high if I understand correctly, and
You basically state that one should float high with pullup and drive down with 000 N-FET low, is my understanding correct?
Sorry for my dumb questions but what is the difference between
010000 is 15k pullup/N-FET low
101000 is 100uA pullup/N-FET low
Why should I choose a current pullup vice versa a resistor one, I guess I lack basic understanding there. Same goes for the value to choose, am I right assuming that a smaller resistor value would pull up faster and would be better for faster speeds?
Just thinking, and that leads to various ideas, I currently think also about a complete new rewrite of my pasm code to support 32 bit also, not just 8 bit.
But first I need to get the basics cleaned up.
Enjoy!
Mike
Yes, the differences are slight. 15k will have an initial pullup of 220uA, dropping to half that at 50% of Vio. I gave both more to illustrate the choices.
Smaller is faster, but you might also like to total up the number of slaves to be connected. A system with 32 slaves, each with a 1mA pullup, could be considered to have excess load, but a system of up to 5 nodes could be fine with a 1mA pullup setting on each one.
If you are giving the option for open drain, it makes sense to allow up to 32b - 9b is another very common UART setting, & P2 to P2 links could do 32b easily.
I looked thru that cryptic table and am not sure if I understand it completely.
The %AAAA_BBBB_FFF_PPPPPPPPPPPP_TT_MMMMM_0 thing.
the input selectors AAAA and BBBB allow for inverting the pin (first bit) and selecting neighboring pins. I already wrote code to test that and it seems to do what it is supposed to do.
That is what my test routines do, they change the input to a neighboring pin so I do not need to use jumper wires. And it works fine.
But the PAD_IO modes, (all those Ps) seem also to be able to invert IN and OUT by setting/clearing bit I or O?
My current settings just use TT_MMMMM_0 for async serial receive/transmit keeping AAAA_BBBB_FFF_PPPPPPPPPPPP as zero and for inverting I use the first bit of AAAA.
Should I instead change the I and O in 0000_CIOHHHLLL of the PPPPPPPPPPPP?
I am pretty sure I am missing some important understanding here.
And for your explanation of the slight difference between resistor pullup and current pullup, am I right in the understanding that this would apply for multiple slaves on the bus and when they use resistor pullup settings those parallel(?) resistors would add up (and make the pullup weaker) where the current setting would avoid that, or am I completely wrong with my assumptions again?
Enjoy!
Mike
So each direction of transmission can be gapless, but there must be large gaps for turnaround.
Current wise you are right, but you have resistor backwards, they also sum the currents, so the load resistance divides by N.
I'm not clear on what you are trying to do in this detail, but usually for any serial mode supported by the hardware itself, you would configure the pins as (eg Open Drain, possibly Inverted, tho that would be rate ) and then use the TX/HW in the pins for shifting the real data out/in.
OK, so using the P version is better, thanks.
Here I am completely at lost. I will post the current working Version in a new Thread but that still just do inverting with the AAAA bits and has no open drain and no echo suppressing.
Enjoy!
Mike
CAN transceivers can avoid needing a DIRN control, as they use a OR wired BUS, but I think the absolute top speed of RS485 is above what CAN specs.
ISTR CAN-FD can be 10~12MHz and RS485 above 50MHz. 50MHz might be pushing a P2, but 30 MHz is likely a practical upper MHz.
Some MCUs generate an interrupt when TX shifter is done, which gives a leverage point, but often that's at the start of the STOP bit, and that is both before RI will trigger (mid-stop-bit), and before you (ideally) want to reverse the BUS, which should be after the stop bit completes.
I don't think P2 has a Tx shifter-empty signal, but it does have a RI, and you could flip this somewhat backwards, if you know RI is always TX connected, you can use RI to indicate TX done.
ie during a TX-burst, inside RI check for IamSending flag, and ignore RXData (or check = expected?, or just count and confirm count on last byte ?)
If IamSending is inactive (now on last byte), check DIRN=TX, if still TX, set DIRN=Rx, and ignore this last byte RX.
Following RI's will have IamSending false, and DIRN=Rx, and those bytes can go into a Rx buffer.
What I want to do is just to be able to provide on the P2 what FullDuplexSerial on the P1 does to make porting more easy.
And full duplex serial has a MODE bit stating open drain. That is the first one to tackle. On the P1 it is usually done by switching dir instead of out. The no echo bit is the last to solve.
I do understand (hopefully) that I can set values for HHH and LLL in the config bits to archive open drain/source, but WHAT values I need to put there to simulate what the P1 would do by switching dir instead of out?
confused,
Mike
Anyhow, just set all the HHH bits to one for no source drive.
Aah finally a answer I can understand. So HHH bits as 1 and LLL bits as 0 will do what the P1 does? Nice, thank you very much.
Mike
I personally never used it, so your assumption might be completely correct and the misunderstanding completely on my side.
So I will change the code to support setting HHH and LLL and try to figure out if I need to use IO for inverting or can just use the first bit of AAAA as I do now.
Mike
Open drain dictates some pullup, somewhere, and at higher baud speeds, that needs to be lower values.
Best avoided entirely on master to one slave case.
If you want to include master to many slaves, with separate TXm -> RX1,RX2,RX3, then that needs TX1,TX2,TX3 -> RXm
It is this last case that needs DIRN management (internal tristate, or external RD485 dirn pin), or open drain.
A 68~120 ohm series terminator for tristate drive designs, is probably enough to protect against rare contention cases & that buys you more ESD protection too.
slowly I understand what it is for. I will do a update tonight, and then someone can maybe test it if it does what it should.
Mike