XC800/XC878 shifting operations on protected SFRs are limited

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
The following is just for the record, something that's been puzzling me for a while and I think this little pitfall should be recorded somewhere public. Where it might spare someone else a frustrating day of debugging.

The following code is an excerpt from my PLL setup.

This code works:

ubyte tmp;
...
tmp = (uword)ndiv >> CNT_NDIVL;
MAIN_vUnlockProtecReg();
PLL_CON1 = (tmp << BIT_NDIVH) | (pdiv << BIT_PDIV);
tmp = ndiv & ((1 << CNT_NDIVL) - 1);
MAIN_vUnlockProtecReg();
PLL_CON = tmp << BIT_NDIVL;


The following code doesn't:

MAIN_vUnlockProtecReg();
PLL_CON1 = (((uword)ndiv >> CNT_NDIVL) << BIT_NDIVH) | (pdiv << BIT_PDIV);
MAIN_vUnlockProtecReg();
PLL_CON = (ndiv & ((1 << CNT_NDIVL) - 1)) << BIT_NDIVL;


The problem occurs both with the C51 and SDCC compilers. It's difficult to debug, because the debugger often looses the µC when the clock speed is too wrong. From glancing at the ASM output I have the impression that using the tmp variable the compiler is better able to optimize the shifting operations. E.g. the variable disappears from the code and SDCC (that's what I looked at) puts the value in a register, properly shifted, right at the beginning of the function where ndiv is calculated.

So my current conclusion is that the 32 cycles during which the bit protection is turned off simply don't suffice for all the shifting done in a single line. It needs to be broken up into little pieces so the bit protection is only unlocked when the final result is written to the SFR.

For your information:

#define BIT_NDIVL 2
#define CNT_NDIVL 6
#define BIT_NDIVH 5
#define CNT_NDIVH 3
0 Likes
2 Replies
Not applicable
Hello
I can not write programs with keil 4 you "Register MOD_PAGE " in my address.
Please help me
EMAIL : avr1083@gmail.com
0 Likes
Not applicable
a) Can you give an example of what doesn't work, i.e. how do you try to switch MOD_PAGE?

b) It's not nice to hijack a topic with something unrelated. It messes up searching for stuff and makes following threads confusing. You should have opened a new thread or found one related to your question.

c) (c and d are not specific to your question, you just triggered my ranting mode) People frequently contact me via PM or e-mail. Probably because it's more personal. I do answer these kinds of messages, but I really don't like to, because it excludes other people who might be looking for a clue to fixing a similar problem.

d) If you ask a question, no one is able to help you and you find the answer on your own, please share the answer with the rest of the world by replying to your own original question.
0 Likes