/*
 * 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 <string.h>
#include <assert.h>
#include "os/mynewt.h"
#include <hal/hal_spi.h>
#include <hal/hal_gpio.h>
#include "mcu/stm32_hal.h"
#include "mcu/cmsis_nvic.h"

#define SPI_0_ENABLED (MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_0_SLAVE))
#define SPI_1_ENABLED (MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_1_SLAVE))
#define SPI_2_ENABLED (MYNEWT_VAL(SPI_2_MASTER) || MYNEWT_VAL(SPI_2_SLAVE))
#define SPI_3_ENABLED (MYNEWT_VAL(SPI_3_MASTER) || MYNEWT_VAL(SPI_3_SLAVE))
#define SPI_4_ENABLED (MYNEWT_VAL(SPI_4_MASTER) || MYNEWT_VAL(SPI_4_SLAVE))
#define SPI_5_ENABLED (MYNEWT_VAL(SPI_5_MASTER) || MYNEWT_VAL(SPI_5_SLAVE))

#define SPI_ENABLED (SPI_0_ENABLED || SPI_1_ENABLED || SPI_2_ENABLED || \
                     SPI_3_ENABLED || SPI_4_ENABLED || SPI_5_ENABLED)

#define STM32_HAL_SPI_TIMEOUT (1000)

#define STM32_HAL_SPI_MAX (6)

extern HAL_StatusTypeDef HAL_SPI_QueueTransmit(SPI_HandleTypeDef *hspi,
        uint8_t *pData, uint16_t Size);

extern HAL_StatusTypeDef HAL_SPI_Slave_Queue_TransmitReceive(
        SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,
        uint16_t Size);

extern HAL_StatusTypeDef HAL_SPI_Transmit_IT_Custom(SPI_HandleTypeDef *hspi,
        uint8_t *pData, uint16_t Size);

extern HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT_Custom(
        SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,
        uint16_t Size);

struct stm32_hal_spi {
    SPI_HandleTypeDef handle;
    uint8_t slave:1;                  /* slave or master? */
    uint8_t tx_in_prog:1;             /* slave: tx'ing user data not def */
    uint8_t selected:1;               /* slave: if we see SS */
    uint8_t def_char[4];              /* slave: default data to tx */
    struct stm32_hal_spi_cfg *cfg;
    hal_spi_txrx_cb txrx_cb_func;     /* callback function */
    void            *txrx_cb_arg;     /* callback arguments */
};

static struct stm32_spi_stat {
    uint32_t irq;
    uint32_t ss_irq;
    uint32_t tx;
    uint32_t eovf;
    uint32_t emodf;
    uint32_t efre;
} spi_stat;

#if SPI_ENABLED
static void spi_irq_handler(struct stm32_hal_spi *spi);
#endif

#if SPI_0_ENABLED
struct stm32_hal_spi stm32_hal_spi0;
#endif
#if SPI_1_ENABLED
struct stm32_hal_spi stm32_hal_spi1;
#endif
#if SPI_2_ENABLED
struct stm32_hal_spi stm32_hal_spi2;
#endif
#if SPI_3_ENABLED
struct stm32_hal_spi stm32_hal_spi3;
#endif
#if SPI_4_ENABLED
struct stm32_hal_spi stm32_hal_spi4;
#endif
#if SPI_5_ENABLED
struct stm32_hal_spi stm32_hal_spi5;
#endif

static struct stm32_hal_spi *stm32_hal_spis[STM32_HAL_SPI_MAX] = {
#if SPI_0_ENABLED
    &stm32_hal_spi0,
#else
    NULL,
#endif
#if SPI_1_ENABLED
    &stm32_hal_spi1,
#else
    NULL,
#endif
#if SPI_2_ENABLED
    &stm32_hal_spi2,
#else
    NULL,
#endif
#if SPI_3_ENABLED
    &stm32_hal_spi3,
#else
    NULL,
#endif
#if SPI_4_ENABLED
    &stm32_hal_spi4,
#else
    NULL,
#endif
#if SPI_5_ENABLED
    &stm32_hal_spi5,
#else
    NULL,
#endif
};

