cancel
Showing results for 
Search instead for 
Did you mean: 

Bit Banding DMA problem

ryan2399
Associate II
Posted on March 20, 2008 at 07:50

Bit Banding DMA problem

5 REPLIES 5
ryan2399
Associate II
Posted on May 17, 2011 at 12:27

I'm trying to use bit banding to enabled/disable a DMA channel. The problem is when I write to the DMA enable bit, other bits in the DMA's CCR register are written to as well. Bits TCIE, MINC, PSIE & MSIZE are zeroed in this case and a bus error results as soon as the DMA transfer starts.

I'm using the recommended method for creating a C macro.

#define PERIPH_BB_BASE ((u32)0x42000000)

#define PERIPH_BASE ((u32)0x40000000)

#define BITBAND_PERI(a,b) ((PERIPH_BB_BASE + (a-PERIPH_BASE)*32 + (b*4)))

#define DMA2_EN *((volatile unsigned char *)(BITBAND_PERI(DMA_Channel2_BASE,0)))So to enable the DMA channel in C:

DMA2_EN = 1;

which creates the assembly code:

LDR R0, [PC, #0x5C] ; R0 is loaded with the correct value of 0x42400380

MOVS R1, #0x1

STRB R1, [R0]A workaround would be to use a read-modify-write method for accessing the CCR register, but that defeats the purpose of having the bit band. Or, if I change the macro to point to a long instead of a char the enable bit is written to correctly and no other bit is modified. But why does this make a difference? The bit band isn't supposed to care if I write 0x01 or 0x00000001 to it. The DMA CCR register is the only one I've had this issue with when using bit banding (so far).

This macro works:

#define DMA2_EN *((volatile unsigned long *)(BITBAND_PERI(DMA_Channel2_BASE,0)))

So to enable the DMA channel in C:

DMA2_EN = 1;

which creates the assembly code:

LDR R0, [PC, #0x5C] ; R0 is loaded with the correct value of 0x42400380

MOVS R1, #0x1

STR R1, [R0]

lanchon
Associate III
Posted on May 17, 2011 at 12:27

hi ryan,

hardware need not be insensitive to access width. for instance, GPIO registers must be accessed in word mode and flash must be written as half-words. I seem to remember that bitband bits must be accessed as words, which makes sense if as a hardware designer you are forced to choose.

in the #define DMA2_EN macros remember to parenthesize the whole definition.

I prefer to use these macros:

#include ''stm32f10x_lib.h''

#define BB_BIT(REGISTER, BIT_NUMBER, BASE, BB_BASE)

((volatile s32*) ((BB_BASE) + (((u32) &(REGISTER)) - (BASE)) * 32 + (BIT_NUMBER) * 4))

#define PERIPHERAL_BIT(REGISTER, BIT_NUMBER)

BB_BIT(REGISTER, BIT_NUMBER, PERIPH_BASE, PERIPH_BB_BASE)

#define SRAM_BIT(REGISTER, BIT_NUMBER)

BB_BIT(REGISTER, BIT_NUMBER, SRAM_BASE, SRAM_BB_BASE)

#define MY_LED PERIPHERAL_BIT(GPIOC->ODR, 12)

// *MY_LED = 1;

ryan2399
Associate II
Posted on May 17, 2011 at 12:27

lanchon,

Thanks for the reply.

It's not really clear in the documentation whether the bit band should be accessed as a byte or word. ARM's technical FAQ shows an SRAM bit-band being accessed as a word and a peripheral bit-band being accessed as a byte.

http://www.arm.com/support/faqdev/15921.html

I guess I'll stick with word access only unless I can find some documentation that states otherwise.

I like those macros... A lot easier to read.

Ryan

lanchon
Associate III
Posted on May 17, 2011 at 12:27

I'm sorry I can't remember where I read about word access. but I'm sure I did read something when I had to choose the ''return type'' of the BB_BIT macro.

bob239955
Associate II
Posted on May 17, 2011 at 12:27

There is a bitbanding example in ST's firmware library here;-

http://www.st.com/mcu/familiesdocs-110.html#Firmware

Look in folder STM32F10xFWLib\FWLib\examples\CortexM3\Example1