// Copyright 2022 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
//
//     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.

// Generated register constants for spi_host.

// This file is licensed under either of:
//   Apache License, Version 2.0 (LICENSE-APACHE <http://www.apache.org/licenses/LICENSE-2.0>)
//   MIT License (LICENSE-MIT <http://opensource.org/licenses/MIT>)

// Build date: 2023-02-06T23:02:43.552609

// Original reference file: ./hw/opentitan-upstream/hw/ip/spi_host/data/spi_host.hjson
use kernel::common::registers::{
    register_bitfields, register_structs, ReadOnly, ReadWrite, WriteOnly
};
use core::cell::Cell;
use kernel::common::cells::{TakeCell, OptionalCell};
use kernel::common::StaticRef;
use kernel::hil::spi::SpiMasterClient;

// The number of active-low chip select (cs_n) lines to create.
pub const SPI_HOST_PARAM_NUM_C_S: u32 = 1;
// The size of the Tx FIFO (in words)
pub const SPI_HOST_PARAM_TX_DEPTH: u32 = 72;
// The size of the Rx FIFO (in words)
pub const SPI_HOST_PARAM_RX_DEPTH: u32 = 64;
// The size of the Cmd FIFO (one segment descriptor per entry)
pub const SPI_HOST_PARAM_CMD_DEPTH: u32 = 4;
// Number of alerts
pub const SPI_HOST_PARAM_NUM_ALERTS: u32 = 1;
// Register width
pub const SPI_HOST_PARAM_REG_WIDTH: u32 = 32;

pub const SPI_HOST0_REGISTERS: StaticRef<SpiHostRegisters> =
    unsafe { StaticRef::new(matcha_config::SPI_HOST0_BASE_ADDRESS as *const SpiHostRegisters) };
pub const SPI_HOST0_REGISTERS8: StaticRef<SpiHostRegisters8> =
    unsafe { StaticRef::new(matcha_config::SPI_HOST0_BASE_ADDRESS as *const SpiHostRegisters8) };
pub static mut SPI_HOST0: SpiHw = SpiHw::new(SPI_HOST0_REGISTERS, SPI_HOST0_REGISTERS8 /*, matcha_config::CHIP_PERIPH_FREQ*/);

register_structs! {
    pub SpiHostRegisters {
        // Interrupt State Register
        (0x0000 => pub(crate) intr_state: ReadWrite<u32, INTR::Register>),
        // Interrupt Enable Register
        (0x0004 => pub(crate) intr_enable: ReadWrite<u32, INTR::Register>),
        // Interrupt Test Register
        (0x0008 => pub(crate) intr_test: ReadWrite<u32, INTR::Register>),
        // Alert Test Register
        (0x000c => pub(crate) alert_test: ReadWrite<u32, ALERT_TEST::Register>),
        // Control register
        (0x0010 => pub(crate) control: ReadWrite<u32, CONTROL::Register>),
        // Status register
        (0x0014 => pub(crate) status: ReadWrite<u32, STATUS::Register>),
        // Configuration options register.
        (0x0018 => pub(crate) configop: [ReadWrite<u32, CONFIGOP::Register>; 1]),
        // Chip-Select ID
        (0x001c => pub(crate) csid: ReadWrite<u32, CSID::Register>),
        // Command Register
        (0x0020 => pub(crate) command: ReadWrite<u32, COMMAND::Register>),
        // Memory area: SPI Receive Data.
        (0x0024 => pub(crate) rxdata: [ReadOnly<u32>; 1]),
        // Memory area: SPI Transmit Data.
        (0x0028 => pub(crate) txdata: [WriteOnly<u32>; 1]),
        // Controls which classes of errors raise an interrupt.
        (0x002c => pub(crate) error_enable: ReadWrite<u32, ERROR_ENABLE::Register>),
        // Indicates that any errors that have occurred.
        (0x0030 => pub(crate) error_status: ReadWrite<u32, ERROR_STATUS::Register>),
        // Controls which classes of SPI events raise an interrupt.
        (0x0034 => pub(crate) event_enable: ReadWrite<u32, EVENT_ENABLE::Register>),
        (0x0038 => @END),
    }
}

register_structs! {
    pub SpiHostRegisters8 {
        // Interrupt State Register
        (0x0000 => pub(crate) intr_state: ReadWrite<u32, INTR::Register>),
        // Interrupt Enable Register
        (0x0004 => pub(crate) intr_enable: ReadWrite<u32, INTR::Register>),
        // Interrupt Test Register
        (0x0008 => pub(crate) intr_test: ReadWrite<u32, INTR::Register>),
        // Alert Test Register
        (0x000c => pub(crate) alert_test: ReadWrite<u32, ALERT_TEST::Register>),
        // Control register
        (0x0010 => pub(crate) control: ReadWrite<u32, CONTROL::Register>),
        // Status register
        (0x0014 => pub(crate) status: ReadWrite<u32, STATUS::Register>),
        // Configuration options register.
        (0x0018 => pub(crate) configop: [ReadWrite<u32, CONFIGOP::Register>; 1]),
        // Chip-Select ID
        (0x001c => pub(crate) csid: ReadWrite<u32, CSID::Register>),
        // Command Register
        (0x0020 => pub(crate) command: ReadWrite<u32, COMMAND::Register>),
        // Memory area: SPI Receive Data.
        (0x0024 => pub(crate) rxdata: [ReadOnly<u32>; 1]),
        // Memory area: SPI Transmit Data.
        (0x0028 => pub(crate) txdata: [WriteOnly<u8>; 1]),
        // Controls which classes of errors raise an interrupt.
        (0x002c => pub(crate) error_enable: ReadWrite<u32, ERROR_ENABLE::Register>),
        // Indicates that any errors that have occurred.
        (0x0030 => pub(crate) error_status: ReadWrite<u32, ERROR_STATUS::Register>),
        // Controls which classes of SPI events raise an interrupt.
        (0x0034 => pub(crate) event_enable: ReadWrite<u32, EVENT_ENABLE::Register>),
        (0x0038 => @END),
    }
}

register_bitfields![u32,
    // Common Interrupt Offsets
    pub(crate) INTR [
        ERROR OFFSET(0) NUMBITS(1) [],
        SPI_EVENT OFFSET(1) NUMBITS(1) []
    ],
    pub(crate) ALERT_TEST [
        FATAL_FAULT OFFSET(0) NUMBITS(1) []
    ],
    pub(crate) CONTROL [
        RX_WATERMARK OFFSET(0) NUMBITS(8) [],
        TX_WATERMARK OFFSET(8) NUMBITS(8) [],
        OUTPUT_EN OFFSET(29) NUMBITS(1) [],
        SW_RST OFFSET(30) NUMBITS(1) [],
        SPIEN OFFSET(31) NUMBITS(1) []
    ],
    pub(crate) STATUS [
        TXQD OFFSET(0) NUMBITS(8) [],
        RXQD OFFSET(8) NUMBITS(8) [],
        CMDQD OFFSET(16) NUMBITS(4) [],
        RXWM OFFSET(20) NUMBITS(1) [],
        BYTEORDER OFFSET(22) NUMBITS(1) [],
        RXSTALL OFFSET(23) NUMBITS(1) [],
        RXEMPTY OFFSET(24) NUMBITS(1) [],
        RXFULL OFFSET(25) NUMBITS(1) [],
        TXWM OFFSET(26) NUMBITS(1) [],
        TXSTALL OFFSET(27) NUMBITS(1) [],
        TXEMPTY OFFSET(28) NUMBITS(1) [],
        TXFULL OFFSET(29) NUMBITS(1) [],
        ACTIVE OFFSET(30) NUMBITS(1) [],
        READY OFFSET(31) NUMBITS(1) []
    ],
    pub(crate) CONFIGOP [
        CLKDIV_0 OFFSET(0) NUMBITS(16) [],
        CSNIDLE_0 OFFSET(16) NUMBITS(4) [],
        CSNTRAIL_0 OFFSET(20) NUMBITS(4) [],
        CSNLEAD_0 OFFSET(24) NUMBITS(4) [],
        FULLCYC_0 OFFSET(29) NUMBITS(1) [],
        CPHA_0 OFFSET(30) NUMBITS(1) [],
        CPOL_0 OFFSET(31) NUMBITS(1) []
    ],
    pub(crate) CSID [
        CSID OFFSET(0) NUMBITS(32) []
    ],
    pub(crate) COMMAND [
        LEN OFFSET(0) NUMBITS(9) [],
        CSAAT OFFSET(9) NUMBITS(1) [],
        SPEED OFFSET(10) NUMBITS(2) [],
        DIRECTION OFFSET(12) NUMBITS(2) []
    ],
    pub(crate) ERROR_ENABLE [
        CMDBUSY OFFSET(0) NUMBITS(1) [],
        OVERFLOW OFFSET(1) NUMBITS(1) [],
        UNDERFLOW OFFSET(2) NUMBITS(1) [],
        CMDINVAL OFFSET(3) NUMBITS(1) [],
        CSIDINVAL OFFSET(4) NUMBITS(1) []
    ],
    pub(crate) ERROR_STATUS [
        CMDBUSY OFFSET(0) NUMBITS(1) [],
        OVERFLOW OFFSET(1) NUMBITS(1) [],
        UNDERFLOW OFFSET(2) NUMBITS(1) [],
        CMDINVAL OFFSET(3) NUMBITS(1) [],
        CSIDINVAL OFFSET(4) NUMBITS(1) [],
        ACCESSINVAL OFFSET(5) NUMBITS(1) []
    ],
    pub(crate) EVENT_ENABLE [
        RXFULL OFFSET(0) NUMBITS(1) [],
        TXEMPTY OFFSET(1) NUMBITS(1) [],
        RXWM OFFSET(2) NUMBITS(1) [],
        TXWM OFFSET(3) NUMBITS(1) [],
        READY OFFSET(4) NUMBITS(1) [],
        IDLE OFFSET(5) NUMBITS(1) []
    ]
];

