mirror of
https://github.com/kalymos/PsNee.git
synced 2026-02-27 17:14:06 +00:00
refactor: optimize sector filtering and unify system initialization
- Core logic: Optimized 'isDataSector' using a single 0xD0 bitwise mask for faster 0x41 sector detection. - Architecture: Moved 'board_detection()' into 'Init()' for a cleaner entry point in 'main()'. - Settings: Updated 'settings.h' with improved constant definitions and macro organization. - Performance: Reduced instruction count in the main loop and improved peripheral power management.
This commit is contained in:
80
PSNee/MCU.h
80
PSNee/MCU.h
@@ -227,28 +227,26 @@
|
||||
#ifdef ATmega328_168
|
||||
|
||||
static inline void optimizePeripherals(void) {
|
||||
// Configuring Port C (A0-A5) as Digital Inputs
|
||||
// DDRC at 0 = Input. Ensure that the first 6 bits are 0.
|
||||
DDRC &= ~0x3F;
|
||||
// --- Port C & Digital Input Configuration (A0-A5) ---
|
||||
// 1. Set Port C as inputs (DDRC bits 0-5 to 0)
|
||||
DDRC &= ~((1<<DDC5)|(1<<DDC4)|(1<<DDC3)|(1<<DDC2)|(1<<DDC1)|(1<<DDC0));
|
||||
// 2. Enable Digital Input Buffers by clearing DIDR0 (Required for digital PINC reads)
|
||||
DIDR0 &= ~((1<<ADC5D)|(1<<ADC4D)|(1<<ADC3D)|(1<<ADC2D)|(1<<ADC1D)|(1<<ADC0D));
|
||||
|
||||
// Disable the ADC (Analog-to-Digital Converter)
|
||||
// ADEN at 0 disables the module. PRADC at 1 disables the module's clock.
|
||||
// --- Analog Modules Shutdown (Power Saving & Noise Reduction) ---
|
||||
// 1. Disable the ADC module (ADEN = 0)
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
PRR |= (1 << PRADC) | (1 << PRTIM2);
|
||||
// 2. Disable the Analog Comparator (ACD = 1) to free resources on PD6/PD7
|
||||
ACSR |= (1 << ACD);
|
||||
|
||||
// Configure DIDR0 (Digital Input Disable Register)
|
||||
// To read digitally via PINC, the bits of DIDR0 MUST be set to 0.
|
||||
// (0 = Digital Buffer enabled)
|
||||
DIDR0 &= ~0x3F;
|
||||
// --- Power Reduction Register (Hard Clock Shut Off) ---
|
||||
// Stops the clock to internal modules: ADC, Timer 0 (millis), and Timer 2
|
||||
PRR |= (1 << PRADC) | (1 << PRTIM0) | (1 << PRTIM2);
|
||||
|
||||
// Stop Timer 0 (Stops Arduino millis/micros)
|
||||
// Setting TCCR0B to 0 stops the clock source. Setting TIMSK0 to 0 disables interrupts.
|
||||
// --- Timer 0 Specific Shutdown ---
|
||||
// Double security: disconnect clock source and disable interrupts
|
||||
TCCR0B = 0;
|
||||
//#define F TIMSK0 = 0;
|
||||
|
||||
// Disable the Analog Comparator (Frees up resources on PD6/PD7)
|
||||
// ACD at 1 = Comparator off.
|
||||
ACSR |= (1 << ACD);
|
||||
TIMSK0 = 0;
|
||||
}
|
||||
|
||||
// Define the clock speed for the microcontroller
|
||||
@@ -322,6 +320,7 @@
|
||||
#define PIN_AX_INTERRUPT_ENABLE EIMSK |= (1 << INT0) // Enable external interrupt on INT0 (PINB2)
|
||||
#define PIN_AX_INTERRUPT_DISABLE EIMSK &= ~(1 << INT0) // Disable external interrupt on INT0
|
||||
#define PIN_AX_INTERRUPT_RISING EICRA |= (1 << ISC01) | (1 << ISC00) // Configure INT0 for rising edge trigger
|
||||
//#define PIN_AX_INTERRUPT_FALLING (EICRA = (1 << ISC01))
|
||||
#define PIN_AX_INTERRUPT_FALLING (EICRA = (EICRA & ~(1 << ISC00)) | (1 << ISC01)) // Configure INT0 for falling edge trigger
|
||||
|
||||
// Interrupt vectors for external interrupts
|
||||
@@ -358,6 +357,36 @@
|
||||
|
||||
#ifdef ATmega32U4_16U4
|
||||
|
||||
static inline void optimizePeripherals(void) {
|
||||
// --- Digital Input Configuration (A0-A5) ---
|
||||
// On 32U4, A0-A5 are spread across Port F (F7-F4) and Port D (D4, D7)
|
||||
// 1. Set all Analog/Digital pins to Input
|
||||
DDRF &= ~((1<<DDF7)|(1<<DDF6)|(1<<DDF5)|(1<<DDF4)); // A0-A3
|
||||
DDRD &= ~((1<<DDD4)|(1<<DDD7)); // A4-A5
|
||||
|
||||
// 2. Disable Digital Input Buffers (DIDR0/DIDR2)
|
||||
// On 32U4, DIDR0 and DIDR2 control the digital buffer for ADC pins.
|
||||
// Setting these bits to 0 ENABLES digital reads (PINF/PIND).
|
||||
DIDR0 &= ~((1<<ADC7D)|(1<<ADC6D)|(1<<ADC5D)|(1<<ADC4D)); // A0-A3
|
||||
DIDR2 &= ~((1<<ADC10D)|(1<<ADC8D)); // A4-A5
|
||||
|
||||
// --- Analog Modules Shutdown (32U4 specific) ---
|
||||
// 1. Disable the ADC module
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
// 2. Disable the Analog Comparator
|
||||
ACSR |= (1 << ACD);
|
||||
|
||||
// --- Power Reduction Register (32U4 Hard Clock Shut Off) ---
|
||||
// PRR0 and PRR1 handle the clocks on 32U4.
|
||||
// Note: We DO NOT touch PRUSB if we want to keep the Serial/USB alive.
|
||||
PRR0 |= (1 << PRADC) | (1 << PRTIM0) | (1 << PRTIM1);
|
||||
PRR1 |= (1 << PRTIM3); // 32U4 has an extra Timer 3
|
||||
|
||||
// --- Timer 0 Specific Shutdown ---
|
||||
TCCR0B = 0;
|
||||
TIMSK0 = 0;
|
||||
}
|
||||
|
||||
#define F_CPU 16000000L
|
||||
|
||||
|
||||
@@ -449,6 +478,23 @@
|
||||
|
||||
#ifdef ATtiny85_45_25
|
||||
|
||||
static inline void optimizePeripherals(void) {
|
||||
// --- Analog Modules Shutdown (ATtiny Specific) ---
|
||||
// 1. Disable the ADC module
|
||||
ADCSRA &= ~(1 << ADEN);
|
||||
// 2. Disable the Analog Comparator
|
||||
ACSR |= (1 << ACD);
|
||||
|
||||
// --- Power Reduction Register (Hard Clock Shut Off) ---
|
||||
// On ATtiny85, PRR controls Timer 0, Timer 1, USI, and ADC.
|
||||
// We stop the ADC and Timer 0 clocks.
|
||||
PRR |= (1 << PRADC) | (1 << PRTIM0);
|
||||
|
||||
// --- Timer 0 Specific Shutdown ---
|
||||
TCCR0B = 0;
|
||||
TIMSK = 0; // On ATtiny85, it's TIMSK (not TIMSK0)
|
||||
}
|
||||
|
||||
#define DF_CPU 8000000L
|
||||
#define TIMER_TCNT_CLEAR TCNT0 = 0x00;
|
||||
#define SET_OCROA_DIV OCR0A = 79; //OCR0A – Output Compare Register A,100KHz
|
||||
|
||||
@@ -19,11 +19,11 @@
|
||||
|
||||
SCPH model number // region code | region
|
||||
-------------------------------------------------------------------------------------------------*/
|
||||
#define SCPH_xxxx // | Universal.
|
||||
//#define SCPH_xxxx // | Universal.
|
||||
//#define SCPH_xxx1 // NTSC U/C | America.
|
||||
//#define SCPH_xxx2 // PAL | Europ.
|
||||
//#define SCPH_xxx3 // NTSC J | Asia.
|
||||
//#define SCPH_5903 // NTSC J | Asia VCD.
|
||||
#define SCPH_5903 // NTSC J | Asia VCD.
|
||||
|
||||
// Models that require a BIOS patch.
|
||||
|
||||
@@ -127,25 +127,29 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
|
||||
|
||||
//Flag initializing for automatic console generation selection 0 = old, 1 = pu-22 end ++
|
||||
uint8_t wfck_mode = 0;
|
||||
volatile uint8_t wfck_mode = 0;
|
||||
|
||||
|
||||
// --- Prototypes (Forward declarations) ---
|
||||
// These tell the compiler that the functions exist later in the code.
|
||||
|
||||
//#ifdef SCPH_5903
|
||||
void logic_SCPH_5903(uint8_t isDataSector);
|
||||
//#else
|
||||
void logic_Standard(uint8_t isDataSector);
|
||||
//#endif
|
||||
|
||||
// Function pointer type definition for the console detection logic.
|
||||
// This allows switching between 'Standard' and 'SCPH-5903' heuristics dynamically.
|
||||
typedef void (*ConsoleLogicPtr)(uint8_t isDataSector);
|
||||
|
||||
#ifdef SCPH_5903
|
||||
void logic_SCPH_5903(uint8_t isDataSector);
|
||||
volatile ConsoleLogicPtr currentLogic = logic_SCPH_5903;
|
||||
#else
|
||||
void logic_Standard(uint8_t isDataSector);
|
||||
volatile ConsoleLogicPtr currentLogic = logic_Standard;
|
||||
#endif
|
||||
|
||||
|
||||
// Global pointer holding the currently active logic function.
|
||||
// Using a function pointer eliminates the need for repetitive 'if/else' checks in the main loop.
|
||||
volatile ConsoleLogicPtr currentLogic = logic_Standard;
|
||||
//volatile ConsoleLogicPtr currentLogic = logic_Standard;
|
||||
|
||||
// Variables de contrôle globales
|
||||
uint8_t scbuf[12] = { 0 };
|
||||
@@ -204,6 +208,10 @@ void board_detection() {
|
||||
|
||||
// Low count implies a static signal (Older boards)
|
||||
wfck_mode = 0; // Target: PU-7 to PU-20
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
Debug_Log(wfck_mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -233,6 +241,10 @@ void captureSubQ(void) {
|
||||
scbuf[scpos++] = bitbuf;
|
||||
} while (scpos < 12);
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
Debug_Scbuf(scbuf);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
@@ -405,6 +417,10 @@ void performInjectionSequence(uint8_t injectSCEx) {
|
||||
#ifdef LED_RUN
|
||||
PIN_LED_OFF;
|
||||
#endif
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
Debug_Inject();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Init() {
|
||||
@@ -453,23 +469,21 @@ void Init() {
|
||||
#elif defined(PSNEE_DEBUG_SERIAL_MONITOR) && !defined(ATtiny85_45_25)
|
||||
Serial.begin(500000); // 60 bytes in 12ms (expected data: ~26 bytes / 12ms) // update: this is actually quicker
|
||||
#endif
|
||||
|
||||
|
||||
board_detection();
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
Init();
|
||||
|
||||
// #ifdef SCPH_5903
|
||||
// currentLogic = logic_SCPH_5903;
|
||||
// #else
|
||||
// currentLogic = logic_Standard;
|
||||
// #endif
|
||||
|
||||
#ifdef SCPH_5903
|
||||
currentLogic = logic_SCPH_5903;
|
||||
#else
|
||||
currentLogic = logic_Standard;
|
||||
#endif
|
||||
board_detection();
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
Debug_Log(lows, wfck_mode);
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
|
||||
@@ -477,10 +491,6 @@ int main() {
|
||||
in cases where the MCU loops too quickly and picks up the laster SUBQ trailing end*/
|
||||
captureSubQ();
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
Debug_Scbuf(scbuf);
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------------------
|
||||
Check if read head is in wobble area
|
||||
We only want to unlock game discs (0x41) and only if the read head is in the outer TOC area.
|
||||
@@ -490,19 +500,22 @@ int main() {
|
||||
While the laser lens moves to correct for the error, they can pick up a few TOC sectors.
|
||||
-------------------------------------------------------------------------------*/
|
||||
|
||||
//This variable initialization macro is to replace (0x41) with a filter that will check that only the three most significant bits are correct. 0x001xxxxx
|
||||
uint8_t isDataSector = (((scbuf[0] & 0x40) == 0x40) && (((scbuf[0] & 0x10) == 0) && ((scbuf[0] & 0x80) == 0)));
|
||||
//This variable initialization macro is to replace (0x41) with a filter that will check that only the three most significant bits are correct. 0x001xxxxx
|
||||
//uint8_t isDataSector = (((scbuf[0] & 0x40) == 0x40) &&
|
||||
// (((scbuf[0] & 0x10) == 0) &&
|
||||
// ((scbuf[0] & 0x80) == 0)));
|
||||
|
||||
// Optimized Sector Filtering:
|
||||
// Masking bits 7, 6, and 4 simultaneously using 0xD0 (binary 11010000).
|
||||
// This verifies that the "Data/TOC" bit (0x40) is SET, while bits 7 and 4 are CLEARED.
|
||||
// Equivalent to: (bit7 == 0 && bit6 == 1 && bit4 == 0).
|
||||
uint8_t isDataSector = ((scbuf[0] & 0xD0) == 0x40);
|
||||
|
||||
// Execute selected logic through function pointer
|
||||
currentLogic(isDataSector);
|
||||
|
||||
if (hysteresis >= HYSTERESIS_MAX) {
|
||||
performInjectionSequence(INJECT_SCEx);
|
||||
}
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
Debug_Inject();
|
||||
#endif
|
||||
// Execute selected logic through function pointer
|
||||
currentLogic(isDataSector);
|
||||
|
||||
if (hysteresis >= HYSTERESIS_MAX) {
|
||||
performInjectionSequence(INJECT_SCEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,13 +144,13 @@
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
|
||||
void Debug_Log (uint16_t Lows, int Wfck_mode){ //Information about the MCU, and old or late console mode.
|
||||
void Debug_Log (int Wfck_mode){ //Information about the MCU, and old or late console mode.
|
||||
|
||||
#if defined(ATtiny85_45_25)
|
||||
mySerial.print("m "); mySerial.println(Wfck_mode);
|
||||
#elif !defined(ATtiny85_45_25)
|
||||
Serial.print(" MCU frequency: "); Serial.print(F_CPU); Serial.println(" Hz");
|
||||
Serial.print(" lows: "); Serial.println(Lows);
|
||||
//Serial.print(" lows: "); Serial.println(Lows);
|
||||
Serial.print(" wfck_mode: "); Serial.println(Wfck_mode);
|
||||
Serial.print(" region: "); Serial.print(region[0]); Serial.print(region[1]); Serial.println(region[2]);
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user