mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-24 03:51:54 +01:00
Add Clock generator calibration option
This commit is contained in:
parent
3f4d8e9728
commit
bbe6e3cceb
@ -17,6 +17,7 @@
|
||||
Rotary Enc lib: https://github.com/mathertel/RotaryEncoder
|
||||
SI5351 lib: https://github.com/etherkit/Si5351Arduino
|
||||
RTC lib: https://github.com/adafruit/RTClib
|
||||
Frequency lib: https://github.com/PaulStoffregen/FreqCount
|
||||
|
||||
Compiled with Arduino 1.8.13
|
||||
|
||||
|
@ -36,8 +36,14 @@ static const char snsMenuItem1[] PROGMEM = "Super Nintendo";
|
||||
static const char snsMenuItem2[] PROGMEM = "NPower SF Memory";
|
||||
static const char snsMenuItem3[] PROGMEM = "Satellaview BS-X";
|
||||
static const char snsMenuItem4[] PROGMEM = "Flash repro";
|
||||
#ifdef clockgen_calibration
|
||||
static const char snsMenuItem5[] PROGMEM = "Calibrate Clock";
|
||||
static const char snsMenuItem6[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsSNS[] PROGMEM = {snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5, snsMenuItem6};
|
||||
#else
|
||||
static const char snsMenuItem5[] PROGMEM = "Reset";
|
||||
static const char* const menuOptionsSNS[] PROGMEM = {snsMenuItem1, snsMenuItem2, snsMenuItem3, snsMenuItem4, snsMenuItem5};
|
||||
#endif
|
||||
|
||||
// SNES menu items
|
||||
static const char SnesMenuItem1[] PROGMEM = "Read Rom";
|
||||
@ -133,8 +139,14 @@ void snsMenu() {
|
||||
// create menu with title and 6 options to choose from
|
||||
unsigned char snsCart;
|
||||
// Copy menuOptions out of progmem
|
||||
#ifdef clockgen_calibration
|
||||
convertPgm(menuOptionsSNS, 6);
|
||||
snsCart = question_box(F("Select Cart Type"), menuOptions, 6, 0);
|
||||
#else
|
||||
convertPgm(menuOptionsSNS, 5);
|
||||
snsCart = question_box(F("Select Cart Type"), menuOptions, 5, 0);
|
||||
#endif
|
||||
|
||||
|
||||
// wait for user choice to come back from the question box menu
|
||||
switch (snsCart)
|
||||
@ -169,6 +181,12 @@ void snsMenu() {
|
||||
#endif
|
||||
|
||||
case 4:
|
||||
#ifdef clockgen_calibration
|
||||
clkcal();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
#endif
|
||||
resetArduino();
|
||||
break;
|
||||
}
|
||||
|
215
Cart_Reader/clkcal.ino
Normal file
215
Cart_Reader/clkcal.ino
Normal file
@ -0,0 +1,215 @@
|
||||
//******************************************
|
||||
// Clock Calibration Module
|
||||
//******************************************
|
||||
|
||||
#ifdef clockgen_calibration
|
||||
#include <FreqCount.h>
|
||||
#include "snes_clk.h"
|
||||
#include "SdFat.h"
|
||||
|
||||
/******************************************
|
||||
Variables
|
||||
*****************************************/
|
||||
int32_t cal_factor = 0;
|
||||
int32_t old_cal = 0;
|
||||
int32_t cal_offset = 100;
|
||||
|
||||
|
||||
/******************************************
|
||||
Clock Calibration
|
||||
*****************************************/
|
||||
void clkcal() {
|
||||
// Adafruit Clock Generator
|
||||
// last number is the clock correction factor which is custom for each clock generator
|
||||
cal_factor = readClockOffset();
|
||||
|
||||
display.clearDisplay();
|
||||
display.setCursor(0, 0);
|
||||
display.print("Read correction: ");
|
||||
display.println(cal_factor);
|
||||
display.display();
|
||||
delay(500);
|
||||
|
||||
if (cal_factor > INT32_MIN) {
|
||||
clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, cal_factor);
|
||||
} else {
|
||||
clockgen.init(SI5351_CRYSTAL_LOAD_8PF, 0, 0);
|
||||
cal_factor = 0;
|
||||
}
|
||||
//clockgen.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
||||
//clockgen.pll_reset(SI5351_PLLA);
|
||||
//clockgen.pll_reset(SI5351_PLLB);
|
||||
clockgen.set_freq(400000000ULL, SI5351_CLK0);
|
||||
clockgen.set_freq(100000000ULL, SI5351_CLK1);
|
||||
clockgen.set_freq(307200000ULL, SI5351_CLK2);
|
||||
clockgen.output_enable(SI5351_CLK1, 1);
|
||||
clockgen.output_enable(SI5351_CLK2, 1);
|
||||
clockgen.output_enable(SI5351_CLK0, 1);
|
||||
|
||||
// Frequency Counter
|
||||
delay(500);
|
||||
FreqCount.begin(1000);
|
||||
while (1)
|
||||
{
|
||||
if (old_cal != cal_factor) {
|
||||
display_Clear();
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F(" Adjusting"));
|
||||
display_Update();
|
||||
clockgen.set_correction(cal_factor, SI5351_PLL_INPUT_XO);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLA);
|
||||
clockgen.set_pll(SI5351_PLL_FIXED, SI5351_PLLB);
|
||||
clockgen.pll_reset(SI5351_PLLA);
|
||||
clockgen.pll_reset(SI5351_PLLB);
|
||||
clockgen.set_freq(400000000ULL, SI5351_CLK0);
|
||||
clockgen.set_freq(100000000ULL, SI5351_CLK1);
|
||||
clockgen.set_freq(307200000ULL, SI5351_CLK2);
|
||||
old_cal = cal_factor;
|
||||
delay(500);
|
||||
}
|
||||
else {
|
||||
clockgen.update_status();
|
||||
while (clockgen.dev_status.SYS_INIT == 1) {
|
||||
}
|
||||
|
||||
if (FreqCount.available()) {
|
||||
float count = FreqCount.read();
|
||||
display_Clear();
|
||||
println_Msg(F("Clock Calibration"));
|
||||
println_Msg(F(""));
|
||||
print_Msg(F("Freq: "));
|
||||
print_Msg(count);
|
||||
println_Msg(F("Hz"));
|
||||
print_Msg(F("Correction:"));
|
||||
print_right(cal_factor);
|
||||
print_Msg(F("Adjustment:"));
|
||||
print_right(cal_offset);
|
||||
#ifdef enable_Button2
|
||||
println_Msg(F("(Hold button to save)"));
|
||||
println_Msg(F(""));
|
||||
println_Msg(F("Decrease Increase"));
|
||||
#else
|
||||
#ifdef enable_rotary
|
||||
println_Msg(F("Rotate to adjust"));
|
||||
#else
|
||||
println_Msg(F("Click/dbl to adjust"));
|
||||
#endif
|
||||
#endif
|
||||
display_Update();
|
||||
}
|
||||
#ifdef enable_Button2
|
||||
// get input button
|
||||
int a = checkButton1();
|
||||
int b = checkButton2();
|
||||
|
||||
// if the cart readers input button is pressed shortly
|
||||
if (a == 1) {
|
||||
old_cal = cal_factor;
|
||||
cal_factor -= cal_offset;
|
||||
}
|
||||
if (b == 1) {
|
||||
old_cal = cal_factor;
|
||||
cal_factor += cal_offset;
|
||||
}
|
||||
|
||||
// if the cart readers input buttons is double clicked
|
||||
if (a == 2) {
|
||||
cal_offset /= 10ULL;
|
||||
if (cal_offset < 1)
|
||||
{
|
||||
cal_offset = 100000000ULL;
|
||||
}
|
||||
}
|
||||
if (b == 2) {
|
||||
cal_offset *= 10ULL;
|
||||
if (cal_offset > 100000000ULL)
|
||||
{
|
||||
cal_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// if the cart readers input button is pressed long
|
||||
if (a == 3) {
|
||||
savetofile();
|
||||
}
|
||||
if (b == 3) {
|
||||
savetofile();
|
||||
}
|
||||
#else
|
||||
//Handle inputs for either rotary encoder or single button interface.
|
||||
int a = checkButton();
|
||||
|
||||
if (a == 1) { //clockwise rotation or single click
|
||||
old_cal = cal_factor;
|
||||
cal_factor += cal_offset;
|
||||
}
|
||||
|
||||
if (a == 2) { //counterclockwise rotation or double click
|
||||
old_cal = cal_factor;
|
||||
cal_factor -= cal_offset;
|
||||
}
|
||||
|
||||
if (a == 3) { //button short hold
|
||||
cal_offset *= 10ULL;
|
||||
if (cal_offset > 100000000ULL)
|
||||
{
|
||||
cal_offset = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (a == 4) { //button long hold
|
||||
savetofile();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void print_right(int32_t number)
|
||||
{
|
||||
int32_t abs_number = number;
|
||||
if (abs_number < 0)
|
||||
abs_number *= -1;
|
||||
else
|
||||
print_Msg(F(" "));
|
||||
|
||||
if (abs_number == 0)
|
||||
abs_number = 1;
|
||||
while(abs_number < 100000000ULL)
|
||||
{
|
||||
print_Msg(F(" "));
|
||||
abs_number *= 10ULL;
|
||||
}
|
||||
println_Msg(number);
|
||||
}
|
||||
|
||||
void savetofile() {
|
||||
display_Clear();
|
||||
println_Msg(F("Saving..."));
|
||||
println_Msg(cal_factor);
|
||||
display_Update();
|
||||
delay(2000);
|
||||
|
||||
if (!myFile.open("/snes_clk.txt", O_WRITE | O_CREAT | O_TRUNC)) {
|
||||
print_Error(F("SD Error"), true);
|
||||
}
|
||||
// Write calibration factor to file
|
||||
myFile.print(cal_factor);
|
||||
|
||||
// Close the file:
|
||||
myFile.close();
|
||||
println_Msg(F("Done"));
|
||||
display_Update();
|
||||
delay(1000);
|
||||
resetArduino();
|
||||
}
|
||||
|
||||
#endif
|
||||
//******************************************
|
||||
// End of File
|
||||
//******************************************
|
Loading…
Reference in New Issue
Block a user