daily pastebin goal
11%
SHARE
TWEET

Untitled

a guest Jan 12th, 2018 87 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //-----------------//
  2. //   Definitions   //
  3. //-----------------//
  4.  
  5. #define readBit(port, pin)        ((port) >> (pin) & 0x01)
  6. #define setBit(port, pin)         ((port) |= (1UL << (pin)))
  7. #define clearBit(port, pin)       ((port) &= ~(1UL << (pin)))
  8. #define writeBit(port, pin, val)  ((val) ? setBit(port, pin) : clearBit(port, pin))
  9. #define invBit(port, pin)         ((port) ^= (1UL << (pin)))
  10.  
  11. ////registers
  12. //#define PORTB                     (volatile uint8_t *)0x25
  13. //#define PORTC                     (volatile uint8_t *)0x28
  14. //#define PORTD                     (volatile uint8_t *)0x2B
  15. //
  16. //#define DDRB                      (volatile uint8_t *)0x24
  17. //#define DDRC                      (volatile uint8_t *)0x27
  18. //#define DDRD                      (volatile uint8_t *)0x2A
  19. //
  20. //#define PINB                      (volatile uint8_t *)0x23
  21. //#define PINC                      (volatile uint8_t *)0x26
  22. //#define PIND                      (volatile uint8_t *)0x29
  23. //
  24. ////trigger register locations
  25. //#define TIMSK0                    *(volatile uint8_t *)0x6E
  26. //#define TIMSK2                    *(volatile uint8_t *)0x70
  27. //#define TCCR0A                    *(volatile uint8_t *)0x24
  28. //#define TCCR0B                    *(volatile uint8_t *)0x25
  29. //#define TCCR2A                    *(volatile uint8_t *)0xB0
  30. //#define TCCR2B                    *(volatile uint8_t *)0xB1
  31. //#define OCR0A                     *(volatile uint8_t *)0x47
  32. //#define OCR2A                     *(volatile uint8_t *)0xB3
  33.  
  34. //user settings
  35. #define LEDS                      4
  36. #define BUTTONS                   5
  37. #define MAXARRAYSIZE              512
  38. #define BUTTONS_PORT              PINC
  39. #define START_TIME                420
  40. #define STEP_TIME                 10
  41.  
  42. #define beeperEnabled             true
  43.  
  44. //----------------------//
  45. //   Global Variables   //
  46. //----------------------//
  47.  
  48. int colorList[MAXARRAYSIZE];
  49. int nextLed = 0;
  50. int level = 0;
  51. int currentLed = 0;
  52. unsigned int currMillis = 0;
  53. bool gameStarted = false;
  54. int currentTime = START_TIME - (level * STEP_TIME);
  55.  
  56. struct hwdata {
  57.     volatile uint8_t *port;
  58.     volatile uint8_t *dir;
  59.     uint8_t pin;
  60. };
  61.  
  62. const hwdata leds[LEDS] = {
  63.         {&PORTB, &DDRB, 0}, //green
  64.         {&PORTB, &DDRB, 1}, //red
  65.         {&PORTB, &DDRB, 3}, //blue
  66.         {&PORTB, &DDRB, 2}  //yellow
  67. };
  68.  
  69. const hwdata buttons[BUTTONS] = {
  70.         {&PORTC, &DDRC, 3}, //green button
  71.         {&PORTC, &DDRC, 2}, //red button
  72.         {&PORTC, &DDRC, 1}, //yellow button
  73.         {&PORTC, &DDRC, 0}, //blue button
  74.         {&PORTC, &DDRC, 4}  //reset button
  75. };
  76.  
  77. const hwdata beeper = { &PORTD, &DDRD, 6 }; //obv beeper is obv
  78.  
  79. const int freq[LEDS] = { 415, 310, 252, 209 };
  80.  
  81. //--------------------//
  82. //   Game Mechanics   //
  83. //--------------------//
  84.  
  85. //pretty sequence to know when you hit the reset button or turned the game on
  86. void bootupLights() {
  87.     for(int i = 0; i < LEDS; i++) {
  88.         blinkLed(leds[i].pin, 100);
  89.     }
  90. }
  91.  
  92. //get next color and show previous level colors
  93. void nextLevel() {
  94.     currentLed = 0;
  95.     colorList[level] = nextLed;
  96.     level++;
  97.     for (int i = 0; i < level; i++) {
  98.         blinkLed(colorList[i], currentTime);
  99.     }
  100. }
  101.  
  102. //reset game stats
  103. void resetGame() {
  104.     level = 0;
  105.     currMillis = 0;
  106.     gameStarted = true;
  107.     bootupLights();
  108.     wait(1000);
  109.     nextLevel();
  110. }
  111.  
  112. //blink all leds to show gameover
  113. void gameOver() {
  114.     for (int i = 0; i < 3; i++) {
  115.         for (int j = 0; j < 2; j++) {
  116.             for (int k = 0; k < LEDS; k++) {
  117.                 ledControl(k, j % 2 == 0 ? true : false);
  118.             }
  119.             wait(500);
  120.             stopBeeper();
  121.         }
  122.     }
  123.     stopBeeper();
  124. }
  125.  
  126. //-------------------------//
  127. //   Hardware Controllers  //
  128. //-------------------------//
  129.  
  130. //get which button was pressed down and handle it
  131. void buttonDown(int button) {
  132.     // check for running game
  133.     if (!gameStarted) {
  134.         return;
  135.     }
  136.    
  137.     // reset button
  138.     if (buttons[button].pin == 4) {
  139.         resetGame();
  140.         return;
  141.     }
  142.    
  143.     // game over if not matched
  144.     if (buttons[button].pin != colorList[currentLed]) {
  145.         gameOver();
  146.         return;
  147.     }
  148.    
  149.     // check if at end of list
  150.     if (level - 1 > currentLed) {
  151.         // move to next in list
  152.         currentLed++;
  153.         wait(250);
  154.         blinkLed(button, 500);
  155.     } else if (level - 1 == currentLed) {
  156.         // go to next level
  157.         wait(250);
  158.         blinkLed(button, 500);
  159.         wait(600);
  160.         nextLevel();
  161.     }
  162. }
  163.  
  164. //turns led on and off and plays a sound if buzzer is enabled
  165. void ledControl(int led, bool enable) {
  166.     writeBit(*leds[led].port, leds[led].pin, (enable ? 1 : 0));
  167.     if (enable) {
  168.         startBeeper(freq[leds[led].pin]);
  169.     }
  170. }
  171.  
  172. //turn the led on, wait for a delay, turn the led off
  173. void blinkLed(int led, int msDelay) {
  174.     ledControl(led, true);
  175.     wait(msDelay);
  176.     ledControl(led, false);
  177.     stopBeeper();
  178.     wait(50);
  179. }
  180.  
  181. //setup the ports for hardware
  182. void setupPorts() {
  183.     //register leds
  184.     for(int i = 0; i < LEDS; i++) {
  185.         writeBit(*leds[i].dir, leds[i].pin, OUTPUT);
  186.     }
  187.  
  188.     //register buttons / pullups
  189.     for(int j = 0; j < BUTTONS; j++) {
  190.         writeBit(*buttons[j].dir, buttons[j].pin, INPUT);
  191.         writeBit(*buttons[j].port, buttons[j].pin, 1);
  192.     }
  193.  
  194.     //register beeper
  195.     writeBit(*beeper.dir, beeper.pin, OUTPUT);
  196. }
  197.  
  198. //--------------------//
  199. //   Beeper Methods   //
  200. //--------------------//
  201.  
  202. //setup beeper to run later
  203. void setupBeeper() {
  204.     TCCR2A = 0;
  205.     TCCR2B = 0;
  206.     writeBit(TCCR2A, 1, 1); //set CTC mode
  207.     writeBit(TIMSK2, 1, 1); //enable interrupt
  208. }
  209.  
  210. //start beeper at a specific frequency(sound)
  211. void startBeeper(int freq) {
  212.     if (beeperEnabled) {
  213.         OCR2A = F_CPU / freq / 256 / 2 - 1;
  214.         writeBit(TCCR2B, 1, 1);
  215.         writeBit(TCCR2B, 2, 1);
  216.     }
  217. }
  218.  
  219. //turn off the beeper
  220. void stopBeeper() {
  221.     writeBit(TCCR2B, 1, 0);
  222.     writeBit(TCCR2B, 2, 0);
  223. }
  224.  
  225. //-------------------//
  226. //   Delay Methods   //
  227. //-------------------//
  228.  
  229. //setup delay for later
  230. void setupDelay() {
  231.     TCCR0A = 0;
  232.     TCCR0B = 0;
  233.     writeBit(TCCR0A, 1, 1);
  234.     writeBit(TCCR0B, 0, 1);
  235.     writeBit(TCCR0B, 1, 1);
  236.     writeBit(TIMSK0, 1, 1);
  237.     OCR0A = 0xFA;
  238. }
  239.  
  240. //doesn't change number while reading
  241. unsigned int mills() {
  242.     writeBit(TIMSK0, 1, 0);
  243.     unsigned int tmp = currMillis;
  244.     writeBit(TIMSK0, 1, 1);
  245.     return tmp;
  246. }
  247.  
  248. //basically delay(ms)
  249. void wait(int ms) {
  250.     unsigned int start = mills();
  251.     while (mills() < start + ms);
  252. }
  253.  
  254. //---------------//
  255. //   Main loop   //
  256. //---------------//
  257. int main() {
  258.     setupPorts();
  259.     setupBeeper();
  260.     setupDelay();
  261.     sei();
  262.  
  263.     //main loop
  264.     while (1) {
  265.         for (int i = 0; i < BUTTONS; i++) {
  266.             if (readBit(BUTTONS_PORT, i) == 0) {
  267.                 wait(25);
  268.                 if (readBit(BUTTONS_PORT, i) == 1) {
  269.                     buttonDown(i);
  270.                 }
  271.             }
  272.         }
  273.     }
  274. }
  275.  
  276. //----------------//
  277. //   Interrupts   //
  278. //----------------//
  279.  
  280. //interrupt for beeper
  281. ISR (TIMER2_COMPA_vect) {
  282.         invBit(*beeper.port, 6);
  283. }
  284.  
  285. //interrupt for delay
  286. ISR (TIMER0_COMPA_vect) {
  287.         ++nextLed %= 4;
  288.         currMillis++;
  289. }
RAW Paste Data
Top