pastebin - collaborative debugging tool
kpaste.net RSS


Untitled
Posted by Anonymous on Sun 20th Feb 2011 21:55
raw | new post

  1. #define RIGHT 10
  2. #define LEFT 9
  3. #define DOWN 8
  4. #define UP 7
  5. #define START 6
  6. #define SELECT 5
  7. #define B 4
  8. #define A 3
  9.  
  10. #define READY 16    // analog pin 2
  11. #define GOBTN 17    // analog pin 3
  12. #define STATUS 14   // analog pin 0
  13. #define SD_LOAD 18  // analog pin 4
  14.  
  15. #include <MsTimer2.h>
  16. #include "MMC.h"
  17.  
  18. volatile unsigned long frame = 0; // This is the frame for which data is currently loaded
  19.  
  20. unsigned long movie_length = 0;
  21.  
  22. byte buttons1[512];
  23. byte buttons2[512];
  24.  
  25. unsigned long data_amount = 0;
  26. unsigned long data_count = 0;
  27. boolean dataRecording = false;
  28. boolean sd_load_init_done = false;
  29. boolean nes_init_done = false;
  30. byte write_me[512];
  31.  
  32. byte sd_init_return = 255;
  33.  
  34. boolean data_read = false;
  35.  
  36. MMC sd_card;
  37.  
  38. volatile char next_buttons = 0;
  39.  
  40. volatile unsigned long time = 0;
  41.  
  42. void latch_pulse()
  43. {
  44. //    detachInterrupt(0);
  45. //    MsTimer2::stop();
  46.     MsTimer2::start();
  47.    
  48.     // If the movie is over, disable the bot  
  49.     if (frame == movie_length - 1) {
  50.         next_buttons = 0;
  51.         writeButtons();
  52.         detachInterrupt(0);
  53. //        Timer1.stop();
  54.     }
  55.    
  56.     // After 512 frames, copy in the next chunk of frame data
  57.     if (frame % 512 == 0)
  58.     {
  59.         for (int i = 0; i < 512; i++)
  60.         {
  61.             buttons1[i] = buttons2[i];
  62.         }
  63.     }
  64.    
  65.     // Flash the status led every 5 latches (~6 times a second)
  66.     if (frame % 10 == 0)
  67.     {
  68.         digitalWrite(STATUS, HIGH);
  69.     }
  70.    
  71.     if (frame % 10 == 5)
  72.     {
  73.         digitalWrite(STATUS, LOW);
  74.     }
  75. }
  76.  
  77. // Write the given button sequence to the shift register
  78. void writeButtons()
  79. {
  80.     // Shift out the button information from the data byte
  81.     // and make each pin HIGH or LOW accordingly
  82.     MsTimer2::stop();  
  83. //    next_buttons = buttons1[frame % 512];
  84.     char buttons = buttons1[frame % 512];
  85.     buttons = ~buttons;
  86.     digitalWrite(A,      buttons & 1);
  87.     buttons = buttons >> 1;
  88.     digitalWrite(B,      buttons & 1);
  89.     buttons = buttons >> 1;
  90.     digitalWrite(SELECT,      buttons & 1);
  91.     buttons = buttons >> 1;
  92.     digitalWrite(START,      buttons & 1);
  93.     buttons = buttons >> 1;
  94.     digitalWrite(UP,      buttons & 1);
  95.     buttons = buttons >> 1;
  96.     digitalWrite(DOWN,      buttons & 1);
  97.     buttons = buttons >> 1;
  98.     digitalWrite(LEFT,      buttons & 1);
  99.     buttons = buttons >> 1;
  100.     digitalWrite(RIGHT,      buttons & 1);
  101.     frame++;
  102. //    attachInterrupt(0,latch_pulse, FALLING);
  103. }
  104.  
  105. // Initialize the system to play the NES
  106. void nes_init()
  107. {
  108.     // Undo the SD loading initialization if previously completed
  109.     if (sd_load_init_done)
  110.     {
  111.         Serial.end();
  112.         sd_load_init_done = false;
  113.     }
  114.    
  115.     // All of our simulated buttons need to be outputs
  116.     pinMode(RIGHT, OUTPUT);
  117.     pinMode(LEFT, OUTPUT);
  118.     pinMode(DOWN, OUTPUT);
  119.     pinMode(UP, OUTPUT);
  120.     pinMode(START, OUTPUT);
  121.     pinMode(SELECT, OUTPUT);
  122.     pinMode(B, OUTPUT);
  123.     pinMode(A, OUTPUT);
  124.    
  125.     // Turn on the ready light
  126.     digitalWrite(READY, HIGH);
  127.    
  128.     frame = 0;
  129.     movie_length = 0;
  130.     data_read = false;
  131.     MsTimer2::set(14, writeButtons); // 500ms period
  132.    
  133.     nes_init_done = true;
  134. }
  135.  
  136. // Initialize the system to load the movie onto the SD card
  137. void sd_load_init()
  138. {
  139.     if (nes_init_done)
  140.     {
  141.         nes_init_done = false;
  142.     }
  143.    
  144.     // Setup the serial port
  145.     Serial.begin(115200);
  146.     Serial.flush();
  147.  
  148.     // Let the computer know we're ready
  149.     Serial.print(sd_init_return,HEX);
  150.     data_count = 0;
  151.     sd_load_init_done = true;
  152. }
  153.  
  154. // General setup
  155. void setup()
  156. {
  157.     // Enable the go button pin with a pullup
  158.     pinMode(GOBTN, INPUT);
  159.     digitalWrite(GOBTN, HIGH);
  160.    
  161.     // Enable the SD loading switch pin with a pullup
  162.     pinMode(SD_LOAD, INPUT);
  163.     digitalWrite(SD_LOAD, HIGH);
  164.    
  165.     // Enable status LED pin and turn it off
  166.     pinMode(STATUS, OUTPUT);
  167.     digitalWrite(STATUS, LOW);
  168.    
  169.     // Enable ready LED pin and turn it off
  170.     pinMode(READY, OUTPUT);
  171.     digitalWrite(READY, LOW);
  172.    
  173.     // Make sure the SD card is ready for communication
  174.     delay(10);
  175.     sd_init_return = sd_card.init();
  176. }
  177.  
  178. void loop()
  179. {
  180.     // We must now decide if we are loading data to the SD card or playing the NES
  181.     switch (digitalRead(SD_LOAD))
  182.     {
  183.         // NES playing mode
  184.         case HIGH:
  185.             // Initialize the NES playing mode if not done already
  186.             if (!nes_init_done)
  187.             {
  188.                 nes_init();
  189.             }
  190.            
  191.             while (digitalRead(GOBTN) == HIGH); // Waiting for the go button to be pressed
  192.            
  193.             // We are now running, turn off the ready light
  194.             digitalWrite(READY, LOW);
  195.            
  196.             // Pull out the first block of data which contains the movie length information
  197.             sd_card.read_data(buttons1,0);
  198.            
  199.             // Convert the ascii characters into an actual number
  200.             for (int i = 0; buttons1[i] != ' '; i++)
  201.             {
  202.                 movie_length = movie_length * 10 + buttons1[i] - 48;
  203.             }
  204.            
  205.             // Pull out the first block of actual button data
  206.             sd_card.read_data(buttons1,512);
  207.            
  208.             // Write the first set of buttons
  209.             next_buttons = buttons1[0];
  210.             writeButtons();
  211.            
  212.             // We are now ready to talk to the console, so turn on interrupts
  213.             attachInterrupt(0,latch_pulse, FALLING);
  214.            
  215.             // Turn on the status LED to announce our readiness
  216.             digitalWrite(STATUS, HIGH);
  217.            
  218.             // Now would be a good time to turn on the console and watch it go!
  219.             while (true)
  220.             {
  221.                 // Buffer the next 512 bytes
  222.                 if (frame % 512 == 1 && data_read == false) {
  223.                     sd_card.read_data(buttons2,frame+1023);
  224.                     data_read = true;
  225.                 }
  226.                 else
  227.                 {
  228.                     data_read = false;
  229.                 }
  230.             }  
  231.            
  232.             /* Unreachable Code */
  233.             break;
  234.        
  235.      
  236.         // SD loading mode  
  237.         case LOW:
  238.             // Initialize the loading mode if not done already
  239.             if (!sd_load_init_done) {
  240.                 sd_load_init();
  241.             }
  242.            
  243.             // Wait for data from the computer
  244.             while (Serial.available()>0)
  245.             {
  246.                 digitalWrite(READY, HIGH);
  247.                
  248.                 // The computer will first send the length of the video
  249.                 if (dataRecording == false)
  250.                 {
  251.                     char inByte;
  252.                     switch (inByte = Serial.read())
  253.                     {
  254.                         case '0':
  255.                         case '1':
  256.                         case '2':
  257.                         case '3':
  258.                         case '4':
  259.                         case '5':
  260.                         case '6':
  261.                         case '7':
  262.                         case '8':
  263.                         case '9':
  264.                             data_amount = data_amount * 10 + inByte - 48;
  265.                             write_me[data_count] = inByte;
  266.                             data_count++;
  267.                             break;
  268.                         case ' ':
  269.                             Serial.println(data_amount);
  270.                             write_me[data_count] = ' ';
  271.                            
  272.                             // Write this movie length as the first block on the SD card
  273.                             sd_card.write_data(write_me, 0);
  274.                            
  275.                             // We are now ready to record actual button data
  276.                             dataRecording = true;
  277.                             data_count = 0;
  278.                             break;
  279.                         default:
  280.                             Serial.flush();
  281.                     }
  282.                 }
  283.                 else
  284.                 {
  285.                     // Loop until we get all the button data expected
  286.                     while (data_count < data_amount)
  287.                     {
  288.                         // Wait for data
  289.                         while (Serial.available() <=0);
  290.                        
  291.                         // Read in the data, and store it
  292.                         int value = Serial.read();
  293.                         write_me[data_count % 512] = value;
  294.                         data_count++;
  295.                        
  296.                         // When we have a full block, write it to the card
  297.                         if (data_count % 512 == 0)
  298.                         {
  299.                             sd_card.write_data(write_me, data_count);
  300.                         }
  301.                     }
  302.                    
  303.                     // Write the rest of the data to the card
  304.                     sd_card.write_data(write_me, data_count - (data_count % 512) + 512);
  305.                 }
  306.                
  307.                 // If the computer sent us more data than we were expecting, just ignore it
  308.                 if (data_count >= data_amount && dataRecording == true)
  309.                 {
  310.                     Serial.flush();
  311.                     Serial.println("DONE");
  312.                 }
  313.             }
  314.             digitalWrite(READY, LOW);
  315.     }
  316. }

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at