Skip to content

Instantly share code, notes, and snippets.

@travischambers
Created November 12, 2012 19:13
Show Gist options
  • Save travischambers/4061250 to your computer and use it in GitHub Desktop.
Save travischambers/4061250 to your computer and use it in GitHub Desktop.
simon-working LED and tones
/**************************************************************************
; Project: simon.c
; Author: Student, Fall2012
;
; Description: A MSP430 assembly language program that plays the game of Simon.
;
; 1. Each round of the game starts by the LEDs flashing several times.
; 2. The colored LEDs (along with the associated tones) then flash one at
; a time in a random sequence.
; 3. The push button switches are sampled and compared with the original
; sequence of colors/tones.
; 4. The sampling the switches continues until the end of the sequence is
; successfully reached or a mistake is made.
; 5. Some congratulatory tune is played if the sequence is correct or some
; raspberry sound is output if a mistake is made.
; 6. If the complete sequence is successfully reproduced, the game is
; repeated with one additional color/tone added to the sequence.
; Otherwise, the game starts over with the default number of colors/tones.
;
; Requirements:
; Timer_B output (TB2) is used for hardware PWM of the transducer (buzzer).
; Subroutines in at least one assembly and one C file are used by your program.
; ALL subroutines must be correctly implemented using Callee-Save protocol.
;
; Bonus:
;
; -Port 1 interrupts are used to detect a depressed switch.
; -Use LCD to display round, score, highest score, and lowest score.
; -Turn on LCD backlight with any activity.
; -Turn off LCD backlight after 5 seconds of inactivity.
;
;*******************************************************************************/
//
// MSP430F2274
// .-----------------------------.
// SW1-->|P1.0^ P2.0|<->LCD_DB0
// SW2-->|P1.1^ P2.1|<->LCD_DB1
// SW3-->|P1.2^ P2.2|<->LCD_DB2
// SW4-->|P1.3^ P2.3|<->LCD_DB3
// ADXL_INT-->|P1.4 P2.4|<->LCD_DB4
// AUX INT-->|P1.5 P2.5|<->LCD_DB5
// SERVO_1<--|P1.6 (TA1) P2.6|<->LCD_DB6
// SERVO_2<--|P1.7 (TA2) P2.7|<->LCD_DB7
// | |
// LCD_A0<--|P3.0 P4.0|-->LED_1 (Green)
// i2c_SDA<->|P3.1 (UCB0SDA) (TB1) P4.1|-->LED_2 (Orange) / SERVO_3
// i2c_SCL<--|P3.2 (UCB0SCL) (TB2) P4.2|-->LED_3 (Yellow) / SERVO_4
// LCD_RW<--|P3.3 P4.3|-->LED_4 (Red)
// TX/LED_5 (G)<--|P3.4 (UCA0TXD) (TB1) P4.4|-->LCD_BL
// RX-->|P3.5 (UCA0RXD) (TB2) P4.5|-->SPEAKER
// RPOT-->|P3.6 (A6) (A15) P4.6|-->LED 6 (R)
// LPOT-->|P3.7 (A7) P4.7|-->LCD_E
// '-----------------------------'
//
//******************************************************************************
// includes
#include "msp430x22x4.h"
#include <stdlib.h>
#include "RBX430-1.h"
#include <time.h>
#include <stdio.h>
//------------------------------------------------------------------------------
// NOTE: LOOK in RBX430.h for some macros to use
//------------------------------------------------------------------------------
// defined constants
#define myCLOCK 8000000 // 8 Mhz clock
#define WDT_CTL WDT_MDLY_32 // WD configuration (Timer, SMCLK, ~32 ms)
#define WDT_CPI 32000 // WDT Clocks Per Interrupt (@1 Mhz)
#define WDT_IPS myCLOCK/WDT_CPI // WDT counts/second (32 ms)
#define TONE 2000 // beep frequency
#define DELAY 100 // beep duration--------------------changed to 50
//-----------------------------------------------------------
// external/internal prototypes
extern int rand16(void); // get random #
int getSwitch(void); // get switch pressed
void toneON(uint16 tone); // Turn on Tone
void toneOFF(void); // Turn off Tone
void delay (void); // Start delay of program
void LEDs (int number); // Set the leds based on the number passed in
void lcd_backlight(uint8 backlight);
void victory_tone(void);
void lcd_printf(char* fmt, ...);
//-----------------------------------------------------------
// global variables
volatile int WDTSecCnt; // WDT second counter
volatile int WDT_Delay; // WDT delay counter
//------------------------------------------------------------------------------
//gameplay delay
void small_delay()
{
int counter = 32000;
int i = 32000;
for (i; i >= 0; i--)
{
counter--;
}
return;
}
//-----------------------------------------------------------
void main(void) {
RBX430_init(_8MHZ); // init board---------------------------------changed this from 1 to 8
// Configure the Watchdog
WDTCTL = WDT_CTL; // Set Watchdog interval
WDTSecCnt = WDT_IPS; // set WD 1 second counter
WDT_Delay = 0; // reset delay counter
IE1 |= WDTIE; // enable WDT interrupt
TBR = 0; //Timer B SMCLK, /1, up mode
TBCTL= TBSSEL_2|ID_0|MC_1; //
TBCCTL2 = OUTMOD_3; // output mode = set/reset
P4DIR |= 0x2f; // P4.5 output (buzzer)
P4SEL |= 0x20; // select alternate output (TB2) for P4.5
__bis_SR_register(GIE); // enable interrupts
while(1){ //Run infinitely
int i = 0;
int r12=0; // value used for random numbers
for(i ; i < 4; i++) { // loop through 4 times
int temp; // temporary value set to r12 and modified to save r12
r12 += 21845; // if we use rand16() then we get a random sequence every time
temp = r12; // Generate "random" number
temp &= 0x0fff; //
temp += TONE;
toneON(temp); // Turn on tones
LEDs(temp); // turn on leds
delay(); // Delay
}
toneOFF(); // Turn off tone
delay(); // get switch
int LED_array[10];
int sound_array[10];
int LED_pin[4] = {1,2,4,8};
int tone_freq[4] = {3000, 8000, 13000, 18000};
int raspberry = 32000;
int user_input[10];
int round_num = 0;
int go = 1;
srand(time(NULL));
do{
int new = rand() % 4; // simon creates a new random number between 0 and 3
int new_LED = LED_pin[new]; // that number then corresponds with a tone and LED from the above arrays
int new_tone = tone_freq[new];
LED_array[round_num] = new_LED;
sound_array[round_num] = new_tone;
for (i = 0; i <= round_num; i++) //playing the new sequence
{
LEDs(LED_array[i]);
toneON(sound_array[i]);
delay();
LED_4_OFF;
LED_3_OFF;
LED_2_OFF;
LED_1_OFF;
toneOFF();
delay();
}
toneOFF();
//delay();
//int input;
for (i = 0; i <= round_num; i++) //user input and cross check against stored combo
{
int input = getSwitch();
LEDs(input);
if (input==1)
toneON(tone_freq[0]);
else if (input==2)
toneON(tone_freq[1]);
else if (input==4)
toneON(tone_freq[2]);
else if (input==8){
toneON(tone_freq[3]);
}
delay();
LED_4_OFF;
LED_3_OFF;
LED_2_OFF;
LED_1_OFF;
toneOFF();
if (input != LED_array[i])
{
toneON(raspberry);
toneON(raspberry);
delay();
toneOFF();
go = 0;
break;
}
delay();
}
if (!go) break;
victory_tone();
round_num++;
}while(go);
}
}
//------------------------------------------------------------------------------
// LEDs
void LEDs (int number){
P4OUT &= 0xf0; // bic.w #0x0f,&P4OUT Turn on led's
number &= 0x0f;
P4OUT |= number; // bis.w r12, &P4OUT Turn on led's based on value of number
return;
}
/* Note: The AND with a 0xf0 and the OR with number is because a bis and bic only
* modify the values that are changed and leave the others alone. So the And only clears
* the last 4 bits and leaves the other bits alone, and the or will only set the bits that
* are set in number, thereby creating a bis and bic in C.
*/
//------------------------------------------------------------------------------
// output tone subroutine
void toneON(uint16 tone)
{
TBCCR0 = tone; // set beep frequency/duty cycle
TBCCR2 = tone >> 1; // 50% duty cycle
return;
} // end toneON
void toneOFF (){
TBCCR0 = 0; // clear beep frequency/duty cycle
return;
} //end ToneOFF
//------------------------------------------------------------------------------
// Get Switch pressed using polling method
int getSwitch (){
int button;
do { // do-while loop used to wait until user presses switch
button = P1IN;
button &= 0x0f;
button ^=0x0f;
} while (button == 0); // button pressed? N-Loop
return button; // return which button was pressed
}
void delay (){
WDT_Delay = DELAY;
__bis_SR_register(LPM0_bits + GIE); // enable interrupts and goto sleep (LPM0)
}
//------------------------------------------------------------------------------
// Watchdog Timer ISR
#pragma vector = WDT_VECTOR
__interrupt void WDT_ISR(void)
{
// decrement delay (if non-zero)
if (WDT_Delay && (--WDT_Delay == 0)) // Delay over?
__bic_SR_register_on_exit(LPM0_bits); // Y-Wake UP Processor
if (--WDTSecCnt == 0) // WDTSecCnt 0?
{ // Y-
WDTSecCnt = WDT_IPS; // reset counter
LED_GREEN_TOGGLE; // toggle green LED
}
} // end WDT_ISR(void)
void victory_tone() {
int victory[10] = {6000, 7000, 6000}; // value used for random numbers
int i = 0;
for(i ; i <= 4; i++) { // loop through 4 times
toneON(victory[i]); // Turn on tones
delay(); // Delay
}
toneOFF(); // Turn off tone
return;
}
@Colelyman
Copy link

