CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Hardware uart parity
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
fobi



Joined: 26 Feb 2015
Posts: 15
Location: BG

View user's profile Send private message

Hardware uart parity
PostPosted: Thu Feb 26, 2015 1:28 pm     Reply with quote

Hello,
I'm new to " C for microcontrollers ". I read what i found about parity in this forum, but it seems not so clear for me.
I know what is PIC and PIC_UART , but i am puzzled from compiler.
My question is why this not works with HW uart ?
Code:

#use rs232(uart2, baud=9600, bits =8, parity=o, stop =1, stream=str2 )
#use rs232(uart1, baud=9600, bits =8, parity=o, stop =1, stream=str1 )
...
 fprintf(str2,"whatever here\n\r");


May be will work with software uart ... ? Anyway i need the 2 uarts on 18f23k22 with interrupts and 9600-8-ODD-1.
After little surfing around, i wrote this:

Code:

#use rs232(uart2, baud=9600, bits =9, parity=n, stop =1, stream=str2 )
#use rs232(uart1, baud=9600, bits =9, parity=n, stop =1, stream=str1 )
...
int8 getParity (char p) {
      p = p ^ (p >> 4 | p << 4);
      p = p ^ (p >> 2);
      p = p ^ (p >> 1);
      return p & 1;
     }
...
void  out_chr( char c ) {
//      if(getParity(c)==1)
//      TX9D2 = TRUE;
//      else
//      TX9D2 = FALSE;
      TX9D2 = getParity(c);    // even this works ? Nice :)
      while(!TXSTA2_TRMT);
      TXREG2 = c;
}
...
out_chr("whatever here\n\r");


... which works fine.
My question is do i really need to go this way or there is a way to "#use rs232" (and associated puts and gets) somehow ?
Thanks
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 26, 2015 1:40 pm     Reply with quote

OK I'm curious..
I have to ask WHAT device are you connecting to that need 8 bits, ODD parity? I haven't seen any 'normal' device needing parity for 2 decades.
Ever since UARTs become a 40 pin device instead of a handful of 7400 chips, there's been very little reason to have 'parity'.

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Thu Feb 26, 2015 1:48 pm     Reply with quote

The hardware UART on chips like PIC16's/18's, does not support parity.
You can generate it by using the 9bit option, and setting the 9th bit to the required parity. Efficient code to do this, has been posted here. On some compiler versions, the compiler will attempt to simulate parity this way. It sounds as if your compiler version is one that doesn't...

Look at the code at the end of:
<http://www.ccsinfo.com/forum/viewtopic.php?t=21363>

Which generates parity efficiently.
fobi



Joined: 26 Feb 2015
Posts: 15
Location: BG

View user's profile Send private message

PostPosted: Thu Feb 26, 2015 3:00 pm     Reply with quote

