Advertisement
acblack

C16 NTSC PAL Rom Switcher

May 20th, 2019
532
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <EEPROM.h>
  2. #include <Wire.h>
  3. #include <Adafruit_SI5351.h>
  4.  
  5. Adafruit_SI5351 clockgen = Adafruit_SI5351();
  6.  
  7. // C16/PLUS4 Kernel Switcher and Clock Generator
  8. // version 1.1 -- 26-March-2019
  9. // By Adrian Black
  10.  
  11. // SCL = A5 --> This might change on different ATMEL MCU
  12. // SDA = A4 --> This might change on different ATMEL MCU
  13.  
  14. const int PowerLED = 4;      // Output Power LED
  15. const int PowerLEDAlt = 13;  // Output Power LED (onboard LED)
  16. const int A14 = 5;           // Output EPROM Address Line 14
  17. const int ResetLine = 6;    // Input Reset line key
  18.  
  19. int ResetDelay = 2000;  // 2000ms delay for Reset key (2 seconds)
  20. const int FlashSpeed = 100; // LED Flash delay
  21.  
  22. const unsigned long repeatdelay = 500; // used for debouncing
  23.  
  24. int CurrentROM; // which rom is select (0-3)
  25. int debouncecounter = 0;       // how many times we have seen new value (for debounce)
  26. int debouncereading;
  27. int debounce_count;
  28. int ResetHeld;
  29. unsigned long TimeHeld; // amount of time Resotre is held down
  30.  
  31. int buttonDuration = 0; // for keeping track of how long Reset is held down
  32. boolean buttonHeld = 0; // for keeping track when you are holding down
  33. boolean Released = 0; // Keeping track when the Reset key is released
  34. boolean holdingReset = 0; // Keeping track if you are holding Reset
  35. boolean resetSystem = 0; // keep track wheter to reset
  36.  
  37. int buttonInput; // used to return if Reset is held
  38. unsigned long time; //used to keep track of millis output
  39. unsigned long htime; //used to keep track of millis output
  40. unsigned long btime; //used to keep track of bounce millis output
  41.  
  42. void setup() {
  43.   clockgen.begin();
  44.   pinMode(PowerLED, OUTPUT);
  45.   pinMode(PowerLEDAlt, OUTPUT);
  46.   pinMode(A14, OUTPUT);
  47.   pinMode(ResetLine, INPUT);
  48.  
  49.   digitalWrite(PowerLED, HIGH); // turn on the power LED
  50.   digitalWrite(ResetLine, LOW); // keep the system reset
  51.   pinMode(ResetLine, OUTPUT); // switch reset line to OUTPUT so it can hold it low
  52.   digitalWrite(ResetLine, LOW); // keep the system reset
  53.  
  54.   CurrentROM = EEPROM.read(1);
  55.   SetSlot(CurrentROM);
  56.   delay(200);
  57.   pinMode(ResetLine, INPUT); // set the reset pin back to high impedance which releases the INPUT line
  58.   delay(1000); // wait 1000ms
  59.   FlashLED(CurrentROM);  // flash the power LED to show the current state
  60.  
  61.   // all set!
  62. }
  63.  
  64. void loop() {
  65.   buttonInput = readButton(); delay(500);
  66.   time = millis(); // load the number of milliseconds the arduino has been running into variable time
  67.   if (buttonInput == 1) {
  68.     if (!buttonHeld) {
  69.       htime = time; TimeHeld = 0; buttonHeld = 1; } //reset button is pushed and held
  70.     else {
  71.       TimeHeld = time - htime; } // button is being held down, keep track of total time held.
  72.   }
  73.   if (buttonInput == 0) {
  74.     if (buttonHeld) {
  75.       Released = 1; buttonHeld = 0; htime = millis(); TimeHeld = 0; //reset button not being held anymore
  76.     }
  77.   }
  78.  
  79.   if (TimeHeld > ResetDelay && !Released) { // do this when the time the button is held is longer than the delay
  80.     htime = millis();
  81.     if (CurrentROM == 0) { CurrentROM = 1; SaveSlot(CurrentROM); resetSystem = 1;} // or you've already been holding Reset, so increment the current ROM slot otherwise reset it to 0
  82.     else { CurrentROM = 0; SaveSlot(CurrentROM); resetSystem = 1;}
  83.  
  84.     if (TimeHeld > ResetDelay) { TimeHeld = 0;}  // reset the time held
  85.     FlashLED(CurrentROM); //flash the LED
  86.   }
  87.  
  88.   if (Released) {
  89.     //if time held greater than Reset delay, reset the system, set the current rom slot, reselt the time held and holding Reset
  90.     if (resetSystem) { // on do this if the reset system has been set above
  91.       htime = millis();
  92.       resetSystem = 0;
  93.       holdingReset = 0;
  94.       Released = 0;
  95.       digitalWrite(ResetLine, LOW); // keep the system reset
  96.       pinMode(ResetLine, OUTPUT);
  97.       digitalWrite(ResetLine, LOW); // keep the system reset
  98.       delay(1000); //
  99.       SetSlot(CurrentROM); // select the appropriate kernal ROM and change the clock appropriately
  100.       delay(200); // wait 200ms before releasing RESET line
  101.       pinMode(ResetLine, INPUT); // set the reset pin back to high impedance so computer boots
  102.     } else { //otherwise do nothing
  103.       htime = millis(); Released = 0; resetSystem = 0; holdingReset = 0;
  104.     }
  105.   }
  106. // finished with loop  
  107. }
  108.  
  109. int readButton() {
  110.  if (!digitalRead(ResetLine) && (millis() - btime >= repeatdelay)) {
  111.   for(int i = 0; i < 10; i++)
  112.     {
  113.       debouncereading = !digitalRead(ResetLine);
  114.  
  115.       if(!debouncereading && debouncecounter > 0)
  116.       {
  117.         debouncecounter--;
  118.       }
  119.       if(debouncereading)
  120.       {
  121.         debouncecounter++;
  122.       }
  123.       // If the Input has shown the same value for long enough let's switch it
  124.       if(debouncecounter >= debounce_count)
  125.       {
  126.         btime = millis();
  127.         debouncecounter = 0;
  128.         ResetHeld = 1;
  129.       }
  130.     delay (10); // wait 10ms
  131.     }
  132.    } else {
  133.     ResetHeld = 0;
  134.    }
  135. return ResetHeld;
  136. }
  137.  
  138.  
  139. void SaveSlot(int CurrentRomSlot) {
  140.   // Save Current ROM selection (0-3) into EPROM
  141.   EEPROM.write(1,CurrentRomSlot);
  142. }
  143.  
  144. void FlashLED(int flashcount) {
  145.     // Flash the LED to represent which ROM slot is selected
  146.     switch (flashcount) {
  147.     case 0:
  148.       digitalWrite(PowerLED, LOW);
  149.       digitalWrite(PowerLEDAlt, LOW);
  150.       delay(FlashSpeed);
  151.       digitalWrite(PowerLED, HIGH);
  152.       digitalWrite(PowerLEDAlt, HIGH);
  153.       break;
  154.     case 1:
  155.       digitalWrite(PowerLED, LOW);
  156.       digitalWrite(PowerLEDAlt, LOW);
  157.       delay(FlashSpeed);
  158.       digitalWrite(PowerLED, HIGH);
  159.       digitalWrite(PowerLEDAlt, HIGH);
  160.       delay(FlashSpeed);
  161.       digitalWrite(PowerLED, LOW);
  162.       digitalWrite(PowerLEDAlt, LOW);
  163.       delay(FlashSpeed);
  164.       digitalWrite(PowerLED, HIGH);
  165.       digitalWrite(PowerLEDAlt, HIGH);
  166.       break;
  167.     default:
  168.       digitalWrite(PowerLED, LOW);
  169.       digitalWrite(PowerLEDAlt, LOW);
  170.       delay(FlashSpeed);
  171.       digitalWrite(PowerLED, HIGH);
  172.       digitalWrite(PowerLEDAlt, HIGH);
  173.       break;
  174.   }
  175. }
  176.  
  177. void SetSlot(int DesiredRomSlot) {
  178.     // Select the actual ROM slot being used
  179.     switch (DesiredRomSlot) {
  180.     case 0:
  181.       digitalWrite(A14, LOW); //select lower half of EPROM
  182.       clockgen.setupPLL(SI5351_PLL_A, 30, 579543, 625000); // setup the clock for NTSC
  183.       clockgen.setupMultisynth(0, SI5351_PLL_A, 54, 0, 1);
  184.       clockgen.enableOutputs(true);
  185.       delay(50);
  186.       break;
  187.     case 1:
  188.       digitalWrite(A14, HIGH); //select higher half of EPROM
  189.       clockgen.setupPLL(SI5351_PLL_A, 26, 478201, 500000); //setup the clock for PAL
  190.       clockgen.setupMultisynth(0, SI5351_PLL_A, 38, 0, 1);
  191.       clockgen.enableOutputs(true);
  192.       delay(50);
  193.       break;
  194.     default: // in case of EPROM error, default to NTSC
  195.       digitalWrite(A14, LOW); //select lower half of EPROM
  196.       clockgen.setupPLL(SI5351_PLL_A, 30, 579543, 625000); // setup the clock for NTSC
  197.       clockgen.setupMultisynth(0, SI5351_PLL_A, 54, 0, 1);
  198.       clockgen.enableOutputs(true);
  199.       delay(50);
  200.       break;
  201.   }
  202. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement