Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //-----------------//
- // Definitions //
- //-----------------//
- #define readBit(port, pin) ((port) >> (pin) & 0x01)
- #define setBit(port, pin) ((port) |= (1UL << (pin)))
- #define clearBit(port, pin) ((port) &= ~(1UL << (pin)))
- #define writeBit(port, pin, val) ((val) ? setBit(port, pin) : clearBit(port, pin))
- #define invBit(port, pin) ((port) ^= (1UL << (pin)))
- ////registers
- //#define PORTB (volatile uint8_t *)0x25
- //#define PORTC (volatile uint8_t *)0x28
- //#define PORTD (volatile uint8_t *)0x2B
- //
- //#define DDRB (volatile uint8_t *)0x24
- //#define DDRC (volatile uint8_t *)0x27
- //#define DDRD (volatile uint8_t *)0x2A
- //
- //#define PINB (volatile uint8_t *)0x23
- //#define PINC (volatile uint8_t *)0x26
- //#define PIND (volatile uint8_t *)0x29
- //
- ////trigger register locations
- //#define TIMSK0 *(volatile uint8_t *)0x6E
- //#define TIMSK2 *(volatile uint8_t *)0x70
- //#define TCCR0A *(volatile uint8_t *)0x24
- //#define TCCR0B *(volatile uint8_t *)0x25
- //#define TCCR2A *(volatile uint8_t *)0xB0
- //#define TCCR2B *(volatile uint8_t *)0xB1
- //#define OCR0A *(volatile uint8_t *)0x47
- //#define OCR2A *(volatile uint8_t *)0xB3
- //user settings
- #define LEDS 4
- #define BUTTONS 5
- #define MAXARRAYSIZE 512
- #define BUTTONS_PORT PINC
- #define START_TIME 420
- #define STEP_TIME 10
- #define beeperEnabled true
- //----------------------//
- // Global Variables //
- //----------------------//
- int colorList[MAXARRAYSIZE];
- int nextLed = 0;
- int level = 0;
- int currentLed = 0;
- unsigned int currMillis = 0;
- bool gameStarted = false;
- int currentTime = START_TIME - (level * STEP_TIME);
- struct hwdata {
- volatile uint8_t *port;
- volatile uint8_t *dir;
- uint8_t pin;
- };
- const hwdata leds[LEDS] = {
- {&PORTB, &DDRB, 0}, //green
- {&PORTB, &DDRB, 1}, //red
- {&PORTB, &DDRB, 3}, //blue
- {&PORTB, &DDRB, 2} //yellow
- };
- const hwdata buttons[BUTTONS] = {
- {&PORTC, &DDRC, 3}, //green button
- {&PORTC, &DDRC, 2}, //red button
- {&PORTC, &DDRC, 1}, //yellow button
- {&PORTC, &DDRC, 0}, //blue button
- {&PORTC, &DDRC, 4} //reset button
- };
- const hwdata beeper = { &PORTD, &DDRD, 6 }; //obv beeper is obv
- const int freq[LEDS] = { 415, 310, 252, 209 };
- //--------------------//
- // Game Mechanics //
- //--------------------//
- //pretty sequence to know when you hit the reset button or turned the game on
- void bootupLights() {
- for(int i = 0; i < LEDS; i++) {
- blinkLed(leds[i].pin, 100);
- }
- }
- //get next color and show previous level colors
- void nextLevel() {
- currentLed = 0;
- colorList[level] = nextLed;
- level++;
- for (int i = 0; i < level; i++) {
- blinkLed(colorList[i], currentTime);
- }
- }
- //reset game stats
- void resetGame() {
- level = 0;
- currMillis = 0;
- gameStarted = true;
- bootupLights();
- wait(1000);
- nextLevel();
- }
- //blink all leds to show gameover
- void gameOver() {
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 2; j++) {
- for (int k = 0; k < LEDS; k++) {
- ledControl(k, j % 2 == 0 ? true : false);
- }
- wait(500);
- stopBeeper();
- }
- }
- stopBeeper();
- }
- //-------------------------//
- // Hardware Controllers //
- //-------------------------//
- //get which button was pressed down and handle it
- void buttonDown(int button) {
- // check for running game
- if (!gameStarted) {
- return;
- }
- // reset button
- if (buttons[button].pin == 4) {
- resetGame();
- return;
- }
- // game over if not matched
- if (buttons[button].pin != colorList[currentLed]) {
- gameOver();
- return;
- }
- // check if at end of list
- if (level - 1 > currentLed) {
- // move to next in list
- currentLed++;
- wait(250);
- blinkLed(button, 500);
- } else if (level - 1 == currentLed) {
- // go to next level
- wait(250);
- blinkLed(button, 500);
- wait(600);
- nextLevel();
- }
- }
- //turns led on and off and plays a sound if buzzer is enabled
- void ledControl(int led, bool enable) {
- writeBit(*leds[led].port, leds[led].pin, (enable ? 1 : 0));
- if (enable) {
- startBeeper(freq[leds[led].pin]);
- }
- }
- //turn the led on, wait for a delay, turn the led off
- void blinkLed(int led, int msDelay) {
- ledControl(led, true);
- wait(msDelay);
- ledControl(led, false);
- stopBeeper();
- wait(50);
- }
- //setup the ports for hardware
- void setupPorts() {
- //register leds
- for(int i = 0; i < LEDS; i++) {
- writeBit(*leds[i].dir, leds[i].pin, OUTPUT);
- }
- //register buttons / pullups
- for(int j = 0; j < BUTTONS; j++) {
- writeBit(*buttons[j].dir, buttons[j].pin, INPUT);
- writeBit(*buttons[j].port, buttons[j].pin, 1);
- }
- //register beeper
- writeBit(*beeper.dir, beeper.pin, OUTPUT);
- }
- //--------------------//
- // Beeper Methods //
- //--------------------//
- //setup beeper to run later
- void setupBeeper() {
- TCCR2A = 0;
- TCCR2B = 0;
- writeBit(TCCR2A, 1, 1); //set CTC mode
- writeBit(TIMSK2, 1, 1); //enable interrupt
- }
- //start beeper at a specific frequency(sound)
- void startBeeper(int freq) {
- if (beeperEnabled) {
- OCR2A = F_CPU / freq / 256 / 2 - 1;
- writeBit(TCCR2B, 1, 1);
- writeBit(TCCR2B, 2, 1);
- }
- }
- //turn off the beeper
- void stopBeeper() {
- writeBit(TCCR2B, 1, 0);
- writeBit(TCCR2B, 2, 0);
- }
- //-------------------//
- // Delay Methods //
- //-------------------//
- //setup delay for later
- void setupDelay() {
- TCCR0A = 0;
- TCCR0B = 0;
- writeBit(TCCR0A, 1, 1);
- writeBit(TCCR0B, 0, 1);
- writeBit(TCCR0B, 1, 1);
- writeBit(TIMSK0, 1, 1);
- OCR0A = 0xFA;
- }
- //doesn't change number while reading
- unsigned int mills() {
- writeBit(TIMSK0, 1, 0);
- unsigned int tmp = currMillis;
- writeBit(TIMSK0, 1, 1);
- return tmp;
- }
- //basically delay(ms)
- void wait(int ms) {
- unsigned int start = mills();
- while (mills() < start + ms);
- }
- //---------------//
- // Main loop //
- //---------------//
- int main() {
- setupPorts();
- setupBeeper();
- setupDelay();
- sei();
- //main loop
- while (1) {
- for (int i = 0; i < BUTTONS; i++) {
- if (readBit(BUTTONS_PORT, i) == 0) {
- wait(25);
- if (readBit(BUTTONS_PORT, i) == 1) {
- buttonDown(i);
- }
- }
- }
- }
- }
- //----------------//
- // Interrupts //
- //----------------//
- //interrupt for beeper
- ISR (TIMER2_COMPA_vect) {
- invBit(*beeper.port, 6);
- }
- //interrupt for delay
- ISR (TIMER0_COMPA_vect) {
- ++nextLed %= 4;
- currMillis++;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement