Serial data conversion using spin.
FORD
Posts: 221
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
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
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·
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
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.
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
This makes it much clearer what you're doing and, if FullDuplexSerial is ever changed, makes updating much easier.
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...
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
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
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
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 Baker
Propeller Applications Engineer
Parallax, Inc.
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