Shop OBEX P1 Docs P2 Docs Learn Events
Serial data conversion using spin. — Parallax Forums

Serial data conversion using spin.

FORDFORD Posts: 221
edited 2007-02-02 11:33 in Propeller 1
Hi all,
I have been thinking of using an SX to convert some serial data from 4800,E,8,1 to 4800,N,8,1 so that I can input it into a stamp. I also need to convert the other way as well.

I am considering using a prop for this to start us off getting into using them more.

I dont really want to have to do it in assembly, otherwise I'd just use an SX and not have the voltage differences (3.3 and 5 etc).

The prop would be perfect to have one cog for each rx (2) and 1 cog for each tx (2), and simply receive a byte on one pin, put it into a global byte, and then another cog checks parity, converts and sends it out.

My question is, would Spin be fast enough to receive a byte, bit by bit, or will I need to use assembly ?
My other question is, would I be better just modifying the existing serial comms objects ?

Sorry if the answer is obvious, but I havent done any prop stuff for Months.

Cheers,
Chris
Western Australia

Comments

  • Martin HebelMartin Hebel Posts: 1,239
    edited 2007-01-17 20:42
    Hi Chris,
    Sounds like a great application for multiple cores. The BS2_Functions library I wrote uses Spin to achieve up to 9600 Baud even with shracter strings, so yes, it's do-able, and you can probably modify it to get the parity going. While it's not the most efficient spin code, you are free to copy what you need from their if you can't modify assembler ones.

    -Martin

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Martin Hebel
    StampPlot - Graphical Data Acquisition and Control
    AppBee -·2.4GHz Wireless Adapters & transceivers·for the BASIC Stamp & Other controllers·
  • FORDFORD Posts: 221
    edited 2007-01-17 20:46
    Thanks Martin,
    Just what I was hoping. I am going to try and do it myself first in Spin, I think the timing etc will be pretty simple with things like waitcnt etc.

    Thanks again,

    Chris
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 00:34
    I also am trying to get 4800 but with odd parity... did you have any luck?
  • Mike GreenMike Green Posts: 23,101
    edited 2007-02-01 00:46
    Do you actually have to check the parity in converting to 4800,N,8,1? If not, just mask it off with "value & $7F" before resending it. To compute the parity you can use "parity := (value ^ (value>>1) ^ (value>>2) ^ (value>>3) ^ (value>>4) ^ (value>>5) ^ (value>>6)) & 1". To add odd parity to "value", do "value := value & $7F | (parity << 7)" after you compute "parity". To add even parity, use "value := value & $7F | ((parity ^ 1) << 7)".

    I would suggest having two FullDuplexSerial objects, one for transferring one way, and one for transferring the other way. You can declare these as 'OBJ ser[noparse][[/noparse] 2] : "FullDuplexSerial"' and initialize them as needed. Your program can just copy from one to the other, adding or removing parity as needed.
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 01:12
    thanks mike!
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 03:52
    so this should send 8 odd 1 stop bit, right??


    PUB txodd(value)

    '' Send byte (may wait for room in buffer)

    parity := (value ^ (value>>1) ^ (value>>2) ^ (value>>3) ^ (value>>4) ^ (value>>5) ^ (value>>6)) & 1
    value := value & $7F | (parity << 7)

    repeat until (tx_tail <> (tx_head + 1) & $F)
    tx_buffer[noparse][[/noparse]tx_head] := txbyte
    tx_head := (tx_head + 1) & $F


    if rxtx_mode & %1000
    rx
  • Mike GreenMike Green Posts: 23,101
    edited 2007-02-01 04:02
    It would work except that the tx routine's parameter is txbyte and I had suggested using value. I really recommend using tx as is and adding
    PUB txodd(value)
       parity := (value ^ (value>>1) ^ (value>>2) ^ (value>>3) ^ (value>>4) ^ (value>>5) ^ (value>>6)) & 1
       tx(value & $7F | (parity << 7))
    
    PUB txeven(value)
       parity := (value ^ (value>>1) ^ (value>>2) ^ (value>>3) ^ (value>>4) ^ (value>>5) ^ (value>>6)) & 1
       tx(value & $7F | ((parity^1) << 7)
    


    This makes it much clearer what you're doing and, if FullDuplexSerial is ever changed, makes updating much easier.
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 04:43
    close, it get 50% correct, but garbage on the lcd on E,F,I,J etc... it runs on hyperterm fine at 4800 8 O 1 ,without a max232 its 5v regulated, I doubt its the voltage as its always the same letters.
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 04:47
    fyi these are cheep.... http://cgi.ebay.com/ws/eBayISAPI.dll?ViewItem&amp;ih=008&amp;sspagename=STRK:MEWN:IT&amp;viewitem=&amp;item=180076224423&amp;rd=1&amp;rd=1

    he has plenty of them, send 12 to go to top display and 16 to switch to bottom, I can also clear the display but I forgot the hex value, Im still hacking, as there is no docs...
  • Mike GreenMike Green Posts: 23,101
    edited 2007-02-01 05:02
    Hmmm!

    I think I gave the parity stuff backwards. The parity bit is supposed to make the parity of the whole character even or odd. Sorry.

    Change txeven to txodd and change txodd to txeven and see what happens.

    Mike
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 05:15
    dont be sorry, I make 40+ an hour, and your worth more. I owe you a bass fishing trip already!, no go on even, I am headed for bed, Ill tackle this tommorrow. thanks for your help Mike, You gave me alot of good idea's. and eventually it will make fullduplex even better for us all.
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 13:56
    I think I understand the problem, To calculate even parity, the XOR operator is used; to calculate odd parity, the XNOR operator is used, but I can not figgure out how to do that, would·THIS work?... (I'm not able to test it right now)...


    PUB txodd(value)
    ·· parity := (value ^! (value>>1) ^! (value>>2) ^! (value>>3) ^! (value>>4) ^! (value>>5) ^! (value>>6)) & 1
    ·· tx(value & $7F | ((parity^1)<< 7))



    Post Edited (bassmaster) : 2/1/2007 2:26:31 PM GMT
  • Mike GreenMike Green Posts: 23,101
    edited 2007-02-01 16:06
    There isn't an XNOR operator. You use the XOR operator as I showed, then complement the result as in "parity ^ 1".
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 16:29
    Tried that, it does not work for some reason, Ill use sysinternals to sniff hyperterms odd parity to confirm everything is what it should be, I might try this:


    PUB txodd(value)
    parity := (value ^ (value>>1) ^(value>>2) ^ (value>>3) ^ (value>>4) ^ (value>>5) ^ (value>>6)) & 1
    value := (value << 6) & parity ^ 1
    tx(value & $7F)



    FYI, here is the test· spin... I have tried various settings in the bitmask, and this is the only one that gives me 50% success.

    CON
    ······· _clkmode······· = xtal1 + pll16x
    ······· _xinfreq······· = 5_000_000
    var
    ········ byte i
    OBJ
    ······ ser: "FullDuplexSerial"'

    PUB go
    · SER.start(0, 1,%0011, 4800)
    · repeat
    ··· i := $31
    ····
    ··· REPEaT·· while i =< 80
    ···· SER.txodd(i)
    ···· i++···



    Post Edited (bassmaster) : 2/1/2007 4:34:13 PM GMT
  • rokickirokicki Posts: 1,000
    edited 2007-02-01 18:30
    That "txodd" routine looks odd. I can't figure out how it is supposed to work.

    Maybe try something like this:

    sub txodd(v) | p
    p := v ^ (v >> 1)
    p ^= p >> 2
    p ^= p >> 4
    tx(v | ((!p) << 7))

    assuming tx will only "use" the top eight bits.

    Can anyone come up with simpler spin code to create an odd-parity byte from an even-parity input?
  • Paul BakerPaul Baker Posts: 6,351
    edited 2007-02-01 19:19
    Too bad you guys aren't working in assembler, the AND function automatically places the parity in the Carry Flag. A simple MUXC·or MUXNC places the even or odd parity into the data.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Mike GreenMike Green Posts: 23,101
    edited 2007-02-01 20:05
    Yes, Paul. Clearly "someone" needs to extend the FullDuplexSerial routines to include even/odd parity handling based on a pair of mode bits.
  • bassmasterbassmaster Posts: 181
    edited 2007-02-01 21:17
    My issue is resolved, I took the 3.95 lcd and used a solder sucker and removed the solder blop on S3 from pins 1 and 2 and now it is no parity!, I can even run it on a stamp now.

    Go get these on ebay on the link above... there cool.

    Someone still needs to figgure out the odd / even parity, but not me, I give up.

    no data, but hacking has shown me...

    ········ {
    ········· '$12 goes to top display
    ········· '$16 goes to bottom display
    ········· '$17 throws 2 bytes away from the next text string??
    ········· '$19 the next byte is ??? like a t = omega??
    ········· '$11 then $0A blanks ?(disabled) top display····················
    ········· '$11 then $01 = clear dosplay and goto home on top display
    ········· '$11 then $04 = clear top and· write backwards scrolling!
    ········· '$11 then $07 = clear top and write forward scrolling!
    ········· '$11 then $0F = blinking cursor on top display
    ··········$11 then $13 = top backspace cursor one space (leaves characters) need to do a $12 before writing over chars....
    ··········$11 then $1D = displays on top display "SPECIAL MESSAGE" whatever that means.
    ········· $11 then &1f = shift top text one space to right
    ········ ·$11 then $80 goes home, but does not clear. on top· display
    }
    ··········· }

    Post Edited (bassmaster) : 2/2/2007 3:02:20 PM GMT
  • bassmasterbassmaster Posts: 181
    edited 2007-02-02 11:33
    The guy on ebay has like 200 of these, I traded "info" for a few and bought 4. Where els can you get 2 - 2x16 serial lcd's in a single package for 3.99 apeice? I just wish I could get into the microcontroller 80C51 and access it, it even appears to have a RTC onboard. I still have to figgure out how to manipulate the bottom display like $11 does.
Sign In or Register to comment.