/**
  *****************************************************************************************************
  * @file    main.c
  * @author  Kiwi Software Team
  * @brief   This example code demonstrates how SCI UART works.
  *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *
  *   3. Neither the name of the copyright holder nor the names of its contributors
  *      may be used to endorse or promote products derived from this software without
  *      specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************************************
  */
#include "main.h"
#include "kpm32xx_demoboard_ddl.h"



#define __MAXIMUM_RD_LENGTH__       8
#define __FIRST_TRANS_THEN_RECEIVE__       1


static volatile uint8_t gUartTxCmplt = 0;
static volatile uint8_t gUartRxCmplt = 0;
static volatile uint8_t gRecvCont = 0;
static volatile uint8_t gTranCont = 0;

uint8_t wrBuf[__MAXIMUM_RD_LENGTH__]  = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
uint8_t rdBuf[__MAXIMUM_RD_LENGTH__]  = {0};


/** Called once when one frame data is received */
void DDL_SCIUART_OneFrmRxCpltCallback(SCI_Type *SCIx)
{
	rdBuf[gRecvCont] = DDL_SCIUART_GetData(SCIx);

	gRecvCont ++;
	/* all data received */
	if(gRecvCont == __MAXIMUM_RD_LENGTH__)
	{
        DDL_SCIUART_IntDisable(SCIx, SCI_IE_FRMERR | SCI_IE_PRTERR | SCI_IE_OVRERR | SCI_IE_RXEND);
        __DDL_SCIUART_RX_DISABLE(SCIx);
		gUartRxCmplt = 1;
	}
}


/** Called once when one frame of data has been sent-out */
void DDL_SCIUART_OneFrmTxCpltCallback(SCI_Type *SCIx)
{
	if (gTranCont > 1)
	{
        DDL_SCIUART_WriteData(SCIx,(wrBuf[__MAXIMUM_RD_LENGTH__ - gTranCont+1]));
		gTranCont--;
	}
	else
	{
        DDL_SCIUART_IntDisable(SCIx, SCI_IE_FRMERR | SCI_IE_PRTERR | SCI_IE_OVRERR | SCI_IE_TXEND);
        __DDL_SCIUART_TX_DISABLE(SCIx);
		gUartTxCmplt = 1;
	}
}


/**
  * @brief  This function is implemented for UART PinMux configuration.
  * @param  None
  * @retval None
  */
void UART_PinMux_Config(void)
{
    DDL_GPIO_Config2AltFunc(GPIOB, GPIO_PIN_3, GPIOB3_AF0_SCI2_TX_SDA_MOSI);
    DDL_GPIO_Config2AltFunc(GPIOB, GPIO_PIN_4, GPIOB4_AF0_SCI2_RX_MISO);
}


/**
  * @brief  This function is implemented for system clock configuration.
  *         where:
  *         System Clock source            = PLL (HIRC)
  *         System Clock frequency         = 100MHz
  * @param  None
  * @retval None
  */
void SystemClock_Config(void)
{
	RCC_PLLInit_T pllInitStruct    = {0};
	RCC_ClkInit_T rccClkInitStruct = {0};

	DDL_RCC_PllStructInit(&pllInitStruct);
	/* FCLK : 100MHz */
	pllInitStruct.pllPrescaler  = 4;
	if (DDL_RCC_PllConfig(&pllInitStruct) != DDL_OK)
	{
		while(1) ;
	}

	/* Select PLL as system clock source */
	rccClkInitStruct.sysClkSource  = RCC_SYSCLKSOURCE_PLLCLK;
	rccClkInitStruct.sysClkDivider = 0;
	if (DDL_RCC_ClkSrcConfig(&rccClkInitStruct) != DDL_OK)
	{
		while(1) ;
	}
}




/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
    SCIUART_Init_T pSCIUartStruct;
    DDL_Init();
    SystemClock_Config();
	DDL_Delay(1000);

    UART_PinMux_Config();
    DDL_SCI_Instance_Active(SCI2);
	DDL_SCIUART_StructInit(&pSCIUartStruct);

    /* 19200 */
    pSCIUartStruct.clkPres     = 3;
	pSCIUartStruct.brDiv1And2  = 0xA1 << 16;

    pSCIUartStruct.wordLength  = SCIUART_WORDLENGTH_8B;
    pSCIUartStruct.mlsb        = SCIUART_LSB_FIRST;
    pSCIUartStruct.parity      = SCIUART_PARITY_EVEN;
    pSCIUartStruct.stopBits    = SCIUART_STOPBITS_1;

    DDL_SCIUART_Init(SCI2, &pSCIUartStruct);
    NVIC_SetPriority(SCI2_IRQn, __PREEMPT_INTRERRUPT_PRIORITY_0__);

	while(1)
	{
#ifdef __FIRST_TRANS_THEN_RECEIVE__
        Uart_TransData_RxTx_Mutual(SCI2, UART_TX);
        gTranCont = __MAXIMUM_RD_LENGTH__;
        DDL_SCIUART_User_Transmit_IT(SCI2, (uint8_t *)wrBuf, __MAXIMUM_RD_LENGTH__);
        /* Wait till data-transmission completes */
		while(gUartTxCmplt == 0);
		gUartTxCmplt = 0;

        Uart_TransData_RxTx_Mutual(SCI2, UART_RX);

        gRecvCont = 0;
        DDL_SCIUART_User_Receive_IT(SCI2);
        /* Wait till data-reception completes */
		while(gUartRxCmplt == 0);
		gUartRxCmplt = 0;
#else
        Uart_TransData_RxTx_Mutual(SCI2, UART_RX);

        gRecvCont = 0;
        DDL_SCIUART_User_Receive_IT(SCI2);
        /* Wait till data-reception completes */
		while(gUartRxCmplt == 0);
		gUartRxCmplt = 0;

        Uart_TransData_RxTx_Mutual(SCI2, UART_TX);
        gTranCont = __MAXIMUM_RD_LENGTH__;
        DDL_SCIUART_User_Transmit_IT(SCI2, (uint8_t *)wrBuf, __MAXIMUM_RD_LENGTH__);
        /* Wait till data-transmission completes */
		while(gUartTxCmplt == 0);
		gUartTxCmplt = 0;
#endif
	}
}

