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 support@ccsinfo.com

Dynamic Parity Changes

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Dynamic Parity Changes
PostPosted: Wed Nov 19, 2003 4:09 pm     Reply with quote

I'm writing code that will need to change parity requirements on the fly as required by the network connection. Because I'm planing to use an interupt driven transmit routine the parity calculation must be as fast as possiable. I also need to be able to use no parity. The #use rs232 does not support this sort of thing. I can manually setup 9 or 8 bit mode as required. The following code uses 9 unneeded goto statements, one for each bit test.

Code:

....................    Byte_To_Send=25;
0022:  MOVLW  19
0024:  MOVWF  05
....................
....................    if(USE_Parity)                      // Only solve parity if it will be used
....................    {  TX9D=0;                          // Set Even parity
0026:  BTFSS  06.0
0028:  GOTO   0076
002C:  BCF    FAC.0
....................       if(Parity_ODD)  TX9D=1;          // Test/Set Odd parity??
002E:  BTFSS  06.1
0030:  GOTO   0036
0034:  BSF    FAC.0
....................       if(Tx_Bit_0)   TX9D=!TX9D;
0036:  BTFSS  05.0
0038:  GOTO   003E
003C:  BTG    FAC.0
....................       if(Tx_Bit_1)   TX9D=!TX9D;
003E:  BTFSS  05.1
0040:  GOTO   0046
0044:  BTG    FAC.0
....................       if(Tx_Bit_2)   TX9D=!TX9D;
0046:  BTFSS  05.2
0048:  GOTO   004E
004C:  BTG    FAC.0
....................       if(Tx_Bit_3)   TX9D=!TX9D;
004E:  BTFSS  05.3
0050:  GOTO   0056
0054:  BTG    FAC.0
....................       if(Tx_Bit_4)   TX9D=!TX9D;
0056:  BTFSS  05.4
0058:  GOTO   005E
005C:  BTG    FAC.0
....................       if(Tx_Bit_5)   TX9D=!TX9D;
005E:  BTFSS  05.5
0060:  GOTO   0066
0064:  BTG    FAC.0
....................       if(Tx_Bit_6)   TX9D=!TX9D;
0066:  BTFSS  05.6
0068:  GOTO   006E
006C:  BTG    FAC.0
....................       if(Tx_Bit_7)   TX9D=!TX9D;
006E:  BTFSS  05.7
0070:  GOTO   0076
0074:  BTG    FAC.0
....................    }
....................    putc(Byte_To_Send);
0076:  MOVF   05,W
0078:  BTFSS  F9E.4
007A:  GOTO   0078
007E:  MOVWF  FAD


Is there some option to turn off ICD compatability or improve optimization? I would not be so bothered by this except for the fact it has to occure within an interupt. Do I need to just write the routine in assembly?
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Wed Nov 19, 2003 5:05 pm     Reply with quote

From the older posts I remember that you can have two (or more) #use RS232 statements with overlapping pins. So I guess one way would be having two #use RS232 lines, one with parity and one without, different stream names and both using the same receive and transmit pins. Then based on your parity requirements you can choose which stream to use.
I haven't done this myself but it should work.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Thu Nov 20, 2003 9:59 am     Reply with quote

I had thought that using more than one #use 232 would work but I cant just use an if statement to check if parity is needed and apply the correct #use statement. The putc() statement is different when using parity. I cant have an interupt transmitting and a function in main chaning the parity on the fly.

Here is an example using no parity.
Code:

CCS PCH C Compiler, Version 3.180, 18844

               Filename: R:\Controlinc Group\TEC2000\Source\Function Library\test parity.LST

               ROM used: 54 (0%)
                         Largest free fragment is 0
               RAM used: 7 (0%) at main() level
                         7 (0%) worst case
               Stack:    0 locations

*
0000:  GOTO   0004
....................  #include "18F6720.h"
....................  //////// Standard Header file for the PIC18F6720 device ////////////////
.................... #device PIC18F6720
.................... #list
....................
.................... #use delay(clock=4194304)
.................... int8  TXBYTE;
.................... #use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,PARITY=N,ERRORS,stream=chanA)
*
0014:  CLRF   06
0016:  MOVLW  1A
0018:  MOVWF  FAF
001A:  MOVLW  26
001C:  MOVWF  FAC
001E:  MOVLW  90
0020:  MOVWF  FAB
.................... void Main(void)
.................... {
*
0004:  CLRF   FF8
0006:  BCF    FD0.7
0008:  CLRF   FEA
000A:  CLRF   FE9
000C:  MOVLW  0F
000E:  MOVWF  FC1
0010:  MOVLW  07
0012:  MOVWF  FB4
....................    TXBYTE=6;                  // Estabilish what byte is going to be transmitted
*
0022:  MOVLW  06
0024:  MOVWF  05
....................    putc(TXBYTE);              // Load the transmit buffer to start transmition
0026:  MOVF   05,W
0028:  BTFSS  F9E.4
002A:  GOTO   0028
002E:  MOVWF  FAD
....................    while(1);
0030:  GOTO   0030
.................... }
....................
0034:  SLEEP

Here is an example using odd parity.
Code:

CCS PCH C Compiler, Version 3.180, 18844

               Filename: R:\Controlinc Group\TEC2000\Source\Function Library\test parity.LST

               ROM used: 98 (0%)
                         Largest free fragment is 0
               RAM used: 7 (0%) at main() level
                         9 (0%) worst case
               Stack:    1 locations

*
0000:  GOTO   0032
....................  #include "18F6720.h"
....................  //////// Standard Header file for the PIC18F6720 device ////////////////
.................... #device PIC18F6720
.................... #list
....................
.................... #use delay(clock=4194304)
.................... int8  TXBYTE;
.................... #use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,PARITY=O,ERRORS,stream=chanA)
0004:  MOVLW  08
0006:  MOVWF  01
0008:  CLRF   08
000A:  INCF   08,F
000C:  MOVF   07,W
000E:  MOVWF  00
0010:  MOVF   00,W
0012:  XORWF  08,F
0014:  RRCF   00,F
0016:  DECFSZ 01,F
0018:  GOTO   0010
001C:  BTFSS  F9E.4
001E:  GOTO   001C
0022:  MOVLW  FE
0024:  ANDWF  FAC,F
0026:  BTFSC  08.0
0028:  BSF    FAC.0
002A:  MOVF   07,W
002C:  MOVWF  FAD
002E:  GOTO   005C (RETURN)
*
0042:  CLRF   06
0044:  MOVLW  1A
0046:  MOVWF  FAF
0048:  MOVLW  66
004A:  MOVWF  FAC
004C:  MOVLW  D0
004E:  MOVWF  FAB
.................... void Main(void)
.................... {
*
0032:  CLRF   FF8
0034:  BCF    FD0.7
0036:  CLRF   FEA
0038:  CLRF   FE9
003A:  MOVLW  0F
003C:  MOVWF  FC1
003E:  MOVLW  07
0040:  MOVWF  FB4
....................    TXBYTE=6;                  // Estabilish what byte is going to be transmitted
*
0050:  MOVLW  06
0052:  MOVWF  05
....................    putc(TXBYTE);              // Load the transmit buffer to start transmition
0054:  MOVFF  05,07
0058:  GOTO   0004
....................    while(1);
005C:  GOTO   005C
.................... }
....................
0060:  SLEEP





Code:

#include "18F6720.h"
#use delay(clock=4194304)           
#define TXSTA1 0xFAC         // TRANSMIT STATUS AND CONTROL REGISTER
#bit TX91 = TXSTA1.6         // Parity enabler bit
#bit TX9D1 = TXSTA1.0        // Parity data bit
#bit TRMT = TXSTA1.1         // Transmit shift status full
int8  TXBYTE;
int1  Comm1_Odd;
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,ERRORS,stream=chanA) 
#inline                      // Inline code runs faster & compiles smaller if called only once
void Comm1_Parity(void)      // Solves parity for USART 1
{
   if(TX91)                  // Only solve parity if it will be used
   {
      #asm
      bcf TX9D1              // Start by assuming even parity
      btfss Comm1_Odd        // Make a test for odd parity
      bsf TX9D1              // Set odd parity
      btfsc TXBYTE, 0
      btg TX9D1
      btfsc TXBYTE, 1
      btg TX9D1
      btfsc TXBYTE, 2
      btg TX9D1
      btfsc TXBYTE, 3
      btg TX9D1
      btfsc TXBYTE, 4
      btg TX9D1
      btfsc TXBYTE, 5
      btg TX9D1
      btfsc TXBYTE, 6
      btg TX9D1
      btfsc TXBYTE, 7
      btg TX9D1
      #endasm
   }
}
void Main(void)
{
   TX91=1;                    // Estabilish that parity will be used. Can be changed on the fly
   Comm1_Odd=0;               // Estabilish that if parity will be used it will be odd. Can be changed on the fly
   TXBYTE=6;                  // Estabilish what byte is going to be transmitted
   Comm1_Parity();            // Set parity bit if parity is enabled
   putc(TXBYTE);              // Load the transmit buffer to start transmition
   while(1);
}


This uses three extra instruction when parity is not required but supports changing on the fly and runs with the best possiable speed. Of course I still got to test it all out.
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Thu Nov 20, 2003 12:01 pm     Reply with quote

Take a look at this is you want to shave a few instructions off your parity calculation.

http://www.mindhertz.com/Parity.php

Here is another routine

;8-bit parity
;This routine will leave the parity of X in X.0
;while blenderizing most of the rest of X
swapf X, W ;x = abcdefgh w = efghabcd
xorwf X, F ;x = abcdefgh w = efghabcd
; xor efghabcd
rrf X, W ;x = abcdefgh w = -abcdefg
; xor efghabcd xor -efghabc
xorwf X, F ;x = abcdefgh w = -abcdefg
; xor efghabcd xor -efghabc
; xor -abcdefg
; xor -efghabc

; at this point, the parity for half the bits
; (a, b, e, and f) is in bit 2 of X, and the
; parity for the other half (bits c, d, g, and h)
; is in bit 0 of X.

btfsc X, 2 ; if the parity of (a,b,e,f) is 0,
; then the parity of (a,b,c,d,e,f,g,h)
; is equal to the parity of (c,d,g,h)...
; which is already in bit 0, so skip ahead.


incf X, F ; otherwise, the parity of (a,b,e,f) is 1,
; so the parity of (a,b,c,d,e,f,g,h) is
; NOT equal to the parity of (c,d,g,h).
; invert bit 0.

; at this point, bit 0 contains the parity of
; (a,b,c,d,e,f,g,h).
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Thu Nov 20, 2003 12:45 pm     Reply with quote

Thats a really good read. I'm supprised CCS are not using that method in their USART functions. I was able to shave off 7 instruction cycles.

Thanks Mark.
Code:

/***********************************************************
*    Solve for parity bit on USART 1                       *
***********************************************************/
#inline
void Comm1_Parity(void)                                     // Solves parity for USART 1
{  Static int8 x;
   if(TX91)                                                 // Only solve parity if it will be used
   {  x=TXBYTE;
      #asm
      bcf TX9D1                                             // Start by assuming even parity
      btfss Comm1_Odd                                       // Make a test for odd parity
      bsf TX9D1                                             // Set odd parity
      swapf x, W                                            // http://www.mindhertz.com/Parity.php
      xorwf x, F                                            // http://www.mindhertz.com/Parity.php
      rrf x, W                                              // http://www.mindhertz.com/Parity.php
      xorwf x, F                                            // http://www.mindhertz.com/Parity.php
      btfsc x, 2                                            // http://www.mindhertz.com/Parity.php
      incf x, F                                             // http://www.mindhertz.com/Parity.php
      btfsc x, 0                                            // If bit 0 is
      btg TX9D1                                             // Toggle
      #endasm
   }
}

Still untested though I'm waiting for new hardware.
piripic



Joined: 15 Jan 2008
Posts: 25

View user's profile Send private message

PostPosted: Fri Feb 01, 2008 2:06 pm     Reply with quote

Someone tried this trick ? I do not think that working, but I am not sure....

Not missing the XOR between X.0 and X.2 ?

Thanks

Claudio

Edit: I just simulated this example ...and.. wow, it works perfectly well without the XOR between x.0 and x.2. Excellent code


Last edited by piripic on Sat Feb 02, 2008 1:12 am; edited 1 time in total
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

parity
PostPosted: Fri Feb 01, 2008 10:07 pm     Reply with quote

takes 29 or 31 PC
joseph
Code:
   int paritycounter=0;
   int bytetosend=0;
   short int TX9D=0;
   bytetosend=0b00000000;
   paritycounter=0;
   if (bit_test(bytetosend,0))
   {
      paritycounter++;
   }
   if (bit_test(bytetosend,1))
   {
      paritycounter++;
   }
   if (bit_test(bytetosend,2))
   {
      paritycounter++;
   }
   if (bit_test(bytetosend,3))
   {
      paritycounter++;
   }
   if (bit_test(bytetosend,4))
   {
      paritycounter++;
   }
   if (bit_test(bytetosend,5))
   {
      paritycounter++;
   }
   if (bit_test(bytetosend,6))
   {
      paritycounter++;
   }
   if (bit_test(bytetosend,7))
   {
      paritycounter++;
   }
   if (bit_test(paritycounter,0))
   {
      TX9D=1;
   }
   else
   {
      TX9D=0;
   }
   restart_wdt();
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Sun Feb 03, 2008 3:24 am     Reply with quote

piripic wrote:
Someone tried this trick ? I do not think that working, but I am not sure....

Not missing the XOR between X.0 and X.2 ?

Thanks

Claudio

Edit: I just simulated this example ...and.. wow, it works perfectly well without the XOR between x.0 and x.2. Excellent code


x.0 and x.2 each have half of the parity at that point. Testing one to toggle the other finishes it.
piripic



Joined: 15 Jan 2008
Posts: 25

View user's profile Send private message

PostPosted: Sun Feb 03, 2008 11:59 am     Reply with quote

It is true! It has taken me a while 'to understand :-)
thx

Claudio
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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