TITLE: ADVENTURES INSTALLING A TRANSMISSION IN A BUTTERFLY
AUTHOR: RETRODAN
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.
AVR_Admin- 04-13-2006
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:
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:
CODE
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
AVR_Admin- 04-13-2006
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:
CODE
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.
AVR_Admin- 04-13-2006
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:
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:
CODE
;----------------------------; ; 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
AVR_Admin- 04-13-2006
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:
CODE
OUT PORTB,FF OUT PORTE,FF
Then we just check which direction joytick is moved to ie: what "Gear" is selected:
Then we just put the clock into the correct "Gear" and start the motor running:
CODE
;-------------------------------------------; ; 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
NOTE: For the curious among you, I have posted a copy of the [SUPERFLY] Bootloader replacement for the Butterfly below.
AVR_Admin- 04-13-2006
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.
AVR_Admin- 04-13-2006
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."
CODE
;-------------------------------------------; ; 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:
CODE
;-------------------------------------------; ; 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.
CODE
DAN's PROGRAM TIP: TRY TO SHARE A PIECE OF ARSE
NOTE: For the curious among you, I have enclosed a copy of the the [SUPERFLEA] tiny Boot replacement for the Butterfly below:
AVR_Admin- 04-13-2006
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:
CODE
;-------------------------------------------; ; 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:
CODE
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 leave a comment in this thread.
Happy Programming!
emsi- 07-09-2007
AWESOME! It reminded me the crazy 256b combo :)
Forumer™ is Voted #1 Free Forum Hosting provider
Build your own community today with the largest message board hosting company.