[DIS] [ASM] Program Tricks: Turbo Charge the Butterfly

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

TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY

SUBTITLE: JOYSTICK TO GEAR-SHIFT, A SLICK GEAR-CHANGER

PURPOSE:

    Discuss programming methods used to reduce size of four-speed routine for AVR Butterfly in AVR machine language.
CONTENTS:
    1. BACKGROUND
    2. CRIPPLED BUTTERFLIES
    3. QUESTIONS ON LIFE IN THE FAST LANE
    4. BIRTH OF A TRANSMISSION
    5. A MATCH MADE IN HEAVEN
    6. A TIGHT CURVE IN THE ROAD
    7. SHARING A PIECE OF ARSE
    8. REDUCTUM AD ABSURDUM
    9. CONCLUSION
    10. FEED-BACK AND COMMENTS
BACKGROUND:
    Many moons ago when Atari 800's and C64's ruled the earth and I was a novice programmer. I ran across a programming technique I call a cascade, although it's more like a ladder or stair. I can't remember where exactly, but I think I saw it while browsing either the original IBM BIOS ROM code or the Atari 800 O/S ROM where a series of checks was being made and an Error Code variable was incremented at each step.

    What I great idea I thought. Not only does it save on memory, rather than having to load a value for each error condition (2 bytes), all that was required was a single INC. And the error code would indicate how far you got into the setup before things went awry to boot!

    Although not exactly the same, I use a similar technique at some point in the following discussion.

CAVEAT LECTOR:
    Some of the programming techniques I use in this and other posts may be outside normal programming practices and offensive to conservative programmers.

Last Edited: Fri. Apr 7, 2006 - 08:28 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY

CHAPTER ONE: CRIPPLED BUTTERFLIES, BIRTH OF SUPERFLY

In another thread someome complained about the Butterfly only running at 2Mhz. Could this be true! Could my beloved Butterflies be handycapped by the factory bootloader to just 2Mhz? What a cruel thing to do!

So I downloaded the AVR Bootloader Source Code from the Atmel Site. Sure enough! The clock was set to just 2Mhz. My poor Butterflies were cripples! Destined to a life of hobbling around at 1/4 of their full speed. What a shame!

I'd been contemplating a bootloader because original kept locking me out and others didn't work properly. How about a booloader that not only stops annoying lock-outs but also supercharges the Butterfly -- the "SUPERFLY" concept was born. While at it I wanted to squeeze it under 512 too, because Dean's Buttload program was being clobbered by bloated factory bootloader and wondered how many others were also.

To change the speed all we need to do is set clock to 8Mhz just prior to starting user's program. Sounds simple enough.

From the schematics we can see the Joystick-Up switch is connected to Pin-6 on Port B. All we need to do is check if switch is closed then jump to users program:

JOYCHECK: SBIS PINB,6   ;JOYSTICK UP?
           RJMP TURBO   ;YUP, START GUYS PROGRAM

To start the users program we tell system where to find new interupt table, change clock to 8Mhz and jump to the startup vector at $0000, where the user is supposed to put an RJMP into his own program:

TURBO: OUT  MCUCR,ONE	;POINT TO USER...
       OUT  MCUCR,ZERO  ;INTERUPT TABLE
       STS  CLKPR,V128  ;KICK CLOCK INTO TURBO
       STS  CLKPR,ZERO  ;TURBO MODE 8Mhz
        JMP  $0000	
Last Edited: Thu. Apr 6, 2006 - 10:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY

CHAPTER TWO: QUESTIONS ON LIFE IN THE FAST LANE

When I later posted [SUPERFLY] as a download, the first complaint was that a higher speed would kill the battery. Well, yes and no, because we are still running the bootloader at only 2Mhz and only going "full tilt" when starting a user program.

So I modified the code to put Butterfly in Power-Down Sleep Mode immediately if there's nothing going on and and also drop clock to 1Mhz to conserve battery life during the nap, something no one else did to "make-up-the-difference". Since Butterflies spend most of their life asleep, these little improvements should actually extend battery life not shorten it:

GOSLEEP: SEI               ;ENABLE INTERUPTS
         STS   TCCR1B,ZERO ;STOP THE CLOCK
         STS   CLKPR,V128  ;DOWN SHIFT TO 1Mhz
         STS   CLKPR,THREE ;FOR THE NAP
         OUT   SMCR,FIVE   ;POWER-DOWN-MODE
         SLEEP             ;REST
          RJMP START       ;RESTART/RECALIBRATE

The next complaint was that by changing the clock speed for everyone, we're gonna' kill any Serial Communications because BAUD Rate would be out. So I immediately posted changes that would be needed to the UBBR register. I later turned it into a mini-tutorial in this section. That way people could make a simple adjustment to their programs and everyone would be happy... well, everyone except me as you'll soon find out.

Last Edited: Wed. Apr 5, 2006 - 11:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY

CHAPTER THREE: THE BIRTH OF A TRANSMISSION

I pondered the BUAD Rate problem for a while. I didn't really feel confortable about asking everyone to modify their code on my behalf. If they wanted to use [SUPERFLY] it should be trouble-free as any well designed software should be. Hmm, I wonder if anyone from Microshaft reads these posts?

Anyhow, it later dawned on me: why not give the user the option of whether they want to go into "Turbo Speed" 8MHz mode or run at the old speed of 2Mhz? But how? Perhaps move the joystick "UP" for High-Speed and "DOWN" for Low -- and the idea of a two-speed transmission was born!

We just need to check if joystick is up or down and launch at different speeds. A quick check of the Butterfly Schematics shows joystick down on Pin-7 Port B:

;---------------------;
; CHECK THE JOYSTICKS ;
;---------------------;
     SBIS    PINB,6       ;JOYSTICK UP?
      RJMP   STARTEM_FAST    	
     SBIS    PINB,7       ;JOYSTICK DOWN?
      RJMP   STARTEM_SLOW   

To launch in Turbo Mode we shift clock to high speed prior to staring user's program and we leave it at 2Mhz if user moves joystick "down" to launch:

;----------------------------;
; START UP USERS OWN PROGRAM ;
;----------------------------;
STARTEM_FAST:
         OUT   MCUCR,ONE    ;MOVE INTERUPTS
         OUT   MCUCR,ZERO
         STS   CLKPR,V128   ;KICK IN TURBO SPEED		
         STS   CLKPR,ZERO
          JMP  $000
STARTEM_SLOW:         	
         OUT   MCUCR,ONE    ;MOVE INTERUPTS
         OUT   MCUCR,ZERO
	  JMP	$0000	
Last Edited: Wed. Apr 5, 2006 - 11:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TITLE: ON INSTALLING A TRANSMISSION IN A BUTTERFLY

CHAPTER FOUR: A MATCH MADE IN HEAVEN

Then I thought: Hey, why stop there...why not have a four-speed transmission? The clock has four basic options for speed: 1,2,4 or 8 MHz and the joystick has four directions -- A match made in Heaven!

After trying the other Port B Pins I finally gave-up and checked the schematics and the Joystick Left and Right are on Pins 2 & 3 of Port "E". Part of the Joystick is on Port B and rest is on Port E? Who'da thougt? What a hack job!

So first thing we need to do is intialize Port E:

		OUT	PORTB,FF
		OUT	PORTE,FF

Then we just check which direction joytick is moved to ie: what "Gear" is selected:

      SBIS    PINB,6       ;JOYSTICK UP?
       RJMP   START_8MHZ    ;TURBO SPEED	
      SBIS    PINB,7       ;JOYSTICK DOWN
       RJMP   START_2MHZ    ;NORMAL SPEED        
      SBIS    PINE,2       ;JOYSTICK LEFT
       RJMP   START_4MHZ    ;FAST
      SBIS    PINE,3       ;JOYSTICK RIGHT
       RJMP   START_1MHZ    ;LOW GEAR 

Then we just put the clock into the correct "Gear" and start the motor running:

;-------------------------------------------;
; START USERS OWN PROGRAM AT SELECTED SPEED ;
;-------------------------------------------;		
START_1MHZ:
         OUT	MCUCR,ONE
         OUT	MCUCR,ZERO
         STS	CLKPR,V128		
         STS	CLKPR,THREE
          JMP   $0000
