/*---------------------------------------------------------------------------------------------
/ This file is a template used to declare and preconfigure the eurocard arduino 2560 Pro mini
/ Used in the Eurocard rack system
/ Author: Alain Lowet
/ Copyfree 2022
/--------------------------------------------------------------------------------------------*/

#include <stdio.h>
#include <SPI.h>
#include <SD.h>
#include <TM1638plus_Model2.h>
#include <EEPROM.h>

#define VERSTRING "ALO 1.0 20221106"

//Digital PA port, buffered, DIR and OE controlled
//---------------------------------------------------------------------------------------------
#define PORTA0  22
#define PORTA1  23
#define PORTA2  24
#define PORTA3  25
#define PORTA4  26
#define PORTA5  27
#define PORTA6  28
#define PORTA7  29
#define PORTA_OE  14      //Port OE control, if HIGH, input/output are tri-stated
#define PORTA_DIR 5       //Port Direction control, HIGH = A --> B (INPUT from BUS), LOW = B --> A (OUTPUT to BUS)

//Digital PB port, buffered, DIR and OE controlled
//---------------------------------------------------------------------------------------------
#define PORTB0  53
#define PORTB1  52
#define PORTB2  51
#define PORTB3  50
#define PORTB4  10
#define PORTB5  11
#define PORTB6  12
#define PORTB7  13
#define PORTB_OE  14      //Port OE control, if HIGH, input/output are tri-stated
#define PORTB_DIR 5       //Port Direction control, HIGH = A --> B (INPUT from BUS), LOW = B --> A (OUTPUT to BUS)

//Digital PC port, buffered, DIR and OE controlled
//---------------------------------------------------------------------------------------------
#define PORTC0  37
#define PORTC1  36
#define PORTC2  35
#define PORTC3  34
#define PORTC4  33
#define PORTC5  32
#define PORTC6  31
#define PORTC7  30
#define PORTC_OE  14      //Port OE control, if HIGH, input/output are tri-stated
#define PORTC_DIR 5       //Port Direction control, HIGH = A --> B (INPUT from BUS), LOW = B --> A (OUTPUT to BUS)

//Digital PL port, buffered, DIR and OE controlled
//---------------------------------------------------------------------------------------------
#define PORTL0  49
#define PORTL1  48
#define PORTL2  47
#define PORTL3  46
#define PORTL4  45
#define PORTL5  44
#define PORTL6  43
#define PORTL7  42
#define PORTL_OE  14      //Port OE control, if HIGH, input/output are tri-stated
#define PORTL_DIR 5       //Port Direction control, HIGH = A --> B (INPUT from BUS), LOW = B --> A (OUTPUT to BUS)

//Analog I/O Ports, unbuffered
//---------------------------------------------------------------------------------------------
#define AN00  A0
#define AN01  A1
#define AN02  A2
#define AN03  A3
#define AN04  A4
#define AN05  A5
#define AN06  A6
#define AN07  A7
#define AN08  A8
#define AN09  A9
#define AN10  A10
#define AN11  A11
#define AN12  A12
#define AN13  A13
#define AN14  A14
#define AN15  A15


//Control and unbuffered misc ports available on DIN41612 BUS
//---------------------------------------------------------------------------------------------
#define IO0 3           //D3
#define IO1 6           //D6  
#define IO2 18          //D18
#define IO3 16          //D16
#define IO4 20          //D20
#define IO5 17          //D17

#define CARD_EN 2       //D2      Card Select line, alloocated for remote control from Raspbarry Pi card

//Internal 9 pins & 5 pins connector bloc 
//---------------------------------------------------------------------------------------------
#define INTSTB 9        //D9      Internal Strobe signal for HexKeyboard controller
#define INTCLK 8        //D8 .    Internal Clock signal for HexKeyboard controller
#define INTDIO 7        //D7 .    Internal Data signal for HexKeyboard controller

//SDCARD control lines 
//---------------------------------------------------------------------------------------------
#define SDCARD_MOSI 51
#define SDCARD_MISO 50
#define SDCARD_SCK  52
#define SDCARD_SS   53

//Setup Global variable and constants
//---------------------------------------------------------------------------------------------