#define STM32_HAL_SPI_RESOLVE(__n, __v)                          \
    if ((__n) >= STM32_HAL_SPI_MAX) {                            \
        rc = -1;                                                 \
        goto err;                                                \
    }                                                            \
    (__v) = (struct stm32_hal_spi *) stm32_hal_spis[(__n)];      \
    if ((__v) == NULL) {                                         \
        rc = -1;                                                 \
        goto err;                                                \
    }

static IRQn_Type
stm32_resolve_spi_irq(SPI_HandleTypeDef *hspi)
{
    uintptr_t spi = (uintptr_t)hspi->Instance;

    switch (spi) {
#if SPI_0_ENABLED
    case (uintptr_t)SPI1:
        return SPI1_IRQn;
#endif
#if SPI_1_ENABLED
    case (uintptr_t)SPI2:
        return SPI2_IRQn;
#endif
#if SPI_2_ENABLED
    case (uintptr_t)SPI3:
        return SPI3_IRQn;
#endif
#if SPI_3_ENABLED
    case (uintptr_t)SPI4:
        return SPI4_IRQn;
#endif
#if SPI_4_ENABLED
    case (uintptr_t)SPI5:
        return SPI5_IRQn;
#endif
#if SPI_5_ENABLED
    case (uintptr_t)SPI6:
        return SPI6_IRQn;
#endif
    default:
        assert(0);
    }
}

/*
 * SPI master IRQ handler.
 */
#if SPI_ENABLED
static void
spim_irq_handler(struct stm32_hal_spi *spi)
{
    if (spi->handle.TxXferCount == 0 && spi->handle.RxXferCount == 0) {
        if (spi->txrx_cb_func) {
            spi->txrx_cb_func(spi->txrx_cb_arg, spi->handle.TxXferSize);
        }
    }
}
#endif

/*
 * SPI slave IRQ handler.
 */
#if SPI_ENABLED
static void
spis_irq_handler(struct stm32_hal_spi *spi)
{
    if (spi->tx_in_prog) {
        if (spi->handle.TxXferCount == 0 && spi->handle.RxXferCount == 0) {
            /*
             * If finished with data tx, start transmitting default char
             */
            spi->tx_in_prog = 0;

            HAL_SPI_Transmit_IT_Custom(&spi->handle, spi->def_char, 2);

            if (spi->txrx_cb_func) {
                spi->txrx_cb_func(spi->txrx_cb_arg, spi->handle.TxXferSize);
            }
        }
    } else {
        /*
         * Reset TX pointer within default data.
         */
        spi->handle.pTxBuffPtr = spi->def_char;
        spi->handle.TxXferCount = 2;
    }
}
#endif

/*
 * Common IRQ handler for both master and slave.
 */
#if SPI_ENABLED
static void
spi_irq_handler(struct stm32_hal_spi *spi)
{
    uint32_t err;

    spi_stat.irq++;

    HAL_SPI_IRQHandler(&spi->handle);
    err = spi->handle.ErrorCode;
    if (err) {
        if (err & HAL_SPI_ERROR_OVR) {
            spi_stat.eovf++;
        }
        if (err & HAL_SPI_ERROR_MODF) {
            spi_stat.emodf++;
        }
        if (err & HAL_SPI_ERROR_FRE) {
            spi_stat.efre++;
        }
        spi->handle.ErrorCode = 0;
    }
    if (!spi->slave) {
        spim_irq_handler(spi);
    } else {
        spis_irq_handler(spi);
    }
}
#endif

/*
 * GPIO interrupt when slave gets selected/deselected.
 */