START_4MHZ:
         OUT	MCUCR,ONE
         OUT	MCUCR,ZERO
         STS	CLKPR,V128		
         STS	CLKPR,ONE
          JMP   $0000
START_8MHZ:
         OUT	MCUCR,ONE
         OUT	MCUCR,ZERO
         STS	CLKPR,V128		
         STS	CLKPR,ZERO
          JMP   $000
START_2MHZ:
         OUT	MCUCR,ONE
         OUT	MCUCR,ZERO
          JMP	$0000	

Attachment(s): 

Last Edited: Fri. Apr 14, 2006 - 05:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY

CHAPTER FIVE: A "TIGHT" CURVE IN THE ROAD

Everything up until now has gone very smoothly, but as you'll learn in a minute, we hit a sharp curve in the road.

PRELUDE TO A PROBLEM:

As a programming challenge I tried to see if I could reduce size of bootloader to under the 250 word mark to free-up another page of user programming space. The result is called [SUPERFLEA} and contains just about all the same functionality as full-blown [SUPERFLY].

Once I got the size to about 240 I stopped because I did not see much sense going any further unless I was going to shoot for the 128 boundary, however, there hadn't been that much interest in the "Under-250" version, so why waste my time fitting it in 128? I was later forced to get it under 200 and you'll soon find out why.

BIG PROBLEMS IN A LITTLE PACKAGE:

I liked the idea of a four-speed transmission, but when it came time to install it into [SUPERFLY]'s little brother: [SUPERFLEA] there was a big problem. The "extra" code was about 30 lines and the present size of the [SUPERFLEA] was at 243. To add these lines meant pushing it's size back over the 255 barrier making the whole effort a waste-of-time. It's entire raison d'etre was to fit under the 255 mark. What to do, the Transmission won't fit!

So I got out the well used memory "shoe-horn" and all I was able to squeeze in was the two-speed version. People would have to make-do with a two-speed Transmission until I had time to get out the cutting torches and make the big four-speed fit.

Last Edited: Wed. Apr 5, 2006 - 11:30 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY

CHAPTER SIX: SHARING A PIECE OF ARSE

Well it's time to get out the cutting torch and get to work.
The first thing I notice is that each routine is almost identical, that means there must be a way to combine them. If we were to adjust our Vector Table AFTER we set the clock speed instead of before, we can use a technique I call "Sharing a Piece of Arse."

;-------------------------------------------;
; START USERS OWN PROGRAM AT SELECTED SPEED ;
;-------------------------------------------;
START_8MHZ:
         OUT	MCUCR,ONE    ;<==
         OUT	MCUCR,ZERO   ;<==
         STS	CLKPR,V128		
         STS	CLKPR,ZERO
          JMP   $000		
START_1MHZ:
         OUT	MCUCR,ONE    ;<===
         OUT	MCUCR,ZERO   ;<===
         STS	CLKPR,V128		
         STS	CLKPR,THREE
          JMP   $0000
START_4MHZ:
         OUT	MCUCR,ONE    ;<==
         OUT	MCUCR,ZERO   ;<==
         STS	CLKPR,V128		
         STS	CLKPR,ONE
          JMP   $0000
START_2MHZ:
         OUT	MCUCR,ONE    ;<==
         OUT	MCUCR,ZERO   ;<==
          JMP	$0000	

After the cutting and a little patch-work this is what we have:

;-------------------------------------------;
; START USERS OWN PROGRAM AT SELECTED SPEED ;
;-------------------------------------------;
START_8MHZ:
         STS   CLKPR,V128		
         STS   CLKPR,ZERO
          RJMP STARTEM	
START_1MHZ:
         STS   CLKPR,V128		
         STS   CLKPR,THREE
          RJMP STARTEM
START_4MHZ:
         STS   CLKPR,V128		
         STS   CLKPR,ONE
          RJMP STARTEM
START_2MHZ:
STARTEM: OUT  MCUCR,ONE  ;SHARED ARSE-END
         OUT  MCUCR,ZERO
          JMP $0000	

From 22 to just 12 words. Not bad, almost 1/2 the size and the best part was that it now fit into the [SUPERFLEA]. So in it went.

