Bit Banding

WHAT?

Bit Banding is a method of performing atomic bitwise modifictions to memory. If you have used small PIC micros before these are like BSF and BCF (Bit Set and Bit Clear)

WHY?

Usually changing a word in memory requires a read-modify-write cycle. If this operation is interrupted there can be data loss. <<info>> Read (0xaa) from A to register
Interrupt!
Write (0x33) to A
Return!
Modify (0xaa to 0xab)
Write (0xab) to A
<</info>>

(0x33) data has been lost!
The is avoided by disabling interrupts/using a supervisor mode or by using bit-banding as shown here.

HARDWARE

Two 1MB 'bit-band' regions, one in the peripheral memory area and one in the SRAM memory areas are each mapped to a 32MB virtual 'alias' region. Each bit in the bit-band region is mapped to a 32bit word in the alias region.

The first bit in the 'bit-band' peripheral memory is mapped to the first word in the alias region, the second bit to the second word etc.

/media/uploads/rod_vdb/arm_bit-band.png Image: UM1360 NXP LPC17XX User Manual, Accessed 12/1/2011

Writing a value to the alias region with Least Significant Bit i.e. bit[0] set to 1 will write a value of 1 to the bit-band bit. Conversely writing a value of 0 will clear the bit-band bit. The value of the bits[31:1] in the alias region for any word are unmapped and will have no effect on the bit-band value.

Calculating addresses

&lt;<code>&gt; alias_word_address = alias_region_base + (bit_band_byte_offset x 32) + (bit_number x 4) &lt;</code>&gt;

alias_word_address =&gt; Where to write to in order to change bit-band value
alias_region_base =&gt; Starting memory location of alias
bit_band_byte_offset =&gt; Difference between target bit-band byte address and base of bit-band memory location
bit_number =&gt; 0-7 the number of the bit in the bit-band you would like to change.

0x20000000 ==&gt; Base address of SRAM
0x22000000 ==&gt; Base address of SRAM alias region

0x40000000 ==&gt; Base address of peripheral region
0x42000000 ==&gt; Base address of peripheral alias region

How it is done

&lt;<code>&gt; Define base address of bit-band

  1. define BITBAND_SRAM_BASE 0x20000000 Define base address of alias band
  2. define ALIAS_SRAM_BASE 0x22000000 Convert SRAM address to alias region
  3. define BITBAND_SRAM(a,b) ((ALIAS_SRAM_BASE + (a-BITBAND_SRAM_BASE)*32 \ + (b*4)))

Define base address of peripheral bit-band

  1. define BITBAND_PERI_BASE 0x40000000 Define base address of peripheral alias band
  2. define ALIAS_PERI_BASE 0x42000000 Convert PERI address to alias region
  3. define BITBAND_PERI(a,b) ((ALIAS_PERI_BASE + (a-BITBAND_PERI_BASE)*32 \ + (b*4)))

Define some memory address

  1. define MAILBOX 0x20004000 Define a hardware register
  2. define TIMER 0x40004000

Mailbox bit 0

  1. define MBX_B0 *((volatile unsigned int *)(BITBAND_SRAM(MAILBOX,0))) Mailbox bit 7
  2. define MBX_B7 *((volatile unsigned int *)(BITBAND_SRAM(MAILBOX,7))) Timer bit 0
  3. define TIMER_B0 *((volatile unsigned char *)(BITBAND_PERI(TIMER,0))) Timer bit 7
  4. define TIMER_B7 *((volatile unsigned char *)(BITBAND_PERI(TIMER,7)))

int main(void){ unsigned int temp = 0; MBX_B0 = 1; Word write temp = MBX_B7; Word read TIMER_B0 = temp; Byte write return TIMER_B7; Byte read }

&lt;</code>&gt; Code: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/CHDJHIDF.html modified for naming used in text

More Code:

There is some nicer written code: http://www.micromouseonline.com/blog/2010/07/13/bit-banding-in-the-stm32 it does the same thing but it a bit prettier.

Recap

Use this method when you need atomic (non interruptible) changes to a bit in SRAM or peripheral mapped memory.

If you don't need atomic changes then this process is slower as you can only change one bit at a time.

In certain circumstances (changing lots of bits) it may be quicker to disable interrupts, make the changes and re-enable interrupts.

Hope this helps

Sources

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0337e/Babgcaie.html

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4203.html

http://www.micromouseonline.com/blog/2010/07/13/bit-banding-in-the-stm32

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dai0179b/CHDJHIDF.html


3 comments on Bit Banding:

12 Jan 2011

FYI, LPC1700 does not implement bit banding. For atomic updates you can use __strex intrinsic. For GPIOs you have set and clear registers using which you can set or clear any set of pins for a port at once, not changing the rest.

12 Jan 2011

Dammit, oh well just put this down to general knowledge! To stop me going mad in future, how can you tell that the LPC17xx does not have it implemented? http://ics.nxp.com/support/documents/microcontrollers/pdf/user.manual.lpc17xx.pdf This data sheet is directly from the NXP website and talks in detail about bit-banding... Is this just info they forgot to take out?? Cheers

12 Jan 2011

Sorry, I remembered wrong. Apparently it's the LPC13xx which doesn't have bit banding.

Please log in to post comments.