/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * 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 <errno.h>
#include <stdint.h>
#include <string.h>

#include <gpio.h>
#include <i2c.h>
#include <seos.h>
#include <util.h>
#include <gpio.h>
#include <atomicBitset.h>
#include <atomic.h>
#include <platform.h>

#include <plat/inc/cmsis.h>
#include <plat/inc/dma.h>
#include <plat/inc/gpio.h>
#include <plat/inc/i2c.h>
#include <plat/inc/pwr.h>
#include <plat/inc/plat.h>

#include <cpu/inc/barrier.h>

#define I2C_VERBOSE_DEBUG       0
#define I2C_MAX_QUEUE_DEPTH     5

#if I2C_VERBOSE_DEBUG
#define i2c_log_debug(x) osLog(LOG_DEBUG, x "\n")
#else
#define i2c_log_debug(x) do {} while(0)
#endif

#define I2C_CR1_PE          (1 << 0)
#define I2C_CR1_SMBUS       (1 << 1)
#define I2C_CR1_SMBTYPE     (1 << 3)
#define I2C_CR1_ENARP       (1 << 4)
#define I2C_CR1_ENPEC       (1 << 5)
#define I2C_CR1_ENGC        (1 << 6)
#define I2C_CR1_NOSTRETCH   (1 << 7)
#define I2C_CR1_START       (1 << 8)
#define I2C_CR1_STOP        (1 << 9)
#define I2C_CR1_ACK         (1 << 10)
#define I2C_CR1_POS         (1 << 11)
#define I2C_CR1_PEC         (1 << 12)
#define I2C_CR1_ALERT       (1 << 13)
#define I2C_CR1_SWRST       (1 << 15)

#define I2C_CR2_FREQ(x)     ((x) & I2C_CR2_FREQ_MASK)
#define I2C_CR2_FREQ_MASK   0x3F
#define I2C_CR2_ITERREN     (1 << 8)
#define I2C_CR2_ITEVTEN     (1 << 9)
#define I2C_CR2_ITBUFEN     (1 << 10)
#define I2C_CR2_DMAEN       (1 << 11)
#define I2C_CR2_LAST        (1 << 12)

#define I2C_OAR1_ADD7(x)    (((x) & I2C_OAR1_ADD7_MASK) << 1)
#define I2C_OAR1_ADD7_MASK  0x7F
#define I2C_OAR1_ADD10(x)   ((x) & I2C_OAR1_ADD10_MASK)
#define I2C_OAR1_ADD10_MASK 0x3FF
#define I2C_OAR1_ADDMODE    (1 << 15)

#define I2C_SR1_SB          (1 << 0)
#define I2C_SR1_ADDR        (1 << 1)
#define I2C_SR1_BTF         (1 << 2)
#define I2C_SR1_ADD10       (1 << 3)
#define I2C_SR1_STOPF       (1 << 4)
#define I2C_SR1_RXNE        (1 << 6)
#define I2C_SR1_TXE         (1 << 7)
#define I2C_SR1_BERR        (1 << 8)
#define I2C_SR1_ARLO        (1 << 9)
#define I2C_SR1_AF          (1 << 10)
#define I2C_SR1_OVR         (1 << 11)
#define I2C_SR1_PECERR      (1 << 12)
#define I2C_SR1_TIMEOUT     (1 << 14)
#define I2C_SR1_SMBALERT    (1 << 15)

#define I2C_SR2_MSL         (1 << 0)
#define I2C_SR2_BUSY        (1 << 1)
#define I2C_SR2_TRA         (1 << 2)
#define I2C_SR2_GENCALL     (1 << 4)
#define I2C_SR2_SMBDEFAULT  (1 << 5)
#define I2C_SR2_SMBHOST     (1 << 6)
#define I2C_SR2_DUALF       (1 << 7)

#define I2C_CCR(x)          ((x) & I2C_CCR_MASK)
#define I2C_CCR_MASK        0xFFF
#define I2C_CCR_DUTY_16_9   (1 << 14)
#define I2C_CCR_FM          (1 << 15)

#define I2C_TRISE(x)        ((x) & I2C_TRISE_MASK)
#define I2C_TRISE_MASK      0x3F

struct StmI2c {
    volatile uint32_t CR1;
    volatile uint32_t CR2;
    volatile uint32_t OAR1;
    volatile uint32_t OAR2;
    volatile uint32_t DR;
    volatile uint32_t SR1;
    volatile uint32_t SR2;
    volatile uint32_t CCR;
    volatile uint32_t TRISE;
    volatile uint32_t FLTR;
};

enum StmI2cSpiMasterState
{
    STM_I2C_MASTER_IDLE,
    STM_I2C_MASTER_START,
    STM_I2C_MASTER_TX_ADDR,
    STM_I2C_MASTER_TX_DATA,
    STM_I2C_MASTER_RX_ADDR,
    STM_I2C_MASTER_RX_DATA,
};

struct I2cStmState {
    struct {
        union {
            uint8_t *buf;
            const uint8_t *cbuf;
            uint8_t byte;
        };
        size_t size;
        size_t offset;
        bool preamble;

        I2cCallbackF callback;
        void *cookie;
    } rx, tx;

    enum {
        STM_I2C_DISABLED,
        STM_I2C_SLAVE,
        STM_I2C_MASTER,
    } mode;

    enum {
        STM_I2C_SLAVE_IDLE,
        STM_I2C_SLAVE_RX_ARMED,
        STM_I2C_SLAVE_RX,
        STM_I2C_SLAVE_TX_ARMED,
        STM_I2C_SLAVE_TX,
    } slaveState;

    // StmI2cSpiMasterState
    uint8_t masterState;
    uint16_t tid;
};

struct StmI2cCfg {
    struct StmI2c *regs;

    uint32_t clock;

    IRQn_Type irqEv;
    IRQn_Type irqEr;
};

struct StmI2cDev {
    const struct StmI2cCfg *cfg;
    const struct StmI2cBoardCfg *board;
    struct I2cStmState state;

    uint32_t next;
    uint32_t last;

    struct Gpio *scl;
    struct Gpio *sda;

    uint8_t addr;
};

static const struct StmI2cCfg mStmI2cCfgs[] = {
    [0] = {
        .regs = (struct StmI2c *)I2C1_BASE,

        .clock = PERIPH_APB1_I2C1,

        .irqEv = I2C1_EV_IRQn,
        .irqEr = I2C1_ER_IRQn,
    },
    [1] = {
        .regs = (struct StmI2c *)I2C2_BASE,

        .clock = PERIPH_APB1_I2C2,

        .irqEv = I2C2_EV_IRQn,
        .irqEr = I2C2_ER_IRQn,
    },
    [2] = {
        .regs = (struct StmI2c *)I2C3_BASE,

        .clock = PERIPH_APB1_I2C3,

        .irqEv = I2C3_EV_IRQn,
        .irqEr = I2C3_ER_IRQn,
    },
};

static struct StmI2cDev mStmI2cDevs[ARRAY_SIZE(mStmI2cCfgs)];

struct StmI2cXfer
{
    uint32_t        id;
    const void     *txBuf;
    size_t          txSize;
    void           *rxBuf;
    size_t          rxSize;
    I2cCallbackF    callback;
    void           *cookie;
    uint8_t         busId; /* for us these are both fine in a uint 8 */
    uint8_t         addr;
};

ATOMIC_BITSET_DECL(mXfersValid, I2C_MAX_QUEUE_DEPTH, static);
static struct StmI2cXfer mXfers[I2C_MAX_QUEUE_DEPTH] = { };

static inline struct StmI2cXfer *stmI2cGetXfer(void)
{
    int32_t idx = atomicBitsetFindClearAndSet(mXfersValid);

    if (idx < 0)
        return NULL;
    else
        return mXfers + idx;
}

static inline void stmI2cPutXfer(struct StmI2cXfer *xfer)
{
    if (xfer)
        atomicBitsetClearBit(mXfersValid, xfer - mXfers);
}

static inline void stmI2cAckEnable(struct StmI2cDev *pdev)
{
    pdev->cfg->regs->CR1 |= I2C_CR1_ACK;
}

static inline void stmI2cAckDisable(struct StmI2cDev *pdev)
{
    pdev->cfg->regs->CR1 &= ~I2C_CR1_ACK;
}

static inline void stmI2cDmaEnable(struct StmI2cDev *pdev)
{
    pdev->cfg->regs->CR2 |= I2C_CR2_DMAEN;
}

static inline void stmI2cDmaDisable(struct StmI2cDev *pdev)
{
    pdev->cfg->regs->CR2 &= ~I2C_CR2_DMAEN;
}

static inline void stmI2cStopEnable(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;

    while (regs->CR1 & (I2C_CR1_STOP | I2C_CR1_START))
        ;
    regs->CR1 |= I2C_CR1_STOP;
}

static inline void stmI2cStartEnable(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;

    while (regs->CR1 & (I2C_CR1_STOP | I2C_CR1_START))
        ;
    regs->CR1 |= I2C_CR1_START;
}

static inline void stmI2cIrqEnable(struct StmI2cDev *pdev,
        uint32_t mask)
{
    pdev->cfg->regs->CR2 |= mask;
}

static inline void stmI2cIrqDisable(struct StmI2cDev *pdev,
        uint32_t mask)
{
    pdev->cfg->regs->CR2 &= ~mask;
}

static inline void stmI2cEnable(struct StmI2cDev *pdev)
{
    pdev->cfg->regs->CR1 |= I2C_CR1_PE;
}

static inline void stmI2cDisable(struct StmI2cDev *pdev)
{
    pdev->cfg->regs->CR1 &= ~I2C_CR1_PE;
}

static inline void stmI2cSpeedSet(struct StmI2cDev *pdev,
        const uint32_t speed)
{
    struct StmI2c *regs = pdev->cfg->regs;
    int ccr, ccr_1, ccr_2;
    int apb1_clk;

    apb1_clk = pwrGetBusSpeed(PERIPH_BUS_APB1);

    regs->CR2 = (regs->CR2 & ~I2C_CR2_FREQ_MASK) |
                 I2C_CR2_FREQ(apb1_clk / 1000000);

    if (speed <= 100000) {
        ccr = apb1_clk / (speed * 2);
        if (ccr < 4)
            ccr = 4;
        regs->CCR = I2C_CCR(ccr);

        regs->TRISE = I2C_TRISE((apb1_clk / 1000000) + 1);
    } else if (speed <= 400000) {
        ccr_1 = apb1_clk / (speed * 3);
        if (ccr_1 == 0 || apb1_clk / (ccr_1 * 3) > speed)
            ccr_1 ++;
        ccr_2 = apb1_clk / (speed * 25);
        if (ccr_2 == 0 || apb1_clk / (ccr_2 * 25) > speed)
            ccr_2 ++;

        if ((apb1_clk / (ccr_1 * 3)) > (apb1_clk / (ccr_2 * 25)))
            regs->CCR = I2C_CCR_FM | I2C_CCR(ccr_1);
        else
            regs->CCR = I2C_CCR_FM | I2C_CCR_DUTY_16_9 | I2C_CCR(ccr_2);

        regs->TRISE = I2C_TRISE(((3*apb1_clk)/10000000) + 1);
    }
}

static inline void stmI2cSlaveIdle(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;

    state->slaveState = STM_I2C_SLAVE_RX_ARMED;
    stmI2cAckEnable(pdev);
    stmI2cIrqDisable(pdev, I2C_CR2_ITBUFEN | I2C_CR2_ITERREN);
}

static inline void stmI2cInvokeRxCallback(struct I2cStmState *state, size_t tx, size_t rx, int err)
{
    uint16_t oldTid = osSetCurrentTid(state->tid);
    state->rx.callback(state->rx.cookie, tx, rx, err);
    osSetCurrentTid(oldTid);
}

static inline void stmI2cInvokeTxCallback(struct I2cStmState *state, size_t tx, size_t rx, int err)
{
    uint16_t oldTid = osSetCurrentTid(state->tid);
    state->tx.callback(state->tx.cookie, tx, rx, err);
    osSetCurrentTid(oldTid);
}

static inline void stmI2cSlaveRxDone(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    size_t rxOffst = state->rx.offset;

    state->rx.offset = 0;
    stmI2cInvokeRxCallback(state, 0, rxOffst, 0);
}

static inline void stmI2cSlaveTxDone(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    size_t txOffst = state->tx.offset;

    stmI2cSlaveIdle(pdev);
    stmI2cInvokeTxCallback(state, txOffst, 0, 0);
}

static void stmI2cSlaveTxNextByte(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;

    if (state->tx.preamble) {
        regs->DR = state->tx.byte;
        state->tx.offset++;
    } else if (state->tx.offset < state->tx.size) {
        regs->DR = state->tx.cbuf[state->tx.offset];
        state->tx.offset++;
    } else {
        state->slaveState = STM_I2C_SLAVE_TX_ARMED;
        stmI2cIrqDisable(pdev, I2C_CR2_ITBUFEN);
        stmI2cInvokeTxCallback(state, state->tx.offset, 0, 0);
    }
}

static void stmI2cSlaveAddrMatched(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;

    i2c_log_debug("addr");

    if (state->slaveState == STM_I2C_SLAVE_RX_ARMED) {
        state->slaveState = STM_I2C_SLAVE_RX;
        stmI2cIrqEnable(pdev, I2C_CR2_ITBUFEN | I2C_CR2_ITERREN);
    } else if (state->slaveState == STM_I2C_SLAVE_TX) {
        stmI2cIrqEnable(pdev, I2C_CR2_ITBUFEN | I2C_CR2_ITERREN);
    }
    /* clear ADDR by doing a dummy reads from SR1 (already read) then SR2 */
    (void)regs->SR2;
}

static void stmI2cSlaveStopRxed(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;

    i2c_log_debug("stopf");

    (void)regs->SR1;
    stmI2cEnable(pdev);
    /* clear STOPF by doing a dummy read from SR1 and strobing the PE bit */

    stmI2cSlaveIdle(pdev);
    stmI2cSlaveRxDone(pdev);
}

static inline void stmI2cSlaveRxBufNotEmpty(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;
    uint8_t data = regs->DR;

    i2c_log_debug("rxne");

    if (state->rx.offset < state->rx.size) {
        state->rx.buf[state->rx.offset] = data;
        state->rx.offset++;
    } else {
        stmI2cAckDisable(pdev);
        /* TODO: error on overflow */
    }
}

static void stmI2cSlaveTxBufEmpty(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;

    i2c_log_debug("txe");

    if (state->slaveState == STM_I2C_SLAVE_RX) {
        state->slaveState = STM_I2C_SLAVE_TX_ARMED;
        stmI2cIrqDisable(pdev, I2C_CR2_ITBUFEN);
        stmI2cAckDisable(pdev);
        stmI2cSlaveRxDone(pdev);
        /* stmI2cTxNextByte() will happen when the task provides a
           TX buffer; the I2C controller will stretch the clock until then */
    } else {
        stmI2cSlaveTxNextByte(pdev);
    }
}

static void stmI2cSlaveNakRxed(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;

    i2c_log_debug("af");

    if (state->slaveState == STM_I2C_SLAVE_TX) {
        state->tx.offset--;
        /* NACKs seem to be preceded by a spurious TXNE, so adjust the offset to
           compensate (the corresponding byte written to DR was never actually
           transmitted) */
        stmI2cSlaveTxDone(pdev);
    }
    regs->SR1 &= ~I2C_SR1_AF;
}

static inline void stmI2cMasterTxRxDone(struct StmI2cDev *pdev, int err)
{
    struct I2cStmState *state = &pdev->state;
    size_t txOffst = state->tx.offset;
    size_t rxOffst = state->rx.offset;
    uint32_t id;
    int i;
    struct StmI2cXfer *xfer;

    if (pdev->board->sleepDev >= 0)
        platReleaseDevInSleepMode(pdev->board->sleepDev);

    state->tx.offset = 0;
    state->rx.offset = 0;
    stmI2cInvokeTxCallback(state, txOffst, rxOffst, 0);

    do {
        id = atomicAdd32bits(&pdev->next, 1);
    } while (!id);

    for (i=0; i<I2C_MAX_QUEUE_DEPTH; i++) {
        xfer = &mXfers[i];

        if (xfer->busId == (pdev - mStmI2cDevs) &&
                atomicCmpXchg32bits(&xfer->id, id, 0)) {
            pdev->addr = xfer->addr;
            state->tx.cbuf = xfer->txBuf;
            state->tx.offset = 0;
            state->tx.size = xfer->txSize;
            state->tx.callback = xfer->callback;
            state->tx.cookie = xfer->cookie;
            state->rx.buf = xfer->rxBuf;
            state->rx.offset = 0;
            state->rx.size = xfer->rxSize;
            state->rx.callback = NULL;
            state->rx.cookie = NULL;
            atomicWriteByte(&state->masterState, STM_I2C_MASTER_START);
            if (pdev->board->sleepDev >= 0)
                platRequestDevInSleepMode(pdev->board->sleepDev, 12);
            stmI2cPutXfer(xfer);
            stmI2cStartEnable(pdev);
            return;
        }
    }

    atomicWriteByte(&state->masterState, STM_I2C_MASTER_IDLE);
}

static void stmI2cMasterDmaTxDone(void *cookie, uint16_t bytesLeft, int err)
{
    struct StmI2cDev *pdev = cookie;
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;

    state->tx.offset = state->tx.size - bytesLeft;
    state->tx.size = 0;
    stmI2cDmaDisable(pdev);
    if (err == 0 && state->rx.size > 0) {
        atomicWriteByte(&state->masterState, STM_I2C_MASTER_START);
        stmI2cStartEnable(pdev);
    } else {
        while (!(regs->SR1 & I2C_SR1_BTF))
            ;

        stmI2cStopEnable(pdev);
        stmI2cMasterTxRxDone(pdev, err);
    }
}

static void stmI2cMasterDmaRxDone(void *cookie, uint16_t bytesLeft, int err)
{
    struct StmI2cDev *pdev = cookie;
    struct I2cStmState *state = &pdev->state;

    state->rx.offset = state->rx.size - bytesLeft;
    state->rx.size = 0;

    stmI2cDmaDisable(pdev);
    stmI2cStopEnable(pdev);
    stmI2cMasterTxRxDone(pdev, err);
}

static inline void stmI2cMasterDmaCancel(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;

    dmaStop(I2C_DMA_BUS, pdev->board->dmaRx.stream);
    state->rx.offset = state->rx.size - dmaBytesLeft(I2C_DMA_BUS,
            pdev->board->dmaRx.stream);
    dmaStop(I2C_DMA_BUS, pdev->board->dmaTx.stream);
    state->tx.offset = state->tx.size - dmaBytesLeft(I2C_DMA_BUS,
            pdev->board->dmaTx.stream);

    stmI2cDmaDisable(pdev);
}

static inline void stmI2cMasterStartDma(struct StmI2cDev *pdev,
        const struct StmI2cDmaCfg *dmaCfg, const void *buf,
        size_t size, DmaCallbackF callback, bool rx, bool last)
{
    struct StmI2c *regs = pdev->cfg->regs;
    struct dmaMode mode;

    memset(&mode, 0, sizeof(mode));
    mode.priority = DMA_PRIORITY_HIGH;
    mode.direction = rx ? DMA_DIRECTION_PERIPH_TO_MEM :
            DMA_DIRECTION_MEM_TO_PERIPH;
    mode.periphAddr = (uintptr_t)&regs->DR;
    mode.minc = true;
    mode.channel = dmaCfg->channel;

    dmaStart(I2C_DMA_BUS, dmaCfg->stream, buf, size, &mode, callback, pdev);
    if (last)
        stmI2cIrqEnable(pdev, I2C_CR2_LAST);
    else
        stmI2cIrqDisable(pdev, I2C_CR2_LAST);
    stmI2cDmaEnable(pdev);
}

static void stmI2cMasterSentStart(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;

    if (atomicReadByte(&state->masterState) == STM_I2C_MASTER_START) {
        if (state->tx.size > 0) {
            atomicWriteByte(&state->masterState, STM_I2C_MASTER_TX_ADDR);
            regs->DR = pdev->addr << 1;
        } else {
            atomicWriteByte(&state->masterState, STM_I2C_MASTER_RX_ADDR);
            stmI2cAckEnable(pdev);
            regs->DR = (pdev->addr << 1) | 0x01;
        }
    }
}

static void stmI2cMasterSentAddr(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;
    uint8_t masterState = atomicReadByte(&state->masterState);

    if (masterState == STM_I2C_MASTER_TX_ADDR) {
        stmI2cMasterStartDma(pdev, &pdev->board->dmaTx, state->tx.cbuf,
                state->tx.size, stmI2cMasterDmaTxDone, false, !!state->rx.size);
        regs->SR2; // Clear ADDR
        atomicWriteByte(&state->masterState, STM_I2C_MASTER_TX_DATA);
    } else if (masterState == STM_I2C_MASTER_RX_ADDR) {
        if (state->rx.size == 1) // Generate NACK here for 1 byte transfers
            stmI2cAckDisable(pdev);

        stmI2cMasterStartDma(pdev, &pdev->board->dmaRx, state->rx.buf,
                state->rx.size, stmI2cMasterDmaRxDone, true,
                state->rx.size > 1);
        regs->SR2; // Clear ADDR
        atomicWriteByte(&state->masterState, STM_I2C_MASTER_RX_DATA);
    }
}

static void stmI2cMasterNakRxed(struct StmI2cDev *pdev)
{
    struct I2cStmState *state = &pdev->state;
    struct StmI2c *regs = pdev->cfg->regs;
    uint8_t masterState = atomicReadByte(&state->masterState);

    if (masterState == STM_I2C_MASTER_TX_ADDR ||
            masterState == STM_I2C_MASTER_TX_DATA ||
            masterState == STM_I2C_MASTER_RX_ADDR ||
            masterState == STM_I2C_MASTER_RX_DATA) {
        stmI2cMasterDmaCancel(pdev);

        regs->SR1 &= ~I2C_SR1_AF;
        stmI2cStopEnable(pdev);
        stmI2cMasterTxRxDone(pdev, 0);
    }
}

static void stmI2cMasterBusError(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;

    stmI2cMasterDmaCancel(pdev);
    regs->SR1 &= ~I2C_SR1_BERR;
    stmI2cMasterTxRxDone(pdev, -EIO);
}

static void stmI2cMasterArbitrationLoss(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;

    stmI2cMasterDmaCancel(pdev);
    regs->SR1 &= ~I2C_SR1_ARLO;
    stmI2cMasterTxRxDone(pdev, -EBUSY);
}

static void stmI2cMasterUnexpectedError(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;

    osLog(LOG_ERROR, "Unexpected I2C ERR interrupt: SR1 = %04lX, SR2 = %04lX\n",
            regs->SR1, regs->SR2);

    stmI2cMasterDmaCancel(pdev);
    regs->SR1 = 0;
    stmI2cMasterTxRxDone(pdev, -EIO);
}

static void stmI2cIsrEvent(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;
    uint16_t sr1 = regs->SR1;

    if (pdev->state.mode == STM_I2C_SLAVE) {
        if (sr1 & I2C_SR1_ADDR) {
            stmI2cSlaveAddrMatched(pdev);
        } else if (sr1 & I2C_SR1_RXNE) {
            stmI2cSlaveRxBufNotEmpty(pdev);
        } else if (sr1 & I2C_SR1_TXE) {
            stmI2cSlaveTxBufEmpty(pdev);
        } else if (sr1 & I2C_SR1_BTF) {
            if (regs->SR2 & I2C_SR2_TRA)
                stmI2cSlaveTxBufEmpty(pdev);
           else
                stmI2cSlaveRxBufNotEmpty(pdev);
        } else if (sr1 & I2C_SR1_STOPF) {
            stmI2cSlaveStopRxed(pdev);
        }
        /* TODO: other flags */
    } else if (pdev->state.mode == STM_I2C_MASTER) {
        if (sr1 & I2C_SR1_SB)
            stmI2cMasterSentStart(pdev);
        else if (sr1 & I2C_SR1_ADDR)
            stmI2cMasterSentAddr(pdev);
    }
}

static void stmI2cIsrError(struct StmI2cDev *pdev)
{
    struct StmI2c *regs = pdev->cfg->regs;
    uint16_t sr1 = regs->SR1;

    if (pdev->state.mode == STM_I2C_SLAVE) {
        if (sr1 & I2C_SR1_AF)
            stmI2cSlaveNakRxed(pdev);
        /* TODO: other flags */
    } else if (pdev->state.mode == STM_I2C_MASTER) {
        if (sr1 & I2C_SR1_AF)
            stmI2cMasterNakRxed(pdev);
        else if (sr1 & I2C_SR1_BERR)
            stmI2cMasterBusError(pdev);
        else if (sr1 & I2C_SR1_ARLO)
            stmI2cMasterArbitrationLoss(pdev);
        else
            stmI2cMasterUnexpectedError(pdev);
    }
}

#define DECLARE_IRQ_HANDLERS(_n)                \
    extern void I2C##_n##_EV_IRQHandler();      \
    extern void I2C##_n##_ER_IRQHandler();      \
                                                \
    extern void I2C##_n##_EV_IRQHandler()       \
    {                                           \
        stmI2cIsrEvent(&mStmI2cDevs[_n - 1]);  \
    }                                           \
                                                \
    extern void I2C##_n##_ER_IRQHandler()       \
    {                                           \
        stmI2cIsrError(&mStmI2cDevs[_n - 1]);  \
    }

DECLARE_IRQ_HANDLERS(1);
DECLARE_IRQ_HANDLERS(3);

static inline struct Gpio* stmI2cGpioInit(const struct StmI2cBoardCfg *board, const struct StmI2cGpioCfg *cfg)
{
    struct Gpio* gpio = gpioRequest(cfg->gpioNum);
    gpioConfigAlt(gpio, board->gpioSpeed, board->gpioPull, GPIO_OUT_OPEN_DRAIN,
            cfg->func);

    return gpio;
}

int i2cMasterRequest(uint32_t busId, uint32_t speed)
{
    if (busId >= ARRAY_SIZE(mStmI2cDevs))
        return -EINVAL;

    const struct StmI2cBoardCfg *board = boardStmI2cCfg(busId);
    if (!board)
        return -EINVAL;

    struct StmI2cDev *pdev = &mStmI2cDevs[busId];
    struct I2cStmState *state = &pdev->state;
    const struct StmI2cCfg *cfg = &mStmI2cCfgs[busId];

    if (state->mode == STM_I2C_DISABLED) {
        state->mode = STM_I2C_MASTER;

        pdev->cfg = cfg;
        pdev->board = board;
        pdev->next = 2;
        pdev->last = 1;
        atomicBitsetInit(mXfersValid, I2C_MAX_QUEUE_DEPTH);

        pdev->scl = stmI2cGpioInit(board, &board->gpioScl);
        pdev->sda = stmI2cGpioInit(board, &board->gpioSda);

        pwrUnitClock(PERIPH_BUS_APB1, cfg->clock, true);

        stmI2cDisable(pdev);

        pwrUnitReset(PERIPH_BUS_APB1, cfg->clock, true);
        pwrUnitReset(PERIPH_BUS_APB1, cfg->clock, false);

        stmI2cIrqEnable(pdev, I2C_CR2_ITEVTEN | I2C_CR2_ITERREN);
        stmI2cSpeedSet(pdev, speed);
        atomicWriteByte(&state->masterState, STM_I2C_MASTER_IDLE);

        NVIC_EnableIRQ(cfg->irqEr);
        NVIC_EnableIRQ(cfg->irqEv);

        stmI2cEnable(pdev);
        return 0;
    } else {
        return -EBUSY;
    }
}

int i2cMasterRelease(uint32_t busId)
{
    if (busId >= ARRAY_SIZE(mStmI2cDevs))
        return -EINVAL;

    struct StmI2cDev *pdev = &mStmI2cDevs[busId];
    struct I2cStmState *state = &pdev->state;
    const struct StmI2cCfg *cfg = pdev->cfg;

    if (state->mode == STM_I2C_MASTER) {
        if (atomicReadByte(&state->masterState) == STM_I2C_MASTER_IDLE) {
            state->mode = STM_I2C_DISABLED;
            stmI2cIrqEnable(pdev, I2C_CR2_ITERREN | I2C_CR2_ITEVTEN);
            stmI2cDisable(pdev);
            pwrUnitClock(PERIPH_BUS_APB1, cfg->clock, false);

            gpioRelease(pdev->scl);
            gpioRelease(pdev->sda);

            return 0;
        } else {
            return -EBUSY;
        }
    } else {
        return -EINVAL;
    }
}


int i2cMasterTxRx(uint32_t busId, uint32_t addr,
        const void *txBuf, size_t txSize, void *rxBuf, size_t rxSize,
        I2cCallbackF callback, void *cookie)
{
    uint32_t id;

    if (busId >= ARRAY_SIZE(mStmI2cDevs))
        return -EINVAL;
    else if (addr & 0x80)
        return -ENXIO;

    struct StmI2cDev *pdev = &mStmI2cDevs[busId];
    struct I2cStmState *state = &pdev->state;

    if (state->mode != STM_I2C_MASTER)
        return -EINVAL;

    struct StmI2cXfer *xfer = stmI2cGetXfer();

    if (xfer) {
        xfer->busId = busId;
        xfer->addr = addr;
        xfer->txBuf = txBuf;
        xfer->txSize = txSize;
        xfer->rxBuf = rxBuf;
        xfer->rxSize = rxSize;
        xfer->callback = callback;
        xfer->cookie = cookie;

        do {
            id = atomicAdd32bits(&pdev->last, 1);
        } while (!id);

        // after this point the transfer can be picked up by the transfer
        // complete interrupt
        atomicWrite32bits(&xfer->id, id);

        // only initiate transfer here if we are in IDLE. Otherwise the transfer
        // completion interrupt will start the next transfer (not necessarily
        // this one)
        if (atomicCmpXchgByte((uint8_t *)&state->masterState,
                STM_I2C_MASTER_IDLE, STM_I2C_MASTER_START)) {
            // it is possible for this transfer to already be complete by the
            // time we get here. if so, transfer->id will have been set to 0.
            if (atomicCmpXchg32bits(&xfer->id, id, 0)) {
                pdev->addr = xfer->addr;
                state->tx.cbuf = xfer->txBuf;
                state->tx.offset = 0;
                state->tx.size = xfer->txSize;
                state->tx.callback = xfer->callback;
                state->tx.cookie = xfer->cookie;
                state->rx.buf = xfer->rxBuf;
                state->rx.offset = 0;
                state->rx.size = xfer->rxSize;
                state->rx.callback = NULL;
                state->rx.cookie = NULL;
                state->tid = osGetCurrentTid();
                if (pdev->board->sleepDev >= 0)
                    platRequestDevInSleepMode(pdev->board->sleepDev, 12);
                stmI2cPutXfer(xfer);
                stmI2cStartEnable(pdev);
            }
        }
        return 0;
    } else {
        return -EBUSY;
    }
}

int i2cSlaveRequest(uint32_t busId, uint32_t addr)
{
    if (busId >= ARRAY_SIZE(mStmI2cDevs))
        return -EINVAL;

    const struct StmI2cBoardCfg *board = boardStmI2cCfg(busId);
    if (!board)
        return -EINVAL;

    struct StmI2cDev *pdev = &mStmI2cDevs[busId];
    const struct StmI2cCfg *cfg = &mStmI2cCfgs[busId];

    if (pdev->state.mode == STM_I2C_DISABLED) {
        pdev->state.mode = STM_I2C_SLAVE;

        pdev->addr = addr;
        pdev->cfg = cfg;
        pdev->board = board;

        pdev->scl = stmI2cGpioInit(board, &board->gpioScl);
        pdev->sda = stmI2cGpioInit(board, &board->gpioSda);

        return 0;
    } else {
        return -EBUSY;
    }
}

int i2cSlaveRelease(uint32_t busId)
{
    if (busId >= ARRAY_SIZE(mStmI2cDevs))
        return -EINVAL;

    struct StmI2cDev *pdev = &mStmI2cDevs[busId];
    const struct StmI2cCfg *cfg = pdev->cfg;

    if (pdev->state.mode == STM_I2C_SLAVE) {
        pdev->state.mode = STM_I2C_DISABLED;
        stmI2cIrqDisable(pdev, I2C_CR2_ITERREN | I2C_CR2_ITEVTEN);
        stmI2cAckDisable(pdev);
        stmI2cDisable(pdev);
        pwrUnitClock(PERIPH_BUS_APB1, cfg->clock, false);

        gpioRelease(pdev->scl);
        gpioRelease(pdev->sda);

        return 0;
    } else {
        return -EBUSY;
    }
}

void i2cSlaveEnableRx(uint32_t busId, void *rxBuf, size_t rxSize,
        I2cCallbackF callback, void *cookie)
{
    struct StmI2cDev *pdev = &mStmI2cDevs[busId];
    const struct StmI2cCfg *cfg = pdev->cfg;
    struct I2cStmState *state = &pdev->state;

    if (pdev->state.mode == STM_I2C_SLAVE) {
        state->rx.buf = rxBuf;
        state->rx.offset = 0;
        state->rx.size = rxSize;
        state->rx.callback = callback;
        state->rx.cookie = cookie;
        state->slaveState = STM_I2C_SLAVE_RX_ARMED;
        state->tid = osGetCurrentTid();

        pwrUnitClock(PERIPH_BUS_APB1, cfg->clock, true);
        pwrUnitReset(PERIPH_BUS_APB1, cfg->clock, true);
        pwrUnitReset(PERIPH_BUS_APB1, cfg->clock, false);

        NVIC_EnableIRQ(cfg->irqEr);
        NVIC_EnableIRQ(cfg->irqEv);

        stmI2cEnable(pdev);
        cfg->regs->OAR1 = I2C_OAR1_ADD7(pdev->addr);
        stmI2cIrqEnable(pdev, I2C_CR2_ITERREN | I2C_CR2_ITEVTEN);
        stmI2cAckEnable(pdev);
    }
}

static int i2cSlaveTx(uint32_t busId, const void *txBuf, uint8_t byte,
        size_t txSize, I2cCallbackF callback, void *cookie)
{
    struct StmI2cDev *pdev = &mStmI2cDevs[busId];
    struct I2cStmState *state = &pdev->state;

    if (pdev->state.mode == STM_I2C_SLAVE) {
        if (state->slaveState == STM_I2C_SLAVE_RX)
            return -EBUSY;

        if (txBuf) {
            state->tx.cbuf = txBuf;
            state->tx.preamble = false;
        } else {
            state->tx.byte = byte;
            state->tx.preamble = true;
        }
        state->tx.offset = 0;
        state->tx.size = txSize;
        state->tx.callback = callback;
        state->tx.cookie = cookie;

        if (state->slaveState == STM_I2C_SLAVE_TX_ARMED) {
            state->slaveState = STM_I2C_SLAVE_TX;
            stmI2cSlaveTxNextByte(pdev);
            stmI2cIrqEnable(pdev, I2C_CR2_ITBUFEN);
        } else {
            state->slaveState = STM_I2C_SLAVE_TX;
        }

        return 0;
    } else {
        return -EBUSY;
    }
}

int i2cSlaveTxPreamble(uint32_t busId, uint8_t byte, I2cCallbackF callback,
        void *cookie)
{
    return i2cSlaveTx(busId, NULL, byte, 0, callback, cookie);
}

int i2cSlaveTxPacket(uint32_t busId, const void *txBuf, size_t txSize,
        I2cCallbackF callback, void *cookie)
{
    return i2cSlaveTx(busId, txBuf, 0, txSize, callback, cookie);
}