boolean LOG_ENABLED = false;
bool swap_nibbles = false;            //HexKeyboard TM1638, Default false. If left out, see note in readme at URL
bool high_freq = false;               //HexKeyboard TM1638, Default false. If using a high freq CPU > ~100 MHZ set to true. 

// Constructor object for led display and main keyboard
//TM1638plus_Model2 tm(INTSTB, INTCLK , INTDIO, swap_nibbles, high_freq);   //Internal connection used
TM1638plus_Model2 hexKeyboard(IO3, IO5 , IO2, swap_nibbles, high_freq);   //External Arduino DB9 used

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  initPorts();

}

void loop() {
  // put your main code here, to run repeatedly:
 // readPortValue('A');
  delay(3000);

}

void logMsg(String content) {
  if(LOG_ENABLED == true) {
    Serial.println(content);
  }
}

//---------------------------------------------------------------------------------------------
// For security purposes, at setup, all the ports are set as imputs and the buffered I/O ports
// are tri-stated. Unbuffered analog ports are set as input
//--------------------------------------------------------------------------------------------- 
void initPorts() {

  DDRA = B00000000;   //Set portA (digital 7-0) to inputs
  DDRB = B00000000;   //Set portB (digital 7-0) to inputs
  DDRC = B00000000;   //Set portC (digital 7-0) to inputs
  DDRL = B00000000;   //Set portL (digital 7-0) to inputs
  DDRF = B00000000;   //Set portL (digital 7-0) to inputs - Analog I/O
  DDRK = B00000000;   //Set portL (digital 7-0) to inputs - Analog I/O

  digitalWrite(PORTA_DIR,HIGH);     //Set 74LS245 buffer as input
  digitalWrite(PORTB_DIR,HIGH);     //Set 74LS245 buffer as input
  digitalWrite(PORTC_DIR,HIGH);     //Set 74LS245 buffer as input
  digitalWrite(PORTL_DIR,HIGH);     //Set 74LS245 buffer as input

  digitalWrite(PORTA_OE,HIGH);      //Set 74LS245 in tri-state mode
  digitalWrite(PORTB_OE,HIGH);      //Set 74LS245 in tri-state mode
  digitalWrite(PORTC_OE,HIGH);      //Set 74LS245 in tri-state mode
  digitalWrite(PORTL_OE,HIGH);      //Set 74LS245 in tri-state mode
      
  
  pinMode(INTSTB,OUTPUT);   //Configure HexaKeyboard pins as output (Stobe output)
  pinMode(INTDIO,OUTPUT);   //Configure HexaKeyboard pins as output (Data output)  
  pinMode(INTCLK,OUTPUT);   //Configure HexaKeyboard pins as output (Clock output)

  delay(500);
  initSDCard();
  initHexKeyboard();

}

void initSDCard() {
  Serial.print(F("SDCard initialization...  "));
  if (!SD.begin(SDCARD_SS)) {
    Serial.println(F("failed!"));
    while (1);
  }
  Serial.println(F("done."));
}

void initHexKeyboard() {
  hexKeyboard.displayBegin(); // Init the module
  delay(1000);
  Serial.println(F("Display module initialized..."));
  hexKeyboard.reset();
  hexKeyboard.brightness(0);
  hexKeyboard.DisplayStr("Ready", 7);
  
}

void readPortValue(char selectedPort) {
  
  int printVal = 0b0000000100000000;
  int dataValue = 0;
  String binView;
  char test[9];

  switch(selectedPort) {

    case 'A':   dataValue=PINA;
                break;
    case 'B':   dataValue=PINB;
                break;
    case 'C':   dataValue=PINC;
                break;
    case 'L':   dataValue=PINL;
                break;
    case 'F':   dataValue=PINF;
                break;
    case 'K':   dataValue=PINK;
                break;
  }
 
  for ( size_t mask = (1 << 8); mask >>= 1 ; ) {
    binView +=   (dataValue & mask) ? '1' : '0';
  }

  Serial.print(dataValue);
  Serial.print(" - ");
  Serial.println(binView);

  binView.toCharArray(test,9);
  hexKeyboard.DisplayStr(test,0);
  
}
