/*
* The MIT License (MIT)
*
* Copyright (c) 2015 David Ogilvy (MetalPhreak)
* Modified 2016 by Radomir Dopieralski
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include "hspi.h"

/*
Wrapper to setup HSPI/SPI GPIO pins and default SPI clock
    spi_no - SPI (0) or HSPI (1)
Not used in MicroPython.
*/
void spi_init(uint8_t spi_no) {
    spi_init_gpio(spi_no, SPI_CLK_USE_DIV);
    spi_clock(spi_no, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
    spi_tx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);
    spi_rx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);

    SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP | SPI_CS_HOLD);
    CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);
}


/*
Configures SPI mode parameters for clock edge and clock polarity.
    spi_no - SPI (0) or HSPI (1)
    spi_cpha - (0) Data is valid on clock leading edge
               (1) Data is valid on clock trailing edge
    spi_cpol - (0) Clock is low when inactive
               (1) Clock is high when inactive
For MicroPython this version is different from original.
*/
void spi_mode(uint8_t spi_no, uint8_t spi_cpha, uint8_t spi_cpol) {
    if (spi_cpol) {
        SET_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
    } else {
        CLEAR_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
    }
    if (spi_cpha == spi_cpol) {
        // Mode 3 - MOSI is set on falling edge of clock
        // Mode 0 - MOSI is set on falling edge of clock
        CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
        SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
    } else {
        // Mode 2 - MOSI is set on rising edge of clock
        // Mode 1 - MOSI is set on rising edge of clock
        SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
        CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
    }
}


/*
Initialise the GPIO pins for use as SPI pins.
    spi_no - SPI (0) or HSPI (1)
    sysclk_as_spiclk -
        SPI_CLK_80MHZ_NODIV (1) if using 80MHz for SPI clock.
        SPI_CLK_USE_DIV     (0) if using divider for lower speed.
*/
void spi_init_gpio(uint8_t spi_no, uint8_t sysclk_as_spiclk) {
    uint32_t clock_div_flag = 0;
    if (sysclk_as_spiclk) {
        clock_div_flag = 0x0001;
    }
    if (spi_no == SPI) {
        // Set bit 8 if 80MHz sysclock required
        WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div_flag << 8));
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);
    } else if (spi_no == HSPI) {
        // Set bit 9 if 80MHz sysclock required
        WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag << 9));
        // GPIO12 is HSPI MISO pin (Master Data In)
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);
        // GPIO13 is HSPI MOSI pin (Master Data Out)
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);
        // GPIO14 is HSPI CLK pin (Clock)
        PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
        // GPIO15 is HSPI CS pin (Chip Select / Slave Select)
        // In MicroPython, we are handling CS ourself in drivers.
        // PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);
    }
}


