/*
* Copyright (c) 2023-2028, SpaceTouch Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date          Author      Notes
* 2023-08-11    jinyaoh     the first version
*/


#include "platform.h"
#include "board.h"
#include "hal_spi.h"
#include "hal_gpio.h"
#include "hal_cmu.h"

#define SPI0_Port   SPI_0
#define SPI1_Port   SPI_1


//static spi_callback_t spi_rx_cb[SPI_NUM];


/**
 * This function initializes the spi
 *
 * @param spi_port: The value ranges from 0 to 1
 * @param config_param: Configuration parameter
 *
 * @return None
 */

void hal_spi_init(uint32_t spi_port, SpiInitTypeDef* config_param)
{
    if (spi_port >= 2) return;

    cmu_spi_set_clk(spi_port, config_param->clockSource, config_param->prescaler);

    if (spi_port == SPI0_Port)
    {
        hal_gpio_pinmux_set_function(HAL_SPI0_CLK_PIN, HAL_SPI0_CLK_MUXSEL_FUNCTION);
        hal_gpio_pinmux_set_function(HAL_SPI0_DAT0_PIN, HAL_SPI0_DAT0_MUXSEL_FUNCTION);
        hal_gpio_pinmux_set_function(HAL_SPI0_DAT1_PIN, HAL_SPI0_DAT1_MUXSEL_FUNCTION);
        hal_gpio_set_pull(HAL_SPI0_DAT1_PIN, GPIO_PULL_UP);
        hal_gpio_pinmux_set_function(HAL_SPI0_CSS_PIN, HAL_SPI0_CSS_MUXSEL_FUNCTION);
    }
    else if (spi_port == SPI1_Port)
    {
        hal_gpio_pinmux_set_function(HAL_SPI1_CLK_PIN, HAL_SPI1_CLK_MUXSEL_FUNCTION);
        hal_gpio_pinmux_set_function(HAL_SPI1_DAT0_PIN, HAL_SPI1_DAT0_MUXSEL_FUNCTION);
        hal_gpio_pinmux_set_function(HAL_SPI1_DAT1_PIN, HAL_SPI1_DAT1_MUXSEL_FUNCTION);
        hal_gpio_set_pull(HAL_SPI1_DAT1_PIN, GPIO_PULL_UP);
        hal_gpio_pinmux_set_function(HAL_SPI1_CSS_PIN, HAL_SPI1_CSS_MUXSEL_FUNCTION);
    }
    uint32_t temp  = DEV_SPIn_CTL_CS_MODE_SOFTWARE | DEV_SPIn_CTL_SPI_CS_NSSHIGH | (config_param->transmitThreshold << 19) | (config_param->receiveThreshold << 24);
    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->CTL = temp;

        DEV_SPI0->IE = (config_param->useTxDMA<<16) + (config_param->useRxDMA<<17);
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->CTL = temp;
        DEV_SPI1->IE = (config_param->useTxDMA<<16) + (config_param->useRxDMA<<17);
    }
}

/**
 * This function deinit the spi
 *
 * @param spi_port: The value ranges from 0 to 1
 *
 * @return None
 */
void hal_spi_deinit(uint32_t spi_port)
{
    if (spi_port >= 2) return;

    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
    }
}

/**
 * This function will transmit data by spi without dma
 *
 * @param spi_port: The value ranges from 0 to 1
 * @param send_buf: Data address to be sent
 * @param length: Data length
 *
 * @return =0, HAL_OK
 */
HAL_StatusTypeDef hal_spi_transmit(uint32_t spi_port, uint8_t *send_buf, uint32_t length)
{
    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->IE &= ~(DEV_SPIn_IE_TX_DMA_EN | DEV_SPIn_IE_RX_DMA_EN) ;
        DEV_SPI0->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL |= (DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL_f.SPI_CS = 1;
        for (uint32_t i = 0; i < length; i++)
        {
            DEV_SPI0->TX_DATA = send_buf[i];
            while ((DEV_SPI0->STA & DEV_SPIn_STA_TX_FULL));
        }
        while (!(DEV_SPI0->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI0->CTL_f.SPI_CS = 0;
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->IE &= ~(DEV_SPIn_IE_TX_DMA_EN | DEV_SPIn_IE_RX_DMA_EN) ;
        DEV_SPI1->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL |= (DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL_f.SPI_CS = 1;

        for (uint32_t i = 0; i < length; i++)
        {
            DEV_SPI1->TX_DATA = send_buf[i];
            while ((DEV_SPI1->STA & DEV_SPIn_STA_TX_FULL));
        }
        while (!(DEV_SPI1->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));
        DEV_SPI1->CTL_f.SPI_CS = 0;
    }
    return HAL_OK;
}

/**
 * This function will receive data by spi without dma
 *
 * @param spi_port: The value ranges from 0 to 1
 * @param recv_buf: Data address to be received
 * @param length: Data length
 *
 * @return =0, HAL_OK
 */
HAL_StatusTypeDef hal_spi_receive(uint32_t spi_port, uint8_t *recv_buf, uint32_t length)
{
    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL |= (DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL_f.SPI_CS = 0;

        for (uint32_t i = 0; i < length; i++)
        {
            DEV_SPI0->TX_DATA = 0x00;

            while (!(DEV_SPI0->STA & DEV_SPIn_STA_TX_EMPTY));

            while ((DEV_SPI0->STA & DEV_SPIn_STA_RX_EMPTY));

            recv_buf[i] = DEV_SPI0->RX_DATA ;
        }

        while (!(DEV_SPI0->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI0->CTL_f.SPI_CS = 1;
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL |= (DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL_f.SPI_CS = 0;

        for (uint32_t i = 0; i < length; i++)
        {
            DEV_SPI1->TX_DATA = 0x00;

            while (!(DEV_SPI1->STA & DEV_SPIn_STA_TX_EMPTY));

            while ((DEV_SPI1->STA & DEV_SPIn_STA_RX_EMPTY));

            recv_buf[i] = DEV_SPI1->RX_DATA ;
        }

        while (!(DEV_SPI1->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI1->CTL_f.SPI_CS = 1;
    }

    return HAL_OK;
}

/**
 * This function will receive and send data by spi without dma
 *
 * @param spi_port: The value ranges from 0 to 1
 * @param send_buf: Data address to be sent
 * @param recv_buf: Data address to be received
 * @param length: Data length
 *
 * @return =0, HAL_OK
 */
HAL_StatusTypeDef hal_spi_transmit_receive(uint32_t spi_port, uint8_t *send_buf, uint8_t *recv_buf, uint32_t length)
{
    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL |= (DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL_f.SPI_CS = 0;

        for (uint32_t i = 0; i < length; i++)
        {
            DEV_SPI0->TX_DATA = send_buf[i];

            while (!(DEV_SPI0->STA & DEV_SPIn_STA_TX_EMPTY));

            while ((DEV_SPI0->STA & DEV_SPIn_STA_RX_EMPTY));

            recv_buf[i] = DEV_SPI0->RX_DATA ;
        }

        while (!(DEV_SPI0->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI0->CTL_f.SPI_CS = 1;
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL |= (DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL_f.SPI_CS = 0;

        for (uint32_t i = 0; i < length; i++)
        {
            DEV_SPI1->TX_DATA = send_buf[i];

            while (!(DEV_SPI1->STA & DEV_SPIn_STA_TX_EMPTY));

            while ((DEV_SPI1->STA & DEV_SPIn_STA_RX_EMPTY));

            recv_buf[i] = DEV_SPI1->RX_DATA ;
        }

        while (!(DEV_SPI1->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI1->CTL_f.SPI_CS = 1;
    }

    return HAL_OK;
}

/**
 * This function will initializes spi dma send handle
 *
 * @param spi_port: The value ranges from 0 to 1
 * @param dma_handle: dma handle
 *
 * @return =1
 */
int32_t hal_spi_tx_dma_init(int32_t spi_port, DMA_HandleTypeDef *dma_handle)
{
    DMA_InitTypeDef init_default = (DMA_InitTypeDef)hal_spi_tx_dma_config_default;
    dma_handle->init = (DMA_InitTypeDef)init_default;
    dma_handle->state = HAL_DMA_STATE_READY;
    return 1;
}

/**
 * This function will initializes spi dma receive handle
 *
 * @param spi_port: The value ranges from 0 to 1
 * @param dma_handle: dma handle
 *
 * @return =1
 */
int32_t hal_spi_rx_dma_init(int32_t spi_port, DMA_HandleTypeDef *dma_handle)
{
    DMA_InitTypeDef init_default = (DMA_InitTypeDef)hal_spi_rx_dma_config_default;
//  init_default.mode = DMA_Mode_Circular;//DMA_Mode_Circular;
    dma_handle->init = init_default;
    dma_handle->state = HAL_DMA_STATE_READY;
    return 1;
}


void hal_spi_tx_dma_start(DMA_HandleTypeDef *hdma, uint32_t srca_ddress, uint32_t data_length, int32_t spi_port, void *param)
{
    if (spi_port == SPI0_Port)
    {
        if (hdma->xfer_cplt_callback == NULL)
            hal_dma_start(hdma, srca_ddress, (uint32_t)&DEV_SPI0->TX_DATA, data_length, param);
        else
            hal_dma_start_it(hdma, srca_ddress, (uint32_t)&DEV_SPI0->TX_DATA, data_length, param);
    }
    else if (spi_port == SPI1_Port)
    {
        if (hdma->xfer_cplt_callback == NULL)
            hal_dma_start(hdma, srca_ddress, (uint32_t)&DEV_SPI1->TX_DATA, data_length, param);
        else
            hal_dma_start_it(hdma, srca_ddress, (uint32_t)&DEV_SPI1->TX_DATA, data_length, param);
    }
}


void hal_spi_rx_dma_start(DMA_HandleTypeDef *hdma, uint32_t dst_address, uint32_t data_length, int32_t spi_port, void *param)
{
    if (spi_port == SPI0_Port)
    {
        if (hdma->xfer_cplt_callback == NULL)
            hal_dma_start(hdma, (uint32_t)&DEV_SPI0->RX_DATA, dst_address, data_length, param);
        else
            hal_dma_start_it(hdma, (uint32_t)&DEV_SPI0->RX_DATA, dst_address, data_length, param);
    }
    else if (spi_port == SPI1_Port)
    {
        if (hdma->xfer_cplt_callback == NULL)
            hal_dma_start(hdma, (uint32_t)&DEV_SPI1->RX_DATA, dst_address, data_length, param);
        else
            hal_dma_start_it(hdma, (uint32_t)&DEV_SPI1->RX_DATA, dst_address, data_length, param);
    }
}

/**
 * This function will transmit data by spi with dma
 *
 * @param hdma: dma handle
 * @param spi_port: The value ranges from 0 to 1
 * @param send_buf: Data address to be send
 * @param length: Data length
 *
 * @return =0, HAL_OK
 */
HAL_StatusTypeDef hal_spi_transmit_dma(DMA_HandleTypeDef *hdma, uint32_t spi_port, uint8_t *send_buf, uint32_t length, void *param)
{
    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->IE &= ~(DEV_SPIn_IE_TX_DMA_EN | DEV_SPIn_IE_RX_DMA_EN) ;
        DEV_SPI0->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL |= (DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->IE |= DEV_SPIn_IE_TX_DMA_EN;
//        DEV_SPI0->CTL_f.SPI_CS = 0;
        hal_spi_tx_dma_start(hdma, (uint32_t)send_buf, length, spi_port, param);
//          while (!(DEV_SPI0->STA & DEV_SPIn_STA_TX_EMPTY));
//
//          uint32_t chx = hdma->init.channel;
//
//          while (!(hal_dma_get_pd(chx)));
//
//          hal_dma_clear_pd(chx);
//
//          while (!(DEV_SPI0->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));
//
//          DEV_SPI0->CTL_f.SPI_CS = 1;
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->IE &= ~(DEV_SPIn_IE_TX_DMA_EN | DEV_SPIn_IE_RX_DMA_EN) ;
        DEV_SPI1->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL |= (DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->IE |= DEV_SPIn_IE_TX_DMA_EN;
//        DEV_SPI1->CTL_f.SPI_CS = 0;
        hal_spi_tx_dma_start(hdma, (uint32_t)send_buf, length, spi_port, NULL);
//        while (!(DEV_SPI1->STA & DEV_SPIn_STA_TX_EMPTY));
//
//        uint32_t chx = hdma->init.channel;
//
//        while (!(hal_dma_get_pd(chx)));
//
//        hal_dma_clear_pd(chx);
//
//        while (!(DEV_SPI1->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));
//
//        DEV_SPI1->CTL_f.SPI_CS = 1;
    }

    return HAL_OK;
}

/**
 * This function will receive data by spi with dma
 *
 * @param hdma: dma handle
 * @param spi_port: The value ranges from 0 to 1
 * @param recv_buf: Data address to be received
 * @param length: Data length
 *
 * @return =0, HAL_OK
 */
HAL_StatusTypeDef hal_spi_receive_dma(DMA_HandleTypeDef *hdma, uint32_t spi_port, uint8_t *recv_buf, uint32_t length)
{
    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL |= (DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->RX_NUM_f.RX_NUM = length;
        DEV_SPI0->CTL_f.SPI_CS = 0;
        hal_spi_rx_dma_start(hdma, (uint32_t)recv_buf, length, spi_port, NULL);
        DEV_SPI0->RX_NUM_f.RX_START = 1;
        uint32_t chx = hdma->init.channel;

//      while(  !(DEV_DMAC->DMA_PD & (1<<chx))  );
//      DEV_DMAC->DMA_PD = (1<<chx);
        while (!(hal_dma_get_pd(chx)));

        hal_dma_clear_pd(chx);

        while (!(DEV_SPI0->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI0->CTL_f.SPI_CS = 1;
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL |= (DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->RX_NUM_f.RX_NUM = length;
        DEV_SPI1->CTL_f.SPI_CS = 0;
        hal_spi_rx_dma_start(hdma, (uint32_t)recv_buf, length, spi_port, NULL);
        DEV_SPI1->RX_NUM_f.RX_START = 1;
        uint32_t chx = hdma->init.channel;

//      while(  !(DEV_DMAC->DMA_PD & (1<<chx))  );
//      DEV_DMAC->DMA_PD = (1<<chx);
        while (!(hal_dma_get_pd(chx)));

        hal_dma_clear_pd(chx);

        while (!(DEV_SPI1->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI1->CTL_f.SPI_CS = 1;
    }

    return HAL_OK;
}

/**
 * This function will receive and send data by spi with dma
 *
 * @param hdma: struch spi_dma_handle contains receice handle and send handle
 * @param spi_port: The value ranges from 0 to 1
 * @param send_buf: Data address to be send
 * @param recv_buf: Data address to be received
 * @param length: Data length
 *
 * @return =0, HAL_OK
 */
HAL_StatusTypeDef hal_spi_transmit_receive_dma(spi_dma_handle *hdma, uint32_t spi_port, uint8_t *send_buf, uint8_t *recv_buf, uint32_t length)
{
    DMA_HandleTypeDef *dma_handle_tx = &hdma->dma_handle_tx;
    DMA_HandleTypeDef *dma_handle_rx = &hdma->dma_handle_rx;

    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL |= (DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI0->CTL_f.SPI_CS = 0;
        hal_spi_rx_dma_start(dma_handle_rx, (uint32_t)recv_buf, length, spi_port, NULL);
        hal_spi_tx_dma_start(dma_handle_tx, (uint32_t)send_buf, length, spi_port, NULL);

        while (!(DEV_SPI0->STA & DEV_SPIn_STA_TX_EMPTY));

        uint32_t chx = dma_handle_rx->init.channel;

//      while(  !(DEV_DMAC->DMA_PD & (1<<chx))  );
//      DEV_DMAC->DMA_PD = (1<<chx);
        while (!(hal_dma_get_pd(chx)));

        hal_dma_clear_pd(chx);

        while (!(DEV_SPI0->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI0->CTL_f.SPI_CS = 1;
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->CTL &= ~(DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL |= (DEV_SPIn_CTL_SPI_TX_EN_ENABLE | DEV_SPIn_CTL_SPI_RX_EN_ENABLE | DEV_SPIn_CTL_SPI_EN_ENABLE);
        DEV_SPI1->CTL_f.SPI_CS = 0;
        hal_spi_rx_dma_start(dma_handle_rx, (uint32_t)recv_buf, length, spi_port, NULL);
        hal_spi_tx_dma_start(dma_handle_tx, (uint32_t)send_buf, length, spi_port, NULL);

        while (!(DEV_SPI1->STA & DEV_SPIn_STA_TX_EMPTY));

        uint32_t chx = dma_handle_rx->init.channel;

//      while(  !(DEV_DMAC->DMA_PD & (1<<chx))  );
//      DEV_DMAC->DMA_PD = (1<<chx);
        while (!(hal_dma_get_pd(chx)));

        hal_dma_clear_pd(chx);

        while (!(DEV_SPI1->STA & DEV_SPIn_STA_SPI_IDLE_SPIIDLE));

        DEV_SPI1->CTL_f.SPI_CS = 1;
    }

    return HAL_OK;
}

/**
 * This function will set spi cpol cpha value
 *
 * @param spi_port: The value ranges from 0 to 1
 * @param spi_clk_mode: The value ranges from 0 to 3
 *                      0: cpol=0, cpha=0
 *                      1: cpol=0, cpha=1
 *                      2: cpol=1, cpha=0
 *                      3: cpol=1, cpha=1
 *
 * @return =0, HAL_OK
 */
void hal_spi_set_cpol_cpha(uint32_t spi_port, spi_clk_mode_t spi_clk_mode)
{
    if (spi_port == SPI0_Port)
    {
        DEV_SPI0->CTL &= ~DEV_SPIn_CTL_SPI_MODE_MASK;
        DEV_SPI0->CTL |= spi_clk_mode;
    }
    else if (spi_port == SPI1_Port)
    {
        DEV_SPI1->CTL &= ~DEV_SPIn_CTL_SPI_MODE_MASK;
        DEV_SPI1->CTL |= spi_clk_mode;
    }
}

