[En-Nut-Discussion] Do we need something like sbv/sbi to complement sbi/cbi?
Uwe Bonnes
bon at elektron.ikp.physik.tu-darmstadt.de
Wed Jan 4 19:11:20 CET 2012
>>>>> "Ulrich" == Ulrich Prinz <ulrich.prinz at googlemail.com> writes:
Ulrich> Hi! Am 01.01.2012 17:26, schrieb Uwe Bonnes:
>> Hello,
>>
>> a happy new year to all!
>>
>>>>>>> "Ulrich" == Ulrich Prinz <ulrich.prinz at googlemail.com> writes:
>> But I see one major obstacle: The ST provided headers mostly only
>> define bit values, not the bit position.
>>
>> As I don't know of a macro to invert the BV() macro, we have to add
>> bit position defines to the header files. Should these definitions
>> go into stm32_<device>.h?
>>
Ulrich> It is the best Place to add them there.
Well, probably at least the _BIxx() macro should go in there. Not the first
one posted and not the corrected one, but the one in my playground code.
>> ...
Ulrich> Please look at the stm32_gpio.c and it's relevant .h file. All
Ulrich> gpio functions are single cycle single access regardless of
Ulrich> their names.
>>
Ulrich> Using the bitband functions as a reference any Cortex Register
Ulrich> can be access atomic for switching single bits in it.
>> Isn't the STM GPIO a bad example. With the BSRR registers, atomic
>> access is also possible without bit banding... So i think e.g.
>> #define GpioPinSetHigh(bank, bit) \
>> GPIOMEM(GPIOBITBAND((bank+GPIOBBREG_BSRR), (int)bit)) = 1
Ulrich> Wrong: If you need to set a ping if a variable has a value that
Ulrich> is non zero and reset the pin as long as the variable is zero,
Ulrich> you produce a lot of code if you use BSRR / BRR as you have to
Ulrich> do an if, free a register, write a bitmask into it and write
Ulrich> that bitmask into the gpio register. if (myvar) BSRR = MY_BIT;
Ulrich> else BRR = MY_BIT;
Ulrich> If you use bitband any value written to the bits register will
Ulrich> result in a written 1 if it is not equal zero and a written 0 if
Ulrich> it is.
Ulrich> bitband(MY_BIT)=myvar;
Ulrich> That's atomic :)
But if there is a need for atomic set/reset of multiple GPIO, the BSRR is
the way to go.
>> could be happily replaced with #define GpioPinSetHigh(bank, bit)
>> GPIOMEM(GPIOBBREG_BSRR, BV(bit)) and #define GpioPinSetLow(bank, bit)
>> GPIOMEM(GPIOBBREG_BSRR, BV(bit+16))
Ulrich> Ups... The second isn't atomic as it requires the shift left as
Ulrich> long as the value is not constant at first pass of the compiler.
Ulrich, the ST rm0008.pdf tells:
Bits 31:16 BRy: Port x Reset bit y (y= 0 .. 15)
These bits are write-only and can be accessed in Word mode only.
0: No action on the corresponding ODRx bit
1: Reset the corresponding ODRx bit
Note: If both BSx and BRx are set, BSx has priority.
Bits 15:0 BSy: Port x Set bit y (y= 0 .. 15)
These bits are write-only and can be accessed in Word mode only.
0: No action on the corresponding ODRx bit
1: Set the corresponding ODRx bit
And also
The purpose of the GPIOx_BSRR and GPIOx_BRR registers is to allow atomic
read/modify accesses to any of the GPIO registers. This way, there is no
risk that an IRQ occurs between the read and the modify access.
So where is it not atomic?
...
Ulrich> Only for special bit that need imediate special attention to
Ulrich> speed up things and to optionally guarantee atomic access, you
Ulrich> could add the bitband thingy.
Why not use someting like
CM3BB(RCC_BASE, RCC_TypeDef, CR, _BI32(RCC_CR_PLLON)) = 1;
for most cases. Is it so much unpleasant in typeing than
RCC->CR |= RCC_CR_PLLON
All the calculations are done at compile time now. Fast and small code...
Bye
--
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
More information about the En-Nut-Discussion
mailing list