/*
Set up the control registers for the SPI clock
    spi_no - SPI (0) or HSPI (1)
    prediv - predivider value (actual division value)
    cntdiv - postdivider value (actual division value)
Set either divider to 0 to disable all division (80MHz sysclock)
*/
void spi_clock(uint8_t spi_no, uint16_t prediv, uint8_t cntdiv) {
    if (prediv == 0 || cntdiv == 0) {
        WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK);
    } else {
        WRITE_PERI_REG(SPI_CLOCK(spi_no),
            (((prediv - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
            (((cntdiv - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
            (((cntdiv >> 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
            ((0 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)
            );
    }
}


/*
Setup the byte order for shifting data out of buffer
    spi_no - SPI (0) or HSPI (1)
    byte_order -
        SPI_BYTE_ORDER_HIGH_TO_LOW (1)
            Data is sent out starting with Bit31 and down to Bit0
        SPI_BYTE_ORDER_LOW_TO_HIGH (0)
            Data is sent out starting with the lowest BYTE, from MSB to LSB,
            followed by the second lowest BYTE, from MSB to LSB, followed by
            the second highest BYTE, from MSB to LSB, followed by the highest
            BYTE, from MSB to LSB 0xABCDEFGH would be sent as 0xGHEFCDAB.
*/
void spi_tx_byte_order(uint8_t spi_no, uint8_t byte_order) {
    if (byte_order) {
        SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
    } else {
        CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
    }
}


/*
Setup the byte order for shifting data into buffer
    spi_no - SPI (0) or HSPI (1)
    byte_order -
        SPI_BYTE_ORDER_HIGH_TO_LOW (1)
            Data is read in starting with Bit31 and down to Bit0
        SPI_BYTE_ORDER_LOW_TO_HIGH (0)
            Data is read in starting with the lowest BYTE, from MSB to LSB,
            followed by the second lowest BYTE, from MSB to LSB, followed by
            the second highest BYTE, from MSB to LSB, followed by the highest
            BYTE, from MSB to LSB 0xABCDEFGH would be read as 0xGHEFCDAB
*/
void spi_rx_byte_order(uint8_t spi_no, uint8_t byte_order) {
    if (byte_order) {
        SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
    } else {
        CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
    }
}


/*
SPI transaction function
    spi_no - SPI (0) or HSPI (1)
    cmd_bits - actual number of bits to transmit
    cmd_data - command data
    addr_bits - actual number of bits to transmit
    addr_data - address data
    dout_bits - actual number of bits to transmit
    dout_data - output data
    din_bits - actual number of bits to receive
Returns: read data - uint32_t containing read in data only if RX was set
    0 - something went wrong (or actual read data was 0)
    1 - data sent ok (or actual read data is 1)
Note: all data is assumed to be stored in the lower bits of the data variables
(for anything <32 bits).
*/
uint32_t spi_transaction(uint8_t spi_no, uint8_t cmd_bits, uint16_t cmd_data,
    uint32_t addr_bits, uint32_t addr_data,
    uint32_t dout_bits, uint32_t dout_data,
    uint32_t din_bits, uint32_t dummy_bits) {
    while (spi_busy(spi_no)) {
    }
    ;                             // Wait for SPI to be ready

// Enable SPI Functions
    // Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
    CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
        SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);

    // Enable functions based on number of bits. 0 bits = disabled.
    // This is rather inefficient but allows for a very generic function.
    // CMD ADDR and MOSI are set below to save on an extra if statement.
    if (din_bits) {
        if (dout_bits) {
            SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN);
        } else {
            SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
        }
    }
    if (dummy_bits) {
        SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_DUMMY);
    }

// Setup Bitlengths
    WRITE_PERI_REG(SPI_USER1(spi_no),
        // Number of bits in Address
        ((addr_bits - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S |
            // Number of bits to Send
                ((dout_bits - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
            // Number of bits to receive
                ((din_bits - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S |
            // Number of Dummy bits to insert
                ((dummy_bits - 1) & SPI_USR_DUMMY_CYCLELEN) << SPI_USR_DUMMY_CYCLELEN_S);

// Setup Command Data
    if (cmd_bits) {
        // Enable COMMAND function in SPI module
        SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_COMMAND);
        // Align command data to high bits
        uint16_t command = cmd_data << (16 - cmd_bits);
        // Swap byte order
        command = ((command >> 8) & 0xff) | ((command << 8) & 0xff00);
        WRITE_PERI_REG(SPI_USER2(spi_no), (
            (((cmd_bits - 1) & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) |
            (command & SPI_USR_COMMAND_VALUE)
            ));
    }

// Setup Address Data
    if (addr_bits) {
        // Enable ADDRess function in SPI module
        SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_ADDR);
        // Align address data to high bits
        WRITE_PERI_REG(SPI_ADDR(spi_no), addr_data << (32 - addr_bits));
    }

// Setup DOUT data
    if (dout_bits) {
        // Enable MOSI function in SPI module
        SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
        // Copy data to W0
        if (READ_PERI_REG(SPI_USER(spi_no)) & SPI_WR_BYTE_ORDER) {
            WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - dout_bits));
        } else {
            uint8_t dout_extra_bits = dout_bits % 8;

            if (dout_extra_bits) {
                // If your data isn't a byte multiple (8/16/24/32 bits) and you
                // don't have SPI_WR_BYTE_ORDER set, you need this to move the
                // non-8bit remainder to the MSBs. Not sure if there's even a use
                // case for this, but it's here if you need it... For example,
                // 0xDA4 12 bits without SPI_WR_BYTE_ORDER would usually be output
                // as if it were 0x0DA4, of which 0xA4, and then 0x0 would be
                // shifted out (first 8 bits of low byte, then 4 MSB bits of high
                // byte - ie reverse byte order).
                // The code below shifts it out as 0xA4 followed by 0xD as you
                // might require.
                WRITE_PERI_REG(SPI_W0(spi_no), (
                    (0xFFFFFFFF << (dout_bits - dout_extra_bits) & dout_data)
                        << (8 - dout_extra_bits) |
                            ((0xFFFFFFFF >> (32 - (dout_bits - dout_extra_bits)))
                        & dout_data)
                    ));
            } else {
                WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
            }
        }
    }

// Begin SPI Transaction
    SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);

// Return DIN data
    if (din_bits) {
        while (spi_busy(spi_no)) {
        }
        ;                            // Wait for SPI transaction to complete
        if (READ_PERI_REG(SPI_USER(spi_no)) & SPI_RD_BYTE_ORDER) {
            // Assuming data in is written to MSB. TBC
            return READ_PERI_REG(SPI_W0(spi_no)) >> (32 - din_bits);
        } else {
            // Read in the same way as DOUT is sent. Note existing contents of
            // SPI_W0 remain unless overwritten!
            return READ_PERI_REG(SPI_W0(spi_no));
        }
        return 0; // Something went wrong
    }

    // Transaction completed
    return 1; // Success
}


/*
Just do minimal work needed to send 8 bits.
*/
inline void spi_tx8fast(uint8_t spi_no, uint8_t dout_data) {
    while (spi_busy(spi_no)) {
    }
    ;                             // Wait for SPI to be ready

// Enable SPI Functions
    // Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
    CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
        SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);

// Setup Bitlengths
    WRITE_PERI_REG(SPI_USER1(spi_no),
        // Number of bits to Send
        ((8 - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
            // Number of bits to receive
                ((8 - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S);


// Setup DOUT data
    // Enable MOSI function in SPI module
    SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
    // Copy data to W0
    if (READ_PERI_REG(SPI_USER(spi_no)) & SPI_WR_BYTE_ORDER) {
        WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - 8));
    } else {
        WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
    }

// Begin SPI Transaction
    SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
}
