Parity Bits Making Me Punchdrunk... (PASM) -- Problem May Be With BST Serial Terminal
JonnyMac
Posts: 9,547
I wrote a simple, half-duplex serial object for RS-485 apps (it enables/disables the transmitter output as required) and it works just great with no parity (8N2). Today I decided I would add Odd (8O1) and Even (8E1) parity so that I could use a derivative object in a MODBUS project (MODBUS spec *requires* even parity).
I'm getting punchy and could use a second set of eyes. Given the tools in PASM this should be pretty simple -- I'm sure it is but I'm missing something. In the terminal window of BST I get "EFX-????" instead of "EFX-TEK"
This the PASM code for the transmitter; again, it works in No parity mode, but odd and even trash parts of my output.
I'm getting punchy and could use a second set of eyes. Given the tools in PASM this should be pretty simple -- I'm sure it is but I'm missing something. In the terminal window of BST I get "EFX-????" instead of "EFX-TEK"
This the PASM code for the transmitter; again, it works in No parity mode, but odd and even trash parts of my output.
txserial rdlong tmp1, txheadpntr ' tmp1 = txhead
rdlong tmp2, txtailpntr ' tmp2 = txtail
cmp tmp1, tmp2 wz ' byte(s) to tx?
if_nz jmp #txenable ' yes, enable transmitter
txdisable andn outa, txemask ' no, disable transmitter
jmp #rxserial ' check rx
txenable test txemask, ina wc ' already enabled?
if_c jmp #gettxbuf ' yes, skip txe delay
or outa, txemask ' enable transmit
mov txtimer, txetix ' set timer
add txtimer, cnt ' start it
waitcnt txtimer, #0 ' let timer expire
gettxbuf mov tmp1, txbufpntr ' tmp1 := @txbuf[0]
add tmp1, tmp2 ' tmp1 := @txbuf[txtail]
rdbyte txwork, tmp1 ' txwork := txbuf[txtail]
updatetxtail add tmp2, #1 ' inc txtail
and tmp2, #BUF_MASK ' wrap to 0 if necessary
wrlong tmp2, txtailpntr ' save
txparity or txwork, STOP_BITS wc ' c = 1 if odd bits
cmp pmode, #0 wz ' parity = none?
if_z jmp #transmit ' yes, ready to go
cmp pmode, #1 wz ' z = 1 for odd parity
if_z muxnc txwork, PARITY_BIT
if_nz muxc txwork, PARITY_BIT
transmit shl txwork, #1 ' add start bit
mov txcount, #11 ' start + 8 data + parit + stop
mov txtimer, bit1x0tix ' load bit timing
add txtimer, cnt ' sync with system counter
txbit shr txwork, #1 wc ' move bit0 to C
muxc outa, txmask ' output the bit
waitcnt txtimer, bit1x0tix ' let timer expire, reload
djnz txcount, #txbit ' update bit count
jmp #txserial
' -------------------------------------------------------------------------------------------------
STOP_BITS long %11_0000_0000 ' for no parity
PARITY_BIT long %01_0000_0000

Comments
Your code does SET and CLEAR parity, rather than EVEN and ODD parity. For the latter, you have to count the number of one bits in the data, and set or clear the parity bit so the total number of ones is even or odd.
-Phil
I'm pretty sure that's what's happening. This line:
arbitrarily adds two stop bits and if the 1s in the result is odd, C will be set. This line sets Z to 1 if the parity is Odd
If I have Odd parity (Z == 1) and and odd # of bits (C == 1), I want to set the parity bit to 0, and vice-versa, correct. Doesn't this code do this?
if_z muxnc txwork, PARITY_BIT if_nz muxc txwork, PARITY_BIT-Phil
-Phil
[ Update ] Both sides of the driver code (tx and rx) work fine with the Termite terminal program that I found on the 'net; TX portion still blows up in BST so I'm hoping Brad can have a look at that.