/***************************************************
*  TBIB_Master.h
*
*  handles the Two-Bit-Interface-Bus protocol as a master
*
*  main program
*    in setup call
*      InitTBIBpins(); 
*
*    in main loop call
*      PollTBIB(); 
*      returns true is both clocks are low
*        main program should only use SPI when both clocks are low
*      
*    to send a byte call
*      SendByteToSlave(b);
*
*  main program must include a declaration of
*    recvTBIB(byte b) {}
*  which will be called whenever a byte is received
*  
*****************************************************/

#ifndef TBIB_Master_h
#define TBIB_Master_h

void InitTBIBpins(); // sets pins to input/output
bool PollTBIB(); // call in main loop
void recvTBIB(byte b); // must be declared in main program
void SendByteToSlave(byte b);
void SendStrToSlave(char *s);

//-----------------------------------------------------------

const int pinMISOa = 15;
const int pinMOSIa = 13;
const int pinMCLK = 2;
const int pinSCLK = 14;

byte bOut = 0;
byte nOut = 0;

//-----------------------------------------------------------
// InitTBIBpins
//-----------------------------------------------------------
void InitTBIBpins() {
  pinMode(pinMISOa, INPUT);   
  pinMode(pinSCLK, INPUT);    
  pinMode(pinMOSIa, OUTPUT);    digitalWrite(pinMOSIa, LOW);
  pinMode(pinMCLK, OUTPUT);     digitalWrite(pinMCLK, LOW);
}

//-----------------------------------------------------------
// SendByteToSlave
//-----------------------------------------------------------
void SendByteToSlave(byte b) {
  bOut = b;
  nOut = 9;
  while (nOut > 0)
    PollTBIB();
}

//-----------------------------------------------------------
// SendStrToSlave
//-----------------------------------------------------------
void SendStrToSlave(char *s) {
  while (*s)
    SendByteToSlave(*(s++));
}

//-----------------------------------------------------------
// PollTBIB() 
//   on entry, both CLKs are low 
//-----------------------------------------------------------
bool PollTBIB() {
  static byte bIn = 0;
  static byte nIn = 0;
  bool bMISO;
  static bool bWaitForCLKhigh = true;

  if (bWaitForCLKhigh) {
    // set MCLK = true
    digitalWrite(pinMCLK, true);
  
    // wait for SCLK
    if (!digitalRead(pinSCLK)) 
      return true;
  
    // read MISO
    bMISO = digitalRead(pinMISOa);
    if ((nIn == 0) && bMISO)
    { // start of incoming data
      nIn = 8;
    } else
    if (nIn > 0) {
      bIn = (bIn >> 1) & 0x7F;
      if (bMISO)
        bIn += 0x80;
      nIn--;
      if (nIn == 0) 
        recvTBIB(bIn);
    }
  
    // set MCLK = false
    digitalWrite(pinMCLK, false);
  
    // can change MOSI  
    if (nOut == 9) {
      digitalWrite(pinMOSIa, true);
      nOut--;
    } else 
    if (nOut > 0) {
      digitalWrite(pinMOSIa, bOut & 1);
      nOut--;
      bOut = (bOut >> 1) & 0x7F;
    } else 
      digitalWrite(pinMOSIa, false);

    bWaitForCLKhigh = false;
    return false;
  } else {
    // wait for !SCLK
    if (digitalRead(pinSCLK)) 
      return false;

    bWaitForCLKhigh = true;
    return true;
  }
}

#endif
