# Copilot Instructions for Pinball Machine Controller

## Project Overview
This is a **Raspberry Pi Pico 2 firmware** for a **pinball machine controller**. The system manages game logic, hardware I/O (lights, solenoids, switches), audio playback, and serial communication with shift registers.

## Architecture & Data Flow

### Hardware Architecture
- **Microcontroller**: Raspberry Pi Pico 2 (ARM Cortex-M33, overclocked to 176 MHz)
- **Serial Shift Registers**: 74HC595 (outputs) and 74HC165 (inputs)
- **I/O Organization**:
  - **Inputs**: 32 bits across 4 bytes in `Inputs[4]` array (bumpers, targets, rollovers, buttons)
  - **Lights**: 8 bytes in `Lights[8]` array, one byte per 8-LED group
  - **Power**: 2 bytes in `Power_0` and `Power_1` for solenoid/motor control
  
### Key Data Structures
- **GPIO Pins** (`blink.h`): Each hardware output/input mapped to a specific GPIO (0-28)
  - Latch lines `L_Power_0`, `L_Power_1`, `L_Lights_0-7`, `L_Player`, `L_Digits_0-3` trigger specific 74HC595s
  - Serial clock `SRCLK` (GP16) and data `SER` (GP17) drive all outputs
  - Input uses `Input_Rd_CLK` (GP8), `LD_L` (GP10), `Input_Data` (GP9)
- **Bit-Field Macros**: Input/output access via `#define` macros for semantic naming (e.g., `Bumper_0_Trigger`, `Target_3_On`)
  - Prefer these macros over direct array access for clarity
- **Patterns**: `Bumper_Pattern[32]` and `Two_Byte_Pattern[62]` enable LED animation sequences with start/end index pairs

### Critical Workflows

#### Build & Deploy
```bash
# Compile (runs Ninja in build/ directory)
Task: "Compile Project" → outputs blink.uf2 to build/

# Flash via USB bootloader
Task: "Run Project" → picotool load <path> -fx

# Flash via OpenOCD debugger (CMSIS-DAP interface)
Task: "Flash" → openocd with cmsis-dap.cfg

# Emergency reset if device unresponsive
Task: "Rescue Reset" or "Risc-V Reset (RP2350)"
```

#### Serial Communication (USB)
- Main loop prints debug messages via USB: `printf("Hello from Pico!...");`
- USB initialized with 2-second delay: `sleep_ms(2000)`
- Must rebuild after `CMakeLists.txt` changes (e.g., disabling UART)

#### Audio Playback
- PWM on GPIO5 (`Sound_Port`) at 176 MHz overclocked rate
- Sample arrays in headers (`background.h`, `ring.h`, `ouch.h`, etc.) define `WAV_DATA[]` and `WAV_DATA_LENGTH`
- PWM interrupt fires every 8 cycles (11 kHz effective sample rate from overclocked base)
- Sample data indexed by `wav_position` (bit-shifted by 3: `>>3` to read, `<<3` for length)

#### Pinball Game Elements
- **Inputs**: Switch triggers routed via `Inputs[4]` (bumpers, targets, rollovers, buttons, coin, tilt)
- **Outputs**: Lights (8 groups of 8 LEDs) and Power (solenoids, bumpers, kickersvia 2 bytes)
- **Game State**: `Balls_In_Play`, `Balls_Left` track game progression

## Development Patterns

### GPIO Initialization
1. Define GPIO constant in `blink.h` (e.g., `#define Heartbeat_L 0`)
2. Call `gpio_init(pin)` and `gpio_set_dir(pin, GPIO_IN/GPIO_OUT)` in `pico_general_io_init()`
3. Use helper functions from `Serial_Out.c` for 74HC595 bit-banging (disables interrupts for atomicity)

### Adding New Hardware Interfaces
1. **Outputs**: Create function in `Serial_Out.c` using `serial_out_byte(data, latch_pin)` template
2. **Inputs**: Implement bit-banging read in `Serial_In.c` using `LD_L` (load latch) and `Input_Rd_CLK` (shift clock)
3. Update `blink.h` with friendly `#define` macros for all bits

### Seven-Segment Display
- Use `Hex_to_7_Seg[17]` lookup table (segments gfedcba) defined in `Serial_Out.c`
- Index 16 = blank digit
- Apply to `L_Digits_0` through `L_Digits_3` latch pins

### Critical Sections
- **Bit-banging**: Wrapped in `save_and_disable_interrupts()` / `restore_interrupts()` to prevent corruption
- **Interrupt Handlers**: Keep minimal; PWM handler only updates audio sample pointer and PWM level

## File Organization

- **`blink.h`**: All GPIO definitions, extern variable declarations, input/output macro definitions
- **`blink.c`**: Main loop, GPIO initialization, PWM setup, interrupt handlers
- **`globals.c`**: Global variable definitions (Inputs, Lights, Power, patterns)
- **`Serial_Out.c/h`**: 74HC595 output driver (lights, solenoids, displays)
- **`Serial_In.c/h`**: 74HC165 input driver (switch matrix, buttons)
- **`*.h` audio files**: Precomputed WAV sample arrays (`background.h`, `ring.h`, etc.)
- **CMakeLists.txt**: Pico SDK configuration (C standard C11, USB enabled, UART disabled)

## Common Pitfalls & Corrections

1. **GPIO Direction**: Always call `gpio_set_dir()` before reading/writing; uninitialized GPIOs may float
2. **Interrupt Atomicity**: Serial bit-banging must disable interrupts to avoid clock/data corruption
3. **PWM Timing**: Audio sample rate depends on system clock (176 MHz) and clkdiv setting (8.0f = 11 kHz); changing clock requires PWM reconfiguration
4. **System Clock**: Overclocking to 176 MHz (non-standard) via `set_sys_clock_khz(176000, true)` for audio alignment
5. **USB Initialization**: 2-second delay required before USB is functional; debug prints to USB before this will be lost
6. **Pattern Indexing**: Pattern arrays use start/end index pairs; ensure indices don't exceed array bounds

## Board & SDK Versions
- **Board**: Pico2 (set in CMakeLists.txt as PICO_BOARD)
- **SDK**: 2.2.0 (enforced by Raspberry Pi Pico VS Code Extension)
- **Toolchain**: ARM GCC 14.2 Rel1 (C17 standard, C++14 for mixed projects)