thanks!
temtronic, the device is Wincor Nixdorf LCD, controlled by VT100 (which i haven't seen from 3.14 decades :))
I need to capture 2 displays, interpret the commands and send the data to DVR as one stream. I almost wrote it in asm, but it seems to me a good task to learn a little C. Not so hard or easy task ....

Ttelmah, i know the PIC hardware well, now i know that #use depends of compiler version.
Thanks for the link, i will check it.
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Thu Feb 26, 2015 3:04 pm     Reply with quote

as a comment, remember you can just have your 'putc_with_parity' function defined, and call this from things like printf, with:

printf(putc_with_parity,"format",values);

Makes it tidier. Smile
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Feb 26, 2015 6:57 pm     Reply with quote

I googled 'Wincor Nixdorf LCD' and downloaded a manual for the BA73A and didn't see anything that said '8 bit + parity' rather lots of info to hookup to a PC, and I don't think PC com ports use 8 bits + parity.
Maybe you've got a 'special' display, it's just 'uncommon' to have 8+Parity.
Now the VT100 is 'new' to me as I used to fix the VT52s when they first came out...then again I was also fixing ASR33s then too.....

Jay
fobi



Joined: 26 Feb 2015
Posts: 15
Location: BG

View user's profile Send private message

PostPosted: Thu Feb 26, 2015 11:05 pm     Reply with quote

h**p://www.wincor-nixdorf.com/internet/cae/servlet/contentblob/49002/publicationFile/76133/BA63_Display_Operating_Manual_english.pdf

The jumpers sets on page 18 do not depend on me.
In fact i did 1 channel VT100 to ESC/p about 6 years ago for GeoVisison. They still working good. But now i have to merge 2 displays, because the DVR do not allow 2 overlays from 2 streams to one camera window.
I will post some pictures later today.

Ttelmah, this didn't work for me

Code:

#use rs232(uart2, baud=9600, bits =8, parity=o, stop =1, stream=cash2 )
#use rs232(uart1, baud=9600, bits =8, parity=o, stop =1, stream=cash1 )
...
void  fput_chr( char d ) {
   fputc(d,cash2);
   }
...
fput_chr("whatever here\n\r")


Any attempt to use 'parity=o' crashes. Even worst, sometimes i got message that 'interrupts will be disabled at line ...' but the line number do not exist in my code ...
I will be happy to see part of working code. Otherwise i will fire the #use RS232 and i will write my own
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 2:24 am     Reply with quote

You misunderstand.

You'd have to have a function like:
Code:

#use rs232(uart1, baud=9600, bits =9, stop =1, ERRORS, stream=str1)

int8 find_parity(int8 data)
{
#asm
swapf data, W
xorwf data, F
rrf   data, W
xorwf data, F
btfsc data, 2
incf  data, F
movf  data, W
andlw 1
movwf _return_
#endasm


void  fput_chr( char data)
{
   //add 9th bit as parity to the data
   if (find_parity(data))
      bit_clear(RS232_ERRORS,7);
   else
      bit_set(RS232_ERRORS,7);
   fputc(data,str1);
}

//Then you can just use
   printf(fput_chr,"What you want to send/n");
//and 9bit data will automatically be sent, and efficiently. :)


I haven't checked whether that will give even or odd. You may need to reverse the set/clear if I've got this the wrong way round. Think I've got it right....
fobi



Joined: 26 Feb 2015
Posts: 15
Location: BG

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 3:43 am     Reply with quote

i see ...
this 90% answers my question, thank you. I came up with similar solution

Code:

void  out_chr( char c ) {
      TX9D2 = getParity(c);    // however calculated
      while(!TXSTA2_TRMT);
      TXREG2 = c;
}
/////////////////////////////////
out_chr("whatever here\n\r");


The rest 10% question is how to distinguish RS232_ERRORS variable for 2 HW uarts ?
If i can not do that, the gets(), puts() and fprints() become useless, so either #USE RS232 . I can set uarts by SFRs instead loading library that i'll never use.
As i said, i'm new to C, may be i'm wrong.
Thanks for you help.

http://oi57.tinypic.com/bhn4pk.jpg
old and the new box, bad photo
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 4:37 am     Reply with quote

You seem to be determined to find a reason for not doing this in C... Just specify "errors" in the use rs232 and let the compiler deal with them. There is no "library" as such, and SFRs are rarely needed to be used in CCS C.

Regardless of that, while that document doesn't explicitly state it, I'll wager it DOES NOT need 8 bit data plus odd parity - 8. O, 1. It's almost certainly straight ASCII, which is seven bit, and therefore like most serial devices uses 7 bit data plus odd parity - 7, O, 1 - no need for nine bit data. When parity is turned off, it'll use 8 bit data with the last bit zero - 8, N, 1. Nine bit serial data is rare. It always was rare; not unheard or but certainly unusual, so much so that if it seems to be needed, then check the spec, and check it again, as it probably isn't 9 bit at all. As you've seen, the PIC hardware doesn't generate or check it (and I suspect the POS unit won't check it either!). That's not because parity is difficult to generate in hardware - its trivial, just a few exclusive or gates, and far easier than in software, which isn#t exactly hard - its because parity was already essentially obsolete when the first PIC appeared.

Generating parity in software is straightforward enough. There are several methods, and you've already got one. Bear in mind that ASCII data is seven bit, while chars are eight bit. So just get that working to generate the *eighth* bit, rather than ninth, and you should be good.

For such a receive-only device (while the spec. talks of "full-duplex" operation,I couldn't see anywhere where it sends anything back) as this, you could let the compiler use a software UART. That will sort out parity for you, but remember you only need to send it. As there is nothing coming from the unit, there is no need to check parity. Even if there was parity on incoming data, I'd strongly suggest you simply ignore it, treating the ASCII data as eight bit and masking out the top bit. Also send-only operation doesn't need interrupts.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 7:56 am     Reply with quote

Like my cat ,curiosity got the better of me, so I downloaded the VT100 manuals(couldn't find mine)...and the serial interface is based on the Intel 8251A so 8 bits and Parity is a valid setup. Now finding PARTS for one could be 'fun'.
It's be easy to confirm the setup though, turn it over, check the dip switches. We always used 8-none and I used to make RS232-current loop adapters to go the distance( 1/2 mile) to the BOF.
I really doubt it's 8+parity though...

Jay
fobi



Joined: 26 Feb 2015
Posts: 15
Location: BG

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 8:11 am     Reply with quote

Hi RF,
The device surely uses 9600 8-ODD-1. I solved this task for one LCD to overlay in 2010. I did that with hw uart to receive and software uart to transmit with PIC16F88. And ofcourse, i set receiving to 9 bits and didn't care for parity . The output stream was 19200-8-N-1. I had no loss of symbols.
Now i have to merge 2 LCDs to one ESC/P stream. In my expirience software serial routines waits a byte to be received. I can not wait because i don't know which one is receiving. So i'm using hw uarts and interrupts. Well, (i guess) i can check kbhit(stream1) and kbhit(stream1) in loop and deal without interrupts with getc(). Or using getc() in interrupts. ok
So far my receive routines looks like this.
Code:

#int_RDA
void  RDA_isr(void)
{
   tmo_A = 0;                 // clear timeout
   rxA = RCREG1;
   switch(cmd_A){             // command in progress flag
      case TRUE:
         cmb_A ++;            // command byte counter
         parse_cmd_A();
         break;
      case FALSE:
         if(rxA==0x1B){       // new command start
            cmd_A = TRUE;
         }
         else{                // receive data here
            buff_A[cnA] = rxA;
            cnA++;
         }
         break;
   }
}


I am receiving somewhat as this : ESC [ Py ; Px10 Px01 H {DATA}

Because the streams are 2 and i need to merge them, it is good idea to use at least twice faster output. I can use one of the uarts to transmit. But on PIC i can not set different speed for receive and transmit. So i am afraid that i could lost characters if i am doing that. The same apply to software output, because i have to switch off the interrupts during transmit. There is competitions everywhere! So my block diagram become like this:

RS232 (1,2) ->[VT100 to ESC/P] ->SPI->[SPI to UART]-> [TTL to 485], with PIC18F23K22 and PIC12F1822.

In my hardware i have option to use uart to transmit bypassing [SPI to UART]. Just to see if it is possible to receive and transmit with one speed. In addition, i can use this out as console out to monitor commands.

About C i'm learninig, this is my first attempt and my code looks like ASM written in C. I know Smile
I have to say, that you all helped me a lot to figure out how to make the code more C-like. For the first time i got 110% answer Smile

a bit better picture. Empty slot for SPI to UART chip.
http://oi58.tinypic.com/1ow2mf.jpg

Old working units with 9600-8-ODD-1
http://oi58.tinypic.com/rirjhl.jpg

PS: I am not on the picture


Last edited by fobi on Fri Feb 27, 2015 8:39 am; edited 2 times in total
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 8:35 am     Reply with quote

RS232_ERRORS, has the value from the last getc met, or is used for the next putc met.
So if you set it in the routine like I show, this applies to the next fputc, whichever stream this involves. If you read a character with fgetc, then RS232_ERRORS contains the status and 9th bit from that read, until you do another one.
So you can use exactly the same code for two UARTs, by just having a second copy of the fput_chr routine, called perhaps fput_chr2 (for the second UART), and using the stream for this UART in it.
The point is of course that written like this the parity calculation is massively quicker, and of course you can use the formatting abilities of printf. Smile

As a comment though, just put a jumper on JP2 of the display. This turns parity off.

Makes everything a lot simpler.
fobi



Joined: 26 Feb 2015
Posts: 15
Location: BG

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 8:43 am     Reply with quote

temtronic wrote:
Like my cat ,curiosity got the better of me, ...

Jay



http://oi61.tinypic.com/200p5qu.jpg
fobi



Joined: 26 Feb 2015
Posts: 15
Location: BG

View user's profile Send private message

PostPosted: Fri Feb 27, 2015 8:49 am     Reply with quote

[quote= ...
As a comment though, just put a jumper on JP2 of the display. This turns parity off.

Makes everything a lot simpler.[/quote]

I have to write 1kg paper (in German) with explanations to get permission to pull in the jumper. And i have to be persuasive ...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group