Shop OBEX P1 Docs P2 Docs Learn Events
simple_serial problem — Parallax Forums

simple_serial problem

kenmackenmac Posts: 96
edited 2009-05-08 00:03 in Propeller 1
Hi folks,
I have been trying to use the "simple_serial.spin" code to send data to another processor.
Unfortunately it reacts as if the two devices cannot get synch - or incorrect data is received.
It is set up correctly for N4800 on both chips.
Anyway, I decided to have a look at the pulse train on a CRO and it didn't look quite right.
On closer examination the Start pulse and subsequent data bytes looked OK, but after the stop byte, it reverted to a "non-idle" state, which of course is the state of a start pulse.
This would throw the rx device into some confusion!
I inserted another line of code to force the Tx pin to "idle" state, after the end of the byte.

The following is the relevant code:

PUB tx(txByte) | t
{{ Transmit a byte; blocks caller until byte transmitted. }}

  if txOkay
    outa[noparse][[/noparse]sout] := !inverted                             ' set idle state
    dira[noparse][[/noparse]sout]~~                                        ' make tx pin an output        
    txByte := ((txByte | $100) << 2) ^ inverted         ' add stop bit, set mode 
    t := cnt                                            ' sync
    repeat 10                                            ' start + eight data bits + stop
      waitcnt(t += bitTime)                             ' wait bit time
      outa[noparse][[/noparse]sout] := (txByte >>= 1) & 1                  ' output bit (true mode) 
 
    outa[noparse][[/noparse]sout] := !inverted                          [b]   ' ########## code added  ##########[/b]

    if sout == sin
      dira[noparse][[/noparse]sout]~                                       ' release to pull-up/pull-down



That fixed it, and it is now working OK.

I'm surprised that this hasn't been noticed before - the file has been downloaded over 2000 times!

kenmac

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8

Comments

  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-26 07:57
    Without testing it - I doubt that having TX in input-mode is a good idea. TX of the propeller is connected to RX of the other device. This is definitely an input. So, both sides are in input-mode not driving the line - the line is free floating. Depending on signals on other lines this can have unwanted sideeffects.
  • kenmackenmac Posts: 96
    edited 2009-04-26 14:22
    MagI02,
    I'm not sure what you mean - are you talking about the last line?
    This code is part of the Object Exchange - I only added the one line (marked with#####)
    The new line only changes the state of the output pin to "idle".

    kenmac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-26 15:03
    Sorry ... it seems that I was a bit confused. Interpreted the outa you added as dira. I guess the dira[noparse]/noparse~~ confused me. I didn't know why dira is set in the TX function. It thought it should be set in init and stay as is the whole time! But now I understand.

    Post Edited (MagIO2) : 4/26/2009 3:12:22 PM GMT
  • Chuck RiceChuck Rice Posts: 210
    edited 2009-04-26 16:04
    It is good to see some of these bugs identified and fixed.

    I would like to make a suggestion though. I think that it would be good to add a "Patch History" section to objects to identify the fixes that are on a particular version of an object. as an example, see the following:

    In the object header comments, add:
    At the top of the object:
    
    '' Patch History:
    ''
    ''   PatchID                 Description
    ''   -------------------     -----------------------------------------------------
    ''   Patch-kenmac-090426     inserted line of code to force Tx pin to "idle" state
                                 after the end of the byte.
    
    



    and in the code:

    PUB tx(txByte) | t
    {{ Transmit a byte; blocks caller until byte transmitted. }}
    
      if txOkay
        outa[noparse][[/noparse]sout] := !inverted                             ' set idle state
        dira[noparse][[/noparse]sout]~~                                        ' make tx pin an output       
        txByte := ((txByte | $100) << 2) ^ inverted         ' add stop bit, set mode
        t := cnt                                            ' sync
        repeat 10                                           ' start + eight data bits + stop
          waitcnt(t += bitTime)                             ' wait bit time
          outa[noparse][[/noparse]sout] := (txByte >>= 1) & 1                  ' output bit (true mode) 
    
        outa[noparse][[/noparse]sout] := !inverted                             ' Return to idle state (Patch-kenmac-090426)
    
        if sout == sin
          dira[noparse][[/noparse]sout]~                                       ' release to pull-up/pull-down
                              
        outa[noparse][[/noparse]sout] := !inverted                            [b] ' Return to idle state (Patch-kenmac-090426)[/b]
    
        if sout == sin
          dira[noparse][[/noparse]sout]~                                       ' release to pull-up/pull-down
    
    
    


    I think that this would help us keep things straight and know what we are getting when we use a canned object.
  • Jeff MartinJeff Martin Posts: 760
    edited 2009-05-07 22:20
    kenmac said...


    I inserted another line of code to force the Tx pin to "idle" state, after the end of the byte.

    PUB tx(txByte) | t
    {{ Transmit a byte; blocks caller until byte transmitted. }}
    
      if txOkay
        outa[noparse][[/noparse]sout] := !inverted                             ' set idle state
        dira[noparse][[/noparse]sout]~~                                        ' make tx pin an output        
        txByte := ((txByte | $100) << 2) ^ inverted         ' add stop bit, set mode 
        t := cnt                                            ' sync
        repeat 10                                            ' start + eight data bits + stop
          waitcnt(t += bitTime)                             ' wait bit time
          outa[noparse][[/noparse]sout] := (txByte >>= 1) & 1                  ' output bit (true mode) 
     
        outa[noparse][[/noparse]sout] := !inverted                          [b]   ' ########## code added  ##########[/b]
    
        if sout == sin
          dira[noparse][[/noparse]sout]~                                       ' release to pull-up/pull-down
    


    That fixed it, and it is now working OK.
    kenmac,

    I don't understand what was happening in your application (hardware/software) to make you see that issue, but all indications are that the tx method is correct.· I even tested it myself just now on a scope exercising all the possible modes of operation.·

    The way the code is written, even without the new line you entered, the output pin is reverted back to the resting state after the last bit of data is transmitted.
    • outa[noparse][[/noparse]sout] := !inverted·· - this initializes the pin's state for the very first time (before first byte).
    • txByte := ((txByte | $100) << 2) ^ inverted·· - this "stuffs" a stop bit (resting state) in bit 9 of the data to transmit, then shifts that data left two bits (1st to get a start bit in the first bit position, 2nd to prep for the first right-shift in the loop) and then inverts the entire data (if inverted mode is being used).
    • the loop repeats 10 times (since our data is now 10 bits; 1 start bit, 8 data bits, 1 stop bit) and the first time through it shifts the data right one bit (throwing away the bit of the extra left-shift done prior to the loop) to output the start bit first.·
    • On the tenth iteration of the loop, the bit of data output is the stop bit that was stuffed into txByte initially.

    Adding the outa[noparse][[/noparse]sout] := !inverted line once again is redundant and has no effect that I can see.

    The only thing I can think of that happened to you was that perhaps in your call to init() you were specifying the same pin number for both the rxPin and txPin parameters (initially) and then just happened to set them to different numbers after you made edit to Simple_Serial... if both rxPin and txPin are the same value,·Simple_Serial sets the txPin to input after the stop bit is sent, allowing the line to be pulled-high or low by an external resistor (or float if there is no resistor)... in your case it would seem it needed to be pulled-low·since you're using inverted mode.·

    This would cause the strange effects you witnessed if, indeed, you didn't have a pull-down resistor on the line and never intended it to be used that way (ie: you seem to indicate it should always be driven in your application, as is normal).

    Any further thoughts or info that I'm missing?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    --Jeff Martin

    · Sr. Software Engineer
    · Parallax, Inc.
  • kenmackenmac Posts: 96
    edited 2009-05-08 00:03
    Jeff,
    Thanks for your reply.
    I thought this thread had disappeared from view.
    I'm working on other things now, but will see if I can re-create the previous set up .
    I was using the code in "tx only" mode, with the RX pin set as -1.
    I can't recall whether I had a pull down resistor fitted but I'll try it.
    I'll get back to you in a few days.

    Ken Mac

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Perth, Western Australia
    Time Zone = GMT + 8
Sign In or Register to comment.