static void
spi_ss_isr(void *arg)
{
    struct stm32_hal_spi *spi = (struct stm32_hal_spi *)arg;
    int ss;
    int len;
    uint16_t reg;

    spi_stat.ss_irq++;
    ss = hal_gpio_read(spi->cfg->ss_pin);
    if (ss == 0 && !spi->selected) {
        /*
         * We're now seeing chip select. Enable SPI, SPI interrupts.
         */
        if (spi->tx_in_prog) {
            __HAL_SPI_ENABLE_IT(&spi->handle,
              SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
        } else {
            __HAL_SPI_ENABLE_IT(&spi->handle, SPI_IT_TXE | SPI_IT_ERR);
        }
        reg = spi->handle.Instance->CR1;
        reg &= ~SPI_CR1_SSI;
        reg |= SPI_CR1_SPE;
        spi->handle.Instance->CR1 = reg;
        spi->selected = 1;
    }
    if (ss == 1 && spi->selected) {
        /*
         * Chip select done. Check whether there's pending data to RX.
         */
        if (spi->handle.Instance->SR & SPI_SR_RXNE && spi->handle.RxISR) {
            spi->handle.RxISR(&spi->handle);
        }

        /*
         * Disable SPI.
         */
        reg = spi->handle.Instance->CR1;
        reg &= ~SPI_CR1_SPE;
        reg |= SPI_CR1_SSI;
        spi->handle.Instance->CR1 = reg;

        __HAL_SPI_DISABLE_IT(&spi->handle, SPI_IT_RXNE|SPI_IT_TXE|SPI_IT_ERR);

        len = spi->handle.RxXferSize - spi->handle.RxXferCount;
        if (len) {
            /*
             * If some data was clocked out, reset to start sending
             * default data and call callback, if user was waiting for
             * data.
             */

            spi->handle.State = HAL_SPI_STATE_READY;

            HAL_SPI_QueueTransmit(&spi->handle, spi->def_char, 2);

            if (spi->tx_in_prog) {
                spi->tx_in_prog = 0;

                if (spi->txrx_cb_func) {
                    spi->txrx_cb_func(spi->txrx_cb_arg, len);
                }
            }
        }
        spi->selected = 0;
    }
}

#if SPI_0_ENABLED
static void
spi1_irq_handler(void)
{
    spi_irq_handler(stm32_hal_spis[0]);
}
#endif

#if SPI_1_ENABLED
static void
spi2_irq_handler(void)
{
    spi_irq_handler(stm32_hal_spis[1]);
}
#endif

#if SPI_2_ENABLED
static void
spi3_irq_handler(void)
{
    spi_irq_handler(stm32_hal_spis[2]);
}
#endif

#if SPI_3_ENABLED
static void
spi4_irq_handler(void)
{
    spi_irq_handler(stm32_hal_spis[3]);
}
#endif

#if SPI_4_ENABLED
static void
spi5_irq_handler(void)
{
    spi_irq_handler(stm32_hal_spis[4]);
}
#endif


#if SPI_5_ENABLED
static void
spi6_irq_handler(void)
{
    spi_irq_handler(stm32_hal_spis[5]);
}
#endif

uint32_t
stm32_resolve_spi_irq_handler(SPI_HandleTypeDef *hspi)
{
    switch((uintptr_t)hspi->Instance) {
#if SPI_0_ENABLED
    case (uintptr_t)SPI1:
        return (uint32_t)&spi1_irq_handler;
#endif
#if SPI_1_ENABLED
    case (uintptr_t)SPI2:
        return (uint32_t)&spi2_irq_handler;
#endif
#if SPI_2_ENABLED
    case (uintptr_t)SPI3:
        return (uint32_t)&spi3_irq_handler;
#endif
#if SPI_3_ENABLED
    case (uintptr_t)SPI4:
        return (uint32_t)&spi4_irq_handler;
#endif
#if SPI_4_ENABLED
    case (uintptr_t)SPI5:
        return (uint32_t)&spi5_irq_handler;
#endif
#if SPI_5_ENABLED
    case (uintptr_t)SPI6:
        return (uint32_t)&spi6_irq_handler;
#endif
    default:
        assert(0);
    }
}

int
hal_spi_init(int spi_num, void *usercfg, uint8_t spi_type)
{
    struct stm32_hal_spi *spi;
    int rc;

    /* Check for valid arguments */
    rc = -1;
    if (usercfg == NULL) {
        goto err;
    }

    if ((spi_type != HAL_SPI_TYPE_MASTER) && (spi_type != HAL_SPI_TYPE_SLAVE)) {
        goto err;
    }

    /* Allow user to specify default init settings for the SPI.
     * This can be done in BSP, so that only the generic SPI settings
     * are passed to the user configure() call.
     */
    STM32_HAL_SPI_RESOLVE(spi_num, spi);

    spi->cfg = usercfg;
    spi->slave = (spi_type == HAL_SPI_TYPE_SLAVE);

    return (0);
err:
    return (rc);
}

static int
stm32_spi_resolve_prescaler(uint8_t spi_num, uint32_t baudrate, uint32_t *prescaler)
{
    uint32_t candidate_br;
    uint32_t apbfreq;
    int i;

    /* SPIx {1,4,5,6} use PCLK2 on the STM32F4/F7, otherwise use PCKL1.
     * The numbers in the switch below are offset by 1, because the HALs index
     * SPI ports from 0.
     */
    switch (spi_num) {
    case 0:
    case 3:
    case 4:
    case 5:
        apbfreq = HAL_RCC_GetPCLK2Freq();
        break;
    default:
        apbfreq = HAL_RCC_GetPCLK1Freq();
        break;
    }

    if (baudrate == 0) {
        *prescaler = 0;
        return 0;
    }

    /* Calculate best-fit prescaler: divide the clock by each subsequent
     * prescaler until we reach the highest prescaler that generates at
     * _most_ the baudrate.
     */
    *prescaler = SPI_BAUDRATEPRESCALER_256;
    for (i = 0; i < 8; i++) {
        candidate_br = apbfreq >> (i + 1);
        if (candidate_br <= baudrate) {
            *prescaler = i << SPI_CR1_BR_Pos;
            break;
        }
    }

    return (0);
}

/**
 * Sets the txrx callback (executed at interrupt context) when the
 * buffer is transferred by the master or the slave using the non-blocking API.
 * Cannot be called when the spi is enabled. This callback will also be called
 * when chip select is de-asserted on the slave.
 *
 * NOTE: This callback is only used for the non-blocking interface and must
 * be called prior to using the non-blocking API.
 *
 * @param spi_num   SPI interface on which to set callback
 * @param txrx      Callback function
 * @param arg       Argument to be passed to callback function
 *
 * @return int 0 on success, non-zero error code on failure.
 */
int
hal_spi_set_txrx_cb(int spi_num, hal_spi_txrx_cb txrx_cb, void *arg)
{
    struct stm32_hal_spi *spi;
    int rc = 0;
    int sr;

    STM32_HAL_SPI_RESOLVE(spi_num, spi);

    __HAL_DISABLE_INTERRUPTS(sr);
    spi->txrx_cb_func = txrx_cb;
    spi->txrx_cb_arg = arg;
    __HAL_ENABLE_INTERRUPTS(sr);
err:
    return rc;
}

/**
 * Enables the SPI. This does not start a transmit or receive operation;
 * it is used for power mgmt. Cannot be called when a SPI transfer is in
 * progress.
 *
 * @param spi_num
 *
 * @return int 0 on success, non-zero error code on failure.
 */
int
hal_spi_enable(int spi_num)
{
    struct stm32_hal_spi *spi;
    int rc;

    rc = 0;
    STM32_HAL_SPI_RESOLVE(spi_num, spi);

    /* XXX power up */
err:
    return rc;
}

/**
 * Disables the SPI. Used for power mgmt. It will halt any current SPI transfers
 * in progress.
 *
 * @param spi_num
 *
 * @return int 0 on success, non-zero error code on failure.
 */
int
hal_spi_disable(int spi_num)
{
    struct stm32_hal_spi *spi;
    int rc;

    rc = 0;
    STM32_HAL_SPI_RESOLVE(spi_num, spi);

    /* XXX power down */
err:
    return rc;
}

int
hal_spi_config(int spi_num, struct hal_spi_settings *settings)
{
    struct stm32_hal_spi *spi;
    struct stm32_hal_spi_cfg *cfg;
    SPI_InitTypeDef *init;
    GPIO_InitTypeDef gpio;
    uint32_t gpio_speed;
    IRQn_Type irq;
    uint32_t prescaler;
    int rc;
    int sr;

    __HAL_DISABLE_INTERRUPTS(sr);
    STM32_HAL_SPI_RESOLVE(spi_num, spi);

    init = &spi->handle.Init;

    cfg = spi->cfg;

    if (!spi->slave) {
        spi->handle.Init.NSS = SPI_NSS_HARD_OUTPUT;
        spi->handle.Init.Mode = SPI_MODE_MASTER;
    } else {
        spi->handle.Init.NSS = SPI_NSS_SOFT;
        spi->handle.Init.Mode = SPI_MODE_SLAVE;
    }

    gpio.Mode = GPIO_MODE_AF_PP;
    gpio.Pull = GPIO_NOPULL;

    /* TODO: also VERY_HIGH for STM32L1x */
    if (settings->baudrate <= 2000) {
        gpio_speed = GPIO_SPEED_FREQ_LOW;
    } else if (settings->baudrate <= 12500) {
        gpio_speed = GPIO_SPEED_FREQ_MEDIUM;
    } else {
        gpio_speed = GPIO_SPEED_FREQ_HIGH;
    }

    /* Enable the clocks for this SPI */
    switch (spi_num) {
#if SPI_0_ENABLED
    case 0:
        __HAL_RCC_SPI1_CLK_ENABLE();
#if !MYNEWT_VAL(MCU_STM32F1)
    #if !MYNEWT_VAL(MCU_STM32L0)
        gpio.Alternate = GPIO_AF5_SPI1;
    #else
        gpio.Alternate = GPIO_AF0_SPI1;
    #endif
#endif
        spi->handle.Instance = SPI1;
        break;
#endif
#if SPI_1_ENABLED
    case 1:
        __HAL_RCC_SPI2_CLK_ENABLE();
#if !MYNEWT_VAL(MCU_STM32F1)
    #if !MYNEWT_VAL(MCU_STM32L0)
        gpio.Alternate = GPIO_AF5_SPI2;
    #else
        gpio.Alternate = GPIO_AF0_SPI2;
    #endif
#endif
        spi->handle.Instance = SPI2;
        break;
#endif
#if SPI_2_ENABLED
    case 2:
        __HAL_RCC_SPI3_CLK_ENABLE();
#if !MYNEWT_VAL(MCU_STM32F1)
        gpio.Alternate = GPIO_AF6_SPI3;
#endif
        spi->handle.Instance = SPI3;
        break;
#endif
#if SPI_3_ENABLED
    case 3:
        __HAL_RCC_SPI4_CLK_ENABLE();
#if !MYNEWT_VAL(MCU_STM32F1)
        gpio.Alternate = GPIO_AF5_SPI4;
#endif
        spi->handle.Instance = SPI4;
        break;
#endif
#if SPI_4_ENABLED
    case 4:
        __HAL_RCC_SPI5_CLK_ENABLE();
#if !MYNEWT_VAL(MCU_STM32F1)
        gpio.Alternate = GPIO_AF5_SPI5;
#endif
        spi->handle.Instance = SPI5;
        break;
#endif
#if SPI_5_ENABLED
    case 5:
        __HAL_RCC_SPI6_CLK_ENABLE();
#if !MYNEWT_VAL(MCU_STM32F1)
        gpio.Alternate = GPIO_AF5_SPI6;
#endif
        spi->handle.Instance = SPI6;
        break;
#endif
   default:
        assert(0);
        rc = -1;
        goto err;
    }

    if (!spi->slave) {
        if (settings->data_mode == HAL_SPI_MODE2 ||
          settings->data_mode == HAL_SPI_MODE3) {
            gpio.Pull = GPIO_PULLUP;
        } else {
            gpio.Pull = GPIO_PULLDOWN;
        }
    }

    /* NOTE: Errata ES0125: STM32L100x6/8/B, STM32L151x6/8/B and
     * STM32L152x6/8/B ultra-low-power device limitations.
     *
     * 2.6.6 - Corrupted last bit of data and or CRC, received in Master
     * mode with delayed SCK feedback
     *
     * This driver is always using very high speed for SCK on STM32L1x
     */

#if defined(STM32L152xC)
    if (!spi->slave) {
        gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    } else {
        gpio.Speed = gpio_speed;
    }
#else
    gpio.Speed = gpio_speed;
#endif

    rc = hal_gpio_init_stm(cfg->sck_pin, &gpio);
    if (rc != 0) {
        goto err;
    }

#if defined(STM32L152xC)
    if (!spi->slave) {
        gpio.Speed = gpio_speed;
    }
#endif

    if (!spi->slave) {
        gpio.Pull = GPIO_NOPULL;
    } else {
        gpio.Mode = GPIO_MODE_AF_OD;
    }

    rc = hal_gpio_init_stm(cfg->mosi_pin, &gpio);
    if (rc != 0) {
        goto err;
    }
    if (!spi->slave) {
        gpio.Mode = GPIO_MODE_AF_OD;
    } else {
        gpio.Mode = GPIO_MODE_AF_PP;
    }
    rc = hal_gpio_init_stm(cfg->miso_pin, &gpio);
    if (rc != 0) {
        goto err;
    }

    switch (settings->data_mode) {
    case HAL_SPI_MODE0:
        init->CLKPolarity = SPI_POLARITY_LOW;
        init->CLKPhase = SPI_PHASE_1EDGE;
        break;
    case HAL_SPI_MODE1:
        init->CLKPolarity = SPI_POLARITY_LOW;
        init->CLKPhase = SPI_PHASE_2EDGE;
        break;
    case HAL_SPI_MODE2:
        init->CLKPolarity = SPI_POLARITY_HIGH;
        init->CLKPhase = SPI_PHASE_1EDGE;
        break;
    case HAL_SPI_MODE3:
        init->CLKPolarity = SPI_POLARITY_HIGH;
        init->CLKPhase = SPI_PHASE_2EDGE;
        break;
    default:
        rc = -1;
        goto err;
    }

    switch (settings->data_order) {
    case HAL_SPI_MSB_FIRST:
        init->FirstBit = SPI_FIRSTBIT_MSB;
        break;
    case HAL_SPI_LSB_FIRST:
        init->FirstBit = SPI_FIRSTBIT_LSB;
        break;
    default:
        rc = -1;
        goto err;
    }

    switch (settings->word_size) {
    case HAL_SPI_WORD_SIZE_8BIT:
        init->DataSize = SPI_DATASIZE_8BIT;
        break;
    case HAL_SPI_WORD_SIZE_9BIT:
        init->DataSize = SPI_DATASIZE_16BIT;
        break;
    default:
        rc = -1;
        goto err;
    }

    rc = stm32_spi_resolve_prescaler(spi_num, settings->baudrate * 1000, &prescaler);
    if (rc != 0) {
        goto err;
    }

    init->BaudRatePrescaler = prescaler;

    /* Add default values */
    init->Direction = SPI_DIRECTION_2LINES;
    init->TIMode = SPI_TIMODE_DISABLE;
    init->CRCCalculation = SPI_CRCCALCULATION_DISABLE;
    init->CRCPolynomial = 1;
#ifdef SPI_NSS_PULSE_DISABLE
    init->NSSPMode = SPI_NSS_PULSE_DISABLE;
#endif

    irq = stm32_resolve_spi_irq(&spi->handle);
    NVIC_SetPriority(irq, cfg->irq_prio);
    NVIC_SetVector(irq, stm32_resolve_spi_irq_handler(&spi->handle));
    NVIC_EnableIRQ(irq);

    /* Init, Enable */
    rc = HAL_SPI_Init(&spi->handle);
    if (rc != 0) {
        goto err;
    }
    if (spi->slave) {
        hal_spi_slave_set_def_tx_val(spi_num, 0);
        rc = hal_gpio_irq_init(cfg->ss_pin, spi_ss_isr, spi, HAL_GPIO_TRIG_BOTH,
                               HAL_GPIO_PULL_UP);
        spi_ss_isr(spi);
    }
    __HAL_ENABLE_INTERRUPTS(sr);
    return (0);
err:
    __HAL_ENABLE_INTERRUPTS(sr);
    return (rc);
}

int
hal_spi_txrx_noblock(int spi_num, void *txbuf, void *rxbuf, int len)
{
    struct stm32_hal_spi *spi;
    int rc;
    int sr;

    STM32_HAL_SPI_RESOLVE(spi_num, spi);

    spi_stat.tx++;
    rc = -1;
    __HAL_DISABLE_INTERRUPTS(sr);
    if (!spi->slave) {
        rc = HAL_SPI_TransmitReceive_IT_Custom(&spi->handle, txbuf, rxbuf, len);
    } else {
        /*
         * Slave: if selected, start transmitting new data.
         * If not selected, queue it for transmission.
         */
        spi->handle.State = HAL_SPI_STATE_READY;
        if (spi->selected) {
            rc = HAL_SPI_TransmitReceive_IT_Custom(&spi->handle, txbuf, rxbuf, len);
        } else {
            rc = HAL_SPI_Slave_Queue_TransmitReceive(&spi->handle, txbuf, rxbuf,
              len);
        }
        if (rc == 0) {
            spi->tx_in_prog = 1;
        }
    }
    __HAL_ENABLE_INTERRUPTS(sr);
err:
    return (rc);
}

/**
 * Sets the default value transferred by the slave. Not valid for master
 *
 * @param spi_num SPI interface to use
 *
 * @return int 0 on success, non-zero error code on failure.
 */
int
hal_spi_slave_set_def_tx_val(int spi_num, uint16_t val)
{
    struct stm32_hal_spi *spi;
    int rc;
    int sr;
    int i;

    STM32_HAL_SPI_RESOLVE(spi_num, spi);

    if (spi->slave) {
        rc = 0;
        __HAL_DISABLE_INTERRUPTS(sr);
        if (spi->handle.Init.DataSize == SPI_DATASIZE_8BIT) {
            for (i = 0; i < 4; i++) {
                ((uint8_t *)spi->def_char)[i] = val;
            }
        } else {
            for (i = 0; i < 2; i++) {
                ((uint16_t *)spi->def_char)[i] = val;
            }
        }
        if (!spi->tx_in_prog) {
            /*
             * Replaces the current default char in tx buffer register.
             */
            spi->handle.State = HAL_SPI_STATE_READY;
            rc = HAL_SPI_QueueTransmit(&spi->handle, spi->def_char, 2);
            assert(rc == 0);
        }
        __HAL_ENABLE_INTERRUPTS(sr);
    } else {
        rc = -1;
    }
err:
    return rc;
}

/**
 * Blocking call to send a value on the SPI. Returns the value received from the
 * SPI slave.
 *
 * MASTER: Sends the value and returns the received value from the slave.
 * SLAVE: Invalid API. Returns 0xFFFF
 *
 * @param spi_num   Spi interface to use
 * @param val       Value to send
 *
 * @return uint16_t Value received on SPI interface from slave. Returns 0xFFFF
 * if called when the SPI is configured to be a slave
 */
uint16_t hal_spi_tx_val(int spi_num, uint16_t val)
{
    int rc;
    struct stm32_hal_spi *spi;
    uint16_t retval;
    int len;
    int sr;

    STM32_HAL_SPI_RESOLVE(spi_num, spi);
    if (spi->slave) {
        retval = -1;
        goto err;
    }
    if (spi->handle.Init.DataSize == SPI_DATASIZE_8BIT) {
        len = sizeof(uint8_t);
    } else {
        len = sizeof(uint16_t);
    }
    __HAL_DISABLE_INTERRUPTS(sr);
    spi_stat.tx++;
    rc = HAL_SPI_TransmitReceive(&spi->handle,(uint8_t *)&val,
                                 (uint8_t *)&retval, len,
                                 STM32_HAL_SPI_TIMEOUT);
    __HAL_ENABLE_INTERRUPTS(sr);
    if (rc != HAL_OK) {
        retval = 0xFFFF;
    }

err:
    return retval;
}

/**
 * Blocking interface to send a buffer and store the received values from the
 * slave. The transmit and receive buffers are either arrays of 8-bit (uint8_t)
 * values or 16-bit values depending on whether the spi is configured for 8 bit
 * data or more than 8 bits per value. The 'cnt' parameter is the number of
 * 8-bit or 16-bit values. Thus, if 'cnt' is 10, txbuf/rxbuf would point to an
 * array of size 10 (in bytes) if the SPI is using 8-bit data; otherwise
 * txbuf/rxbuf would point to an array of size 20 bytes (ten, uint16_t values).
 *
 * NOTE: these buffers are in the native endian-ness of the platform.
 *
 *     MASTER: master sends all the values in the buffer and stores the
 *             stores the values in the receive buffer if rxbuf is not NULL.
 *             The txbuf parameter cannot be NULL.
 *     SLAVE: cannot be called for a slave; returns -1
 *
 * @param spi_num   SPI interface to use
 * @param txbuf     Pointer to buffer where values to transmit are stored.
 * @param rxbuf     Pointer to buffer to store values received from peer.
 * @param cnt       Number of 8-bit or 16-bit values to be transferred.
 *
 * @return int 0 on success, non-zero error code on failure.
 */
int
hal_spi_txrx(int spi_num, void *txbuf, void *rxbuf, int len)
{
    int rc;
    struct stm32_hal_spi *spi;
    int sr;

    rc = -1;
    if (!len) {
        goto err;
    }
    STM32_HAL_SPI_RESOLVE(spi_num, spi);
    if (spi->slave) {
        goto err;
    }
    __HAL_DISABLE_INTERRUPTS(sr);
    spi_stat.tx++;
    __HAL_SPI_ENABLE(&spi->handle);
    rc = HAL_SPI_TransmitReceive(&spi->handle, (uint8_t *)txbuf,
                                 (uint8_t *)rxbuf, len,
                                 STM32_HAL_SPI_TIMEOUT);
    __HAL_ENABLE_INTERRUPTS(sr);
    if (rc != HAL_OK) {
        rc = -1;
        goto err;
    }
    rc = 0;
err:
    return rc;
}

int
hal_spi_abort(int spi_num)
{
    int rc;
    struct stm32_hal_spi *spi;
    int sr;

    rc = 0;
    STM32_HAL_SPI_RESOLVE(spi_num, spi);
    if (spi->slave) {
        goto err;
    }
    __HAL_DISABLE_INTERRUPTS(sr);
    spi->handle.State = HAL_SPI_STATE_READY;
    __HAL_SPI_DISABLE_IT(&spi->handle, SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR);
    spi->handle.Instance->CR1 &= ~SPI_CR1_SPE;
    __HAL_ENABLE_INTERRUPTS(sr);
err:
    return rc;
}
