/*
 Rocrail - Model Railroad Software
 Copyright (c) 2002-2022 Robert Jan Versluis, Rocrail.net
 All rights reserved.
*/
#ifndef _RCAN_io_H_
#define _RCAN_io_H_

#include "RCAN_dfs.h"

// Check on which board we compile.
/*
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
byte  BoardType = TYPE_MEGA;
byte  NrAnalog  = 16;
byte  NrDigital = 54;
byte APORT[16] = {A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15};
#elif defined(__AVR_ATmega328P__)
byte  BoardType = TYPE_UNO;
byte  NrAnalog  = 6;
byte  NrDigital = 14;
byte APORT[16] = {A0,A1,A2,A3,A4,A5,A6,A7};
#else
byte  BoardType = TYPE_UNO; // Default to UNO
byte  NrAnalog  = 6;
byte  NrDigital = 14;
byte APORT[16] = {A0,A1,A2,A3,A4,A5,A6,A7};
#endif
*/

#define MAX_PORTS  16

#define SOD 0xFF


// port config
#define PORTCFG_IO          0x01   // port I/O mask
#define PORTCFG_IN          0x01
#define PORTCFG_OUT         0x00
#define PORTCFG_OFFDELAY    0x02   // input 2 seconds off delay for occupancy detectors
#define PORTCFG_PULSE       0x02   // output 0.5 seconds pulse length
#define PORTCFG_INV         0x04   // invert
#define PORTCFG_IR          0x08   // Infrared port
#define PORTCFG_SYNC        0x10   // Synchronise with th SYNCID

typedef struct {
  byte   state;
  byte   duration;
  byte   timer;
  byte   timerval;
  byte   blink;
  byte   ack;
  int    ivalue;
} Port;

#define ACK_PENDING 0x80
#define ACK_OK      0x00

class IO
{
private:
  byte m_LED;
  void setPinLayout(bool init);

public:
  byte m_Pins[16];
  Port m_Port[16];
  IO();
  void initIO(byte portnr);
  void initPorts(bool in);
  void confIO(byte port, byte conf);
  void setOutput(byte port, byte on, bool inv);
  bool getInput(byte port);
  void SoD();
  void increasePortTimers();
  void setPortDuration(byte port, byte duration);
  bool ackInput(byte port, byte state);
  bool isAckInput(byte port);
  byte setPortState(byte port, byte state, byte blink=false, byte resetAck=false);
  byte getPortState(byte port);
  int getPortValue(byte port);
  byte isPortTimer(byte port);
  byte isPortBlink(byte port);
  void resetPortTimer(byte port);
  byte getPortTimer(byte port);
  void setLED(bool on);
  void tick10ms();

};


#endif
