/*
 * Copyright 2023 Google LLC
 *
 * 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
 *
 *      http://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 "sw/device/lib/camera_hm01b0.h"

#include "hw/top_matcha/sw/autogen/top_matcha.h"
#include "sw/device/lib/camera_hm01b0_regs.h"
#include "sw/device/lib/dif/dif_base.h"
#include "sw/device/lib/dif/dif_i2c.h"
#include "sw/device/lib/dif/dif_rv_plic.h"
#include "sw/device/lib/testing/test_framework/check.h"

// Camera address and registers
#define HM01B0_ADDR (0x24 << 1)

// Expected values of Chip ID registers
#define HM01B0_MODEL_ID_H_EXPECTED (0x01)
#define HM01B0_MODEL_ID_L_EXPECTED (0xB0)

// I2C R/W bits
static const uint8_t kI2cWrite = 0;
static const uint8_t kI2cRead = 1;

// IRQ statuses
static volatile bool fmt_irq_seen = false;
static volatile bool rx_irq_seen = false;
static volatile bool done_irq_seen = false;

// Device handles
static dif_i2c_t cam_i2c;
static dif_rv_plic_t plic;

static dif_result_t camera_hm01b0_write_reg(uint16_t reg, uint8_t val) {
  CHECK(!done_irq_seen);
  // Cam address + start
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, HM01B0_ADDR | kI2cWrite,
                                  kDifI2cFmtStart, true));
  // addr hi
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, (reg >> 8), kDifI2cFmtTx, true));
  // addr lo
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, (reg & 0xFF), kDifI2cFmtTx, true));
  // val + stop
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, val, kDifI2cFmtTxStop, true));

  while (!done_irq_seen) {
    asm volatile("wfi");
  }
  CHECK(done_irq_seen);
  done_irq_seen = false;

  return kDifOk;
}

static dif_result_t camera_hm01b0_read_reg(uint16_t reg, uint8_t* val_out) {
  if (!val_out) return kDifBadArg;

  CHECK(!done_irq_seen);
  // Cam address + start
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, HM01B0_ADDR | kI2cWrite,
                                  kDifI2cFmtStart, true));
  // addr hi
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, (reg >> 8), kDifI2cFmtTx, true));
  // addr lo + stop
  CHECK_DIF_OK(
      dif_i2c_write_byte(&cam_i2c, (reg & 0xFF), kDifI2cFmtTxStop, true));

  while (!done_irq_seen) {
    asm volatile("wfi");
  }
  CHECK(done_irq_seen);
  done_irq_seen = false;

  // start + id
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, HM01B0_ADDR | kI2cRead,
                                  kDifI2cFmtStart, true));
  // rx
  CHECK_DIF_OK(dif_i2c_write_byte(&cam_i2c, 1, kDifI2cFmtRxStop, false));
  while (!done_irq_seen) {
    asm volatile("wfi");
  }
  CHECK(done_irq_seen);
  done_irq_seen = false;

  CHECK_DIF_OK(dif_i2c_read_byte(&cam_i2c, val_out));

  return kDifOk;
}

dif_result_t camera_hm01b0_init(void) {
  CHECK_DIF_OK(dif_i2c_init(mmio_region_from_addr(TOP_MATCHA_CAM_I2C_BASE_ADDR),
                            &cam_i2c));
  dif_i2c_config_t cam_i2c_config;
  dif_i2c_timing_config_t cam_i2c_timing_config = {
      .lowest_target_device_speed = kDifI2cSpeedStandard,
      .clock_period_nanos = 400,
      .sda_rise_nanos = 800,
      .sda_fall_nanos = 600,
      .scl_period_nanos = 1000000 / 100000,
  };
  CHECK_DIF_OK(dif_i2c_compute_timing(cam_i2c_timing_config, &cam_i2c_config));
  CHECK_DIF_OK(dif_i2c_configure(&cam_i2c, cam_i2c_config));
  CHECK_DIF_OK(
      dif_i2c_set_watermarks(&cam_i2c, kDifI2cLevel1Byte, kDifI2cLevel1Byte));
  CHECK_DIF_OK(dif_i2c_irq_set_enabled(&cam_i2c, kDifI2cIrqFmtThreshold,
                                       kDifToggleEnabled));
  CHECK_DIF_OK(dif_i2c_irq_set_enabled(&cam_i2c, kDifI2cIrqRxThreshold,
                                       kDifToggleEnabled));
  CHECK_DIF_OK(dif_i2c_irq_set_enabled(&cam_i2c, kDifI2cIrqCmdComplete,
                                       kDifToggleEnabled));
  CHECK_DIF_OK(dif_i2c_host_set_enabled(&cam_i2c, kDifToggleEnabled));

  uint8_t id_h, id_l;
  CHECK_DIF_OK(camera_hm01b0_read_reg(HM01B0_MODEL_ID_H, &id_h));
  CHECK_DIF_OK(camera_hm01b0_read_reg(HM01B0_MODEL_ID_L, &id_l));
  CHECK(id_h == HM01B0_MODEL_ID_H_EXPECTED);
  CHECK(id_l == HM01B0_MODEL_ID_L_EXPECTED);
  return kDifOk;
}

dif_result_t camera_hm01b0_set_default_registers(
    camera_hm01b0_resolution_t resolution,
    camera_hm01b0_frame_rate_t frame_rate) {
  // These settings are derived from
  // Himax's HM01B0_RAW8_QVGA_8bits_lsb_1fps.txt.
  // Any registers without a name are labeled as RESERVED in the
  // datasheet.

  uint8_t qvga_win_en;
  if (resolution == kCameraHm01b0Resolution324x324) {
    qvga_win_en = 0;
  } else if (resolution == kCameraHm01b0Resolution320x240) {
    qvga_win_en = 1;
  } else {
    return kDifBadArg;
  }

  uint8_t intg_h, intg_l, frame_length_h, frame_length_l;
  switch (frame_rate) {
    case kCameraHm01b0FrameRate1Fps:
      intg_h = 0x3E;
      intg_l = 0x58;
      frame_length_h = 0x3E;
      frame_length_l = 0x5A;
      break;
    case kCameraHm01b0FrameRate30Fps:
      intg_h = 0x02;
      intg_l = 0x14;
      frame_length_h = 0x02;
      frame_length_l = 0x16;
      break;
    case kCameraHm01b0FrameRate60Fps:
      intg_h = 0x01;
      intg_l = 0x0A;
      frame_length_h = 0x01;
      frame_length_l = 0x0C;
      break;
    default:
      return kDifBadArg;
  }

  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_SW_RESET, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MODE_SELECT, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_IMAGE_ORIENTATION, 0x03));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_BLC_TGT, 0x08));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_BLC2_TGT, 0x08));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3044, 0x0A));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3045, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3047, 0x0A));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3050, 0xC0));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3051, 0x42));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3052, 0x50));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3053, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3054, 0x03));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3055, 0xF7));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3056, 0xF8));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3057, 0x29));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x3058, 0x1F));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_BIT_CONTROL, 0x1E));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_SYNC_EN, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_OUTPUT_PIN_STATUS_CTRL, 0x04));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_BLC_CFG, 0x43));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x1001, 0x40));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x1002, 0x32));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x0350, 0x7F));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_BLC2_EN, 0x01));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x1008, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x1009, 0xA0));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x100A, 0x60));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x100B, 0x90));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x100C, 0x40));
  CHECK_DIF_OK(
      camera_hm01b0_write_reg(HM01B0_VSYNC_HSYNC_PIXEL_SHIFT_EN, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_STATISTIC_CTRL, 0x07));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x2003, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x2004, 0x1C));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x2007, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x2008, 0x58));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x200B, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x200C, 0x7A));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x200F, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(0x2010, 0xB8));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MD_LROI_Y_START_H, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MD_LROI_Y_START_L, 0x58));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MD_LROI_X_END_H, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MD_LROI_X_END_L, 0x9B));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_AE_CTRL, 0x01));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_CONVERGE_OUT_TH, 0x07));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MAX_INTG_H, intg_h));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MAX_INTG_L, intg_l));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MAX_AGAIN_FULL, 0x03));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MAX_AGAIN_BIN2, 0x03));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MAX_DGAIN, 0x80));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_FS_60HZ_H, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_FS_60HZ_L, 0x85));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_FS_50HZ_H, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_FS_50HZ_L, 0xA0));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MD_CTRL, 0x03));
  CHECK_DIF_OK(
      camera_hm01b0_write_reg(HM01B0_FRAME_LENGTH_LINES_H, frame_length_h));
  CHECK_DIF_OK(
      camera_hm01b0_write_reg(HM01B0_FRAME_LENGTH_LINES_L, frame_length_l));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_LINE_LENGTH_PCK_H, 0x01));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_LINE_LENGTH_PCK_L, 0x78));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_QVGA_WIN_EN, qvga_win_en));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_READOUT_X, 0x01));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_READOUT_Y, 0x01));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_BINNING_MODE, 0x00));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_SIX_BIT_MODE_EN, 0x70));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_BIT_CONTROL, 0x02));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_OSC_CLK_DIV, 0x01));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_GRP_PARAM_HOLD, 0x01));
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MODE_SELECT, 0x05));
  return kDifOk;
}

dif_result_t camera_hm01b0_set_test_pattern(
    camera_hm01b0_test_pattern_t pattern) {
  if (pattern == kCameraHm01b0TestPatternNone) {
    camera_hm01b0_write_reg(HM01B0_AE_CTRL, 0x01);
    camera_hm01b0_write_reg(HM01B0_BLC_CFG, 0x43);
    camera_hm01b0_write_reg(HM01B0_TEST_PATTERN_MODE, 0x00);
  } else if (pattern == kCameraHm01b0TestPatternWalkingOnes ||
             pattern == kCameraHm01b0TestPatternColorBar) {
    camera_hm01b0_write_reg(HM01B0_AE_CTRL, 0x00);
    camera_hm01b0_write_reg(HM01B0_BLC_CFG, 0x00);
    camera_hm01b0_write_reg(HM01B0_TEST_PATTERN_MODE, pattern);
  } else {
    return kDifBadArg;
  }
  return kDifOk;
}

dif_result_t camera_hm01b0_set_streaming_mode(
    camera_hm01b0_streaming_mode_t mode) {
  CHECK_DIF_OK(camera_hm01b0_write_reg(HM01B0_MODE_SELECT, mode));
  return kDifOk;
}

dif_result_t camera_hm01b0_set_frame_count(uint16_t count) {
  CHECK_DIF_OK(
      camera_hm01b0_write_reg(HM01B0_PMU_PROGRAMMABLE_FRAMECNT, count));
  return kDifOk;
}

dif_result_t camera_hm01b0_irq_init(const dif_rv_plic_t* plic,
                                    const top_matcha_plic_target_smc_t target) {
  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
      plic, kTopMatchaPlicIrqIdCamI2cFmtThreshold, kTopMatchaPlicTargetIbex0Smc,
      kDifToggleEnabled));
  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
      plic, kTopMatchaPlicIrqIdCamI2cRxThreshold, kTopMatchaPlicTargetIbex0Smc,
      kDifToggleEnabled));
  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
      plic, kTopMatchaPlicIrqIdCamI2cCmdComplete, kTopMatchaPlicTargetIbex0Smc,
      kDifToggleEnabled));
  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
      plic, kTopMatchaPlicIrqIdCamI2cFmtThreshold, kDifRvPlicMaxPriority));
  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
      plic, kTopMatchaPlicIrqIdCamI2cRxThreshold, kDifRvPlicMaxPriority));
  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
      plic, kTopMatchaPlicIrqIdCamI2cCmdComplete, kDifRvPlicMaxPriority));
  return kDifOk;
}

dif_result_t camera_hm01b0_irq_handler(dif_rv_plic_irq_id_t interrupt_id) {
  dif_i2c_irq_t i2c_irq =
      (dif_i2c_irq_t)(interrupt_id - kTopMatchaPlicIrqIdCamI2cFmtThreshold);
  CHECK_DIF_OK(dif_i2c_irq_acknowledge(&cam_i2c, i2c_irq));
  switch (i2c_irq) {
    case kDifI2cIrqFmtThreshold:
      fmt_irq_seen = true;
      break;
    case kDifI2cIrqRxThreshold:
      rx_irq_seen = true;
      break;
    case kDifI2cIrqCmdComplete:
      done_irq_seen = true;
      break;
    default:
      LOG_ERROR("Unexpected interrupt (at I2C): %d\r\n", i2c_irq);
      return kDifError;
  }
  return kDifOk;
}

static uint8_t walking_ones_next(uint8_t in) {
  uint8_t out;
  if (in == 0) {
    out = 1;
  } else {
    out = in << 1;
  }
  return out;
}

dif_result_t camera_hm01b0_validate_test_pattern(
    const uint8_t* addr, camera_hm01b0_test_pattern_t pattern,
    camera_hm01b0_resolution_t resolution) {
  if (pattern != kCameraHm01b0TestPatternWalkingOnes) {
    return kDifBadArg;
  }

  if (resolution == kCameraHm01b0Resolution324x324) {
    size_t size = 324 * 324;
    uint8_t expected = 0;
    for (size_t i = 0; i < size; ++i) {
      if (addr[i] != expected) {
        LOG_ERROR("Mismatch at %d: 0x%x != 0x%x", i, addr[i], expected);
        return kDifError;
      }
      expected = walking_ones_next(expected);
    }
    return kDifOk;
  } else if (resolution == kCameraHm01b0Resolution320x240) {
    size_t width = 320, height = 240;
    uint8_t expected = 0;
    for (size_t y = 0; y < height; ++y) {
      // In this mode, we start 2 pixels in.
      expected = walking_ones_next(expected);
      expected = walking_ones_next(expected);
      for (size_t x = 0; x < width; ++x) {
        size_t offset = (y * 320) + x;
        if (addr[offset] != expected) {
          LOG_ERROR("Mismatch at %d: 0x%x != 0x%x", offset, addr[offset], expected);
          return kDifError;
        }
        expected = walking_ones_next(expected);
      }
      // We also lose the last two pixels.
      expected = walking_ones_next(expected);
      expected = walking_ones_next(expected);
    }
    return kDifOk;
  } else {
    return kDifBadArg;
  }
}
