ECE 477 Digital Systems Senior Design Project Rev 9/12

ECE 477 Digital Systems Senior Design Project Rev 9/12

Homework 9: Software Design Considerations

Team Code Name: Team Hex Me, Baby! Group No. 3

Team Member Completing This Homework: Spencer Julian

E-mail Address of Team Member:

Evaluation:

SEC

/

DESCRIPTION

/

MAX

/

SCORE

1.0 /

Introduction

/

5

/
2.0 /

Software Design Considerations

/

30

/
3.0 /

Software Design Narrative

/

30

/
4.0 /

Summary

/

5

/
5.0 /

List of References

/

10

/
App A /

Flowchart/Pseudo-code for Main Program

/

10

/
App B /

Hierarchical Block Diagram of Code Organization

/

10

/

TOTAL

/

100

/

Comments:

1.0  Introduction

“Hackers of Catron” is an electronically enhanced version of the popular Settlers of Catan board game. Game setup will be automated, placement of physical pieces on the board will be tracked, and resource trading will be handled through handheld devices. These enhancements to the game will make the game easier to set up and play, resulting in a much improved game play experience.

The economy and game board are handled by a Raspberry Pi and a microcontroller, respectively. The Raspberry Pi is running an apache web server with a series of Python CGI's that are served to a device with Wi-Fi access as simple web pages. The microcontroller communicates with the Raspberry Pi using a two-wire interface, and controls the board display and piece sensing using a state machine.

While the Raspberry Pi has little to deal with as far as external peripherals go, other than Wi-Fi and I2C, the microcontroller has to communicate with 38 RGB LEDs to display resource information, 19 seven segment displays to display scarcity information, and 145 hall effect sensors to read where pieces are on the board. The next section (Section 2.0) will elaborate on these considerations, among others, while Section 3.0 will talk about the specifics of the software we are developing.

2.0  Software Design Considerations

As indicated in the introduction, the program is primarily a state machine; however the microcontroller will be performing some polling in many of the states. A state machine was chosen as it is the most appropriate for emulating the physical game's turn-based system. The majority of states will poll the current status of the Hall Effect sensors, however, in order to check for invalid pieces or updates to valid pieces, such as additional pieces placed or pieces removed. Appendix A has a high-level flowchart of the game flow.

While no data will be stored on the microcontroller in any sort of semi-permanent form, such as Flash, we will be storing game status on the microcontroller in SRAM with the program itself. Most of the game information will be stored in structs and arrays, so there are few special considerations that need to be made for memory.

Within the game itself, the microcontroller needs to be able to keep track of the current board state as well as the current players' turn, while the Raspberry Pi needs to keep track of the economy and related information. Specifically, the microcontroller will keep a map, likely in an array or a struct, of every hexagon's resource and scarcity. Additionally, the microcontroller will keep a multi-dimensional array of the status of each of the Hall Effect sensor's states. Since each sensor can only have one or two kinds of pieces placed on it, it is quite simple to store a 2-dimensional array of the state of every sensor on the board. Finally, an array of positions owned by each player will need to be kept as well, to determine what piece is owned by what player. As mentioned earlier, since none of the information needs to be stored after the micro has shut down, and there isn't a large amount of data to store, it can all be stored live with the program in SRAM.

The Raspberry Pi will be keeping track of the economy and some basic player information. This basically entails each player's available resources, development cards, and score. For each player, it will also store their name and a timeout value. Additionally, it needs to store the deck of development cards. Because it uses an asynchronous, non-persistent connection with the connected devices, these are stored in JSON files in a “players” directory. Because the JSON store will be available even after the Raspberry Pi has been rebooted, a combination of a timeout on the JSON files and cookies on the connected devices will ensure the files are valid and do not need replaced.

The microcontroller only requires a few integrated peripherals. By default, the microcontroller clocks at a relatively slow speed of 100 kHz, however in order for reasonable speeds on I2C and SPI, we need the microcontroller to clock faster. We do this by clocking against an external oscillator which runs at 12 MHz. We additionally need the DSP, as this microcontroller's random number generator functions are included in the DSP module. We will need I2C and SPI to communicate with our Raspberry Pi and 7 segment displays, respectively. The I2C will be running at 100 kHz with the Raspberry Pi as the master. This is simply because it is much easier to get the microcontroller to work as a slave than it is to get the Raspberry Pi to do the same. There appears to be little to no documentation on getting the Raspberry Pi to work as an I2C slave. The SPI will be running in 8-bit Mode 0, as that is what the 7 segment display drivers require. The SPI will run at 2 MHz. Finally, we will need the GPIO Module to communicate with the LED drivers and the Hall Effect Sensor multiplexers, and the Delay module for wait functions. The LED Drivers communicate using a non-standard protocol that is vaguely reminiscent of SPI, however it deviates just enough from the protocol that we need to manually communicate with the drivers using some custom functions that communicate over pins 10 and 11 of Port B. The hall effect sensors are connected to 8 to 1 multiplexers, 1 to a hexagon, that are oriented in a logical table, with each hexagon being a column. The GPIO Module will select a row and scan for changes in each column using a mask on Port A, where all of the multiplexers are attached.

Finally, various debug routines are already developed. We have developed a basic LED Heartbeat test, which simply blinks an LED, an RGB LED Color Test that cycles through various colors, a Hall Effect Selection Test that will select a specific column (that is, a hexagon), and watch each hall effect for a change, a 7-Segment display test that lights each segment, an I2C EEPROM test, where the microcontroller acts as a simple EEPROM, and an I2C Terminal on the Raspberry Pi, that allows for communication to the microcontroller through I2C through a highly simplified telnet-style terminal. Many of these can be included as routines in the final product as self-test functions. Additionally, during the Raspberry Pi's boot up, the RGB LEDs will be displaying in some visually interesting fashion that will also serve as a self-test.

3.0  Software Design Narrative

Appendix B shows a high-level diagram of our code modules. After powering on, we move directly into the microcontroller initialization phase. This module simply calls Atmel functions for initializing the system clock [1], the various GPIO Pins [2], the I2C Interface [3], the SPI Interface [4], the random number generator [5], and the delay function [6].

The next phase is the Initial Board Generation phase. This is the phase that generates the board setup. It effectively contains 2 modules, resource generation and scarcity generation. The resource generation module selects a random resource out of the resource pool (that is, the resources that are currently available but not assigned) and assigns it to a particular hexagon. This generates a map of the available resources on the playing field. The scarcity generation module selects a random hexagon on the edge of the playing surface that is not a desert, and sets each hexagon's scarcity from a list of available scarcities in a circular, spiraling fashion. It is done this way instead of completely randomly so that common numbers are not placed very close to one another, so the game does not get any points that are “too strong” or “too weak” on resources.

At this point, the Raspberry Pi will boot, so here's a brief overview of the software running on it. It uses an apache web server using a few python CGIs, extensive HTML 5 and CSS 3, and a small bit of AJAX [7] for constant communication. The main display shows the current resources available and the number of development cards available, along with the player's current score. Each button calls an external CGI that performs some action. Among these are the Player Name CGI, that simply changes the player's name. The Trading CGI asks the player what resources he wishes to trade and with whom, requests a confirmation or modification on the given player, and returns the confirmation to the requesting player. The Purchasing CGI asks the player what he wishes to purchase and then removes the resources from his available resources after confirmation and piece placement. The End Turn CGI ends the turn after a confirmation. The Game Status CGI returns the scores of all of the current players and their awards. Finally, there's the Error CGI which will prevent any other action from happening while there is an error on the playing surface, such as a misplaced piece. Each CGI shows in a modal dialog box that then communicates its results using simple query strings back to the index page. The index page calls yet another CGI, which does not have a modal dialog, that simply returns a 1 if the page needs refreshed (that is, there is new information for the given player), or a 0 if it does not.

After the Raspberry Pi has booted, we enter the initial piece placement stage. This stage calls modified versions of the Place Road and Place Settlement modules from the game loop phase for each player, twice (once in forward order, once in reverse order). The Place Settlement module waits for the player to place a settlement at any given intersection of three hexagons and stores its position, while the Place Road module waits for the player to place a road at any of the three lines radiating from the position of the last placed Settlement, which can be done by simply passing the location of the settlement to the module and checking around it. Additionally, it will run a procedure to check for the longest road, which will be done via a lookup table, containing all possible adjacent positions.

At last, the system enters the game loop. This loop goes through each player's turn and repeats the same five checks until the player's turn has ended. These checks are mostly looking at I2C registers for communication from the Raspberry Pi. The first check is the Dice Roll. If the dice is rolled, it will roll the dice by selecting 2 random numbers between 1 and 6, and adding them together. This is slightly different then selecting a single random number between 1 and 12, as the odds are slightly different of rolling any given number (for example, there are 6 different ways to make a seven with 2 6-sided dice, but only 1 with a 12-sided die). If the roll was a seven, it will tell the Raspberry Pi to force the players to discard half of their available resources, should they have more than 7 available, and will then wait for the thief to be moved to a different position on the board, and will randomly take one resource from any effected player. If the roll was not a 7, it will simply assign resources based on whatever the roll was. It will then set a flag to prevent the dice from being rolled again.

The next check is the Development Card check. If a development card is played, it will check if the card was a knight card, and if so, it will run the move thief routine. If it was not, it will run the place road routine twice, with the modification in this stage of the game that the road must be next to a road, settlement, or city owned by the same player. Other than that, the place road routine is the same as described earlier. If a different sort of development card has been played, that is, a monopoly card, then the raspberry pi will handle it with no interaction from the microcontroller. If it is a monopoly card, then all resources of a certain type will go to a player, which can be done by simply moving numbers around in the json store.

Now the microcontroller will check if a piece has been purchased. If a piece has been purchased, then the microcontroller will enter the appropriate “place routine”. The place road routine is the same as described in the Development card check, and the place settlement routine has the added requirement that the settlement be attached to one of the player's existing roads. The place city routine will first check for a settlement to be removed, and will then require the city to be placed in that location.

After that, the microcontroller will enter the Update Board State routine. This routine checks each position on the board to ensure that there has been no change. If there has been a change, then it checks if it was a legal change. Legal changes at this point are changes that will launch the Raspberry Pi into the purchasing CGI, which are limited to placing a road at particular locations, placing a settlement at particular locations, or removing existing settlements with the intent to place a city. If any other event occurs, or if a player cancels an event that was initiated physically, then the board and pi will enter an error state that notifies the player of the error using the RGB LEDs and the Raspberry Pi's interface and wait until the error is corrected before it will allow the game to continue.