/*
 * InputPinController.cpp
 *
 *  Created on: May 31, 2018
 *      Author: Andreas Schneider, Johannes Wendel, Jonas Zeunert
 */

#include "InputPinController.h"

#include <thread>

#include "json/json.hpp"
#include "easylogging/easylogging++.h"
#include "utility/config.h"

namespace flippR_driver
{
namespace input
{
namespace detail
{

using namespace nlohmann;

InputPinController::InputPinController(std::map<std::string, uint8_t> pins)
: pins(std::move(pins))
{
  init_pins();
}

bool InputPinController::read_data(uint8_t pin) const
{
  // setting address to read
  write_row(pin / INPUT_MATRIX_SIZE);
  write_col(pin % INPUT_MATRIX_SIZE);

  // wait for mux to set address
  std::this_thread::sleep_for(std::chrono::nanoseconds(INPUT_SLEEP_DURATION_NANO));

  return read_pin(this->pins.at("data_address"));
}

void InputPinController::write_row(uint8_t data) const
{
  write_pin(this->pins.at("row_address_A"), data & 0b001u);
  write_pin(this->pins.at("row_address_B"), data & 0b010u);
  write_pin(this->pins.at("row_address_C"), data & 0b100u);
}

void InputPinController::write_col(uint8_t data) const
{
  write_pin(this->pins.at("col_address_A"), data & 0b001u);
  write_pin(this->pins.at("col_address_B"), data & 0b010u);
  write_pin(this->pins.at("col_address_C"), data & 0b100u);
}

void InputPinController::init_pins() const
{
  initialize_output_pin(this->pins.at("col_address_A"));
  initialize_output_pin(this->pins.at("col_address_B"));
  initialize_output_pin(this->pins.at("col_address_C"));

  initialize_output_pin(this->pins.at("row_address_A"));
  initialize_output_pin(this->pins.at("row_address_B"));
  initialize_output_pin(this->pins.at("row_address_C"));

  initialize_input_pin(this->pins.at("data_address"));
}

}
}
}
