1 Reply Latest reply on May 8, 2012 5:11 PM by r..t.

    UART Parity Bit Enumerated Types and Parameters

    peter.taylor

      I feel like I missed the first day of class when some basic idea was taught that makes the world make sense.  I just spent an entire day troubleshooting my UART code.  When my project initializes the UART connection, it starts with no parity, then sends the +ICF command to change the modem's UART to an ODD parity.  Then my UART quickly reconfigures to ODD parity and off we go, saving the world and whatnot.  However, I was loosing all communications as soon as I told the modem to switch to ODD parity.  It turned out to be a problem with how I was reconfiguring my UART to ODD parity.  Here's how I was trying to do it:

         

      UART_WriteControlRegister( (UART_ReadControlRegister() & ~UART_CNTRL_PARITY_TYPE_MASK) | UART__B_UART__ODD_REVB );

         

      It never occurred to me that I might need to modify the ODD_REVB constant to set the correct bits.  Finally, I noticed with debugging that the wrong bits were being set by this command so I looked up the #define for these constants in the header file.  Here are the #defines:

         

      /* Control Register definitions */

         

      ...

         

      #define UART_CTRL_PARITY_TYPE0_SHIFT            (0x03u) /* Defines the type of parity implemented */

         

      #define UART_CTRL_PARITY_TYPE1_SHIFT            (0x04u) /* Defines the type of parity implemented */

         

      ...

         

      #define UART_CTRL_PARITY_TYPE_MASK              (0x03u << UART_CTRL_PARITY_TYPE0_SHIFT)

         

      ...

         


      /***************************************

         

      * Enumerated Types and Parameters*

         

      **************************************/

         

      ...

         

      #define UART__B_UART__NONE_REVB 0

         

      #define UART__B_UART__EVEN_REVB 1

         

      #define UART__B_UART__ODD_REVB 2

         

      #define UART__B_UART__MARK_SPACE_REVB 3

         

      ...

         


      As you can see, the parity constant values are relative to the mask, whereas I expected them to be shifted to the correct position in the byte.  So, after making the change below, everything works a whole lot better:

         


      UART_WriteControlRegister( (UART_ReadControlRegister() & ~UART_CTRL_PARITY_TYPE_MASK) | (UART__B_UART__ODD_REVB << UART_CTRL_PARITY_TYPE0_SHIFT) );

         


      I am not a classically trained programmer.  When I define constants for addressing bits in a bitfield, I will "pre-shift" them in the #define.  Is it more standard practice to do it the way this UART API is written?  Hopefully, this will help anyone else who missed the first day of class to save themselves a concussion from beating their heads on their keyboards like I did.