#include <Arduino.h>
#include "SPI.h"
#include "RX231_Shield.h"

void RX231_Shield::begin()
{
  SPI.begin();
  SPI.setBitOrder(LSBFIRST);
  SPI.setDataMode(SPI_MODE0);
  SPI.setClockDivider(SPI_CLOCK_DIV128);
  pinMode(2, OUTPUT);
  pinMode(3, INPUT_PULLUP);
  digitalWrite(2, HIGH);
}

void RX231_Shield::end()
{
  SPI.end();
  digitalWrite(2, LOW);
  pinMode(3, OUTPUT);
}

void RX231_Shield::sendData(uint8_t cmd, const uint8_t * data_buf) {
  uint8_t tx_buf[18] = {0,};
  uint8_t check = 0;
  uint16_t sum = 0;
  int i = 0, j = 0;
  tx_buf[0] = 0x02;
  tx_buf[1] = cmd;
  tx_buf[17] = 0x03;

  for (i = 2 ; i < 16 ; i++) {
    tx_buf[i] = data_buf[i - 2];
    sum += tx_buf[i];
  }
  tx_buf[16] = sum & 0xFF;

  while (check != 18) {
    check = 0;
    digitalWrite(2, HIGH);
    digitalWrite(2, LOW);
    for (j = 0 ; j < 18; j++) {
      check += receiving(tx_buf[j]);
    }
  }
}

uint8_t * RX231_Shield::receiveData() {
  uint16_t sum = 0;
  uint8_t result = 0;
  static uint8_t data_buf[18] = {0,};
  int i = 0;
  data_buf[0] = receiving(0);
  if (data_buf[0] == 0x02) {
    data_buf[1] = receiving(0);
    for (i = 2 ; i < 16 ; i++) {
      data_buf[i] = receiving(0);
      sum += data_buf[i];
    }

    sum = sum & 0xFF;
    data_buf[16] = receiving(0);
    if (data_buf[16] == sum) result = 18;
    data_buf[17] = receiving(result);
    if (data_buf[0] == 0x02 && data_buf[17] == 0x03 && result == 18) {
      return data_buf;
    }
  }
  return 0;
}

void RX231_Shield::setLed(uint8_t TS15, uint8_t TS16, uint8_t TS22, uint8_t TS23, uint8_t TS27, uint8_t TS30) {
  uint8_t buf[14] = {0,};

  buf[0] |= TS15 >= 1 ? 0x01 : 0x00;
  buf[0] |= TS16 >= 1 ? 0x02 : 0x00;
  buf[0] |= TS22 >= 1 ? 0x08 : 0x00;
  buf[0] |= TS23 >= 1 ? 0x20 : 0x00;
  buf[0] |= TS27 >= 1 ? 0x40 : 0x00;
  buf[0] |= TS30 >= 1 ? 0x80 : 0x00;

  sendData(0x40, buf);
}

void RX231_Shield::requestBLT(uint8_t data) {
  uint8_t buf[14] = {0,};
  buf[0] = data;
  sendData(0x10, buf);
}

void RX231_Shield::requestSPK(uint16_t hz, uint16_t ms) {
  uint8_t buf[14] = {0,};
  buf[0] = hz >> 8;
  buf[1] = hz & 0xFF;

  buf[2] = ms >> 8;
  buf[3] = ms & 0xFF;
  sendData(0x04, buf);
}

void RX231_Shield::requestMPU() {
  uint8_t buf[14] = {0,};
  sendData(0x20, buf);
}

void RX231_Shield::requestIR(uint8_t customData, uint8_t data) {
  uint8_t buf[14] = {0,};
  buf[0] = customData;
  buf[1] = data;

  sendData(0x01, buf);
}

byte RX231_Shield::receiving(byte txData) {
  byte data;
  digitalWrite(10, LOW);
  data = SPI.transfer(txData);
  digitalWrite(10, HIGH);
  return data;
}


