C: Bit mask question

Bas Jacobs basfriends at gmail.com
Thu Apr 30 12:14:10 UTC 2009


On Thu, Apr 30, 2009 at 1:49 PM, Karl Auer <kauer at biplane.com.au> wrote:

> On Thu, 2009-04-30 at 13:19 +0200, Bas Jacobs wrote:
> > Consider a control register, which includes flags and bitfields. When
> > writing such a register you often see constructions like register =
> > flaga | flagb | flagc; etc. In a library those flags are then defined
> > as #define flaga (1 << 6) and #define flagb (1 << 13) (for instance).
> > In my library there is also a definition for a bitfield, which looks
> > something like this: #define bitfieldA (0x0F << 16) for a 4bit
> > bitfield located at bits 19 .. 16. Lets say that I want write 0x6 into
> > this field, how do I do this (using the macro of course)?
>
> Assuming C, you bitwise OR the desired value with the existing value,
> just as you do with single-bit values.
>
> #define bitfieldA (0x0F << 16)
> #define mybits    (0x06)
> #define myflags   (bitfieldA | mybits)
>
> Alternatively if it is bitfieldA you want changed:
>
> #define bitfieldA ((0x0F << 16) | 0x06)
>
> Uncompiled, untested, but roughly like that.
>
> Regards, K.
>
> PS: Try not to use reserved words like "register" as variable names :-)
>
> PPS Try to make your macro names look like macro names and not like
> ordinary variables. So "FLAGA" rather than "flaga"...
>
> PPPS: "16", "0x06" and "0x0F" are all candidates for getting the
>
> --
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Karl Auer (kauer at biplane.com.au)                   +61-2-64957160 (h)
> http://www.biplane.com.au/~kauer/ <http://www.biplane.com.au/%7Ekauer/>
>                +61-428-957160 (mob)
>
> GPG fingerprint: 07F3 1DF9 9D45 8BCD 7DD5 00CE 4A44 6A03 F43A 7DEF
>
> --
> ubuntu-users mailing list
> ubuntu-users at lists.ubuntu.com
> Modify settings or unsubscribe at:
> https://lists.ubuntu.com/mailman/listinfo/ubuntu-users
>
>
Karl, thanks for your fast reply.

I tried both your options but unfortunately they didn't do the trick. Your
comments were very helpful, but I used those names to simplify the problem.
I am using a library in which those macros are defined. I copied some
relevant pieces from it:

// ========== Register definition for SPI1 peripheral ==========
#define AT91C_SPI1_CSR  ((AT91_REG *)     0xFFFE4030) // (SPI1) Chip Select
Register
#define AT91C_SPI1_IDR  ((AT91_REG *)     0xFFFE4018) // (SPI1) Interrupt
Disable Register
#define AT91C_SPI1_SR   ((AT91_REG *)     0xFFFE4010) // (SPI1) Status
Register
#define AT91C_SPI1_RDR  ((AT91_REG *)     0xFFFE4008) // (SPI1) Receive Data
Register
#define AT91C_SPI1_CR   ((AT91_REG *)     0xFFFE4000) // (SPI1) Control
Register
#define AT91C_SPI1_IMR  ((AT91_REG *)     0xFFFE401C) // (SPI1) Interrupt
Mask Register
#define AT91C_SPI1_IER  ((AT91_REG *)     0xFFFE4014) // (SPI1) Interrupt
Enable Register
#define AT91C_SPI1_TDR  ((AT91_REG *)     0xFFFE400C) // (SPI1) Transmit
Data Register
#define AT91C_SPI1_MR   ((AT91_REG *)     0xFFFE4004) // (SPI1) Mode
Register

// -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register --------
#define AT91C_SPI_SPIEN       ((unsigned int) 0x1 <<  0) // (SPI) SPI Enable