DAN's PROGRAM TIP: TRY TO SHARE A PIECE OF ARSE
Last Edited: Wed. Apr 5, 2006 - 11:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY

CHAPTER SEVEN: REDUCTUM AD ABSURDUM

Most people would probably stop at this point, but not me. There was just "something" about the above code that bothered me everytime I looked at it. Deep down inside my subconscious well telling me something, but what could it be?

One day a fellow mentioned that he was going to toss his Butterfly because the joystick was "pooched" and the centre position did not work, so he had no way to program it. I did a quick hack-job on the joystick part of program so that "down" was the programming mode instead of "center" then I had to re-arrange the "gear-shift" arrangement so I scrapped the 1MHz speed and re-shuffle the remaining gears. I believe "Up" was 2Mhz, Right was 4MHz and Left was 8MHz. Then I quickly uploaded it for him to download.

When I went back to my code to "tidy-up" a little I saw something like this:

;-------------------------------------------;
; START USERS OWN PROGRAM AT SELECTED SPEED ;
;-------------------------------------------;
START_8MHZ:
         STS   CLKPR,V128		
         STS   CLKPR,ZERO   ;<== ZERO
          RJMP STARTEM		
START_4MHZ:
         STS   CLKPR,V128		
         STS   CLKPR,ONE    ;<== ONE
          RJMP STARTEM
START_2MHZ:                 ;<== TWO
STARTEM: OUT  MCUCR,ONE 
         OUT  MCUCR,ZERO
          JMP $0000
;START_1MHZ:
;        STS   CLKPR,V128		
;        STS   CLKPR,THREE  ;<== THREE
;         RJMP STARTEM	

Notice the zero, one, two, three sequence of things? By moving the 1MHz out-of-the-way I could see that there was a possible way to reduce this code using the "cascade" (or ladder) programming trick I mentioned earlier. Here is what it looks like after a complete re-write:

START_1MHZ: INC TMP
START_2MHZ: INC TMP
START_4MHZ: INC TMP
START_8MHZ: STS CLKPR,V128  ;SET CLOCK SPEED
            STS CLKPR,TMP     
            OUT MCUCR,ONE   ;MOVE INTERUPTS
            OUT MCUCR,ZERO
            JMP $0000	    ;START USER APP

I'm not going to give a full explanation on how it works because it should be obvious. So not only is the routine only 8 steps long, it looks nice and tidy and my subconscious has stopped bugging me about it. Now if I can just figure out why I feel ill when I see the size of Microshaft Windoze...

CONCLUSION:

I hope that you found this tutorial entertaining as well as educational. If you'd like to see more like it, be sure to let the moderator(s) know.

Happy Programming!

Attachment(s): 

Last Edited: Fri. Apr 14, 2006 - 11:20 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Every time I read one of these tutorials, Dan, I keep thinking that - given enough time - you could cram ButtLoad in its entirety into 512 words!

Nice tutorial. I love these little examples and always mentally file them away for a rainy day when I need to save a couple of bytes in my C programs. Keep 'em comming!

- Dean :twisted:

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

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

Thanks for the positive feed-back, and if you remember, I offered to help you do just that at one point... squeeze Buttload down.

"Squeezing Butts" almost sound naughty doesn't it? Ha ha ha!

Have a great day!

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

You did? Must have read that late at night. I welcome all input and (above all), help. ButtLoad 1.3 is out (as of two days ago) but i'm looking for input for the next version. I have about 130 bytes left, so plenty of room to add smaller features. Larger feature requests will, most probably, require your expert assistance in shrinking choice parts of the code but for now there's no point compressing the code further until it's nessesary.

But enough hijacking. You released SuperFly while I was on holiday, so I missed my chance to congratulate you on a job-well-done soon after the fact. I see you are giving GeoLoad some healthy competition ;).

- Dean :twisted:

PS: Believe me, since I first released my intentions of making a program named "ButtLoad" waaay back in last September or so, i've heard almost every rear-related joke ever made...

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

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

Well I assume you have an OSCCAL routine, so maybe with a crow-bar and some duct-tape we could splice in that condensed version I've been working on and save you some space when the time arrives. Might be a great "C" re-introduction for me. You "up" on how to integrate ASM into C at all?

I tried to look at your code a few times, but I'll need to re-acquaint myself with the lingo and get my "C" legs back. It still looks like a bunch of gibberish to me even though I used to program in it back when first hit in early 80s. I didn't think it would go anywhere, thought maybe FORTH was the future. Hah! What the heck did I know eh? I still feel that if UNIX had not caught on the way it did, "C" would have been just another curiosity like FORTH. And we'd probably be using some Pascal derivative.

Of course things were different back then. You'd get clobbered for writing something like
i += i or +j, back then you had to show all increments on separate line for clarity - man how things have changed.... well enough of that, I'm just gettin' old man! And I ain't complainin' so please no flamewars. I certainly ain't putting the language down by any means. I've just forgot how to speak it temporarily.

TTYL

Last Edited: Wed. Apr 5, 2006 - 11:56 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My OSCCAL routine is slightly modified from the "vanilla" version from Atmel, and was "borrowed" from a fellow user here before I modified to suit my needs. Your routine is small, but what about the extra time needed to calibrate? What's the average calibration time - and what happens if the AVR is unable to get inside the tollerance you set?

The reason my code looks like gibberish is because it mainly is! I'm still suprised I havn't had more experienced coders chipping in explaining why the techniques i'm using are wrong.

- Dean :twisted:

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

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

On a human level there's no difference on the time it takes, besides, you'r supposed to wait around 1 second for oscillator to stablize anyhow, but if you have a need for a quick calibration there's tons of ways to speed it up.

As for the "tighter" calibration, not a problem, I'm sure if you check your code you'll see they use +/- 50uS and I'm using +/-40uS so not big difference, and I've never had a problem. I've acutally run tests taking it down to +/-5uS to see if it would speed-up communications by lowering transmission errors. at +/-5uS it can take some time to calibrate.

Attachment(s): 

Last Edited: Fri. Apr 14, 2006 - 11:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey guys,

If this helps, I have the C version of OSCCAL_retrocal(), but right now I am in the office so allow me 8 hours to return home, and I will post the OSCAL_minical (function that is small from retroDan tutorial and still readable for human beings) and the OSCCAL_retrocal(function that is even small but not readable for normal mortals)... and the functions takes the same space as the asm... I am using gcc... so I think is really to go in any project that use the win-avr gcc compiler...

Retro,
sorry for hjack'in your thread! :oops:

---
ARod

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

abcminiuser wrote:
Every time I read one of these tutorials, Dan, I keep thinking that - given enough time - you could cram ButtLoad in its entirety into 512 words!

Nice tutorial. I love these little examples and always mentally file them away for a rainy day when I need to save a couple of bytes in my C programs. Keep 'em comming!

- Dean :twisted:

Thanks for the wonderful review, coming from the "MODERATOR" of this Forum adds special significance. The other moderators: Sean and Colin have both paid me a compliments on tutorials as well.. glad I can pay-you-back for helping me with Butterfly problems -- I was ready to pack-it-in for AVR. Thank God for your Buttload program!

Last Edited: Mon. Apr 10, 2006 - 03:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

CONTINUING EDUCATION:

To learn more about the Butterfly in gerneral, you can visit the Butterfly & Beginner's Web Site at: http://retrodan.tripod.com/ or you can visit the Butterfly & Beginners Forum at: http://groups.yahoo.com/group/AVRButterFly/ or the AVR Assembler Site at: http://avr-asm.tripod.com

REQUEST FOR FEED-BACK:

If you find this tutorial useful, and would like to see more like it, or to suggest a new topic, please notify the Forum Moderator(s).

Thank you and have a great day.

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

I've recieved a ton of wonderful feed-back on my tutorials and it was suggested that I might want to consider setting up a separate web-site for them, so that's part of the reason for the Butterfly Beginners Site http://retrodan.tripod.com it's still under contruction because I have not come-up with a web format for the tutorials that I am happy with yet, although there are already some greats links for Butterfly and Beginners there. Based on the number of hits in just a few hours of it going up, I'd say it's going to be very popular indeed.

Last Edited: Tue. Apr 11, 2006 - 12:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MOM, that is harassment. Please refrain from such activity in the future or I will need to take action.

- Dean :twisted:

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