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