// Copyright 2022 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

#include "pw_spi_pico/initiator.h"

#include <algorithm>

#include "hardware/spi.h"
#include "pico/stdlib.h"
#include "pw_assert/check.h"
#include "pw_log/log.h"
#include "pw_status/try.h"

namespace pw::spi {

namespace {

constexpr spi_order_t GetBitOrder(BitOrder bit_order) {
  switch (bit_order) {
    case BitOrder::kLsbFirst:
      return SPI_LSB_FIRST;
    case BitOrder::kMsbFirst:
      return SPI_MSB_FIRST;
  }
  PW_CRASH("Unknown bit order");
  return SPI_LSB_FIRST;
}

constexpr spi_cpha_t GetPhase(ClockPhase phase) {
  switch (phase) {
    case ClockPhase::kFallingEdge:
      return SPI_CPHA_1;
    case ClockPhase::kRisingEdge:
      return SPI_CPHA_0;
  }
  PW_CRASH("Unknown phase");
  return SPI_CPHA_0;
}

constexpr spi_cpol_t GetPolarity(ClockPolarity polarity) {
  switch (polarity) {
    case ClockPolarity::kActiveHigh:
      return SPI_CPOL_1;
    case ClockPolarity::kActiveLow:
      return SPI_CPOL_0;
  }
  PW_CRASH("Unknown polarity");
  return SPI_CPOL_0;
}

}  // namespace

PicoInitiator::PicoInitiator(spi_inst_t* spi, uint32_t baud_rate)
    : spi_(spi),
      baud_rate_(baud_rate),
      last_config_{
          .polarity = ClockPolarity::kActiveHigh,
          .phase = ClockPhase::kRisingEdge,
          .bits_per_word = BitsPerWord(8),
          .bit_order = BitOrder::kMsbFirst,
      } {}

Status PicoInitiator::LazyInit() {
  // Already initialized - nothing to do.
  // The Pico SDK needs to call spi_init() earlier so that the
  // various GPIO pins (MISO, etc.) can be assigned to the SPI
  // bus.
  return OkStatus();
}

Status PicoInitiator::Configure(const Config& config) {
  last_config_ = config;
#if 0
  spi_set_format(spi_,
                 config.bits_per_word(),
                 GetPolarity(config.polarity),
                 GetPhase(config.phase),
                 GetBitOrder(config.bit_order));
#endif

  return OkStatus();
}

Status PicoInitiator::WriteRead(ConstByteSpan write_buffer,
                                ByteSpan read_buffer) {
  PW_TRY(LazyInit());

  // TODO(cmumford): Remove this hack once changing SPI device modes is added.
  bool do_16_bit_write = write_buffer.size() > 8;

  if (!write_buffer.empty()) {
    if (!read_buffer.empty()) {
      PW_CRASH("Not implemented");
    } else {
      if (do_16_bit_write) {
        spi_write16_blocking(
            spi_,
            reinterpret_cast<const uint16_t*>(write_buffer.data()),
            write_buffer.size());
      } else {
        spi_write_blocking(
            spi_,
            reinterpret_cast<const uint8_t*>(write_buffer.data()),
            write_buffer.size());
      }
    }
  } else {
    spi_read_blocking(spi_,
                      /*repeated_tx_data=*/0,
                      reinterpret_cast<uint8_t*>(read_buffer.data()),
                      read_buffer.size());
    PW_CRASH("Not implemented");
  }

  return OkStatus();
}

}  // namespace pw::spi
