Coldfire register access, best practice and compiler dependency

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Coldfire register access, best practice and compiler dependency

875 Views
mjbcswitzerland
Specialist V

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

Labels (1)
0 Kudos
2 Replies

310 Views
scifi
Senior Contributor I

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

0 Kudos

310 Views
mjbcswitzerland
Specialist V

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

 

0 Kudos