2.3.3 Group Configuration Masks and Enumerators

It is often required to consult the data sheet to check the bit pattern to be used when setting a bit field to the desired configuration, which also applies when reading or debugging code. Several group configuration masks are defined in the header file to increase the readability and minimize the possibility of setting bits in bit fields incorrectly. Each group configuration mask selects a configuration for a specific group mask.

The name of a group configuration mask is a concatenation of the module type, the bit field name, a description of the configuration, and a suffix, _gc, indicating that this is a group configuration. An example of the ADC prescaler configuration is presented in Figure 2-3.

Figure 2-3. Naming Convention of Group Configuration Masks

The group configuration presented in Figure 2-3 sets the prescaler from the peripheral clock (CLK_PER) to the ADC clock with the division factor 4.

The ADC prescaler bit field consists of three bits defining the division factor. The possible configuration names are DIV2, DIV4, DIV8, DIV16, DIV32, DIV64, DIV128, and DIV256. These names make writing and maintaining code very easy, as it requires little effort to understand what configuration the specific mask selects. Table 2-2 shows the available configurations for this bit field.

Table 2-2. PRESC Bits and Corresponding Bit Group Configurations
PRESC2PRESC1PRESC0Division FactorGroup Configuration Mask
000CLK_PER divided by 2ADC_PRESC_DIV2_gc
001CLK_PER divided by 4ADC_PRESC_DIV4_gc
010CLK_PER divided by 8ADC_PRESC_DIV8_gc
011CLK_PER divided by 16ADC_PRESC_DIV16_gc
100CLK_PER divided by 32ADC_PRESC_DIV32_gc
101CLK_PER divided by 64ADC_PRESC_DIV64_gc
110CLK_PER divided by 128ADC_PRESC_DIV128_gc
111CLK_PER divided by 256ADC_PRESC_DIV256_gc

The bit group configuration is typically used in conjunction with the bit group mask to first ensure clearing the old configuration to change a bit field to a new configuration.

Unlike bit masks and group masks, the bit group configuration masks are defined using C enumerations. One enumeration is defined for each bit field. The code below shows the enumeration for the USART CMODE bit field.

typedef enum USART_CMODE_enum
{
    USART_CMODE_ASYNCHRONOUS_gc = (0x00<<6),  /* Asynchronous mode */
    USART_CMODE_SYNCHRONOUS_gc = (0x01<<6),   /* Synchronous mode */
    USART_CMODE_IRCOM_gc = (0x02<<6),         /* Infrared communication */
    USART_CMODE_MSPI_gc = (0x03<<6),          /* Host SPI mode */
} USART_CMODE_t;

The name of the enumeration is a concatenation of the module type (USART), the bit field (CMODE), and a suffix (_enum).

Figure 2-4 presents the naming convention.

Figure 2-4. Naming Convention of Enumerations

Each of the enumeration constants behaves much like an ordinary constant when used on its own. However, using an enumeration type definition has the advantage of creating a new data type. The name of the data type, for this example, is USART_CMODE_t. A USART_CMODE_t variable can be used directly as an integer, but assigning an integer to an enumeration type will trigger a compiler warning, which can be used to the programmer’s advantage.

Any legal or illegal value can, for example, be passed to the function if a function that sets the communication mode for a USART module accepts the communication mode as an integer type (for example, unsigned char). Only the four predefined constants in the USART_CMODE_t enumeration type can be passed to the function if the function instead accepts a parameter of type USART_CMODE_t. Passing anything else will result in a compiler warning.

Note: It is important to notice that the constants in the code listing are already shifted to their bit position. The enumeration constants are the actual values to be written in the register, and no additional shifting is needed.