SIMON Project Overview



Table of Contents
1. Introduction
2. Hardware Organization
3. Overall Software Organization
4. Mode 1 Execution and Organization
5. Mode 2 Execution and Organization
6. Conclusion


Introduction

Below is a detailed description of my project. I first examine and explain the hardware setup I chose, and then give an overall description of the software setup which discusses overall program organization, interrupt structure, subroutines, and timing. Then I go more in depth to look at the two main blocks of my program, the sections which make up the code implementing the two different modes of play. Finally, I offer some concluding remarks on my project, including what I would have done differently if I had to do it over and other general comments.


Hardware Organization

Appendix B contains a schematic of the project hardware, which this section discusses. For this project, as mentioned earlier, I used the AT90S4414 microprocessor. I felt this chip best suited my design goals because of the number of I/O ports--the project employs all four I/O ports on the 4414--and the presence of two timers. The program does make use of code from EE 476 Lab 3, the one-octave synthesizer, to play the tones associated with each button. However, that program was written for the AT90S1200, which was not suitable for this project due to the fact that it only has two I/O ports and one 8-bit timer, as well as a reduced instruction set.

This project also makes use of some external hardware. The display used is a standard 16x1 LCD, and is employed in 4-bit mode, no cursor, no blink, address increment, no scrolling, and 5x7 font. The speaker is also externally connected. There are also four external LEDs corresponding to each of the four colors in the original SIMON game--red, yellow, green, and blue. Finally, there are four external pushbuttons, which are unfortunately packaged together so that I couldn't separate them and do the same layout as the original game, which had the four buttons in a circular arrangement. The external components are connected to the development board via a protoboard which has slots for wires and pins. The wires to the board connect to the ports through female-to-female headers which are placed over the port pins. The one exception to this is the speaker; its jack is connected to an adapter which is plugged directly into the header on Port A.

Some of the wiring of familiar components may be slightly different than in previous labs; in particular, the LCD takes inputs from Port C rather than Port D, and it takes its power source from pin D7. The change to Port C came about largely because of the order in which I developed my project. I first wrote the majority of my code to work with the pushbuttons and LEDs on the development board. The standard setup for those components is to wire the LEDs to Port B and the switches to Port D, so I followed that convention for the first two weeks of development. Therefore, I decided that it would be much easier to add the LCD to Port C, since adding external pushbuttons and LEDs only required me to wire them so that they were consistent with the way the components on the development board were wired. For the buttons, this required me to connect the common lead on the pushbuttons to ground and set the pullups on their port pins, so that a read of those pins would yield a 1 unless one was pressed. For the LEDs, I had to wire their positive leads to a constant Vcc, and their negative leads to port pins which I would clear to turn them on. Switching the LCD to Port C was then a simple matter of modifying all of the references to Port D within the existing LCD code. I also changed the LCD power pin to Port D, pin 7, because Port A is modified by the Timer0 overflow interrupt service routine--specifically, the only pin that is ever set on the entire port is pin 6, the output for the speaker. Rather than modify the ISR, which worked perfectly well with the code I wrote for the switches and LEDs on the development board, I chose to change the LCD connection.

The overall external hardware wiring is summarized below (see the schematic for a pictorial representation):

	Component	Pin	Connection
	----------------------------------------
	LCD		1	Port D gnd 
     			2       +5 volts--Port D7 (under program control
				for LCD power-up/power down sequence)
     			3       10k trimpot wiper 
				(the ends of the trimpot go to ground and +5)
     			4       Port C6
     			5       Port C5
     			6       Port C4
     			7-10    no connection
     			11      Port C0
     			12      Port C1
     			13      Port C2
     			14      Port C3
	Speaker		input	Port A6
			ground	Port A gnd
	Yellow LED	pos	Port B0
	(LED 0)		neg	Port B4
	Red LED		pos	Port B1
	(LED 1)		neg	Port B5
	Green LED	pos	Port B2
	(LED 2)		neg	Port B6
	Blue LED	pos	Port B3
	(LED 3)		neg	Port B7
	Pushbuttons	S0	Port D0
			S1	Port D1
			S2	Port D2
			S3	Port D3
			common	Port D gnd

Note: For the LED connections, pos and neg indicate the positive and negative terminals, respectively, for a positive bias across the LED. For the pushbutton connections, Sx refers to the connection exclusively to switch x, and common is the common connection between all four buttons.


Overall Software Organization

Appendix A contains the program listing for the assembly language used in the implementation of this project. This section focuses on the overall organization of the code, covering its execution in general from beginning to end in a sequential fashion.

The program begins with several special definitions, since almost all of the 4414's 32 registers are required at some point in the program. Low-order registers r1-r8 are used mostly for temporary storage, and are rarely manipulated, and high-order registers r16-r27 are used for operations which require more operations to be performed on their value. The comments in the program provide a short description of each register's function, but the following list examines each one's use in slightly more detail, so that the remainder of this overview can use the defined names and assume that the reader knows what the registers are:

There are also a number of special defines for constants, selected ones of which will be discussed in terms of their names only, not their values:

The program's lone data segment (.dseg) contains an array in RAM called tones, which holds a sequence of up to 100 tones. This is used in Mode 1 to store the sequence intended to be replicated by the user, so that it can be easily compared against user input. The actual use of the array--how values are stored and read from it--is discussed in the Mode 1 section.

The program only uses two interrupts, the Timer0 overflow and Timer1 overflow interrupts. The Timer0 interrupt is used in both modes for tone playback. Each time a Timer0 interrupt is taken, it toggles the output bit to the speaker unless the value in reload is 0x00, in which case no tone is meant to be played and a logical 0 is output to the speaker. The frequency with which these interrupts occur depends on the value of the reload register; a higher reload value corresponds to a higher frequency and thus a higher tone output to the speaker. It also sets the T bit just before it returns so that it can be used in the LCD setup code, since that code has several spin loops which only break when they detect a set T bit.

The Timer1 interrupt also has two functions, depending on the mode of play. In Mode 1, it is set to run with a prescaler of 1 (4 MHz), and is used to provide pseudorandom values during level 2 play if more than one tones are added to the current sequence (based on the number held in rndnum). In Mode 2, it is set to run with a prescaler of 8 (.5 MHz), and is used to provide the intervals that the computer waits for a user to replicate a tone before declaring the game over.

The program also makes use of several subroutines. Most of them are LCD subroutines written by Charles Ott and modified by Bruce Land. I also wrote my own subroutines to output an entire string to the LCD, and one to wait for roughly two seconds so that I could display a message for a certain period of time before changing to the next one in a sequence. The subroutines are briefly summarized here: