Programming CLKPR

Go To Last Post
28 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!
I'm trying to set prescaler on Arduino2009 by using Atmel Studio 6
After I realised that I can't change fuses without programming a bootloader, I choose to modify prescaler to test the MCU in other conditions of clock.

So, I wrote this

# define F_CPU 16000000UL
#include 
#include 


int main(void)
{
	
	CLKPR=_BV(CLKPCE);
	CLKPR=(CLKPR & (~_BV(CLKPS0) | ~_BV(CLKPS1) | ~_BV(CLKPS2) | _BV(CLKPS3)));
	DDRB=0x20;
	unsigned int i;
    while(1)
    {
	for(i=0; i<65000; i++);
	for(i=0; i<65000; i++);
	for(i=0; i<65000; i++);
	for(i=0; i<65000; i++);
     //_delay_ms(1000); it was for test if was a real 16Mhz
	 PINB=0x20;
    }
}

But after that, the for cycles seems to be the same. I mean, the toggling speed is the same. WHY?

Thank to all!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

But after that, the for cycles seems to be the same. I mean, the toggling speed is the same. WHY?

You need to read: Optimization and the importance of volatile in GCC

Bottom line: your for() loops will be "eaten". As your own commented code shows if you want a delay that is not eaten by the optimiser then use _delay_ms() instead.

Also assuming you are just writing CLKPR to clear the effect of CKDIV8 (yet I don't believe any Arduino has that fuse set??) then just use:

CLKPR = _BV(CLKPCE);
CLKPR = 0;

simple as that - this sets CLKPR to the /1 value so the chip behaves as if CKDIV8 is not set (whether it is or not).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Read and inwardly digest avr-libc documentation to see how to use clock_prescale_set(x).

If you use the facilities, it will work regardless of how stupid AS5 or avr-gcc is about Optimisation.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

Bottom line: your for() loops will be "eaten". As your own commented code shows if you want a delay that is not eaten by the optimiser then use _delay_ms() instead.

Can I disable this optimization? But even what you say is right, about others for() are erased, the remaining one should be change its speed, anyway.
EDIT: I try to erase others 3 loops: it goes faster. THere's no eating and the mistery remain

clawson wrote:

Also assuming you are just writing CLKPR to clear the effect of CKDIV8 (yet I don't believe any Arduino has that fuse set??) then just use:

CLKPR = _BV(CLKPCE);
CLKPR = 0;

simple as that - this sets CLKPR to the /1 value so the chip behaves as if CKDIV8 is not set (whether it is or not).

The arduino has a preprogrammed fuses in bootloader (they're protected without a programmer) with clock div disable and external clock.
OT section: this don't deserve a topic, please let me ask :)
The external clock is used, I suppose, with already squared waveform because use only one xtal pin. But the arduino clock is a crystal connected to both XTAL pins, so the source should be the external crystal, not external clock.
Reading L fuses, if it can be useful:
:0100000000FF
:00000001FF

Others like H and E fuses are the same. I dont know how to read those one with consciousness.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

EPIC! I just reused the setting of the register clock prescaler with a decimal number. It works!

Thanks :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What was "EPIC!"? Show your code so that others can benefit from it. :)

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can read your fuses by simply compiling and running this:

#include 

void print_val(char *msg, uint8_t val)
{
  Serial.print(msg);
  Serial.println(val, HEX);
}

void setup(void)
{
  
  Serial.begin(9600);
    print_val("lockb = 0x", boot_lock_fuse_bits_get(1));
    print_val("ext fuse = 0x", boot_lock_fuse_bits_get(2));
    print_val("high fuse = 0x", boot_lock_fuse_bits_get(3));
    print_val("low fuse = 0x", boot_lock_fuse_bits_get(0));
#define SIGRD 5
#if defined(SIGRD) || defined(RSIG)
    Serial.print("Signature : ");
    for (uint8_t i = 0; i < 5; i += 2) {
        Serial.print(" 0x");
        Serial.print(boot_signature_byte_get(i), HEX);
    }
    Serial.println();
#endif

}

void loop(void)
{
}

Remove the signature reading if you have a non-P or non-A chip.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Also assuming you are just writing CLKPR to clear the effect of CKDIV8
Moreover, the original code may not have worked anyways because it likely violates the timing constraints of 4 clocks.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:
Quote:
Also assuming you are just writing CLKPR to clear the effect of CKDIV8
Moreover, the original code may not have worked anyways because it likely violates the timing constraints of 4 clocks.

Maybe was the only problem. But if it was read or interpreted by an equivalent assignment, it was take less than 4.

larryvc wrote:
What was "EPIC!"? Show your code so that others can benefit from it.

I just applied what's written on this thread XD

Moreover, I try to understand this:
1/16Mhz=tck
tck*256=t_ck_cpu
Now, after every other setting, i just increment one variable and compare this, but trascurating this:
t_ck_cpu*65000=time every transition of led.
And it's about 1 s instead of real 4 seconds. Can one try to help me this difference of time?

About fuses, thanks for the code. The low fuses are 0xFF... it's mean that are programmed or not? If programmed are zeros, but every bit of the exa FF refers to the programmed bit (0) or logic one? I mean
1111=F or, for not logic, 0000=F? Because if 1111=F I've the CLKDIV8 enabled and external clock (it can't work for actual crystal oscillator because the presence of one XTAL, imho... section 8.8 p 34 of datasheet)
Oh, and always about the 1111=F, the SUT fuses are in reserved mode XD
Maybe, at this point, I just answered by my self.. but of course I'm not sure :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
But if it was read or interpreted by an equivalent assignment, it was take less than 4.
It would not be interpreted as an assignment, it is a read-modify-write statement. And this is irrelevant since the statement was incorrect anyways:

CLKPR=(CLKPR & (~_BV(CLKPS0) | ~_BV(CLKPS1) | ~_BV(CLKPS2) | _BV(CLKPS3))); 

which is the same as:

CLKPR=(CLKPR & (0xfe | 0xfd | 0xfb | 0xf7));

which is the same as:

CLKPR=(CLKPR & 0xff);

which s the same as:

CLKPR=CLKPR;

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok thanks, you're very pro ;)

And for my others doubts?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As suggested earlier, you should always use the facilities provided by the Compiler. e.g. or
The reason is simple. Avr-gcc is brain-dead with "zero optimisation". It is also likely that some C statements will produce read-modify-write sequences. And hence violate the strict 4-cycle timing of some critical hardware operations.

Simple rules:
1. if there is a library call or Arduino method, USE it.
2. use the |= operation only when necessary. = is often suitable. think about the effect.

Many things are already supplied by the Arduino system. Just look and / or ask.

Fuses are difficult for Humans to understand. So I always go to http://www.engbedded.com/fusecalc/
Believe me, most people get brain-ache from trying to set fuses via the data sheet. Use the website.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In these days I don't like anymore the Arduino method. At university we learned stuff about MCUs and we used Freescalers. The approach was completely different, we worked on registers strctly for understand it.
Only in C, with simple programs that manage ADCs, PLLs, timers, interrupts, output to stepper motors: all togheter this function are less than blik program on arduino. Because we don't use any library or objects.

I just simply want to use the same approach on easier mcu like the 328p, with every optimization possible. And for doing this, I need to understand most things possible, so I will use Arduino stuff and pre-made libraries only if undertand those things.

Hope you'll still help me. :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using the correct method does not mean that you don't have to understand it.

It is important that you learn how to use libraries. Whether you use AVR or Freescale or Linux, you must learn how to read documentation.

Then you make library or system calls correctly.

You can examine the generated code and understand how and why it performs its purpose.

Of course you can always dig up your own iron ore to make your own motor car.
Or even dig up your own sand to make a silicon chip.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:

Of course you can always dig up your own iron ore to make your own motor car.
Or even dig up your own sand to make a silicon chip.

It's sarcasm? Because it seems that you don't understand that for learn something you have to do with yourself and only after you can use other libs, if you want. No offense.
If I see a code that I never wrote, I can't (usually for me) rewrite this by my self. That's why we do things that we call "exercises" over all the entire academic career.

Btw, your association with sand to make silicon, it's not compatible with using or not object and pleasant libraries. Someone had to say it to you.

I was searching for help for a misunderstanding.

I repost my question:

If I read an F, about fuses, it means that I've 4 bit programmed or unprogrammed?

Maybe I've post in the wrong section. Sorry :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

for learn something you have to do with yourself and only after you can use other

No, that isn't true. Otherwise, there would be no need for textbooks or schools.

Indeed some of us do original work--true research--from time to time. Yet even that, including patentable applications, are very largely built on the work of others.

I've expressed the same thoughts as you are objecting to many times on these forums.

Now, I'm old and can't keep up with all the new-fangled stuff. But it seems that many posters here do not have a sound basis in the basics. I had many courses at university starting at the basics of circuits and logic blocks and computer architecture and algorithms and programming languages. While certainly outdated most or all of the principles still apply. And I still refer to the books from a bygone era. When I want to do a PID, I consult my books. I still learn a lot but I don't just post "Help me with my PID and don't give me any references to prior art."

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thexeno wrote:
If I read an F, about fuses, it means that I've 4 bit programmed or unprogrammed?

According to Atmel any bit in the fuses that is a 1 is unprogrammed, and likewise, any bit that is a 0 is programmed. So, to answer your question, the 4 bit is unprogrammed.

I dislike the terms programmed and unprogrammed, as they lead to ambiguity of what that really means. I prefer to think that when a fuse bit is a 1 it is disabled, and when it is a 0 it is enabled.

Also go to the link David had kindly provided.

david.prentice wrote:
...Fuses are difficult for Humans to understand. So I always go to http://www.engbedded.com/fusecalc/
Believe me, most people get brain-ache from trying to set fuses via the data sheet. Use the website.

David.

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can be a world greatest guru in CPUs, I can be a co-founder of AMD, but if I don't know if syntax used in the script is the same used in datasheet, it's useless. XD
But never mind. Let's talk to useful AND (NOT OT) stuff :D

If I read an F, about fuses, using the useful script posted by David, it means that I've 4 bit programmed or unprogrammed?

EDIT: @larryvc I read you post after that I wrote this. :)

After all this stuff, thanks. :) :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
It's sarcasm? Because it seems that you don't understand that for learn something you have to do with yourself and only after you can use other libs, if you want. No offense.
If I see a code that I never wrote, I can't (usually for me) rewrite this by my self. That's why we do things that we call "exercises" over all the entire academic career.

No, it is real life. The reason that humans have progressed is because they have made use of prior knowledge.

We would have to wait a few thousand years for a Newton, Pascal, Einstein, ...
I bet that even they made use of work by the Arabs and Greeks before developing their own theories.

I quite agree with you about practice. Your Maths teacher shows you a method. It is only after you have practised the exercises that it begins to sink in. But how far would you get if you had to develop each method yourself? Without a teacher.

I am sure that I speak for those that do AVR for a living. They read documentation, and use proven methods. Yes, of course they will read the underlying source code, and read textbooks on algorithms. So they understand how and why something works in exactly the same way as you follow your Maths teacher.

So yes, practice makes perfect for an unseen Exam.
Real life means that you can use textbooks and public information for your school project or paid employment. Should we ban the Internet ?

I wrote an Arduino sketch for your benefit. (and possibly others)

It is up to you to quietly digest the advice that you have been given. Or ignore it if you prefer.

A clear explanation has been given for the CLKPR and 4-cycle timing constraint. All normal compilers will generate code that is efficient enough. Avr-gcc does not (for various optimisation settings). The important lesson is that NO C compiler can or will guarantee specific timing.

Regarding fuses. You have to learn this for yourself. This is the reason for documentation. And why some handy web tools can help a human brain.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was only try to understand for my sadic pleasure "understand how and why something works". I feel like you don't like if someone try to go under the libraries. Your advice is very helpful for who would try Arduino without understand how works a prescaler (done, btw XD) or a fuse or a tool chain in C or blablablabing. And for this I thank you. Really.
But I think that I'm only not explained fully. Who cares right now :)

PS: Did you know a forum that can help using medium level languages (but not only asm) or hardware in microcontrollers like AVR without saying "you have to learn this for yourself"?
PPS: if my english isnt perfect, I'm Italian. I'm sorry. xD
PPPS: If you read the post above here, you will dicover that I resolve my problem very fast, and even understand that my though wasn't about how fuses works, but how "Humans" say their things.

Thanks again!

Last Edited: Sun. Jul 22, 2012 - 06:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thexeno wrote:
...I'm Italian...

Ah sì, questo è il problema. :wink:

"I may make you feel but I can't make you think" - Jethro Tull - Thick As A Brick

"void transmigratus(void) {transmigratus();} // recursio infinitus" - larryvc

"It's much more practical to rely on the processing powers of the real debugger, i.e. the one between the keyboard and chair." - JW wek3

"When you arise in the morning think of what a privilege it is to be alive: to breathe, to think, to enjoy, to love." -  Marcus Aurelius

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ahahaXD

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You misunderstand me. I advise downloading and using proven libraries. I also advise reading the source code.

The simple answer about CLKPR and avr-gcc is "you must use gobbledygook".
I am quite happy that there is a way to avoid this. i.e. use

And the solution is : 'the gobbledygook is done for you'.

I will do anything to avoid gobbledygook. Others really enjoy it.

I am quite happy to read the generated ASM in Studio. It is gobbledygook that I dislike. You can in fact write proper ASM for avr-gcc i.e a .S file.

Regarding websites. You can pick up tips from many places.
This is a very good site.

Just downloading some well written code is an inspiration. You learn by example.

As we have seen, giving straightforward advice is not appreciated. So it is up to you. In my personal opinion you find something that works, and is neatly written. Then see if you can improve on it. i.e. I choose the methods / styles that impress me. This is the story of human development.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I prefer leave the .S file to compiler, I'm not at that level ;)
"Humans are fascinating. More or less." said the guy named "xeno" XD

Thank for all!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Because it seems that you don't understand that for learn something you have to do with yourself and only after you can use other libs, if you want. No offense.

Quote:

I prefer leave the .S file to compiler, I'm not at that level

Am I the only one who can see the irony here? ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

@Cliff,

Quote:
I am sure that I speak for those that do AVR for a living. They read documentation, and use proven methods. Yes, of course they will read the underlying source code, and read textbooks on algorithms. So they understand how and why something works in exactly the same way as you follow your Maths teacher.

As someone who does "more advanced" things than AVR for a living, perhaps you might comment on whether you agree with my assertion above.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Absolutely. In fact the reason that so many "large scale" embedded designs are now moving to Linux is because of the unprecedented wealth of existing software available. No one these days would write their own TCP/IP or USB OHCI/EHCI/UHCI or Bluetooth or media decoder or just about anything else you care to mention. I guess it's losing an original skill a bit but software engineering these days is now a lot about writing the "glue" that binds together a lot of existing technologies into a solution rather than writing core technologies. Even when a new technology does turn up it's kind of expected that the developer of that technology provides the ready made libs to support it rather than just giving a 3000 page technical manual and saying to others "OK, here's the hardware, get on with it".

To a certain extent this modus operandi is working it's way back into the lower levels of lesser micros. Atmel's ASF for example is just one lib from one vendor that tries to provide generic driver/library code for their hardware. Perhaps more widespread is something like CMSIS for ARM Cortex. (actually Arduino is perhaps currently more widespread than ASF in the AVR arena too?).

Certainly on "bigger" silicon with complex OS it's unheard of for complex silicon not to be provided with a "board support package" (BSP) from the vendor. No one would pick a high end SoC if they faced the prospect of many man years of software development even to just get the basic building blocks up and running. Perhaps the ultimate example (in my experience anyway) is complex chips from TI - an installation of the compiler is about 0.5GB while an installation of the compiler and silicon supporting libraries is >5GB. This puts the 0.3GB or whatever it is that Atmel's ASF "costs" into the two-penny place!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

@Clawson
it wasn't sarcams. David talks about asm, which suggests something good about his personal knowledge.

For your last post, if I understand, I agree with you.
But if I'm interested to make (remake) my version of usb just because it's interesting, I've the right to know things near to HW level.
Of course in a work environment, everyone should use many premaked "blocks" as possible.

EDIT: I think that I had a big misundertood with david, in particular. I said that I don't like things pre made, but I was talking about Arduino, not other stuff potentially powerful.
If I blink a led with 800 byte of code, there's something that is not optimized. But I know that Arduino is for people which don't have a deep interest of micros or not yet the minimal knowledge to start alone. (like me, before that the right basics knowledges had come from the university)
After that, if I like making library from nothing or stuff near to HW layer it can be more powerful beacuse I can use less stuff than the library offers, or at least it's only for my pleasure.