// End generated register constants for spi_host

pub struct SpiHw {
    registers: StaticRef<SpiHostRegisters>,
    registers8: StaticRef<SpiHostRegisters8>,
    client: OptionalCell<&'static dyn SpiMasterClient>,
    chip_select: OptionalCell<u32>,
    tx_buf: TakeCell<'static, [u8]>,
    rx_buf: TakeCell<'static, [u8]>,
    transfer_len: Cell<usize>,
    busy: Cell<bool>,
    hold_low: Cell<bool>,
}

impl SpiHw {
    pub const fn new(base: StaticRef<SpiHostRegisters>, base8: StaticRef<SpiHostRegisters8>) -> SpiHw {
        SpiHw {
            registers: base,
            registers8: base8,
            client: OptionalCell::empty(),
            chip_select: OptionalCell::empty(),
            tx_buf: TakeCell::empty(),
            rx_buf: TakeCell::empty(),
            transfer_len: Cell::new(0),
            busy: Cell::new(false),
            hold_low: Cell::new(false),
        }
    }

    pub fn handle_interrupt(&self) {
        // dprintf!("intr_state: {:?}\r\n", self.registers.intr_state.get());
        // dprintf!("intr_enable: {:?}\r\n", self.registers.intr_enable.get());
        // Cache interrupt state, and clear the register.
        let intr_state = self.registers.intr_state.extract();
        self.registers.intr_state.set(intr_state.get());

        if intr_state.is_set(INTR::SPI_EVENT) {
            // For now, only event enabled is IDLE.
            self.client.map(|client| match self.tx_buf.take() {
                None => (),
                Some(tx_buf) => {
                    self.busy.set(false);
                    client.read_write_done(tx_buf, self.rx_buf.take(), self.transfer_len.take());
                }
            });
        }
    }

    fn reset(&self) {
        self.registers.control.modify(CONTROL::SW_RST::SET);
        let mut active: bool;
        loop {
            active = self.registers.status.is_set(STATUS::ACTIVE);
            if !active {
                break;
            }
        }
        let mut txqd: bool;
        let mut rxqd: bool;
        loop {
            let reg = self.registers.status.extract();
            txqd = reg.is_set(STATUS::TXQD);
            rxqd = reg.is_set(STATUS::RXQD);
            if !txqd && !rxqd {
                break;
            }
        }
        self.registers.control.modify(CONTROL::SW_RST::CLEAR);
    }

    fn enable(&self, enable: bool) {
        if enable {
            self.registers.control.modify(CONTROL::SPIEN::SET);
        } else {
            self.registers.control.modify(CONTROL::SPIEN::CLEAR);
        }
    }

    fn rx_fifo_wait(&self) {
        loop {
            let rxqd = self.registers.status.read(STATUS::RXQD);
            if rxqd != 0 {
                break;
            }
        }
    }

    fn rx_fifo_read32(&self) -> u32 {
        self.registers.rxdata[0].get()
    }

    fn tx_fifo_wait(&self) {
        loop {
            let txqd = self.registers.status.read(STATUS::TXQD);
            if txqd != SPI_HOST_PARAM_TX_DEPTH {
                break;
            }
        }
    }

    fn tx_fifo_write8(&self, val: u8) {
        self.tx_fifo_wait();
        self.registers8.txdata[0].set(val);
    }
    
    fn tx_fifo_write32(&self, val: u32) {
        self.tx_fifo_wait();
        self.registers.txdata[0].set(val);
    }

    fn fifo_write(&self, buf: &[u8], len: usize) {
        // dprintf!("start writing fifo {:?}\r\n", len);
        let single_write_count = len % 4;
        // for i in 0..single_write_count {
        //     self.tx_fifo_write8(buf[i]);
        // }
        // for i in (single_write_count..len).step_by(4) {
        //     let val: u32 = u32::from_le_bytes([buf[i], buf[i+1], buf[i+2], buf[i+3]]);
        //     self.tx_fifo_write32(val);
        // }
        for i in (0..len-single_write_count).step_by(4) {
            let val: u32 = u32::from_le_bytes([buf[i], buf[i+1], buf[i+2], buf[i+3]]);
            self.tx_fifo_write32(val);
            if len == 5 {
                // dprintf!("write32 {} {}\r\n", i, val);
            }
        }
        for i in len-single_write_count..len {
            if len == 5 {
                // dprintf!("write8 {} {}\r\n", i, buf[i]);
            }
            self.tx_fifo_write8(buf[i]);
        }
        // dprintf!("done writing fifo\r\n");
    }

    fn fifo_read(&self, buf: &mut [u8], len: usize) {
        for i in 0..(len / 4) {
            self.rx_fifo_wait();
            let val = self.rx_fifo_read32();
            buf[i*4] = (val & 0xFF) as u8;
            buf[(i*4)+1] = ((val >> 8) & 0xFF) as u8;
            buf[(i*4)+2] = ((val >> 16) & 0xFF) as u8;
            buf[(i*4)+3] = ((val >> 24) & 0xFF) as u8;
        }
        if (len % 4) != 0 {
            self.rx_fifo_wait();
            self.rx_fifo_read32();
        }
    }

    fn write_command_reg(&self, len: usize, bidir: bool) {
        self.registers.command.modify(
            COMMAND::LEN.val((len - 1) as u32) +
            COMMAND::SPEED::CLEAR +
            (if bidir { COMMAND::DIRECTION.val(3) } else { COMMAND::DIRECTION.val(2) }) +
            (if self.hold_low.get() { COMMAND::CSAAT::SET } else { COMMAND::CSAAT::CLEAR })
        );
    }
}

impl kernel::hil::spi::SpiMaster for SpiHw {
    type ChipSelect = u32;
    fn set_client(&self, client: &'static (dyn kernel::hil::spi::SpiMasterClient + 'static)) { 
        self.client.set(client); 
    }
    fn init(&self) {
        let peripheral_clock_freq_hz = 2_500_000;
        let spi_clock = 2_500_000;
        let divider = peripheral_clock_freq_hz / spi_clock;
        self.reset();
        // TODO(atv): Many elided settings from the original init,
        // since we leave them as zero.
        self.registers.configop[0].modify(CONFIGOP::CLKDIV_0.val(divider));
        self.enable(true);
        self.registers.control.modify(CONTROL::OUTPUT_EN::SET);
        self.registers.intr_enable.modify(INTR::SPI_EVENT::SET);
        self.registers.event_enable.modify(EVENT_ENABLE::IDLE::SET);
    }
    fn is_busy(&self) -> bool { todo!() }
    fn read_write_bytes(&self,
        write_buffer: &'static mut [u8],
        read_buffer: core::option::Option<&'static mut [u8]>,
        len: usize) -> kernel::ReturnCode {
        self.chip_select.map(|cs| {
            self.registers.csid.set(*cs);
        });
        self.tx_buf.replace(write_buffer);
        self.tx_buf.map(|write_buffer| {
            self.fifo_write(write_buffer, len);
        });
        match read_buffer {
            Some(read_buffer) => {
                self.rx_buf.put(Some(read_buffer));
                self.busy.set(true);
                self.write_command_reg(len, true);
                self.rx_buf.map(|read_buffer| {
                    self.fifo_read(read_buffer, len);
                });
            },
            None => {
                self.rx_buf.put(None);
                self.busy.set(true);
                self.write_command_reg(len, false);
            }
        };
        self.transfer_len.set(len);
        // dprintf!("SpiHostHal::read_write_bytes ok\r\n");
        kernel::ReturnCode::SUCCESS
    }
    fn write_byte(&self, _: u8) { todo!() }
    fn read_byte(&self) -> u8 { todo!() }
    fn read_write_byte(&self, _: u8) -> u8 { todo!() }
    fn specify_chip_select(&self, chip_select: <Self as kernel::hil::spi::SpiMaster>::ChipSelect) {
        self.chip_select.set(chip_select);
    }
    fn set_rate(&self, _: u32) -> u32 { todo!() }
    fn get_rate(&self) -> u32 { todo!() }
    fn set_clock(&self, _: kernel::hil::spi::ClockPolarity) { todo!() }
    fn get_clock(&self) -> kernel::hil::spi::ClockPolarity { todo!() }
    fn set_phase(&self, _: kernel::hil::spi::ClockPhase) { todo!() }
    fn get_phase(&self) -> kernel::hil::spi::ClockPhase { todo!() }
    fn hold_low(&self) { self.hold_low.set(true); }
    fn release_low(&self) { self.hold_low.set(false); }
}
