Written by Pat Hanrahan
Due: Tuesday, January 22 at 6:00 pm
Glen A. Larson, the man responsible for producing the original Battlestar Galactica and Knight Rider television series, often used simple lighting effects in his shows. One famous example is a scanner that consists of a set of red LEDs that scan back and forth. The front of the Knight Rider car had a scanner.
Check out this short video tribute to Glen Larson. How many times does the scanner pattern appear?
Check out the Larson Scanner Kit Demo from evilmadscientist.com.
When you’re done with this assignment, you should
understand ARM assembly language,
feel fluent with the ARM cross-development tools,
know how to use breadboards and use LEDs,
and be able to program general-purpose input/output (GPIO) pins.
Basic part: simple scan pattern
This assignment involves modifying the blink program showed in class.
blink.s is an ARM assembly language program that blinks a single LED.
To implement a scanner, you will need to control at least 4 LEDs.
1. Wire up your breadboard
The basic scanner should have a row of 4 LEDs. If you feel ambitious and want to make more interesting patterns, wire up 8 LEDs. Validate your breadboard wiring by testing that each LED lights up when powered.
2. Connect the LEDs to GPIO 20-23
The leftmost LED in your scanner should be connected to GPIO 20 of your Raspberry Pi, the second from the left to GPIO 21, and so on, such that the rightmost LED in your scanner is connected to GPIO 23 (or GPIO 27 if using 8 LEDs). Refer to the Raspberry Pi pinout to map each GPIO to the physical pin so that you correctly wire up the connections.
3. Clone starter, test blink
To get the starter code, go to your assignments repository and pull the latest version of the master branch:
$ cd cs107e_home/assignments $ git checkout master $ git pull
If you get an error message with your
git pull command, contact the course
staff for help.
You will do your work for each assignment on a separate branch. We have already created the branch for you. The branch is called
assign1-basic and it contains the assignment starter code. To switch to a specific branch, use the
git checkout command. The following command will switch to the
$ git checkout assign1-basic
Once you switch to the
assign1-basic branch, the new files
Makefile will be added to your assignment directory. The
larson.s is the file in which you will write your code for the assignment. The starter version of
larson.s is simply a copy of
blink.s from lab.
Note that we have also included a file called
Makefile in the starter code. This script
is similar to the
doit scripts you saw in class—it will use the
to compile your
larson.s into a
larson.bin file that you can install to the Pi. To execute
the Makefile, you should run
make from the command line in the directory containing the Makefile, e.g.
$ make $ rpi-install.py larson.bin
For now, don’t worry about how
make works. We’ll go through Makefiles in-depth in the next lab.
If you build and test the starter program, it should blink the leftmost LED of your scanner on a correctly-wired breadboard. You’re now ready to write your scanner program!
4. Configure scanner GPIOs
The starter program is a copy of the
blink.s you studied in lab1. This program configures the single pin GPIO 20 and enters an infinite loop to set and clear that pin. Carefully review this code and be sure you understand how it accomplishes its tasks. Ask questions if anything is unclear! Your job is to modify this program to instead blink the scanner sequence.
A good first step is to extend the initialization code to configure all of the GPIOs your scanner uses, not just GPIO 20. Refer to section 6 of the Broadcom ARM Peripheral for the details on the GPIO registers.
Be sure to verify that your configuration code is correct. You can test an individual pin by changing the existing loop to blink GPIO 21 or GPIO 22 and so on instead of GPIO 20. Once you have verified that all pins are properly configured, you’re now ready to tackle changing the loop body to blink the pins in the scanner sequence.
5. Generate scanner pattern
The loop will scan back and forth from the GPIO 20 LED to the GPIO 23 LED. Each iteration of the loop still turns on/off one GPIO, but instead of blinking the same GPIO each time, it will blink the next GPIO pin in sequence. If you invest a little bit of cleverness in how the loop advances from pin to pin, you can implement the entire scanner sequence with a fairly tight single loop.
To receive full credit, the scanning pattern should look smooth. In particular, exactly one LED should be on at any given time, so it looks like the light is “moving” between LEDs. Make sure you handle the left and right sides properly (that is, the leftmost and rightmost LED should be each on for the same amount of time that a middle LED would be on). The scanning frequency should be around 1Hz (that is, the light should bounce back and force about once per second).
Writing clean, readable assembly code is a challenge. Commenting is essential! Be sure to choose good label names and add named constants using
.equ to aid readability. You should write the program without any function calls (because we haven’t taught you how to create and call functions in assembly language yet). Although you cannot use functions, you can still strive for simplicity in your design. When you need the same/similar code, please don’t resort to duplicating code via copy and paste, instead consider how to structure your code to enable unification and code reuse. A rule of thumb for style is that if your code is well-designed, it should take no additional code to extend it from 4 to 8 LEDs, ideally just changing a constant. If there is a lot of code duplication in your solution, that’s a bad sign. We will be grading your code quality and hope to see your best work in what you submit!
Congratulations on completing your first step on the path to bare-metal mastery! Sit back and enjoy the show. Turn off the lights and impress your friends.
Before moving on, you should be sure that you have committed and pushed a working copy of your basic portion of this assignment. Refer to the instructions in the assign0 writeup if you have trouble getting your files pushed to GitHub.
Each assignment is structured into a basic part and one or more proposed extensions. Completing the basic part is required. Doing solid work on the basic part puts you on track for earning a B grade. Adding in the optional extensions is what will boost your grade up into the A range. We encourage everyone to try out some of the extensions, they are a fun way to go further with the material and advance your understanding!
(Read more about how grading works on the assignments page.)
The basic part of this assignment should not take too long once you understand ARM assembly.
If you want to explore further, extend the program. The extension is more challenging, and may involve using additional ARM assembly instructions.
If you watch the Larson scanner carefully, several LEDs are turned on at once. The center one is at full brightness, and the ones on the edge are dimmer. How would you dim an LED? Your challenge for the assignment extension is to implement a scanner with LEDs aesthetically dimmed in a way that would please Glen Larson.
You should have a central, full-brightness light that scans just like in the basic version of the assignment, but you should visibly dim the neighbors of that central light as it moves. It should look similar to the Larson Scanner Kit Demo.
Try to have at least three distinct levels of brightness.
If you choose to implement the extension, you should create a new branch after you have committed a working copy of your basic
$ git checkout -b assign1-extension
Now, you can commit and push your changes for the extension on this new branch. To implement the extension, you should directly modify larson.s. DO NOT create any new files for the extension.
Make sure you have committed and pushed a working copy of the basic assignment
assign1-basic branch) before you start on the extension!
Submit and automated check
Submit the finished version of your assignment by making a git “pull request”
assign1-basic branch to
master, following steps given in the
Assignment 0 writeup. If you implemented the
extension, you should create a separate pull request for
The automated check here is more likely to fail than in assignment 0, since there are more things that can go wrong. In this assignment, the automated checker is verifying that:
- you have a Makefile (which we’ve included in the starter code, so you should be fine if you keep that as is)
- you have NOT checked larson.bin in (you should only be checking in your source code, and then we’ll build larson.bin from it on our end)
makeruns successfully on the clean testing virtual machine
When we actually grade your submission, the human grader will assemble
larson.bin file again, then test it on a physical Raspberry Pi
with the LEDs plugged in.
As stated on the assignment policy page, if you submit an assignment solution that does not compile on CI, we will deduct 1 point from your basic grade.
See the automated checker guide for more information about the system, and details on how to see what went wrong.