/**
 ******************************************************************************
 * @file    kpm32xx_ddl_uart.h
 * @author  Kiwi Software Team
 * @brief   Header file of SCI UART DDL module.
 * @note
 *		   V1.0.0, 2024/12/20.
 *
 * 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.
 ******************************************************************************
 */

#ifndef __KPM32xx_DDL_SCI_UART_H
#define __KPM32xx_DDL_SCI_UART_H

#ifdef __cplusplus
extern "C" {
#endif

#include "kpm32xx_ddl_def.h"
#include "kpm32xx_ddl_sci_common.h"


/* SCI UART init Structure definition */
typedef struct
{
	uint32_t clkPres;         /* clkPres and brDiv1And2 are used for SCI UART baudrate */
	uint32_t brDiv1And2;      /* clkPres and brDiv1And2 are used for SCI UART baudrate */
	uint32_t wordLength;      /* SCI UART data-frame length */
	uint32_t stopBits;        /* SCI UART stop bits */
	uint32_t parity;          /* SCI UART parity */
	uint32_t mlsb;            /* MSB or LSB first*/
	uint32_t dataInv;         /* Data Inversion */
	uint32_t mpSupported;     /* Multi-processor supported */
	uint32_t mpAddress;       /* The address in Multi-Processor mode */
	uint32_t dataFlt;         /* SCI UART Data filter function */
	uint32_t hwFlwCtrl;       /* SCI UART hardware flow control */
} SCIUART_Init_T;


/* SCI UART error types */
#define DDL_SCIUART_ERROR_NONE                              ((uint32_t)0x00000000U)    /* No error                */
#define DDL_SCIUART_ERROR_PE                                ((uint32_t)0x00000001U)    /* parity error            */
#define DDL_SCIUART_ERROR_FE                                ((uint32_t)0x00000002U)    /* Frame error             */
#define DDL_SCIUART_ERROR_ORE                               ((uint32_t)0x00000004U)    /* Overrun error           */
#define DDL_SCIUART_ERROR_DMA                               ((uint32_t)0x00000008U)    /* DMA transfer error      */

/* SCI UART stop bits */
#define SCIUART_STOPBITS_1                                  (((uint32_t)0x00000000U) << SCI_MUART_STPLEN_Pos)     /* UART frame with 1 stop bit    */
#define SCIUART_STOPBITS_2                                  (((uint32_t)0x00000001U) << SCI_MUART_STPLEN_Pos)     /* UART frame with 2 stop bits   */

/* SCI UART parity */
#define SCIUART_PARITY_NONE                                 (((uint32_t)0x00000000U) << SCI_MUART_PRTSEL_Pos)   /* No parity   */
#define SCIUART_PARITY_MARK                                 (((uint32_t)0x00000001U) << SCI_MUART_PRTSEL_Pos)   /* Mark        */
#define SCIUART_PARITY_ODD                                  (((uint32_t)0x00000002U) << SCI_MUART_PRTSEL_Pos)   /* Odd parity  */
#define SCIUART_PARITY_EVEN                                 (((uint32_t)0x00000003U) << SCI_MUART_PRTSEL_Pos)   /* Even parity */

/* SCI UART communication data-frame length */
#define SCIUART_WORDLENGTH_7B                               (((uint32_t)0x00000002U) << SCI_MUART_DATLEN_Pos)
#define SCIUART_WORDLENGTH_8B                               (((uint32_t)0x00000000U) << SCI_MUART_DATLEN_Pos)
#define SCIUART_WORDLENGTH_9B                               (((uint32_t)0x00000003U) << SCI_MUART_DATLEN_Pos)

/* MSB or LSB first*/
#define SCIUART_LSB_FIRST                                   SCI_MC_DATDIR
#define SCIUART_MSB_FIRST                                   0


#define SCIUART_HWCTRL_NONE                                 0x00000000UL
#define SCIUART_HWCTRL_RTS_CTS                              (SCI_MUART_CTSEN | SCI_MUART_RTSEN)

/* supported SCI UART baudrate */
#define SCIUART_BAUDRATE_BPS_1200                           1200
#define SCIUART_BAUDRATE_BPS_2400                           2400
#define SCIUART_BAUDRATE_BPS_4800                           4800
#define SCIUART_BAUDRATE_BPS_9600                           9600
#define SCIUART_BAUDRATE_BPS_19200                          19200
#define SCIUART_BAUDRATE_BPS_38400                          38400
#define SCIUART_BAUDRATE_BPS_57600                          57600
#define SCIUART_BAUDRATE_BPS_115200                         115200

#define IS_SCIUART_BAUDRATE(__BAUDRATE__)                    (((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_1200)    || \
										                      ((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_2400)    || \
										                      ((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_4800)    || \
										                      ((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_9600)    || \
										                      ((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_19200)   || \
										                      ((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_38400)   || \
										                      ((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_57600)   || \
										                      ((__BAUDRATE__) == SCIUART_BAUDRATE_BPS_115200))


#define IS_SCIUART_WORD_LENGTH(__LENGTH__)                    (((__LENGTH__) == SCIUART_WORDLENGTH_7B) || \
										                       ((__LENGTH__) == SCIUART_WORDLENGTH_8B) || \
										                       ((__LENGTH__) == SCIUART_WORDLENGTH_9B))

#define IS_SCIUART_STOPBITS(__STOPBITS__)                     (((__STOPBITS__) == SCIUART_STOPBITS_1) || ((__STOPBITS__) == SCIUART_STOPBITS_2))

#define IS_SCIUART_PARITY(__PARITY__)                         (((__PARITY__) == SCIUART_PARITY_NONE)   || \
										                       ((__PARITY__) == SCIUART_PARITY_MARK)   || \
                                                               ((__PARITY__) == SCIUART_PARITY_EVEN)   || \
                                                               ((__PARITY__) == SCIUART_PARITY_ODD))

#define IS_SCIUART_MODE(__MODE__)                             (((__MODE__) == SCIUART_MODE_RX) || ((__MODE__) == SCIUART_MODE_TX))

#define IS_SCIUART_INSTANCE(__INSTANCE__)	                  (((__INSTANCE__) == SCI0) || ((__INSTANCE__) == SCI1) || ((__INSTANCE__) == SCI2))

/* set SCI UART DMA enable */
#define __DDL_SCIUART_DMA_ENABLE(__INSTANCE__)                  SET_BIT((__INSTANCE__)->MC, SCI_MC_DMAEN)

/* set SCI UART DMA disable */
#define __DDL_SCIUART_DMA_DISABLE(__INSTANCE__)                 CLEAR_BIT((__INSTANCE__)->MC, SCI_MC_DMAEN)

/* set SCI UART TX enable */
#define __DDL_SCIUART_TX_ENABLE(__INSTANCE__)                   SET_BIT((__INSTANCE__)->MC, SCI_MC_TXEN)

/* set SCI UART TX disable */
#define __DDL_SCIUART_TX_DISABLE(__INSTANCE__)                  CLEAR_BIT((__INSTANCE__)->MC, SCI_MC_TXEN)

/* set SCI UART RX enable */
#define __DDL_SCIUART_RX_ENABLE(__INSTANCE__)                   SET_BIT((__INSTANCE__)->MC, SCI_MC_RXEN)

/* set SCI UART RX disable */
#define __DDL_SCIUART_RX_DISABLE(__INSTANCE__)                  CLEAR_BIT((__INSTANCE__)->MC, SCI_MC_RXEN)


/**
  * @brief  Configure the elements of structure SCIUART_Init_T to default values.
  *
  * @param  pSCIUartStruct Pointer to a SCIUART_Init_T structure that contains
  *                  the configuration information for the given SCI UART module.
  *
  * @retval None
  */
void DDL_SCIUART_StructInit(SCIUART_Init_T *pSCIUartStruct);

/**
  * @brief  Initializes the SCI UART by the specified parameters in the SCIUART_Init_T.
  *
  * @param  SCIx Pointer to SCI UART instance.
  * @param  pSCIUartStruct Pointer to a SCIUART_Init_T structure that contains
  *                  the configuration information for the given SCI UART module.
  *
  * @retval DDL status
  */
DDL_Status_T DDL_SCIUART_Init(SCI_Type *SCIx, SCIUART_Init_T *pSCIUartStruct);


/**
  * @brief  Enable SCI UART TX or RX interrupt.
  *
  * @param  SCIx Pointer to SCI UART instance.
  * @param  intrMask SCI UART TX and RX mask.
  *
  * @retval None
  */
void DDL_SCIUART_IntEnable(SCI_Type *SCIx, uint32_t intrMask);

/**
  * @brief  Disable SCI UART TX or RX interrupt.
  *
  * @param  SCIx Pointer to SCI UART instance.
  * @param  intrMask SCI UART TX and RX mask.
  *
  * @retval None
  */
void DDL_SCIUART_IntDisable(SCI_Type *SCIx, uint32_t intrMask);

/**
  * @brief  Write one frame of data into SCI UART.
  * @param  SCIx  SCI instance.
  *
  * @param  data  the value to be writen into SCI UART module.
  *
  * @retval none.
  */
void DDL_SCIUART_WriteData(SCI_Type *SCIx, uint16_t data);

/**
  * @brief  Get one byte from SCI UART.
  * @param  SCIx  SCI instance.
  *
  * @retval uint16_t type.
  */
uint16_t DDL_SCIUART_GetData(SCI_Type *SCIx);

/**
  * @brief  Put one byte into SCI UART.
  * @param  SCIx  SCI instance.
  * @param  ch    the value to be put into SCI UART module.
  *
  * @retval none
  */
void DDL_SCIUART_WaitPutCharCmplt(SCI_Type *SCIx, uint8_t ch);

/**
  * @brief  Get one byte from SCI UART.
  * @param  SCIx  SCI instance.
  *
  * @retval uint16_t type.
  */
uint16_t DDL_SCIUART_WaitGetCharCmplt(SCI_Type *SCIx);


/**
  * @brief  Transmits an amount of data through polling mode.
  *
  * @param  SCIx Pointer to SCI UART instance.
  * @param  pData    pointer to data buffer.
  * @param  size     the amount of data frame to be sent.
  * @param  timeout  timeout duration.
  *
  * @retval DDL status
  */
DDL_Status_T DDL_SCIUART_Transmit(SCI_Type *SCIx, uint8_t *pData, uint16_t size, uint32_t timeout);

/**
  * @brief  Receives an amount of data through polling mode.
  *
  * @param  SCIx     SCIx Pointer to SCI UART instance.
  * @param  pData    pointer to data buffer.
  * @param  size     the amount of data frame to receive.
  * @param  timeout  timeout duration.
  *
  * @retval DDL status
  */
DDL_Status_T DDL_SCIUART_Receive(SCI_Type *SCIx, uint8_t *pData, uint16_t size, uint32_t timeout);


#ifdef __cplusplus
}
#endif

#endif /* __KPM32xx_DDL_SCI_UART_H */
