/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 <xc.h>
#include <os/mynewt.h>
#include <bsp/bsp.h>
#include <hal/hal_gpio.h>
#include <hal/hal_i2c.h>
#include <mcu/mips_hal.h>

#define I2CxCON(I)              (base_address[I][0x00 / 0x04])
#define I2CxCONCLR(I)           (base_address[I][0x04 / 0x04])
#define I2CxCONSET(I)           (base_address[I][0x08 / 0x04])
#define I2CxSTAT(I)             (base_address[I][0x10 / 0x04])
#define I2CxBRG(I)              (base_address[I][0x40 / 0x04])
#define I2CxTRN(I)              (base_address[I][0x50 / 0x04])
#define I2CxRCV(I)              (base_address[I][0x60 / 0x04])
#define WRITE_MODE              (0)
#define READ_MODE               (1)
#define PULSE_GOBBLER_DELAY     (104)   /* In nanoseconds */

static volatile uint32_t *base_address[I2C_CNT] = {
    (volatile uint32_t *)_I2C1_BASE_ADDRESS,
#ifdef _I2C2_BASE_ADDRESS
    (volatile uint32_t *)_I2C2_BASE_ADDRESS,
#else
    NULL,
#endif
    (volatile uint32_t *)_I2C3_BASE_ADDRESS,
    (volatile uint32_t *)_I2C4_BASE_ADDRESS,
    (volatile uint32_t *)_I2C5_BASE_ADDRESS
};

static int
send_byte(uint8_t i2c_num, uint8_t data, uint32_t deadline)
{
    I2CxTRN(i2c_num) = data;

    while (I2CxSTAT(i2c_num) & _I2C1STAT_TRSTAT_MASK) {
        if (os_time_get() > deadline) {
            return 0;
        }
    }

    if (I2CxSTAT(i2c_num) & _I2C1STAT_ACKSTAT_MASK) {   /* NACK received */
        return 0;
    }

    return 1;
}

static int
receive_byte(uint8_t i2c_num, uint8_t *data, uint8_t nak, uint32_t deadline)
{
    I2CxCONSET(i2c_num) = _I2C1CON_RCEN_MASK;

    /* Wait for some data in RX FIFO */
    while (!(I2CxSTAT(i2c_num) & _I2C1STAT_RBF_MASK)) {
        if (os_time_get() > deadline) {
            return 0;
        }
    }

    /* Send ACK/NAK */
    if (nak) {
        I2CxCONSET(i2c_num) = _I2C1CON_ACKDT_MASK;
    } else {
        I2CxCONCLR(i2c_num) = _I2C1CON_ACKDT_MASK;
    }

    I2CxCONSET(i2c_num) = _I2C1CON_ACKEN_MASK;
    while (I2CxCON(i2c_num) & _I2C1CON_ACKEN_MASK) {
        if (os_time_get() > deadline) {
            return 0;
        }
    }

    *data = I2CxRCV(i2c_num);
    return 1;
}

static int
send_address(uint8_t i2c_num, uint8_t address, uint8_t read_byte,
             uint32_t deadline)
{
    return send_byte(i2c_num, (address << 1) | (read_byte & 0x1), deadline);
}

static int
send_start(uint8_t i2c_num, uint32_t deadline)
{
    I2CxCONSET(i2c_num) = _I2C1CON_SEN_MASK;
    while (I2CxCON(i2c_num) & _I2C1CON_SEN_MASK) {
        if (os_time_get() > deadline) {
            return -1;
        }
    }

    return 0;
}

static int
send_stop(uint8_t i2c_num, uint32_t deadline)
{
    I2CxCONSET(i2c_num) = _I2C1CON_PEN_MASK;
    while (I2CxCON(i2c_num) & _I2C1CON_PEN_MASK) {
        if (os_time_get() > deadline) {
            return -1;
        }
    }

    return 0;
}

static uint32_t
hal_i2c_get_peripheral_clock(void)
{
    return SystemCoreClock / ((PB2DIV & _PB2DIV_PBDIV_MASK) + 1);
}

int
hal_i2c_init(uint8_t i2c_num, void *cfg)
{
    struct mips_i2c_cfg *config;
    uint64_t baudrate;

    if (cfg == NULL) {
        return -1;
    }

    config = (struct mips_i2c_cfg *)cfg;

    /* Configure SCL and SDA as digital output */
    if (hal_gpio_init_out(config->scl, 1) ||
        hal_gpio_init_out(config->sda, 1)) {
        return -1;
    }

    I2CxCON(i2c_num) = 0;

    /*
     * From PIC32 family reference manual,
     * Section 24. Inter-Integrated Circuit, Equation 24-1:
     *
     *               10^9
     *              -------  - PGD
     *              2*Fsck
     * baudrate = ----------------- * Pbclk - 2
     *                10^9
     */
    baudrate =
        (1000 * 1000 * 1000) / (2 * config->frequency) - PULSE_GOBBLER_DELAY;
    baudrate *= hal_i2c_get_peripheral_clock();
    baudrate /= (1000 * 1000 * 1000);
    baudrate -= 2;

    /* I2CxBRG must not be set to 0 or 1 */
    if (baudrate == 0 || baudrate == 1)
        return -2;

    I2CxBRG(i2c_num) = baudrate;
    I2CxCONSET(i2c_num) = _I2C1CON_SMEN_MASK;
    I2CxCONSET(i2c_num) = _I2C1CON_ON_MASK;

    return 0;
}

int
hal_i2c_master_write(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
                     uint32_t timeout, uint8_t last_op)
{
    uint16_t byte_sent_count = 0;
    int ret = 0;
    uint32_t deadline = os_time_get() + timeout;

    if (send_start(i2c_num, deadline)) {
        ret = -1;
        goto hal_i2c_master_write_stop;
    }

    if (send_address(i2c_num, pdata->address, WRITE_MODE, deadline) != 1) {
        ret = -1;
        goto hal_i2c_master_write_stop;
    }

    while (byte_sent_count < pdata->len) {
        if (send_byte(i2c_num, pdata->buffer[byte_sent_count],
                      deadline) != 1) {
            ret = -1;
            goto hal_i2c_master_write_stop;
        }
        ++byte_sent_count;
    }

    if (!last_op) {
        return ret;
    }

hal_i2c_master_write_stop:
    if (send_stop(i2c_num, deadline)) {
        ret = -1;
    }

    return ret;
}

int
hal_i2c_master_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
                    uint32_t timeout, uint8_t last_op)
{
    int ret = 0;
    uint16_t byte_received_count = 0;
    uint32_t deadline = os_time_get() + timeout;

    if (i2c_num >= I2C_CNT) {
        return -1;
    }

    if (send_start(i2c_num, deadline)) {
        ret = -1;
        goto hal_i2c_master_read_stop;
    }

    if (send_address(i2c_num, pdata->address, READ_MODE, deadline) != 1) {
        ret = -1;
        goto hal_i2c_master_read_stop;
    }

    while (byte_received_count < pdata->len) {
        if (receive_byte(i2c_num, &pdata->buffer[byte_received_count],
                         (byte_received_count + 1) == pdata->len,
                         deadline) != 1) {
            ret = -1;
            goto hal_i2c_master_read_stop;
        }
        ++byte_received_count;
    }

    if (!last_op) {
        return ret;
    }

hal_i2c_master_read_stop:
    if (send_stop(i2c_num, deadline)) {
        ret = -1;
    }

    return ret;
}

int
hal_i2c_master_probe(uint8_t i2c_num, uint8_t address,
                     uint32_t timeout)
{
    struct hal_i2c_master_data data;

    data.address = address;
    data.buffer = NULL;
    data.len = 0;

    return hal_i2c_master_write(i2c_num, &data, timeout, 1);
}
