/*
 *  Copyright (C) 2009-2011 Florent Bedoiseau (buzz.computer@free.fr)
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

// File : irda.c
// Arduino 0017
// Boarduino (http://www.ladyada.net/make/boarduino) 
// IrDA (SIR): 9600 8N1 : 0 : 0 pendant 84 us + 1 pendant 16us, 1 : 0 pendant 100us

// Assignation des pins :
// ---------------------------------------------------
// Avr : Rôle				    : Pin Sub9
// ---------------------------------------------------
// A0 : Potentiomètre JOY_0        	    : 9
// A1 : Potentiomètre JOY_1                 : 5
// D4 : Joystick numérique : J_BUTTON	    : 6
// D5 : Joystick numérique : J_UP           : 1
// D6 : Joystick numérique : J_DOWN         : 2
// D7 : Joystick numérique : J_LEFT         : 3
// D8 : Joystick numérique : J_RIGHT        : 4
// D2 : LED IR				    : Néant
// VCC/VDD				    : 7
// GND/VSS				    : 8
// -----------------------------------------------

// Frame : 5 bytes : 	'#',
// 						[X,UP,DN,LT,RT,BT0,AN0-b9,AN0-b8],
//						[AN0-b7,AN0-b6,AN0-b5,AN0-b4,AN0-b3,AN0-b1,AN0-b1,AN0-b0],
//						[X,X,X,X,X,BT1,AN1-b9,AN0-b8],
//						[AN1-b7,AN1-b6,AN1-b5,AN1-b4,AN1-b3,AN1-b1,AN1-b1,AN1-b0]


// PORTS
const int pinLed=2; 
const int pinButton_0=3;
const int pinButton_1=4;
const int pinUp=5;
const int pinDw=6;
const int pinLt=7;
const int pinRt=8;

const int pinPot_0 = 0;
const int pinPot_1 = 1;

// STATES
#define PREPARE_CONV 0
#define START_CONV   1
#define WAIT_CONV    2
#define PREPARE_MSG  3
#define SEND_MSG     4

#define FRAME_SIZE   5


// Protos
void irda_send_byte (byte val);

// 1 byte sent : 1040us ~
void irda_send_byte (byte val) {
  byte cnt;
  // Sending Start bit (pulse)
  delayMicroseconds(84); // 84us  
  digitalWrite(pinLed, HIGH);
  delayMicroseconds(16); // 16us
  digitalWrite(pinLed, LOW);
  // Sending 8 bits

  cnt=8;
  while (cnt) {
    delayMicroseconds(84); // 84us  
    if (!(val & 0x01)) digitalWrite(pinLed, HIGH); // pulse
    delayMicroseconds(16); // 16us  
    digitalWrite(pinLed, LOW);
    val >>=1;
    --cnt;
  }

  // Sending Stop bit (no pulse)
  delayMicroseconds(100); // 100us  
}

void setup () {
  // out
  pinMode(pinLed, OUTPUT);      
  
  // in
  pinMode (pinButton_0, INPUT);
  pinMode (pinButton_1, INPUT);
  pinMode (pinUp, INPUT);
  pinMode (pinDw, INPUT);
  pinMode (pinLt, INPUT);
  pinMode (pinRt, INPUT);

  // enables pullup
  digitalWrite (pinButton_0, HIGH);
  digitalWrite (pinButton_1, HIGH);
  digitalWrite (pinUp, HIGH);
  digitalWrite (pinDw, HIGH);
  digitalWrite (pinLt, HIGH);
  digitalWrite (pinRt, HIGH);

  // Led Off
  digitalWrite (pinLed, LOW);
  
  //Serial.begin(9600);
  //Serial.print("INIT");
}

void loop () {
  byte i, atari;
  int pot_0, pot_1; // analog values
  byte frame [5]; // current frame

  // Conversions
  pot_0 = analogRead(pinPot_0);
  pot_1 = analogRead(pinPot_1);

  // Building the frame
  frame [0] = '#'; // Simple start tag
  frame [1] = (byte) ((pot_0 & 0xFF00) >> 8); // AN0 : JOY_0 MSB
  frame [2] = (byte) (pot_0 & 0x00FF);		// JOY_0 LSB
  frame [3] = (byte) ((pot_1 & 0xFF00) >> 8); // AN1 : JOY_1 MSB
  frame [4] = (byte) (pot_1 & 0x00FF);		// JOY_1 LSB
  
  // Adding button states. 0 : Not pressed, 1 : Pressed
  if (!digitalRead (pinButton_0)) { frame [1] |= 0x04; }
  if (!digitalRead (pinButton_1)) { frame [3] |= 0x04; }
  
  // Adding atari joystick port
  atari = 0;
  if (digitalRead (pinUp)) atari |= 0x40; // Bit 6 : Up
  if (digitalRead (pinDw)) atari |= 0x20; // Bit 5 : Down
  if (digitalRead (pinLt)) atari |= 0x10; // Bit 4 : Left
  if (digitalRead (pinRt)) atari |= 0x08; // Bit 3 : Right

  frame [1] |= atari;						

  //Serial.print("->");
  for (i=0; i < FRAME_SIZE; i++) { // Sending IrDA frame 
    irda_send_byte (frame[i]);
    //Serial.print(frame[i], HEX);
    //Serial.print(".");
  }
  //Serial.print("<-\n");                        
  // Wait 20ms between 2 frames
  delay (20); // 20ms
}

