Skip to main content
John F.
Associate III
August 31, 2012
Question

STM32F4 Bit Set Reset Register

  • August 31, 2012
  • 4 replies
  • 1581 views
Posted on August 31, 2012 at 12:09

The file stm32f4xx.h defines the BSRR as two 16 bit ''halves''.

typedef struct
{
__IO uint32_t MODER; /*!< GPIO port mode register, Address offset: 0x00 */
__IO uint32_t OTYPER; /*!< GPIO port output type register, Address offset: 0x04 */
__IO uint32_t OSPEEDR; /*!< GPIO port output speed register, Address offset: 0x08 */
__IO uint32_t PUPDR; /*!< GPIO port pull-up/pull-down register, Address offset: 0x0C */
__IO uint32_t IDR; /*!< GPIO port input data register, Address offset: 0x10 */
__IO uint32_t ODR; /*!< GPIO port output data register, Address offset: 0x14 */
__IO uint16_t BSRRL; /*!< GPIO port bit set/reset low register, Address offset: 0x18 */
__IO uint16_t BSRRH; /*!< GPIO port bit set/reset high register, Address offset: 0x1A */
__IO uint32_t LCKR; /*!< GPIO port configuration lock register, Address offset: 0x1C */
__IO uint32_t AFR[2]; /*!< GPIO alternate function registers, Address offset: 0x24-0x28 */
} GPIO_TypeDef;

The Ref. Manual says the BSRR bits, ''can be accessed in word, half-word or byte mode.''. Can I just declare,

__IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */

to write 32 bits in one write? Anyone done this?
    This topic has been closed for replies.

    4 replies

    Tesla DeLorean
    Guru
    August 31, 2012
    Posted on August 31, 2012 at 13:39

    Probably, you'd need to watch for dependencies within the library, or use a nameless union if the compiler permits.

    Not used it on the F4, but on  F0, see no reason the hardware side would work as you expect.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    John F.
    John F.Author
    Associate III
    August 31, 2012
    Posted on August 31, 2012 at 13:56

    Hi Clive,

    ''dependencies within the library'' seems to be the problem. If I add the line,

    __IO uint32_t BSRR; /*!< GPIO port bit set/reset register, Address offset: 0x18 */

    to the library structure, it breaks the normal GPIOX->BSRRL and GPIOX->BSRRH operations. Although as you guessed, the 32 bit write to the BSRR does seem to work OK. I could just define the various port BSRR addresses as const pointers to uint32_t I suppose?
    Tesla DeLorean
    Guru
    August 31, 2012
    Posted on August 31, 2012 at 15:12

    *((uint32_t *)&GPIOD->BSRRL) = 0x10002000;

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    John F.
    John F.Author
    Associate III
    September 3, 2012
    Posted on September 03, 2012 at 11:43

    Thanks for the hint. If anyone wants to do this, the style below works.

    *((uint32_t *)&GPIOG->BSRRL) = ((uint32_t)GPIO_Pin_8); //set bit
    *((uint32_t *)&GPIOG->BSRRL) = ((uint32_t)GPIO_Pin_8) << 16; //reset bit

    However it seems to be optimised away at (Keil ARM) level 3 optimisation. I thought adding ''volatile'' would do the job but it seems not. It seems to be necessary to add a synchronisation instruction. Either DSB (Data Synchronisation Barrier) or DMB seems to work and also keeps execution in order. Does anyone know which is correct? This following code (including ''volatile'' and a barrier) seems to work OK at level 3 optimisation. (DSB works too.)

    while(1)
    {
    *((volatile uint32_t *)&GPIOG->BSRRL) = ((uint32_t)GPIO_Pin_8); //set bit
    __DMB();
    *((volatile uint32_t *)&GPIOG->BSRRL) = ((uint32_t)GPIO_Pin_8) << 16; //reset bit
    __DMB();
    }