mirror of
https://github.com/kalymos/PsNee.git
synced 2026-05-09 08:37:11 +00:00
Refactor: Clean up serial debug logs and header organization
This commit is contained in:
275
PSNee/PSNee.ino
275
PSNee/PSNee.ino
@@ -1,136 +1,125 @@
|
||||
|
||||
// PSNee-V9.0
|
||||
/*********************************************************************************************************************
|
||||
* CONSOLE MODEL SELECTION (SCPH Hardware Configuration)
|
||||
*********************************************************************************************************************/
|
||||
/*--------------------------------------------------------------------------------------------------------------------
|
||||
* Models below do not require BIOS patching.
|
||||
* Standard USB injection is supported.
|
||||
*
|
||||
* SCPH model number // region code | region
|
||||
*--------------------------------------------------------------------------------------------------------------------*/
|
||||
#define SCPH_xxx1 // NTSC U/C | America.
|
||||
// #define SCPH_xxx2 // PAL | Europ.
|
||||
// #define SCPH_xxx3 // NTSC J | Asia.
|
||||
// #define SCPH_xxxx // Universal
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
Console selection
|
||||
--------------------------------------------------------------------------------------------------
|
||||
|
||||
No BIOS patching.
|
||||
You can use injection via USB.
|
||||
|
||||
SCPH model number // region code | region
|
||||
-------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#define SCPH_xxx1 // NTSC U/C | America.
|
||||
//#define SCPH_xxx2 // PAL | Europ.
|
||||
//#define SCPH_xxx3 // NTSC J | Asia.
|
||||
//#define SCPH_xxxx // Universal
|
||||
|
||||
//#define SCPH_5903 // NTSC J | Asia VCD:
|
||||
|
||||
// Models that require a BIOS patch.
|
||||
|
||||
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
Caution!
|
||||
|
||||
It is only possible to inject the code via ISP!
|
||||
|
||||
For the patch to work, the BIOS version is more important than the SCPH number.
|
||||
|
||||
The delay in starting up caused by the bootloader of the Arduino cards prevents the injection of the BIOS patch within the delay,
|
||||
that's why you have to use the ISP which eliminates the bootloader.
|
||||
|
||||
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
||||
// #define SCPH_5903 // NTSC J | Asia VCD:
|
||||
|
||||
|
||||
| Adres pin |
|
||||
SCPH model number // Data pin | 32-pin BIOS | 40-pin BIOS | BIOS version
|
||||
-------------------------------------------------------------------------------------------------*/
|
||||
//#define SCPH_102 // DX - D0 | AX - A7 | | 4.4e - CRC 0BAD7EA9, 4.5e -CRC 76B880E5
|
||||
//#define SCPH_100 // DX - D0 | AX - A7 | | 4.3j - CRC F2AF798B
|
||||
//#define SCPH_7500_9000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0
|
||||
//#define SCPH_7000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0 Enables hardware support for disabling BIOS patching.
|
||||
//#define SCPH_3500_5500 // DX - D0 | AX - A16 | AX - A15 | 3.0j - CRC FF3EEB8C, 2.2j - CRC 24FC7E17, 2.1j - CRC BC190209
|
||||
//#define SCPH_3000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.1j - CRC 3539DEF6
|
||||
//#define SCPH_1000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.0j - CRC 3B601FC8
|
||||
/*------------------------------------------------------------------------------------------------------------------
|
||||
* WARNING: These models REQUIRE a BIOS patch.
|
||||
*
|
||||
* ISP programming is MANDATORY.
|
||||
* The Arduino bootloader introduces a delay that prevents the BIOS patch injection.
|
||||
* Using an ISP programmer eliminates this delay.
|
||||
*
|
||||
* Note: BIOS version is more critical than the SCPH number for patch success.
|
||||
*-------------------------------------------------------------------------------------------------------------------
|
||||
*
|
||||
* | Adres pin |
|
||||
* SCPH model number // Data pin | 32-pin BIOS | 40-pin BIOS | BIOS version
|
||||
*------------------------------------------------------------------------------------------------------------------*/
|
||||
// #define SCPH_102 // DX - D0 | AX - A7 | | 4.4e - CRC 0BAD7EA9, 4.5e -CRC 76B880E5
|
||||
// #define SCPH_100 // DX - D0 | AX - A7 | | 4.3j - CRC F2AF798B
|
||||
// #define SCPH_7500_9000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0
|
||||
// #define SCPH_7000 // DX - D0 | AX - A7 | | 4.0j - CRC EC541CD0 Enables hardware support for disabling BIOS patching.
|
||||
// #define SCPH_3500_5500 // DX - D0 | AX - A16 | AX - A15 | 3.0j - CRC FF3EEB8C, 2.2j - CRC 24FC7E17, 2.1j - CRC BC190209
|
||||
// #define SCPH_3000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.1j - CRC 3539DEF6
|
||||
// #define SCPH_1000 // DX - D5 | AX - A7, AY - A8 | AX - A6, AY - A7 | 1.0j - CRC 3B601FC8
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
Options
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
/*******************************************************************************************************************
|
||||
* Options
|
||||
*******************************************************************************************************************/
|
||||
|
||||
#define LED_RUN // Turns on the LED when injections occur.
|
||||
// D13 for Arduino, ATtiny add a led between PB3 (pin 2) and gnd with a 1k resistor in series, ATmega32U4 (Pro Micro) add a led between PB6 (pin 10) and gnd with a 1k resistor in series.
|
||||
#define LED_RUN // Turns on the LED when injections occur.
|
||||
// D13 for Arduino, ATtiny add a led between PB3 (pin 2) and gnd with a 1k resistor in series,
|
||||
// ATmega32U4 (Pro Micro) add a led between PB6 (pin 10) and gnd with a 1k resistor in series.
|
||||
|
||||
// #define DEBUG_SERIAL_MONITOR // Enables serial monitor output.
|
||||
|
||||
//#define PSNEE_DEBUG_SERIAL_MONITOR // Enables serial monitor output.
|
||||
/* Requires compilation with Arduino libs!
|
||||
For Arduino connect TXD and GND, for ATtiny PB3 (pin 2) and GND, to your serial card RXD and GND.
|
||||
Arduino | ATtiny
|
||||
---------------------
|
||||
TXD--RXD | PB3--RXD
|
||||
GND--GND | GND--GND */
|
||||
/******************************************************************************************************************
|
||||
* Requires compilation with Arduino libs!
|
||||
* For Arduino connect TXD and GND, for ATtiny PB3 (pin 2) and GND, to your serial card RXD and GND.
|
||||
* Arduino | ATtiny
|
||||
* ---------------------
|
||||
* TXD--RXD | PB3--RXD
|
||||
* GND--GND | GND--GND
|
||||
*******************************************************************************************************************/
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
Hysteresis
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
#define HYSTERESIS_MAX 25 // Coupled with hysteresis-reset post-injection; allows for a
|
||||
// wider tuning range without drifting out of the sweet spot
|
||||
// between hysteresis_max and hysteresis_reset.
|
||||
/******************************************************************************************************************
|
||||
* Summary of practical information. Fuses. Pinout
|
||||
*******************************************************************************************************************
|
||||
* Fuses
|
||||
* MCU | High | Low | Extended
|
||||
* --------------------------------------------------
|
||||
* ATmega | DF | EE | FF
|
||||
* ATtiny | DF | E2 | FF
|
||||
*
|
||||
* Pinout
|
||||
* Arduino | PSNee |
|
||||
* ---------------------------------------------------
|
||||
* VCC | VCC |
|
||||
* GND | GND |
|
||||
* RST | RESET | Only for JAP_FAT
|
||||
* D2 | BIOS AX | Only for Bios patch
|
||||
* D3 | BIOS AY | Only for BIOS patch ver, 1.0j, 1.1j
|
||||
* D4 | BIOS DX | Only for Bios patch
|
||||
* D5 | SWITCH | Optional for disabling Bios patch
|
||||
* D6 | SQCK |
|
||||
* D7 | SUBQ |
|
||||
* D8 | DATA |
|
||||
* D9 | WFCK |
|
||||
* D13 ^ D10 | LED | D10 only for ATmega32U4_16U4
|
||||
*
|
||||
* ATtiny | PSNee | ISP |
|
||||
* ---------------------------------------------------
|
||||
* Pin1 | | RESET |
|
||||
* Pin2 | LED ^ serial | | serial only for PSNEE_DEBUG_SERIAL_MONITOR
|
||||
* Pin3 | WFCK | |
|
||||
* Pin4 | GND | GND |
|
||||
* Pin5 | SQCK | MOSI |
|
||||
* Pin6 | SUBQ | MISO |
|
||||
* Pin7 | DATA | SCK |
|
||||
* Pin8 | VCC | VCC |
|
||||
*******************************************************************************************************************/
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
Summary of practical information. Fuses. Pinout
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
Fuses
|
||||
MCU | High | Low | Extended
|
||||
--------------------------------------------------
|
||||
ATmega | DF | EE | FF
|
||||
ATtiny | DF | E2 | FF
|
||||
|
||||
Pinout
|
||||
Arduino | PSNee |
|
||||
---------------------------------------------------
|
||||
VCC | VCC |
|
||||
GND | GND |
|
||||
RST | RESET | Only for JAP_FAT
|
||||
D2 | BIOS AX | Only for Bios patch
|
||||
D3 | BIOS AY | Only for BIOS patch ver, 1.0j, 1.1j
|
||||
D4 | BIOS DX | Only for Bios patch
|
||||
D5 | SWITCH | Optional for disabling Bios patch
|
||||
D6 | SQCK |
|
||||
D7 | SUBQ |
|
||||
D8 | DATA |
|
||||
D9 | WFCK |
|
||||
D13 ^ D10 | LED | D10 only for ATmega32U4_16U4
|
||||
|
||||
ATtiny | PSNee | ISP |
|
||||
---------------------------------------------------
|
||||
Pin1 | | RESET |
|
||||
Pin2 | LED ^ serial | | serial only for PSNEE_DEBUG_SERIAL_MONITOR
|
||||
Pin3 | WFCK | |
|
||||
Pin4 | GND | GND |
|
||||
Pin5 | SQCK | MOSI |
|
||||
Pin6 | SUBQ | MISO |
|
||||
Pin7 | DATA | SCK |
|
||||
Pin8 | VCC | VCC |
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
pointer and variable section
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
/*******************************************************************************************************************
|
||||
* pointer and variable section
|
||||
*******************************************************************************************************************/
|
||||
|
||||
#include "MCU.h"
|
||||
#include "settings.h"
|
||||
#include "BIOS_patching.h"
|
||||
|
||||
|
||||
//Flag initializing for automatic console generation selection 0 = old, 1 = pu-22 end ++
|
||||
uint8_t wfck_mode = 0;
|
||||
uint8_t wfck_mode = 0; //Flag initializing for automatic console generation selection 0 = old, 1 = pu-22 end ++
|
||||
uint8_t SUBQBuffer[12]; // Global buffer to store the 12-byte SUBQ channel data
|
||||
|
||||
#define HYSTERESIS_MAX 25 // Coupled with hysteresis-reset post-injection; allows for a
|
||||
// wider tuning range without drifting out of the sweet spot
|
||||
// between hysteresis_max and hysteresis_reset.
|
||||
|
||||
// Variables de contrôle globales
|
||||
// Global buffer to store the 12-byte SUBQ channel data
|
||||
uint8_t subqBuffer[12];
|
||||
uint8_t hysteresis = 0;
|
||||
|
||||
//Initializing values for region code injection timing
|
||||
#define DELAY_BETWEEN_BITS 4000 // 250 bits/s (microseconds) (ATtiny 8Mhz works from 3950 to 4100) PU-23 PU-22 MAX 4250 MIN 3850
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
Code section
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
/*******************************************************************************************************************
|
||||
* Code section
|
||||
********************************************************************************************************************/
|
||||
|
||||
|
||||
/*******************************************************************************************************************
|
||||
* FUNCTION : BoardDetection
|
||||
*
|
||||
* DESCRIPTION :
|
||||
@@ -156,11 +145,12 @@ uint8_t hysteresis = 0;
|
||||
* - Initial/Protection Phase: ~7.3 kHz.
|
||||
* - Standard Data Reading: ~14.6 kHz.
|
||||
*
|
||||
*-----------------------------------------------------------------------*/
|
||||
*******************************************************************************************************************/
|
||||
|
||||
void BoardDetection() {
|
||||
// Default state: 0 (Static/GATE mode for PU-7 to PU-20)
|
||||
wfck_mode = 0;
|
||||
uint8_t debounce = 100;
|
||||
|
||||
/**
|
||||
* INITIAL STABILIZATION DELAY (300ms)
|
||||
@@ -181,7 +171,6 @@ void BoardDetection() {
|
||||
*/
|
||||
if (!PIN_WFCK_READ) {
|
||||
// Software debounce to filter out micro-glitches or parasitic noise
|
||||
uint8_t debounce = 100;
|
||||
while (--debounce);
|
||||
|
||||
/**
|
||||
@@ -198,7 +187,7 @@ void BoardDetection() {
|
||||
}
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
Debug_Log(debounce, wfck_mode);
|
||||
BoardDetectionLog(debounce, wfck_mode, INJECT_SCEx);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -209,14 +198,14 @@ void BoardDetection() {
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* Captures a complete 12-byte SUBQ frame from the CD controller.
|
||||
* Synchronizes with the SQCK (Sub-Q Clock) pin to shift in serial data from
|
||||
* Synchronizes with the SQCK (SUBQ Clock) pin to shift in serial data from
|
||||
* the SUBQ pin. This implementation follows the standard PlayStation CDIC
|
||||
* protocol (Synchronous Serial, LSB first).
|
||||
******************************************************************************************************************/
|
||||
|
||||
void CaptureSUBQ(void) {
|
||||
uint8_t bytesRemaining = 12; // Total frame size for a complete SUBQ
|
||||
uint8_t* bufferPtr = subqBuffer;
|
||||
uint8_t* bufferPtr = SUBQBuffer;
|
||||
|
||||
do {
|
||||
uint8_t currentByte = 0;
|
||||
@@ -247,7 +236,7 @@ void CaptureSUBQ(void) {
|
||||
} while (--bytesRemaining); // Efficient countdown for AVR binary size
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
LogSUBQ(subqBuffer);
|
||||
CaptureSUBQLog(SUBQBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -275,8 +264,8 @@ void CaptureSUBQ(void) {
|
||||
|
||||
// --- STEP 1: SUBQ Frame Synchronization ---
|
||||
// Fast filtering: ignore raw data if sync markers (index 1 and 6) are not 0x00.
|
||||
if (subqBuffer[1] == 0x00 && subqBuffer[6] == 0x00) {
|
||||
uint8_t pointAddress = subqBuffer[2];
|
||||
if (SUBQBuffer[1] == 0x00 && SUBQBuffer[6] == 0x00) {
|
||||
uint8_t pointAddress = SUBQBuffer[2];
|
||||
|
||||
/**
|
||||
* HIT INCREMENT CONDITIONS:
|
||||
@@ -284,8 +273,8 @@ void CaptureSUBQ(void) {
|
||||
* (uint8_t)(pointAddress - 0xA0) <= 2 is an optimized check for 0xA0, 0xA1, 0xA2.
|
||||
* B. TRACKING MAINTENANCE: Keeps count if already synced and reading Mode 0x01 or Data.
|
||||
*/
|
||||
if ( (isDataSector && (uint8_t)(pointAddress - 0xA0) <= 2 && subqBuffer[3] != 0x02) ||
|
||||
(currentHysteresis > 0 && (subqBuffer[0] == 0x01 || isDataSector)) )
|
||||
if ( (isDataSector && (uint8_t)(pointAddress - 0xA0) <= 2 && SUBQBuffer[3] != 0x02) ||
|
||||
(currentHysteresis > 0 && (SUBQBuffer[0] == 0x01 || isDataSector)) )
|
||||
{
|
||||
hysteresis = currentHysteresis + 1;
|
||||
return;
|
||||
@@ -316,23 +305,30 @@ void CaptureSUBQ(void) {
|
||||
* INPUT : isDataSector (bool) - Filtered flag based on raw sector control bits.
|
||||
******************************************************************************************/
|
||||
|
||||
|
||||
void FilterSUBQSamples(uint8_t isDataSector) {
|
||||
uint8_t currentHysteresis = hysteresis;
|
||||
|
||||
// --- STEP 1: SUBQ Frame Synchronization ---
|
||||
// Ignore the raw bitstream unless sync markers (1 & 6) are 0x00.
|
||||
if (subqBuffer[1] == 0x00 && subqBuffer[6] == 0x00) {
|
||||
uint8_t pointAddress = subqBuffer[2];
|
||||
if (SUBQBuffer[1] == 0x00 && SUBQBuffer[6] == 0x00) {
|
||||
uint8_t pointAddress = SUBQBuffer[2];
|
||||
|
||||
// uint8_t syncMarker1 = SUBQBuffer[1];
|
||||
// uint8_t syncMarker2 = SUBQBuffer[6];
|
||||
|
||||
// if (syncMarker1 == 0x00 && syncMarker2 == 0x00) {
|
||||
// uint8_t addrControl = SUBQBuffer[0];
|
||||
// uint8_t pointAddress = SUBQBuffer[2];
|
||||
// uint8_t trackNumber = SUBQBuffer[3];
|
||||
|
||||
/*
|
||||
* HIT INCREMENT CONDITIONS:
|
||||
* A. LEAD-IN PATTERNS: Detects TOC markers (A0-A2) or Track 01 at spiral start.
|
||||
* (uint8_t)(subqBuffer[3] - 0x03) >= 0xF5 handles the 0x98 to 0x02 wrap-around.
|
||||
* (uint8_t)(SUBQBuffer[3] - 0x03) >= 0xF5 handles the 0x98 to 0x02 wrap-around.
|
||||
* B. TRACKING LOCK: Maintains count if already synced and reading valid sectors.
|
||||
*/
|
||||
if ( (isDataSector && (pointAddress >= 0xA0 || (pointAddress == 0x01 && ( (uint8_t)(subqBuffer[3] - 0x03) >= 0xF5)))) ||
|
||||
(currentHysteresis > 0 && (subqBuffer[0] == 0x01 || isDataSector)) )
|
||||
if ( (isDataSector && (pointAddress >= 0xA0 || (pointAddress == 0x01 && ( (uint8_t)(SUBQBuffer[3] - 0x03) >= 0xF5)))) ||
|
||||
(currentHysteresis > 0 && (SUBQBuffer[0] == 0x01 || isDataSector)) )
|
||||
{
|
||||
hysteresis = currentHysteresis + 1;
|
||||
return;
|
||||
@@ -374,15 +370,15 @@ void PerformInjectionSequence(uint8_t injectSCEx) {
|
||||
{ 0x59, 0xC9, 0x4B, 0x5D, 0xFA, 0x02 }, // SCEA
|
||||
{ 0x59, 0xC9, 0x4B, 0x5D, 0xEA, 0x02 } // SCEE
|
||||
};
|
||||
|
||||
|
||||
|
||||
const uint16_t BIT_DELAY = 4000; // 4000us is the standard bit timing for SCEx signal (approx. 250 bps)
|
||||
const uint8_t isWfck = wfck_mode; // Cache wfck_mode to save CPU cycles during the bit loop
|
||||
hysteresis = (HYSTERESIS_MAX - 10); // Reset hysteresis to mid-point after triggering
|
||||
|
||||
#ifdef LED_RUN
|
||||
PIN_LED_ON;
|
||||
#endif
|
||||
|
||||
// Cache wfck_mode to save CPU cycles during the bit loop
|
||||
uint8_t isWfck = wfck_mode;
|
||||
PIN_DATA_OUTPUT;
|
||||
PIN_DATA_CLEAR;
|
||||
|
||||
@@ -416,13 +412,13 @@ void PerformInjectionSequence(uint8_t injectSCEx) {
|
||||
// BIT 0: Pull DATA low-
|
||||
PIN_DATA_CLEAR;
|
||||
if (!isWfck) PIN_DATA_OUTPUT;
|
||||
_delay_us(DELAY_BETWEEN_BITS);
|
||||
_delay_us(BIT_DELAY);
|
||||
} else {
|
||||
// BIT 1: Handle based on board generation
|
||||
if (!isWfck) {
|
||||
// Legacy Mode: Set DATA to High-Z (floating)
|
||||
PIN_DATA_INPUT;
|
||||
_delay_us(DELAY_BETWEEN_BITS);
|
||||
_delay_us(BIT_DELAY);
|
||||
} else {
|
||||
/*
|
||||
WFCK Modulation Loop: Syncs to 7.3kHz or 14.6kHz.
|
||||
@@ -476,7 +472,7 @@ void PerformInjectionSequence(uint8_t injectSCEx) {
|
||||
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
DebugInject();
|
||||
InjectLog();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -522,7 +518,7 @@ void Init() {
|
||||
// --- Console Analysis ---
|
||||
// Identify board revision (PU-7 to PU-22+) to set correct injection timings
|
||||
BoardDetection();
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
@@ -540,14 +536,17 @@ int main() {
|
||||
// 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);
|
||||
uint8_t isDataSector = ((subqBuffer[0] & 0xD0) == 0x40);
|
||||
// uint8_t firstByte = SUBQBuffer[0];
|
||||
// uint8_t isDataSector = ((firstByte & 0xD0) == 0x40);
|
||||
uint8_t isDataSector = ((SUBQBuffer[0] & 0xD0) == 0x40);
|
||||
|
||||
|
||||
// Execute selected logic
|
||||
FilterSUBQSamples(isDataSector);
|
||||
|
||||
// 5. Execution: Trigger SCEx injection once confidence (hysteresis) is reached
|
||||
// uint8_t currentHysteresis = hysteresis;
|
||||
// if (currentHysteresis >= HYSTERESIS_MAX) {
|
||||
if (hysteresis >= HYSTERESIS_MAX) {
|
||||
PerformInjectionSequence(INJECT_SCEx);
|
||||
}
|
||||
|
||||
155
PSNee/settings.h
155
PSNee/settings.h
@@ -210,115 +210,90 @@
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------------------------
|
||||
serial debug section
|
||||
------------------------------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(PSNEE_DEBUG_SERIAL_MONITOR)
|
||||
#if defined(DEBUG_SERIAL_MONITOR)
|
||||
extern uint8_t hysteresis;
|
||||
|
||||
void Debug_Log (uint16_t debounce, int Wfck_mode){ //Information about the MCU, and old or late console mode.
|
||||
void BoardDetectionLog (uint16_t debounce, uint8_t Wfck_mode, uint8_t region){ //Information about the MCU, and old or late console mode.
|
||||
|
||||
#if defined(IS_ATTINY_FAMILY)
|
||||
mySerial.print("m "); mySerial.println(Wfck_mode);
|
||||
#else
|
||||
Serial.print(" MCU frequency: "); Serial.print(F_CPU); Serial.println(" Hz");
|
||||
static const char* regionNames[] = {
|
||||
"NTSC-J", // 0
|
||||
"NTSC-U/C", // 1
|
||||
"PAL", // 2
|
||||
"Universal" // 3
|
||||
};
|
||||
Serial.print(F(" MCU frequency: ")); Serial.print(F_CPU / 1000000L); Serial.println(F(" MHz"));
|
||||
Serial.print(" debounce: "); Serial.println(debounce);
|
||||
Serial.print(" wfck_mode: "); Serial.println(Wfck_mode);
|
||||
Serial.print(" region: "); Serial.print(region[0]); Serial.print(region[1]); Serial.println(region[2]);
|
||||
Serial.print(" region: "); Serial.print(regionNames[region]);
|
||||
#endif
|
||||
}
|
||||
|
||||
// log SUBQ packets. We only have 12ms to get the logs written out. Slower MCUs get less formatting.
|
||||
void Debug_Scbuf (uint8_t *Scbuf){ // Data from the DATA bus
|
||||
#if defined(IS_ATTINY_FAMILY)
|
||||
if (!(Scbuf[0] == 0 && Scbuf[1] == 0 && Scbuf[2] == 0 && Scbuf[3] == 0)) { // a bad sector read is all 0 except for the CRC fields. Don't log it.
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (Scbuf[i] < 0x10) {
|
||||
mySerial.print("0"); // padding
|
||||
#if defined(IS_ATTINY_FAMILY)
|
||||
// --- COMPACT SYSTEM LOG (ATtiny) ---
|
||||
// Minimalistic output to save CPU cycles and maintain timing precision.
|
||||
mySerial.print("m ");
|
||||
mySerial.println(Wfck_mode); // Mode indicator
|
||||
#else
|
||||
// --- VERBOSE DIAGNOSTICS (ATmega) ---
|
||||
// Detailed system information for standard development and debugging.
|
||||
Serial.print(" MCU frequency: ");
|
||||
Serial.print(F_CPU);
|
||||
Serial.println(" Hz");
|
||||
|
||||
Serial.print(" wfck_mode: ");
|
||||
Serial.println(Wfck_mode); // Board generation (0: Legacy, 1: Modern)
|
||||
|
||||
Serial.print(" region: ");
|
||||
Serial.print(region[0]);
|
||||
Serial.print(region[1]);
|
||||
Serial.println(region[2]); // Active injection string (e.g., SCEE)
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
/******************************************************************************************
|
||||
* FUNCTION : LogSUBQ
|
||||
*
|
||||
* DESCRIPTION :
|
||||
* Logs captured SUBQ frames to the serial interface.
|
||||
* Timing is critical: the entire 12-byte frame must be processed and transmitted
|
||||
* within the ~12ms window before the next SUBQ packet arrives.
|
||||
*
|
||||
* - ATtiny: Uses minimal formatting (no spaces) to stay within the timing budget.
|
||||
* - Standard MCUs: Includes spaces for better readability.
|
||||
*
|
||||
* INPUT : dataBuffer (uint8_t*) - Pointer to the 12-byte SUBQ frame.
|
||||
******************************************************************************************/
|
||||
|
||||
void LogSUBQ(uint8_t *dataBuffer) {
|
||||
void CaptureSUBQLog(uint8_t *dataBuffer) {
|
||||
static uint16_t errorCount = 0; // Tracks missed sectors between valid reads
|
||||
|
||||
/**
|
||||
* ERROR FILTERING:
|
||||
* A failed sector read usually results in zeroed data (excluding CRC).
|
||||
* Skip logging if the first 4 bytes are null to reduce bus traffic.
|
||||
*/
|
||||
if (!(dataBuffer[0] == 0 && dataBuffer[1] == 0 && dataBuffer[2] == 0 && dataBuffer[3] == 0)) {
|
||||
// Cache the first 4 bytes for a quick null check (failed read)
|
||||
uint8_t b0 = dataBuffer[0], b1 = dataBuffer[1], b2 = dataBuffer[2], b3 = dataBuffer[3];
|
||||
|
||||
// --- ERROR FILTERING ---
|
||||
// If the sector is empty (all zeros), increment error counter and exit
|
||||
if (b0 == 0 && b1 == 0 && b2 == 0 && b3 == 0) {
|
||||
errorCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// --- ERROR REPORTING ---
|
||||
// If errors occurred before this valid read, report the total count
|
||||
if (errorCount > 0) {
|
||||
#if defined(IS_ATTINY_FAMILY)
|
||||
mySerial.print(F(" [Err x")); mySerial.print(errorCount); mySerial.println(F("]"));
|
||||
#else
|
||||
Serial.print(F(" [Missed sectors: ")); Serial.print(errorCount); Serial.println(F("]"));
|
||||
#endif
|
||||
errorCount = 0; // Reset counter after reporting
|
||||
}
|
||||
|
||||
// --- DATA & HYSTERESIS DISPLAY ---
|
||||
#if defined(IS_ATTINY_FAMILY)
|
||||
// Compact hex output for ATtiny to maintain 12ms timing
|
||||
for (uint8_t i = 0; i < 12; i++) {
|
||||
uint8_t val = dataBuffer[i];
|
||||
if (val < 0x10) mySerial.print("0");
|
||||
mySerial.print(val, HEX);
|
||||
}
|
||||
// Append global hysteresis on the same line
|
||||
mySerial.print(F(" h:"));
|
||||
mySerial.println(hysteresis);
|
||||
#else
|
||||
// Formatted hex output for ATmega
|
||||
for (uint8_t i = 0; i < 12; i++) {
|
||||
uint8_t val = dataBuffer[i];
|
||||
if (val < 0x10) Serial.print("0");
|
||||
Serial.print(val, HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
// Append global hysteresis on the same line
|
||||
Serial.print(F("| Hyst: "));
|
||||
Serial.println(hysteresis);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InjectLog(){
|
||||
|
||||
#if defined(IS_ATTINY_FAMILY)
|
||||
// --- COMPACT FORMATTING (ATtiny) ---
|
||||
// Minimal formatting to meet the strict 12ms timing constraint on slower MCUs.
|
||||
for (uint8_t i = 0; i < 12; i++) {
|
||||
if (dataBuffer[i] < 0x10) {
|
||||
mySerial.print("0"); // Leading zero padding for hex alignment
|
||||
|
||||
}
|
||||
mySerial.print(Scbuf[i, HEX]);
|
||||
}
|
||||
mySerial.println("");
|
||||
}
|
||||
#elif !defined(IS_ATTINY_FAMILY)
|
||||
if (!(Scbuf[0] == 0 && Scbuf[1] == 0 && Scbuf[2] == 0 && Scbuf[3] == 0)) {
|
||||
for (int i = 0; i < 12; i++) {
|
||||
if (Scbuf[i] < 0x10) {
|
||||
Serial.print("0"); // padding
|
||||
}
|
||||
Serial.print(Scbuf[i], HEX);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Debug_Inject(){ // Confirmation of region code injection
|
||||
|
||||
|
||||
#if defined(IS_ATTINY_FAMILY)
|
||||
// --- MINIMALIST NOTIFICATION (ATtiny) ---
|
||||
mySerial.print("!");
|
||||
#else
|
||||
// --- VERBOSE NOTIFICATION (ATmega) ---
|
||||
// Standard visual feedback for debugging and monitoring.
|
||||
mySerial.print("!"); // --- MINIMALIST NOTIFICATION (ATtiny) ---
|
||||
#else
|
||||
Serial.println(" INJECT ! ");
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user