// 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) : spi_(spi), bits_per_word_(8) {}

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) {
  bits_per_word_ = config.bits_per_word;
  spi_set_format(spi_,
                 config.bits_per_word(),
                 GetPolarity(config.polarity),
                 GetPhase(config.phase),
                 GetBitOrder(config.bit_order));

  return OkStatus();
}

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

  if (!write_buffer.empty()) {
    if (!read_buffer.empty()) {
      PW_CRASH("Not implemented");
    } else {
      if (bits_per_word_() == 16) {
        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());
  }

  return OkStatus();
}

}  // namespace pw::spi
