Skip to content

ValeraBat/VWCDC_Driver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VWCDC_Driver

A fully abstracted, non-RTOS C++ library emulating the Volkswagen CD Changer (CDC) protocol. It seamlessly works with VW Group head units (RNS-MFD, Gamma, Beta, Delta, Chorus, Symphony) over the customized VW SPI and NEC IR data bus.

Why "Universal"?

Originally engineered with the ESP32’s dual-core FreeRTOS architecture, the CDC driver demanded massive RAM and SMP (Symmetric Multiprocessing) task pinning to prevent network jitter. VWCDC drops all OS requirements:

  • Zero FreeRTOS Tasks: Entirely replaced by a single, non-blocking loop().
  • Zero String allocations: Operates entirely on raw uint8_t memory mapping, protecting low-memory chips (ATmega328, ATTiny) from fragmentation crashes.
  • Universal ISR Pattern: Drops attachInterruptArg (an ESP32-only feature) in favor of a fast static ISR wrapper, meaning attachInterrupt(..., CHANGE) functions immediately on Arduino Uno, STM32, and PIC MCUs.

Minimal Example (Arduino Nano)

This sketch turns a lightweight $3 Arduino clone into a fully functioning CDC emulator that reports 6 discs, responds to steering wheel / radio faceplate buttons, and outputs status data.

#include <Arduino.h>
#include <SPI.h>
#include "VWCDC.h"

// Initialize instance
VWCDC cdc;

// CDC PIN Definitions (Example for typical Uno/Nano)
#define PIN_DATA_OUT 2  // Must be an interrupt-capable pin (D2 on Uno/Nano)
#define PIN_SCK      13 // SPI SCK
#define PIN_MOSI     11 // SPI MOSI
#define PIN_MISO     12 // SPI MISO (Not strictly used, logic strictly reads DataOut)

// Callback for VW Radio buttons being pressed
void onCdcButton(VWButton button) {
    switch(button) {
        case VWButton::NEXT: Serial.println("User pressed >> (Next)"); break;
        case VWButton::PREV: Serial.println("User pressed << (Prev)"); break;
        case VWButton::CD1:  Serial.println("Selected Disc 1 (Custom Action)"); break;
        case VWButton::CD6:  Serial.println("Selected Disc 6"); break;
        default: Serial.println("Other VW button pressed."); break;
    }
}

// Telemetry/Diagnostic callback (Low-memory footprint text passing)
void onCdcDiag(const char* logMsg) {
    Serial.print("CDC_DIAG: ");
    Serial.println(logMsg);
}

void setup() {
    Serial.begin(115200);
    Serial.println("Starting VWCDC emulator...");

    cdc.setButtonCallback(onCdcButton);
    cdc.setDiagCallback(onCdcDiag);

    // Binds hardware SPI and the NEC receiver ISR.
    // The DataOut pin MUST support attachInterrupt(CHANGE).
    cdc.begin(PIN_DATA_OUT, PIN_SCK, PIN_MOSI, PIN_MISO);

    // Initial Dashboard spoofing
    cdc.setDisc(1);
    cdc.setTrack(1);
    
    Serial.println("CDC Subsystem online.");
}

void loop() {
    // This MUST be called as quickly and as often as possible.
    // It processes SPI queues, calculates ISR buffer differences, and fires callbacks.
    cdc.loop();

    // Do NOT place multi-millisecond delay() statements in this loop,
    // otherwise CDC SPI timing limits (3200µs) may be violated.
}

API Reference

  • begin(int dataOutPin, int sckPin, int mosiPin, int misoPin) - Start the hardware modules (SPI and External ISR).
  • loop() - Non-blocking state machine processor. Put it in void loop().
  • setDisc(uint8_t disc), setTrack(uint8_t track) - Send spoofing updates to the radio's LCD (Track 01-99).
  • setButtonCallback(VWCDCButtonCallback cb) - Register a listener for button presses from the head unit.
  • setDiagCallback(VWCDCDiagCallback cb) - Receive debug strings without heap tracking.

About

A universal, non-RTOS superloop C++ library emulating the Volkswagen CD Changer (CDC) protocol. Compatible with Arduino, ESP32, and STM32.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages