#include "spi.h"
#include "alps_board.h"

#include "nrf_log.h"
#include "app_error.h"


#define SPI_SCK_PIN     SPIM2_SCK_PIN
#define SPI_MISO_PIN    SPIM2_MISO_PIN
#define SPI_MOSI_PIN    SPIM2_MOSI_PIN
#define SPI_SS_PIN      SPIM2_SS_PIN


#define SPI_INSTANCE  2              /**< SPI instance index. */
const nrf_drv_spi_t icm_spi_instance = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);

#ifdef SPI_HANDLER
static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */

uint8_t spim_tx_buf[SPI_MAX_TX_LENGTH] = {0};
uint8_t spim_rx_buf[SPI_MAX_RX_LENGTH];


void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                       void *p_context)
{
    spi_xfer_done = true;
    NRF_LOG_INFO("Transfer completed.");
    //if (spim_rx_buf[0] != 0)
    {
        NRF_LOG_INFO(" Received:");
        NRF_LOG_HEXDUMP_INFO(spim_rx_buf, strlen((const char *)spim_rx_buf));
    }
}
#endif

void spi_init(void)
{
    nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;;
#ifdef BOARD_ALPS
    spi_config.sck_pin  = SPI_SCK_PIN;
    spi_config.mosi_pin = SPI_MOSI_PIN;
    spi_config.miso_pin = SPI_MISO_PIN;
#else
    spi_config.sck_pin  = 28; //22;
    spi_config.mosi_pin = 29; //23;
    spi_config.miso_pin = 30; //28;
#endif
    spi_config.ss_pin   = SPI_SS_PIN;
    spi_config.mode     = NRF_DRV_SPI_MODE_0;
    spi_config.frequency = NRF_DRV_SPI_FREQ_8M;
#ifdef SPI_HANDLER
    APP_ERROR_CHECK(nrf_drv_spi_init(&icm_spi_instance, &spi_config, spi_event_handler, NULL));
#else
    APP_ERROR_CHECK(nrf_drv_spi_init(&icm_spi_instance, &spi_config, NULL, NULL));
#endif

    NRF_LOG_INFO("SPI is initialize success.");
}

#ifdef SPI_HANDLER
ret_code_t spi_transfer(uint8_t const *tx_buf, uint8_t tx_len, uint8_t *rx_buf, uint8_t rx_len)
{
    nrf_drv_spi_transfer(&icm_spi_instance, tx_buf, tx_len, rx_buf, rx_len);

    while (!spi_xfer_done)
    {
        //__WFE();
    }
}

#else
ret_code_t spi_transfer(uint8_t const *tx_buf, uint8_t tx_len, uint8_t *rx_buf, uint8_t rx_len)
{
    ret_code_t err_code;

    err_code = nrf_drv_spi_transfer(&icm_spi_instance, tx_buf, tx_len, rx_buf, rx_len);
    if(err_code != NRFX_SUCCESS)
    {
        NRF_LOG_ERROR("SPI ERROR\r\n");
    }

    return err_code;
}
#endif

void spi_disable(void)
{
    nrf_drv_spi_uninit(&icm_spi_instance);
}