void victory() {
int victory[10] = {9000, 8500, 8000, 5500, 7000}; // value used for random numbers
int i = 0;
for(i ; i <= 4; i++) { // loop through 4 times
toneON(victory[i]); // Turn on tones
delay(); // Delay
}
toneOFF(); // Turn off tone
return;
}

@travischambers
Copy link
Author

void rasberry() {
int rasberry[10] = {6000, 9000, 10000}; // value used for random numbers
int i = 0;
for(i ; i <= 2; i++) { // loop through 4 times
toneON(rasberry[i]); // Turn on tones
delay(); // Delay
}
toneOFF(); // Turn off tone
return;
}

@travischambers
Copy link
Author

void rasberry() {
int rasberry[10] = {6000, 9000, 10000}; // value used for random numbers
int i = 0;
for(i ; i <= 2; i++) { // loop through 4 times
toneON(rasberry[i]); // Turn on tones
delay(); // Delay
}
toneOFF(); // Turn off tone
return;
}

@travischambers
Copy link
Author

void rasberry() {
int rasberry[10] = {6000, 9000, 10000}; // value used for random numbers
int i = 0;
for(i ; i <= 2; i++) { // loop through 4 times
toneON(rasberry[i]); // Turn on tones
delay(); // Delay
}
toneOFF(); // Turn off tone
return;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment