register definitions in headers files (why append _mask)

All design tool related questions: compiler, assembler, linker. Embedded programming questions: assembler, C code.

Moderator: nferre

nick9995
Posts: 2
Joined: Fri Jan 17, 2014 2:49 pm

register definitions in headers files (why append _mask)

Fri Mar 07, 2014 10:14 pm

Hello all,

I have a question about header file definitions. I am using the Rowley Crossworks IDE for a SAM9N12. If I look in one of the include files, I see lots of register definitions. For example, for the PMC controller:

Code: Select all

#define PMC_PCER (*(volatile unsigned long *)0xFFFFFC10)
and then some of the options of this register:

Code: Select all

#define PMC_PCER_PIOA_PIOB_MASK 0x4
#define PMC_PCER_PIOA_PIOB 0x4
#define PMC_PCER_PIOA_PIOB_BIT 2
So if I want to apply a clock signal to the peripheral controller, I can do so by:

Code: Select all

 PMC_PCER |= PMC_PCER_PIOA_PIOB;      // enable PIOA_PIOB peripheral clock
what is the difference between PMC_PCER_PIOA_PIOB_MASK and PMC_PCER_PIOA_PIOB. They are both defined with the same value. Is it a 'c' convention to use the mask in certain circumstances? What about the definition of _BIT as 2, what can that be used for?

This trivial question has brickwalled me for the moment. Thanks all!
jharley
Posts: 238
Joined: Thu Dec 06, 2012 6:40 am

Re: register definitions in headers files (why append _mask)

Sat Mar 08, 2014 1:19 am

Hello,

These are all handy for bit operations...

The *_BIT values can be used to shift a value to the proper location for the register and the *_MASK is used to make sure the value doesn't exceed the bit field size.

The *_MASK can also be used to clear a bit field in the register.

Code: Select all

SPI0_CSR1 = ((0 << SPI0_CSR1_CPOL_BIT) & SPI0_CSR1_CPOL_MASK) |
            ((1 << SPI0_CSR1_NCPHA_BIT) & SPI0_CSR1_NCPHA_MASK) |
            ((0 << SPI0_CSR1_CSAAT_BIT) & SPI0_CSR1_CSAAT_MASK) |
            ((10 << SPI0_CSR1_BITS_BIT) & SPI0_CSR1_BITS_MASK) |
            ((0x5A << SPI0_CSR1_SCBR_BIT) & SPI0_CSR1_SCBR_MASK) |
            ((24 << SPI0_CSR1_DLYBS_BIT) & SPI0_CSR1_DLYBS_MASK) |
            ((255 << SPI0_CSR1_DLYBCT_BIT) & SPI0_CSR1_DLYBCT_MASK);

// Clear the SCBR bits
SPI0_CSR1 &= ~SPI0_CSR1_SCBR_MASK;
Items that have only one bit size will have the several of these defined the same.

Code: Select all

#define SPI0_CSR1 (*(volatile unsigned long *)0xF0000034)
#define SPI0_CSR1_OFFSET 0x34
#define SPI0_CSR1_CPOL_MASK 0x1
#define SPI0_CSR1_CPOL 0x1
#define SPI0_CSR1_CPOL_BIT 0
#define SPI0_CSR1_NCPHA_MASK 0x2
#define SPI0_CSR1_NCPHA 0x2
#define SPI0_CSR1_NCPHA_BIT 1
#define SPI0_CSR1_CSAAT_MASK 0x8
#define SPI0_CSR1_CSAAT 0x8
#define SPI0_CSR1_CSAAT_BIT 3
#define SPI0_CSR1_BITS_MASK 0xF0
#define SPI0_CSR1_BITS_BIT 4
#define SPI0_CSR1_SCBR_MASK 0xFF00
#define SPI0_CSR1_SCBR_BIT 8
#define SPI0_CSR1_DLYBS_MASK 0xFF0000
#define SPI0_CSR1_DLYBS_BIT 16
#define SPI0_CSR1_DLYBCT_MASK 0xFF000000
#define SPI0_CSR1_DLYBCT_BIT 24
nick9995
Posts: 2
Joined: Fri Jan 17, 2014 2:49 pm

Re: register definitions in headers files (why append _mask)

Tue Mar 11, 2014 11:37 pm

Thanks! That clears up a few questions. I see the terms flag and interrupt used in datasheets and I am not sure if they are being used synonymously. Sometimes the datasheet gives the option to either use an interrupt or poll the status register. Do I need to enable interrupts for the status register to change?

I have been trying to poll the MCKRDY flag as such but my loop just hangs.

Code: Select all

void enable_xtal_osc(void){						
	PMC_MCKR |= ((0x0 << PMC_MCKR_CSS_BIT) & PMC_MCKR_CSS_MASK);	
	while(PMC_SR_MCKRDY);						
}

Return to “Development Tools”

Who is online

Users browsing this forum: No registered users and 2 guests