#include <Arduino.h>

#define IR_ARDUINO_PIN 10
#define LED_PIN 3

// RC-6 timing constants
// 1 time unit (1t) = 444us (16 cycles of 36kHz carrier)
static const uint16_t RC6_T = 444;

// Mark = LOW on wire (simulating TSOP receiving an IR burst)
void sendMark(uint16_t us) {
  digitalWrite(IR_ARDUINO_PIN, LOW);
  delayMicroseconds(us);
}

// Space = HIGH on wire (simulating TSOP idle)
void sendSpace(uint16_t us) {
  digitalWrite(IR_ARDUINO_PIN, HIGH);
  delayMicroseconds(us);
}

// Send a single RC-6 bit using Manchester encoding
// RC-6 Logic '1': Mark then Space
// RC-6 Logic '0': Space then Mark
void sendRC6Bit(uint8_t bit, uint8_t width) {
  if (bit) {
    sendMark(RC6_T * width);
    sendSpace(RC6_T * width);
  } else {
    sendSpace(RC6_T * width);
    sendMark(RC6_T * width);
  }
}

// Send RC-6 Mode 6A (MCE) frame
void sendRC6_MCE(uint32_t data, uint8_t toggle) {
  // Leader: 6t mark + 2t space
  sendMark(RC6_T * 6);
  sendSpace(RC6_T * 2);

  // Start bit: always 1
  sendRC6Bit(1, 1);

  // Mode bits: 1, 1, 0 (mode 6)
  sendRC6Bit(1, 1);
  sendRC6Bit(1, 1);
  sendRC6Bit(0, 1);

  // Toggle bit (double width = 2t per half-bit)
  sendRC6Bit(toggle & 1, 2);

  // 32 data bits, MSB first
  for (int i = 31; i >= 0; i--) {
    sendRC6Bit((data >> i) & 1, 1);
  }

  // Final return to idle state (HIGH)
  sendSpace(40000); 
}

static uint8_t toggleBit = 0;

void setup() {
  pinMode(IR_ARDUINO_PIN, OUTPUT);
  digitalWrite(IR_ARDUINO_PIN, HIGH); // Idle state

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
}

void loop() {
  digitalWrite(LED_PIN, HIGH);

  // MCE scancode for Volume Up: 0x800f0410
  sendRC6_MCE(0x800f0410, toggleBit);
  toggleBit ^= 1; // MCE requires alternating toggle bit
  
  digitalWrite(LED_PIN, LOW);
  delay(1000); // Send every 1 second
}
