[DIS] [ASM] Program Tricks: Shrinking the OSCCAL Routine

Go To Last Post
61 posts / 0 new

Pages

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

These are the values that are set by the hardware on reset, no bootloader involved.

I have another shrinkage for you. Your routine has 24 lines, but 16 of those lines are LDS and STS instructions. Both these opcodes take up two words, so your routine is 40 words long. If you load 0x0080 into the Y register, you can replace most of them with LDD and STD (load and store with displacement). Doing the same thing with the Z register and 0x0061 catches the rest of them. Setting the Y and Z registers costs you 4 words, but using them this way saves you 16, so the net gain is 12 words, dropping your total to 28 words. That's a 30% savings! Of course the number of lines will go up, but the goal is saving space in flash, not in the asm file.

Regards,
Steve A.

The Board helps those that help themselves.

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

Wow, now there's a technique I've not come across before. Good one!
I didn't realize that LDS/STS were two and LDD/STD were only one word.
My '169 reference sheet here only lists flags and clock cycles no mention of opcode+operand length.

Why two pointers and not only one, and why the base addresses of $80 and $61?

If I chose $0 couldn't I use the port-name itself as an offset, since it's a defined constant in def file?

I'd actually like to try this out, thanks Steve!

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

The displacement has a maximum value of only 63 (i.e. it is a 6 bit displacement). You could choose other base addresses, but I think that those are the most convenient.

CALL, JMP, LDS and STS are the only opcodes that are 2 words. The second word is a 16 bit absolute address.

Regards,
Steve A.

The Board helps those that help themselves.

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

Wow you're fast. I just checked data sheets and found displacements are 0-63 so that answers my own question.
Your choices make perfect sense now.

BTW - thank for the small list of double-opcodes. I been tearing around all the PDFs trying to find an opcode table that lists opcode sizes.

Those are the only big ones, eh?

Thanks a million Steve!

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

Quote:
My '169 reference sheet here only lists flags and clock cycles no mention of opcode+operand length.

http://www.atmel.com/dyn/product...

Scroll down to the User Guide section, download the AVR Instruction set document.

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

What good is internal OSCCAL calibration at start-up if you need an external crystal? I can only see worth in it if you already need a 32.67k Hz oscillator for a real-time clock...

Otherwise, why not just go with a crystal or clock?

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

Low power. It takes less power to run the AVR at a low RC oscillator value rather than a high-speed external crystal. Error percentage aside, you can also calibrate to any frequency you like, which can be handy.

If you've already got a 32.768KHz crystal on board for a RTC, you might as well save board space, power and cost and use it to calibrate the internal oscillator in appropriate applications.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

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

danielson wrote:
What good is internal OSCCAL calibration at start-up if you need an external crystal? I can only see worth in it if you already need a 32.67k Hz oscillator for a real-time clock...

Otherwise, why not just go with a crystal or clock?

ATmega169PV shares RTC_OSC_XTAL pins AND XTAL_OSC pins! which means, if your application needs 32k Xtal, you have to live with internal RC oscillator of M169PV!

Cheers,
Vignesh

If everything seems to be coming onto your way, then you are probably driving on a wrong lane..

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

I think this thread is very interesting. Sometimes it is just very fun to do optimization. I wont make any comment about RetroDan but I give him that I have had learned some new stuff because of him. It is not very important to have a optimized calibration routine as the bootloader is not the right place for it. But as I said, it was fun to make it. So now I have made a version that I named OsccalMicrofast that is better and even smaller (76 bytes) but the line
ASSR = BIT(AS2);
must be executed at least 1 second before entering OsccalMicrofast.

/Edit, removed the code . Ask for it if you need it.

My favorites:
1. My oscilloscope, Yokogawa DLM2024.
2. My soldering iron, Weller WD2M, WMRP+WMRT.
3. JTAGICE3 debugger.

Last Edited: Tue. Sep 15, 2009 - 10:09 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Strider: "Are you frightened?"
Frodo: "Yes"
Stride: "Not near frightened enough."

Pages