I need a UART configuration that supports 8M1 (8 bit, MARK parity, 1 stop bit)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Hi,

I'm working on a 20-year project where the equipment I'm asked to upgrade uses a UART at 9600 baud 8-bit MARK parity and 1 stop bit.

I'm setting my UART to Data bits: 9-bits with Parity Type: Mark/Space.

Len_CONSULTRON_0-1674442999408.png

By default the SPACE parity is set when sending the bytes in the packet.   After many coding experiments, I have failed to set the parity to MARK.

Does any have an example project where the MARK parity is continuously set for all the bytes?

Thanks in advance.

 

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
1 Solution
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Hi,

I have created my own 'no-frills' component for transmitting MARK/SPACE parity data reliably and predictably.

The demo project with the component can be found at:

UART-component-that-supports-controlled-MARK-SPACE-parity-transmissions 

I'd like to thank @BiBi_1928986  for his attention and help in this matter.

Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

0 Likes
11 Replies
pacr_284376
Level 5
Level 5
100 replies posted 10 solutions authored 50 sign-ins

Sorry, no direct answer but why are you setting up to 9 databits when you need 8 ? Parity bit is NOT part of the databits or am I wrong ?

0 Likes

pacr,

I can understand the confusion.

Here is a snip from the UART datasheet about using the 9-bit setting and Mark/Space parity:

Len_CONSULTRON_0-1674478251014.png

It appears that in the UDB implementation that the 9-th bit is needed to make room for the Mark/Space parity however, it is not needed for the Odd or Even parity.

If I set "Mark/Space" parity without setting the Data Bits to 9 then I get this configuration error:

Len_CONSULTRON_1-1674478530327.png

 

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
ncbs
Moderator
Moderator
Moderator
500 replies posted 50 likes received 250 sign-ins

Hi @Len_CONSULTRON,

I am yet to try this on my kit(s), but I have some pointers that might help you.

In the datasheet of UART_v2_50 component, the TX and RX usage models are given with sample snippets. If already not explored, can you implement these on your kit and check if it works?

TX:

ncbs_0-1674477228067.png

RX:

ncbs_1-1674477316301.png

 

Regards,
Nikhil

 

 

0 Likes

Nikhil,

I will give it a try.   However, this protocol I'm trying to be compatible with doesn't use UART Rx addressing.

Additionally the Rx addressing assumes that the bulk of the packet is data  which is SPACE parity and the address is MARK parity.  The is the complete opposite to the protocol I'm trying to implement with the SPACE parity only on one byte of the packet.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
BiBi_1928986
Level 7
Level 7
First comment on blog 500 replies posted 250 replies posted

Hi Len.

PSoC does not support the "classic" UART for Mark or Space parity.  Instead, PSoC supports the 9-bit address/data mode when 9-bit is configured.  The reason PSoC names the parity bit Mark/Space when configured for 9-bit is the parity bit is set to Mark for the address byte and automatically changed to Space for subsequent data bytes.

void main()
{
UART_TX_Start();
/*Set UART_CTRL_MARK bit in Control register*/
UART_TX_SetTxAddressMode(UART_TX_SET_MARK);
/*Send data packet with the address in first byte*/
/*The address byte is character '1', which is equal to 0x31 in hex format*/
UART_TX_PutString("1UART TEST\r");
/*Clear UART_CTRL_MARK bit in Control register*/
UART_TX_SetTxAddressMode(UART_TX_SET_SPACE);
}

If you use 9-bit config, you'd need to UART_TX_SetTxAddressMode(UART_TX_SET_MARK) for each data byte being sent in order to get continuous Mark.  At the receive side, the data would be flagged as an address field.  Can't say I've ever tried this.

However, here's how I got around this.
Config UART for 8-bit data, No parity, 2 Stop bits, 8N2.
The first Stop mimics Mark parity.  The second is the real Stop.  If there's an error in the Mark parity position (first Stop bit), then you'll get a Framing Error.  PSoC does not check the second Stop bit upon receive (shame on them!!!).  The amount of TX time is the same as 8M1.

edit: Wow, you guys type fast. I'm already out of date with my reply.

BiBi,

Thank you.  In principle, that might work.  Kind of brilliant actually.

Here is the issue I might have:   Although 90% of the data I transmit needs to be MARK parity, there is one sole byte in the packet that needs to be SPACE parity.

If I use 8N2 as the UART spec for the MARK parity emulation, can I switch the UART "on-the-fly" for the one byte to 8S1?

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Hi Len.

For that 1 Space case, I think you'd have to switch to 9N1 and explicitly change the parity bit to Space using the same control register mentioned in my reply above.  And then configure back to 8N2.

That said, if you have extra UDB's floating around, you could enable/trigger a counter to clobber the parity bit when that specific byte is being transmitted.  Triggering might not be exactly in sync with Start bit, but you do have the baud rate clock to work with.

Or, maybe bit-bash that 1 byte.

On receive side, you'd expect a Framing Error.

An interesting packet protocol I'm sure.  It's the inverse of Intel's 9-bit address/data protocol.

edit: Second thoughts..., since UART is compiled (from UDB's), might not be able to reconfigure on the fly.

edit: pacr may be on to something.  I wonder if you configure for 8-bit data, and select parity as API Controll enabled, can you still write to the control register and set the parity you want?

0 Likes

BiBi,


...

For that 1 Space case, I think you'd have to switch to 9N1 and explicitly change the parity bit to Space using the same control register mentioned in my reply above.  And then configure back to 8N2.

 

...

edit: Second thoughts..., since UART is compiled (from UDB's), might not be able to reconfigure on the fly.

...


Yes it appears the support for 9-bit Mark/Space parity is a UDB compile issue. If compiled as 8-bit, NONE, EVEN or ODD are possible for parity.   However according to the datasheet, MARK or SPACE requires the 9-bit setting.

...

 

edit: pacr may be on to something.  I wonder if you configure for 8-bit data, and select parity as API Controll enabled, can you still write to the control register and set the parity you want?


I think in 8-bit data mode, only NONE, EVEN or ODD are possible for parity are possible.  Of course I could be wrong.

Note: Although you're suggestion of 8N2 is awesome if ALL my bytes are to be transmitted as 8M1, I've tested a different route.

For Tx,  I've changed my UART to a SPI Master in 11-bit mode.   I convert my 8-bits of data to START_BIT, 8-bit data, PARITY_BIT, STOP_BIT format.   I then send out the preformatted 11-bit data packets.   This works but is not as elegant as a HW UART solution with true MARK/SPACE parity control. 

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Hello Len.

I tried 8N1 and checked the box for API Control Enabled thinking it might add the parity.  I then used the UART_TX_SetTxAddressMode(UART_TX_SET_MARK) and UART_TX_SetTxAddressMode(UART_TX_SET_SPACE), but it just transmitted 8-data bits ( as observed on oscilloscope).  No parity bit was added.

SPI, that's clever!

I guess you then use an RX-only UART for receive?
8N2 config and handle the special case for framing error?

0 Likes

BiBi,


I tried 8N1 and checked the box for API Control Enabled thinking it might add the parity.  I then used the UART_TX_SetTxAddressMode(UART_TX_SET_MARK) and UART_TX_SetTxAddressMode(UART_TX_SET_SPACE), but it just transmitted 8-data bits ( as observed on oscilloscope).  No parity bit was added.


As I suspected.  


...

SPI, that's clever!

...


Thanks.   I just use the MOSI line.  CLK is not needed.  However, I can use the CS line to control the OE of the Tx/Rx drivers (The protocol is half-duplex).

I've encoded UART data on SPI before.  It's more SW intensive.  The UART approach, if working as I hoped, would be virtually all HW state machine.

Although I'm working on an idea that uses UDBs to HW generate the needed START, STOP and parity bits and add it to the input data.  Hopefully it will reduce some of the SW computations.


...

I guess you then use an RX-only UART for receive?
8N2 config and handle the special case for framing error?


Correct.  It might be a "wash" for the number of UDBs used to implement.  I've yet to measure this.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Hi,

I have created my own 'no-frills' component for transmitting MARK/SPACE parity data reliably and predictably.

The demo project with the component can be found at:

UART-component-that-supports-controlled-MARK-SPACE-parity-transmissions 

I'd like to thank @BiBi_1928986  for his attention and help in this matter.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes