Shop OBEX P1 Docs P2 Docs Learn Events
Smart Pin asyncron serial transmit how to config to open-drain/source — Parallax Forums

Smart Pin asyncron serial transmit how to config to open-drain/source

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
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

  • jmgjmg Posts: 15,140
    msrobots wrote: »
    Another thing I am stuck with is how to suppress tx echo on rx with a buffered driver.

    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

  • evanhevanh Posts: 15,126
    msrobots wrote: »
    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.
    As JMG described for config bits. The detail is those config bits always define the OUT/DIR drive behaviour. ie: When OUT is high the HHH bits are in operation and when OUT is low the LLL bits are in operation.
    Another thing I am stuck with is how to suppress tx echo on rx with a buffered driver.
    Driver/ISR would normally flush the rx data for anything received between start of tx until about 50% of specified turn-around window time.
  • Ok, thanks @jmg

    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?
    evanh wrote: »
    msrobots wrote: »
    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.
    As JMG described for config bits. The detail is those config bits always define the OUT/DIR drive behaviour. ie: When OUT is high the HHH bits are in operation and when OUT is low the LLL bits are in operation.
    Another thing I am stuck with is how to suppress tx echo on rx with a buffered driver.
    Driver/ISR would normally flush the rx data for anything received between start of tx until about 50% of specified turn-around window time.

    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
  • jmgjmg Posts: 15,140
    msrobots wrote: »
    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)?
    If a part lacks a true open drain port, and you are bit-banging, then you can flip the direction bit to simulate open drain.
    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.

    msrobots wrote: »
    Where do I find that the PAD_IO modes table you mentioned?

    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]:'
  • Thanks again @jmg,

    sure, now I understand what you meant by cryptic manner. I need to digest that.
    jmg wrote: »
    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

    here you give examples for floating high if I understand correctly, and
    jmg wrote: »
    If a part lacks a true open drain port, and you are bit-banging, then you can flip the direction bit to simulate open drain.
    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.

    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
  • jmgjmg Posts: 15,140
    msrobots wrote: »
    You basically state that one should float high with pullup and drive down with 000 N-FET low, is my understanding correct?
    Yes, P2 includes pullups for free, and that saves a prt on the board, and makes testing & moving pins easier.

    msrobots wrote: »
    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?
    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.

    msrobots wrote: »
    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.
    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.

  • msrobotsmsrobots Posts: 3,701
    edited 2019-04-03 05:28
    well @jmg, as usual your answers open more questions, if you don't mind.

    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
  • evanhevanh Posts: 15,126
    msrobots wrote: »
    evanh wrote: »
    msrobots wrote: »
    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.
    As JMG described for config bits. The detail is those config bits always define the OUT/DIR drive behaviour. ie: When OUT is high the HHH bits are in operation and when OUT is low the LLL bits are in operation.
    Another thing I am stuck with is how to suppress tx echo on rx with a buffered driver.
    Driver/ISR would normally flush the rx data for anything received between start of tx until about 50% of specified turn-around window time.

    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.
    The turnaround window for a bussed RS485 or similar is much much longer than one or two character times. It needs to be long enough for all slaves to know the master has finished and that one slave can reply. Such systems always have transmission gaps. The turnaround window is specified as part of the protocol in operation.

    So each direction of transmission can be gapless, but there must be large gaps for turnaround.

  • evanhevanh Posts: 15,126
    msrobots wrote: »
    Should I instead change the I and O in 0000_CIOHHHLLL of the PPPPPPPPPPPP?
    For input, AAAA invert config is just an extra invert. Either works, but to get output invert there is only the P config bits.

  • jmgjmg Posts: 15,140
    msrobots wrote: »
    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?

    Current wise you are right, but you have resistor backwards, they also sum the currents, so the load resistance divides by N.
    msrobots wrote: »
    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'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.

  • evanh wrote: »
    msrobots wrote: »
    Should I instead change the I and O in 0000_CIOHHHLLL of the PPPPPPPPPPPP?
    For input, AAAA invert config is just an extra invert. Either works, but to get output invert there is only the P config bits.

    OK, so using the P version is better, thanks.
    evanh wrote: »
    msrobots wrote: »
    evanh wrote: »
    msrobots wrote: »
    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.
    As JMG described for config bits. The detail is those config bits always define the OUT/DIR drive behaviour. ie: When OUT is high the HHH bits are in operation and when OUT is low the LLL bits are in operation.
    Another thing I am stuck with is how to suppress tx echo on rx with a buffered driver.
    Driver/ISR would normally flush the rx data for anything received between start of tx until about 50% of specified turn-around window time.

    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.
    The turnaround window for a bussed RS485 or similar is much much longer than one or two character times. It needs to be long enough for all slaves to know the master has finished and that one slave can reply. Such systems always have transmission gaps. The turnaround window is specified as part of the protocol in operation.

    So each direction of transmission can be gapless, but there must be large gaps for turnaround.

    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
  • jmgjmg Posts: 15,140
    edited 2019-05-01 23:47
    msrobots wrote: »
    ...
    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.
    All this does get tricky, more so if you also want to pulse a DIRN enable on a RS485 system.
    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.


  • Now you are throwing that bi-directional thing on one line into it, CAN bus and RS485 and confusing me even more.

    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

  • I have a pin description syntax in TAQOZ that allows me to say "1K5 SOURCE FAST SINK" etc. The main thing is here are some values for the HHH LLL fields.
    pub FAST			0 ;
    pub 1K5				1 ;
    pub 15K				2 ;
    pub 150K			3 ;
    pub 1ma				4 ;
    pub 100ua			5 ;
    pub 10ua			6 ;
    pub OPEN			7 ; ( float )
    
    (For some reason I forget I made these constants as functions)
    Anyhow, just set all the HHH bits to one for no source drive.
  • I have a pin description syntax in TAQOZ that allows me to say "1K5 SOURCE FAST SINK" etc. The main thing is here are some values for the HHH LLL fields.
    pub FAST			0 ;
    pub 1K5				1 ;
    pub 15K				2 ;
    pub 150K			3 ;
    pub 1ma				4 ;
    pub 100ua			5 ;
    pub 10ua			6 ;
    pub OPEN			7 ; ( float )
    
    (For some reason I forget I made these constants as functions)
    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
  • evanhevanh Posts: 15,126
    There was a presumption you were wanting to handle multi-drop (bus) type networks of devices all tied together. Something like RS485 or CANbus. The comments about using open-drain and echo suppression together were the key phrases.

  • well @evanh, I have no clue at all what the use of the bit is in the original FullDuplexSerial from Chip, Or how somebody wants to use it.

    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
  • jmgjmg Posts: 15,140
    msrobots wrote: »
    Now you are throwing that bi-directional thing on one line into it, CAN bus and RS485 and confusing me even more.

    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.
    If you want Full duplex (separate wires for TX,RX), not CAN and not RS485, then you do not need Open Drain either, for a simple master-slave connection.
    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.
  • thanks @jmg,

    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
Sign In or Register to comment.