Skip to main content
ryan2399
Associate II
March 20, 2008
Question

Bit Banding DMA problem

  • March 20, 2008
  • 5 replies
  • 1204 views
Posted on March 20, 2008 at 07:50

Bit Banding DMA problem

    This topic has been closed for replies.

    5 replies

    ryan2399
    ryan2399Author
    Associate II
    May 17, 2011
    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
    May 17, 2011
    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.

    ryan2399
    ryan2399Author
    Associate II
    May 17, 2011
    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
    May 17, 2011
    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;

    bob239955
    Associate III
    May 17, 2011
    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