#define AT91C_SPI_SPIDIS      ((unsigned int) 0x1 <<  1) // (SPI) SPI
Disable
#define AT91C_SPI_SWRST       ((unsigned int) 0x1 <<  7) // (SPI) SPI
Software reset
#define AT91C_SPI_LASTXFER    ((unsigned int) 0x1 << 24) // (SPI) SPI Last
Transfer
// -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register --------
#define AT91C_SPI_MSTR        ((unsigned int) 0x1 <<  0) // (SPI)
Master/Slave Mode
#define AT91C_SPI_PS          ((unsigned int) 0x1 <<  1) // (SPI) Peripheral
Select
#define     AT91C_SPI_PS_FIXED                ((unsigned int) 0x0 <<  1) //
(SPI) Fixed Peripheral Select
#define     AT91C_SPI_PS_VARIABLE             ((unsigned int) 0x1 <<  1) //
(SPI) Variable Peripheral Select
#define AT91C_SPI_PCSDEC      ((unsigned int) 0x1 <<  2) // (SPI) Chip
Select Decode
#define AT91C_SPI_FDIV        ((unsigned int) 0x1 <<  3) // (SPI) Clock
Selection
#define AT91C_SPI_MODFDIS     ((unsigned int) 0x1 <<  4) // (SPI) Mode Fault
Detection
#define AT91C_SPI_LLB         ((unsigned int) 0x1 <<  7) // (SPI) Clock
Selection
#define AT91C_SPI_PCS         ((unsigned int) 0xF << 16) // (SPI) Peripheral
Chip Select
#define AT91C_SPI_DLYBCS      ((unsigned int) 0xFF << 24) // (SPI) Delay
Between Chip Selects
// -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register --------
#define AT91C_SPI_RD          ((unsigned int) 0xFFFF <<  0) // (SPI) Receive
Data
#define AT91C_SPI_RPCS        ((unsigned int) 0xF << 16) // (SPI) Peripheral
Chip Select Status
// -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register --------
#define AT91C_SPI_TD          ((unsigned int) 0xFFFF <<  0) // (SPI)
Transmit Data
#define AT91C_SPI_TPCS        ((unsigned int) 0xF << 16) // (SPI) Peripheral
Chip Select Status
// -------- SPI_SR : (SPI Offset: 0x10) Status Register --------
#define AT91C_SPI_RDRF        ((unsigned int) 0x1 <<  0) // (SPI) Receive
Data Register Full
#define AT91C_SPI_TDRE        ((unsigned int) 0x1 <<  1) // (SPI) Transmit
Data Register Empty
#define AT91C_SPI_MODF        ((unsigned int) 0x1 <<  2) // (SPI) Mode Fault
Error
#define AT91C_SPI_OVRES       ((unsigned int) 0x1 <<  3) // (SPI) Overrun
Error Status
#define AT91C_SPI_ENDRX       ((unsigned int) 0x1 <<  4) // (SPI) End of
Receiver Transfer
#define AT91C_SPI_ENDTX       ((unsigned int) 0x1 <<  5) // (SPI) End of
Receiver Transfer
#define AT91C_SPI_RXBUFF      ((unsigned int) 0x1 <<  6) // (SPI) RXBUFF
Interrupt
#define AT91C_SPI_TXBUFE      ((unsigned int) 0x1 <<  7) // (SPI) TXBUFE
Interrupt
#define AT91C_SPI_NSSR        ((unsigned int) 0x1 <<  8) // (SPI) NSSR
Interrupt
#define AT91C_SPI_TXEMPTY     ((unsigned int) 0x1 <<  9) // (SPI) TXEMPTY
Interrupt
#define AT91C_SPI_SPIENS      ((unsigned int) 0x1 << 16) // (SPI) Enable
Status
// -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register --------

// -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register
--------
// -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register --------
// -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register --------
#define AT91C_SPI_CPOL        ((unsigned int) 0x1 <<  0) // (SPI) Clock
Polarity
#define AT91C_SPI_NCPHA       ((unsigned int) 0x1 <<  1) // (SPI) Clock
Phase
#define AT91C_SPI_CSAAT       ((unsigned int) 0x1 <<  3) // (SPI) Chip
Select Active After Transfer
#define AT91C_SPI_BITS        ((unsigned int) 0xF <<  4) // (SPI) Bits Per
Transfer
#define     AT91C_SPI_BITS_8                    ((unsigned int) 0x0 <<  4)
// (SPI) 8 Bits Per transfer
#define     AT91C_SPI_BITS_9                    ((unsigned int) 0x1 <<  4)
// (SPI) 9 Bits Per transfer
#define     AT91C_SPI_BITS_10                   ((unsigned int) 0x2 <<  4)
// (SPI) 10 Bits Per transfer
#define     AT91C_SPI_BITS_11                   ((unsigned int) 0x3 <<  4)
// (SPI) 11 Bits Per transfer
#define     AT91C_SPI_BITS_12                   ((unsigned int) 0x4 <<  4)
// (SPI) 12 Bits Per transfer
#define     AT91C_SPI_BITS_13                   ((unsigned int) 0x5 <<  4)
// (SPI) 13 Bits Per transfer
#define     AT91C_SPI_BITS_14                   ((unsigned int) 0x6 <<  4)
// (SPI) 14 Bits Per transfer
#define     AT91C_SPI_BITS_15                   ((unsigned int) 0x7 <<  4)
// (SPI) 15 Bits Per transfer
#define     AT91C_SPI_BITS_16                   ((unsigned int) 0x8 <<  4)
// (SPI) 16 Bits Per transfer
#define AT91C_SPI_SCBR        ((unsigned int) 0xFF <<  8) // (SPI) Serial
Clock Baud Rate
#define AT91C_SPI_DLYBS       ((unsigned int) 0xFF << 16) // (SPI) Delay
Before SPCK
#define AT91C_SPI_DLYBCT      ((unsigned int) 0xFF << 24) // (SPI) Delay
Between Consecutive Transfers

As you can see in the last few lines the boudrate is a good example. How do
I write a given value to that field using this macro?

Thanks in advance!!!

Bas
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/ubuntu-users/attachments/20090430/94369758/attachment.html>


More information about the ubuntu-users mailing list