Hi All
Consider the following code:
ADC_CTRL1 |= 0x2000; // start an ADC conversion (address is 0x40190000 and is defined as a short word)
Now consider this code
ADC_CTRL1 = (ADC_CTRL | 0x2000); // start an ADC conversion (address is 0x40190000 and is defined as a short word)
Is there a difference?
Assembler gives, in the two cases,
0x0000000E 0x207C40190000 movea.l #1075380224,a0 ; '@...'
0x00000014 0x08D00005 bset #5,(a0)
and
0x00000018 0x7000 moveq #0,d0
0x0000001A 0x303940190000 move.w 0x40190000,d0
0x00000020 0x08C0000D bset #13,d0
0x00000024 0x33C040190000 move.w d0,0x40190000
The first fails and the second works....(the reason being that the access to the register in the first case is performed as a bit set acting on the first byte in the register whereas the second manipulates the value in a data register and performs a short word destination write - presumably this register doesn't like to be addresses as a byte.)
This leads to a question as to best practice in these situations? The problem can be solved by:
a) disabling optimisation
b) ensuring that the register is declared as volatile (although the volatile declaration is not explicitly causing the register to be handled as a volatile but does avoid the use of bset directed to a single byte).
c) use CW 6.4 rather than CW 7.2 (CW6.4 tends to use ori rather than bset when setting bits)
Maybe a bit of a theoretical topic but still interesting in some way....
Regards
Mark
Hi Mark,
I'm assuming the second example should read as
ADC_CTRL1 = (ADC_CTRL1 | 0x2000); // start an ADC conversion (address is 0x40190000 and is defined as a short word)
(ADC_CTRL1 rather than ADC_CTRL)
To me it's clear: it's a case of missing volatile keyword.
Why would anyone want to disable optimization or stick with a certain compiler version just to avoid declaring the register as volatile? It's beyond me.
Regards,
- mike
Hi Mike
Sorry, typo on the regster name in second case.
It is hyperthetical so, of course, the compiler change is also only hyperthetical, but I must admit that I thought compilers would compile the two cases x |= y; and x = (x | y); the sameway but one learns something new every day...
Regards
Mark