cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 Bit Set Reset Register

John F.
Senior
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?
4 REPLIES 4
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
Up vote any posts that you find helpful, it shows what's working..
John F.
Senior
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?
Posted on August 31, 2012 at 15:12

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
John F.
Senior
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();
}